From eddfbb3b7c5a7fb849299ae630e83369e2580785 Mon Sep 17 00:00:00 2001 From: Zane Meyers Date: Tue, 4 Nov 2025 16:43:34 -0500 Subject: [PATCH] vault backup: 2025-11-04 16:43:34 --- .obsidian/community-plugins.json | 3 +- .obsidian/plugins/novel-word-count/data.json | 6270 +++++++++++++++++ .obsidian/plugins/novel-word-count/main.js | 2065 ++++++ .../plugins/novel-word-count/manifest.json | 11 + .obsidian/plugins/novel-word-count/styles.css | 129 + 1960-04-04_durant-daily-democrat.md | 1 + 2025-11-04_belle-meade-director-review.md | 99 + 90-day-performance-review.md | 1 + accubid-setup.md | 12 + construction-estimating-using-excel.md | 2 +- convex-hull.md | 72 + estimator-skills.md | 1 + ibc-construction-types.md | 2 +- ibc-occupancy-classifications.md | 24 + ...ustrated-guide-to-electrical-estimating.md | 2 +- misc-budgets-takeoff.md | 70 +- nfpa-101_life-safety-code.md | 1 + nfpa-70_100_definitions.md | 1 + ...quirements-for-electrical-installations.md | 1 + nfpa-70_210_branch-circuits.md | 1 + nfpa-70_215_feeders.md | 1 + nfpa-70_220_load-calculations.md | 1 + nfpa-70_300_general-requirements.md | 1 + nfpa-70_310_conductors_for_general_wiring.md | 1 + nfpa-70_314_boxes.md | 1 + nfpa-70_430_motors.md | 1 + nfpa-70_450_transformers.md | 1 + nfpa-70_520_theaters.md | 1 + nfpa-70_national-electric-code.md | 1 + nfpa-72_national-fire-alarm-code.md | 1 + note-taking.md | 12 +- sleeving-takeoff.md | 13 +- the-failure-of-risk-management.md | 80 +- the-story-of-ymar.md | 1 + topics-to-revisit.md | 4 - wiring-method-selection.md | 9 +- 36 files changed, 8811 insertions(+), 86 deletions(-) create mode 100644 .obsidian/plugins/novel-word-count/data.json create mode 100644 .obsidian/plugins/novel-word-count/main.js create mode 100644 .obsidian/plugins/novel-word-count/manifest.json create mode 100644 .obsidian/plugins/novel-word-count/styles.css create mode 100644 2025-11-04_belle-meade-director-review.md create mode 100644 convex-hull.md create mode 100644 ibc-occupancy-classifications.md diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index b781dbf..1f48119 100644 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -13,5 +13,6 @@ "recent-files-obsidian", "obsidian-latex-suite", "obsidian-pretty-bibtex", - "obsidian-tikzjax" + "obsidian-tikzjax", + "novel-word-count" ] \ No newline at end of file diff --git a/.obsidian/plugins/novel-word-count/data.json b/.obsidian/plugins/novel-word-count/data.json new file mode 100644 index 0000000..41698b2 --- /dev/null +++ b/.obsidian/plugins/novel-word-count/data.json @@ -0,0 +1,6270 @@ +{ + "settings": { + "useAdvancedFormatting": true, + "countType": "word", + "countConfig": { + "customSuffix": "w", + "$sessionCountType": "word" + }, + "countType2": "readtime", + "countConfig2": { + "$sessionCountType": "word" + }, + "countType3": "none", + "countConfig3": { + "$sessionCountType": "word" + }, + "pipeSeparator": "|", + "abbreviateDescriptions": false, + "alignment": "inline", + "showSameCountsOnFolders": true, + "folderCountType": "word", + "folderCountConfig": { + "customSuffix": "w", + "$sessionCountType": "word" + }, + "folderCountType2": "none", + "folderCountConfig2": { + "$sessionCountType": "word" + }, + "folderCountType3": "none", + "folderCountConfig3": { + "$sessionCountType": "word" + }, + "folderPipeSeparator": "|", + "folderAbbreviateDescriptions": false, + "folderAlignment": "inline", + "showSameCountsOnRoot": true, + "rootCountType": "word", + "rootCountConfig": { + "customSuffix": "w", + "$sessionCountType": "word" + }, + "rootCountType2": "none", + "rootCountConfig2": { + "$sessionCountType": "word" + }, + "rootCountType3": "none", + "rootCountConfig3": { + "$sessionCountType": "word" + }, + "rootPipeSeparator": "|", + "rootAbbreviateDescriptions": false, + "showAdvanced": true, + "labelOpacity": 0.75, + "wordsPerMinute": 265, + "charsPerMinute": 500, + "wordsPerPage": 300, + "charsPerPage": 1500, + "charsPerPageIncludesWhitespace": false, + "characterCountType": "AllCharacters", + "pageCountType": "ByWords", + "includeDirectories": "", + "excludeComments": false, + "excludeCodeBlocks": false, + "excludeNonVisibleLinkPortions": true, + "excludeFootnotes": false, + "momentDateFormat": "", + "debugMode": false + }, + "cachedCounts": { + "4913": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": null, + "createdDate": 1756122472403, + "modifiedDate": 1756122472403, + "sizeInBytes": 0, + "sessionStart": { + "noteCount": 1, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "2025-11-04_belle-meade-director-review.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 288, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.96, + "characterCount": 2073, + "nonWhitespaceCharacterCount": 1725, + "newlineCount": 91, + "readingTimeInMinutes": 1.0867924528301887, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1762285925701, + "modifiedDate": 1762287950684, + "sizeInBytes": 2231, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.96, + "wordCount": 288, + "characterCount": 2073, + "nonWhitespaceCharacterCount": 1725, + "newlineCount": 91 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/complete", + "type/minutes" + ], + "title": "2025-11-04 Belle Meade Director Review" + } + }, + "ibc-occupancy-classifications.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 102, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.34, + "characterCount": 632, + "nonWhitespaceCharacterCount": 526, + "newlineCount": 15, + "readingTimeInMinutes": 0.3849056603773585, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1762271559142, + "modifiedDate": 1762272087544, + "sizeInBytes": 816, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.34, + "wordCount": 102, + "characterCount": 632, + "nonWhitespaceCharacterCount": 526, + "newlineCount": 15 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/other-for-now", + "destiny/permanent", + "status/incomplete", + "topic/construction", + "type/encyclopedia" + ], + "title": "IBC Occupancy Classifications" + } + }, + "convex-hull.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 107, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.3566666666666667, + "characterCount": 1330, + "nonWhitespaceCharacterCount": 942, + "newlineCount": 68, + "readingTimeInMinutes": 0.4037735849056604, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1762261983998, + "modifiedDate": 1762262044463, + "sizeInBytes": 1426, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.3566666666666667, + "wordCount": 107, + "characterCount": 1330, + "nonWhitespaceCharacterCount": 942, + "newlineCount": 68 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [], + "title": "Convex Hull" + } + }, + "topics-to-revisit.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 44, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.14666666666666667, + "characterCount": 293, + "nonWhitespaceCharacterCount": 237, + "newlineCount": 18, + "readingTimeInMinutes": 0.1660377358490566, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1762261213965, + "modifiedDate": 1762261992771, + "sizeInBytes": 403, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.14666666666666667, + "wordCount": 44, + "characterCount": 293, + "nonWhitespaceCharacterCount": 237, + "newlineCount": 18 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [], + "title": "Topics To Revisit" + } + }, + "note-taking.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 157, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5233333333333333, + "characterCount": 939, + "nonWhitespaceCharacterCount": 756, + "newlineCount": 44, + "readingTimeInMinutes": 0.5924528301886792, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1762261213965, + "modifiedDate": 1762290731801, + "sizeInBytes": 1060, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5233333333333333, + "wordCount": 157, + "characterCount": 939, + "nonWhitespaceCharacterCount": 756, + "newlineCount": 44 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/organization" + ], + "title": "Note-Taking" + } + }, + "write-more-philosophy.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 54, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.18, + "characterCount": 441, + "nonWhitespaceCharacterCount": 351, + "newlineCount": 22, + "readingTimeInMinutes": 0.2037735849056604, + "linkCount": 4, + "embedCount": 0, + "aliases": [], + "createdDate": 1762207228110, + "modifiedDate": 1762261213965, + "sizeInBytes": 582, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.18, + "wordCount": 54, + "characterCount": 441, + "nonWhitespaceCharacterCount": 351, + "newlineCount": 22 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "type/task" + ], + "title": "Write More Philosophy" + } + }, + "wiring-device-research.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 121, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.4033333333333333, + "characterCount": 993, + "nonWhitespaceCharacterCount": 823, + "newlineCount": 27, + "readingTimeInMinutes": 0.45660377358490567, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1761327632354, + "modifiedDate": 1761582374833, + "sizeInBytes": 1172, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.4033333333333333, + "wordCount": 121, + "characterCount": 993, + "nonWhitespaceCharacterCount": 823, + "newlineCount": 27 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/incomplete", + "type/encyclopedia" + ], + "title": "Wiring Device Selection" + } + }, + "wiring-method-selection.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 703, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 2.3433333333333333, + "characterCount": 5587, + "nonWhitespaceCharacterCount": 4208, + "newlineCount": 210, + "readingTimeInMinutes": 2.6528301886792454, + "linkCount": 6, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472505, + "modifiedDate": 1762268497276, + "sizeInBytes": 5927, + "sessionStart": { + "noteCount": 1, + "pageCount": 2.3433333333333333, + "wordCount": 703, + "characterCount": 5587, + "nonWhitespaceCharacterCount": 4208, + "newlineCount": 210 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/incomplete", + "type/guide", + "authorship/original" + ], + "title": "Wiring Method Selection" + } + }, + "windows-setup.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 132, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.44, + "characterCount": 927, + "nonWhitespaceCharacterCount": 737, + "newlineCount": 61, + "readingTimeInMinutes": 0.4981132075471698, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760028465092, + "modifiedDate": 1761314347369, + "sizeInBytes": 1146, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.44, + "wordCount": 132, + "characterCount": 927, + "nonWhitespaceCharacterCount": 737, + "newlineCount": 61 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/meta", + "type/guide", + "authorship/original" + ], + "title": "Windows Setup" + } + }, + "when-i-die.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 405, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.35, + "characterCount": 2275, + "nonWhitespaceCharacterCount": 1837, + "newlineCount": 93, + "readingTimeInMinutes": 1.528301886792453, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761047128950, + "modifiedDate": 1761315862832, + "sizeInBytes": 2478, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.35, + "wordCount": 405, + "characterCount": 2275, + "nonWhitespaceCharacterCount": 1837, + "newlineCount": 93 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/uncertain", + "status/draft", + "type/anecdote", + "topic/hobbies" + ], + "title": "when i die", + "changelog": { + "2025-10-21": "v1 draft and initial commentary" + } + } + }, + "two-way-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 101, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.33666666666666667, + "characterCount": 866, + "nonWhitespaceCharacterCount": 721, + "newlineCount": 36, + "readingTimeInMinutes": 0.38113207547169814, + "linkCount": 2, + "embedCount": 0, + "aliases": [ + "2-way-communication", + "area-of-rescue", + "two-way-communication" + ], + "createdDate": 1756122472420, + "modifiedDate": 1761667129107, + "sizeInBytes": 1114, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.33666666666666667, + "wordCount": 101, + "characterCount": 866, + "nonWhitespaceCharacterCount": 721, + "newlineCount": 36 + }, + "frontmatter": { + "id": null, + "aliases": [ + "2-way-communication", + "area-of-rescue", + "two-way-communication" + ], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/standalone-systems", + "status/draft", + "type/guide" + ], + "title": "Two-Way Takeoff" + } + }, + "voltage-drop.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 226, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.7533333333333333, + "characterCount": 1791, + "nonWhitespaceCharacterCount": 1448, + "newlineCount": 99, + "readingTimeInMinutes": 0.8528301886792453, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1762197369134, + "modifiedDate": 1762197464462, + "sizeInBytes": 1942, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.7533333333333333, + "wordCount": 226, + "characterCount": 1791, + "nonWhitespaceCharacterCount": 1448, + "newlineCount": 99 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction/electrical" + ], + "title": "Voltage Drop" + } + }, + "units-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 328, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.0933333333333333, + "characterCount": 2924, + "nonWhitespaceCharacterCount": 2381, + "newlineCount": 109, + "readingTimeInMinutes": 1.2377358490566037, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472530, + "modifiedDate": 1761938473061, + "sizeInBytes": 3102, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.0933333333333333, + "wordCount": 328, + "characterCount": 2924, + "nonWhitespaceCharacterCount": 2381, + "newlineCount": 109 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/units", + "status/draft", + "type/guide" + ], + "title": "Unit Takeoff" + } + }, + "uncertainty.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 314, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.0466666666666666, + "characterCount": 2373, + "nonWhitespaceCharacterCount": 1985, + "newlineCount": 91, + "readingTimeInMinutes": 1.1849056603773584, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472529, + "modifiedDate": 1761683785752, + "sizeInBytes": 2559, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.0466666666666666, + "wordCount": 314, + "characterCount": 2373, + "nonWhitespaceCharacterCount": 1985, + "newlineCount": 91 + }, + "frontmatter": { + "id": "uncertainty", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/risk", + "type/encyclopedia" + ], + "title": "Uncertainty" + } + }, + "traditional-estimating-methods.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 491, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.6366666666666667, + "characterCount": 3183, + "nonWhitespaceCharacterCount": 2658, + "newlineCount": 85, + "readingTimeInMinutes": 1.8528301886792453, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472528, + "modifiedDate": 1761679741745, + "sizeInBytes": 3379, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.6366666666666667, + "wordCount": 491, + "characterCount": 3183, + "nonWhitespaceCharacterCount": 2658, + "newlineCount": 85 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "topic/estimating", + "destiny/uncertain", + "status/incomplete", + "type/philosophy", + "authorship/original" + ], + "title": "Traditional Estimating Methods" + } + }, + "the-story-of-ymar.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760960478434, + "modifiedDate": 1762291321585, + "sizeInBytes": 5460, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "this-notebook.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 324, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.08, + "characterCount": 2013, + "nonWhitespaceCharacterCount": 1650, + "newlineCount": 71, + "readingTimeInMinutes": 1.2226415094339622, + "linkCount": 6, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472526, + "modifiedDate": 1761077133326, + "sizeInBytes": 2229, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.08, + "wordCount": 324, + "characterCount": 2013, + "nonWhitespaceCharacterCount": 1650, + "newlineCount": 71 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/meta", + "type/encyclopedia" + ], + "title": "This Notebook" + } + }, + "TODO.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 56, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.18666666666666668, + "characterCount": 509, + "nonWhitespaceCharacterCount": 431, + "newlineCount": 33, + "readingTimeInMinutes": 0.21132075471698114, + "linkCount": 2, + "embedCount": 5, + "aliases": [ + "todo" + ], + "createdDate": 1760109756896, + "modifiedDate": 1761328686494, + "sizeInBytes": 716, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.18666666666666668, + "wordCount": 56, + "characterCount": 509, + "nonWhitespaceCharacterCount": 431, + "newlineCount": 33 + }, + "frontmatter": { + "id": "TODO", + "aliases": [ + "todo" + ], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/meta", + "type/encyclopedia", + "authorship/original" + ], + "title": "TODO" + } + }, + "topics.base": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760114988916, + "modifiedDate": 1761582446454, + "sizeInBytes": 746, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "telecom-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 252, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.84, + "characterCount": 2710, + "nonWhitespaceCharacterCount": 1926, + "newlineCount": 110, + "readingTimeInMinutes": 0.9509433962264151, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472524, + "modifiedDate": 1761747605964, + "sizeInBytes": 2870, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.84, + "wordCount": 252, + "characterCount": 2710, + "nonWhitespaceCharacterCount": 1926, + "newlineCount": 110 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/telecom", + "status/draft", + "type/guide" + ], + "title": "Telecom" + } + }, + "the-constructor-dot-org.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 2, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.006666666666666667, + "characterCount": 50, + "nonWhitespaceCharacterCount": 45, + "newlineCount": 5, + "readingTimeInMinutes": 0.007547169811320755, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761325475787, + "modifiedDate": 1761582342266, + "sizeInBytes": 186, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.006666666666666667, + "wordCount": 2, + "characterCount": 50, + "nonWhitespaceCharacterCount": 45, + "newlineCount": 5 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "type/idea" + ], + "title": "TheConstructor.Org" + } + }, + "the-failure-of-risk-management.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 1077, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 3.59, + "characterCount": 7307, + "nonWhitespaceCharacterCount": 6068, + "newlineCount": 240, + "readingTimeInMinutes": 4.064150943396227, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472525, + "modifiedDate": 1762290074970, + "sizeInBytes": 7564, + "sessionStart": { + "noteCount": 1, + "pageCount": 3.59, + "wordCount": 1077, + "characterCount": 7307, + "nonWhitespaceCharacterCount": 6068, + "newlineCount": 240 + }, + "frontmatter": { + "id": "the-failure-of-risk-management", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/complete", + "topic/risk", + "type/media-commentary" + ], + "title": "_The Failure of Risk Management_" + } + }, + "Templates/blank-system.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 10, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.03333333333333333, + "characterCount": 89, + "nonWhitespaceCharacterCount": 67, + "newlineCount": 13, + "readingTimeInMinutes": 0.03773584905660377, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472428, + "modifiedDate": 1761316590042, + "sizeInBytes": 222, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.03333333333333333, + "wordCount": 10, + "characterCount": 89, + "nonWhitespaceCharacterCount": 67, + "newlineCount": 13 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "occupational/takeoff", + "type/guide" + ], + "title": "Blank System" + } + }, + "Templates/idea.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 1, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.0033333333333333335, + "characterCount": 8, + "nonWhitespaceCharacterCount": 5, + "newlineCount": 3, + "readingTimeInMinutes": 0.0037735849056603774, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759416849314, + "modifiedDate": 1760092400680, + "sizeInBytes": 84, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.0033333333333333335, + "wordCount": 1, + "characterCount": 8, + "nonWhitespaceCharacterCount": 5, + "newlineCount": 3 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "type/idea" + ], + "title": "Idea" + } + }, + "tasks.base": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760109865147, + "modifiedDate": 1761076697350, + "sizeInBytes": 262, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "tags.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 569, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.8966666666666667, + "characterCount": 4301, + "nonWhitespaceCharacterCount": 3609, + "newlineCount": 191, + "readingTimeInMinutes": 2.147169811320755, + "linkCount": 12, + "embedCount": 0, + "aliases": [], + "createdDate": 1759347885820, + "modifiedDate": 1761316611332, + "sizeInBytes": 4519, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.8966666666666667, + "wordCount": 569, + "characterCount": 4301, + "nonWhitespaceCharacterCount": 3609, + "newlineCount": 191 + }, + "frontmatter": { + "id": "tags", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/meta", + "type/encyclopedia" + ], + "title": "Tags" + } + }, + "takeoff-review.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 25, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.08333333333333333, + "characterCount": 156, + "nonWhitespaceCharacterCount": 125, + "newlineCount": 9, + "readingTimeInMinutes": 0.09433962264150944, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761583475198, + "modifiedDate": 1761586457262, + "sizeInBytes": 322, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.08333333333333333, + "wordCount": 25, + "characterCount": 156, + "nonWhitespaceCharacterCount": 125, + "newlineCount": 9 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/incomplete", + "type/encyclopedia" + ], + "title": "Takeoff Review" + } + }, + "switchgear-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 213, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.71, + "characterCount": 1801, + "nonWhitespaceCharacterCount": 1476, + "newlineCount": 100, + "readingTimeInMinutes": 0.8037735849056604, + "linkCount": 2, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472522, + "modifiedDate": 1761316590519, + "sizeInBytes": 1970, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.71, + "wordCount": 213, + "characterCount": 1801, + "nonWhitespaceCharacterCount": 1476, + "newlineCount": 100 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational/takeoff/switchgear", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Switchgear" + } + }, + "supertopics.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 41, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.13666666666666666, + "characterCount": 247, + "nonWhitespaceCharacterCount": 202, + "newlineCount": 10, + "readingTimeInMinutes": 0.15471698113207547, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472521, + "modifiedDate": 1761677609248, + "sizeInBytes": 407, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.13666666666666666, + "wordCount": 41, + "characterCount": 247, + "nonWhitespaceCharacterCount": 202, + "newlineCount": 10 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "topic/organization", + "type/encyclopedia", + "authorship/original", + "status/incomplete" + ], + "title": "Supertopics" + } + }, + "subfeeds-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 173, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5766666666666667, + "characterCount": 1475, + "nonWhitespaceCharacterCount": 1095, + "newlineCount": 55, + "readingTimeInMinutes": 0.6528301886792452, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472519, + "modifiedDate": 1761329597715, + "sizeInBytes": 1676, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5766666666666667, + "wordCount": 173, + "characterCount": 1475, + "nonWhitespaceCharacterCount": 1095, + "newlineCount": 55 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational/takeoff/subfeeds", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Subfeeds" + } + }, + "strategy.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 118, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.3933333333333333, + "characterCount": 906, + "nonWhitespaceCharacterCount": 750, + "newlineCount": 52, + "readingTimeInMinutes": 0.44528301886792454, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472517, + "modifiedDate": 1761680526922, + "sizeInBytes": 1060, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.3933333333333333, + "wordCount": 118, + "characterCount": 906, + "nonWhitespaceCharacterCount": 750, + "newlineCount": 52 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/risk", + "type/encyclopedia", + "authorship/original" + ], + "title": "Strategy" + } + }, + "statistical-significance.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 195, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.65, + "characterCount": 1249, + "nonWhitespaceCharacterCount": 1045, + "newlineCount": 38, + "readingTimeInMinutes": 0.7358490566037735, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761836700004, + "modifiedDate": 1761837883156, + "sizeInBytes": 1482, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.65, + "wordCount": 195, + "characterCount": 1249, + "nonWhitespaceCharacterCount": 1045, + "newlineCount": 38 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [], + "title": "Statistical Significance" + } + }, + "stochastic-branch-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 93, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.31, + "characterCount": 703, + "nonWhitespaceCharacterCount": 578, + "newlineCount": 37, + "readingTimeInMinutes": 0.35094339622641507, + "linkCount": 1, + "embedCount": 1, + "aliases": [], + "createdDate": 1759858648035, + "modifiedDate": 1761677434854, + "sizeInBytes": 930, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.31, + "wordCount": 93, + "characterCount": 703, + "nonWhitespaceCharacterCount": 578, + "newlineCount": 37 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/construction/electrical", + "topic/estimating", + "type/idea" + ], + "title": "Stochastic Branch Takeoff" + } + }, + "standalone-systems-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 16, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.05333333333333334, + "characterCount": 186, + "nonWhitespaceCharacterCount": 157, + "newlineCount": 17, + "readingTimeInMinutes": 0.06037735849056604, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472516, + "modifiedDate": 1761662896399, + "sizeInBytes": 375, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.05333333333333334, + "wordCount": 16, + "characterCount": 186, + "nonWhitespaceCharacterCount": 157, + "newlineCount": 17 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational/takeoff/standalone-systems", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Standalone Systems" + } + }, + "spatial-sampling.gif": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760093162650, + "modifiedDate": 1760093162678, + "sizeInBytes": 5970115, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "software-based-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 187, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6233333333333333, + "characterCount": 1373, + "nonWhitespaceCharacterCount": 1167, + "newlineCount": 32, + "readingTimeInMinutes": 0.7056603773584905, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472514, + "modifiedDate": 1761679843792, + "sizeInBytes": 1606, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6233333333333333, + "wordCount": 187, + "characterCount": 1373, + "nonWhitespaceCharacterCount": 1167, + "newlineCount": 32 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "topic/software", + "type/philosophy", + "authorship/original" + ], + "title": "Software Based Estimating" + } + }, + "sleeving-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 56, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.18666666666666668, + "characterCount": 451, + "nonWhitespaceCharacterCount": 371, + "newlineCount": 19, + "readingTimeInMinutes": 0.21132075471698114, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472513, + "modifiedDate": 1762285919400, + "sizeInBytes": 616, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.18666666666666668, + "wordCount": 56, + "characterCount": 451, + "nonWhitespaceCharacterCount": 371, + "newlineCount": 19 + }, + "frontmatter": { + "id": "sleeving", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/draft", + "type/guide" + ], + "title": "Sleeving Takeoff" + } + }, + "sketch-over-photo-style-example.png": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1758037470129, + "modifiedDate": 1758037834991, + "sizeInBytes": 513924, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "risk.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 336, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.12, + "characterCount": 2291, + "nonWhitespaceCharacterCount": 1908, + "newlineCount": 72, + "readingTimeInMinutes": 1.2679245283018867, + "linkCount": 7, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472509, + "modifiedDate": 1762208450838, + "sizeInBytes": 2628, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.12, + "wordCount": 336, + "characterCount": 2291, + "nonWhitespaceCharacterCount": 1908, + "newlineCount": 72 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/risk", + "type/encyclopedia" + ], + "title": "Risk" + } + }, + "separating-estimating-concerns.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 187, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6233333333333333, + "characterCount": 1465, + "nonWhitespaceCharacterCount": 1243, + "newlineCount": 55, + "readingTimeInMinutes": 0.7056603773584905, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472511, + "modifiedDate": 1761677114471, + "sizeInBytes": 1680, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6233333333333333, + "wordCount": 187, + "characterCount": 1465, + "nonWhitespaceCharacterCount": 1243, + "newlineCount": 55 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/estimating", + "topic/software", + "type/philosophy" + ], + "title": "Separating Estimating Concerns" + } + }, + "sigmoid-functions.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 67, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.22333333333333333, + "characterCount": 712, + "nonWhitespaceCharacterCount": 586, + "newlineCount": 29, + "readingTimeInMinutes": 0.2528301886792453, + "linkCount": 0, + "embedCount": 1, + "aliases": [], + "createdDate": 1761677432591, + "modifiedDate": 1761760421595, + "sizeInBytes": 875, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.22333333333333333, + "wordCount": 67, + "characterCount": 712, + "nonWhitespaceCharacterCount": 586, + "newlineCount": 29 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/math", + "type/encyclopedia" + ], + "title": "Sigmoid Functions" + } + }, + "risk-oriented-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 790, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 2.6333333333333333, + "characterCount": 5310, + "nonWhitespaceCharacterCount": 4450, + "newlineCount": 150, + "readingTimeInMinutes": 2.981132075471698, + "linkCount": 8, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472508, + "modifiedDate": 1762280170548, + "sizeInBytes": 5680, + "sessionStart": { + "noteCount": 1, + "pageCount": 2.6333333333333333, + "wordCount": 790, + "characterCount": 5310, + "nonWhitespaceCharacterCount": 4450, + "newlineCount": 150 + }, + "frontmatter": { + "id": "risk-oriented-estimating", + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "topic/risk", + "type/philosophy", + "authorship/original" + ], + "title": "Risk Oriented Estimating" + } + }, + "reverend-william-h-alexander.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 179, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5966666666666667, + "characterCount": 1166, + "nonWhitespaceCharacterCount": 967, + "newlineCount": 36, + "readingTimeInMinutes": 0.6754716981132075, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1761143333468, + "modifiedDate": 1761143672881, + "sizeInBytes": 1588, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5966666666666667, + "wordCount": 179, + "characterCount": 1166, + "nonWhitespaceCharacterCount": 967, + "newlineCount": 36 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/other", + "destiny/uncertain", + "status/incomplete", + "topic/other" + ], + "title": "Reverend Dr. William Hamilton Bill Alexander" + } + }, + "rev-william-h-alexander_senate-press.jpg": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761143333468, + "modifiedDate": 1761143333468, + "sizeInBytes": 73225, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "rev-william-h-alexander_ddd-obit.png": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761143333464, + "modifiedDate": 1761143333464, + "sizeInBytes": 364061, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "resolving-process-uncertainty.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 142, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.47333333333333333, + "characterCount": 1008, + "nonWhitespaceCharacterCount": 826, + "newlineCount": 53, + "readingTimeInMinutes": 0.5358490566037736, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1762194723366, + "modifiedDate": 1762198764584, + "sizeInBytes": 1267, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.47333333333333333, + "wordCount": 142, + "characterCount": 1008, + "nonWhitespaceCharacterCount": 826, + "newlineCount": 53 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/organization", + "type/guide" + ], + "title": "Resolving Process Uncertainty" + } + }, + "refactor-system-scripts.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 87, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.29, + "characterCount": 661, + "nonWhitespaceCharacterCount": 550, + "newlineCount": 34, + "readingTimeInMinutes": 0.3283018867924528, + "linkCount": 2, + "embedCount": 1, + "aliases": [], + "createdDate": 1761078644884, + "modifiedDate": 1761314268407, + "sizeInBytes": 831, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.29, + "wordCount": 87, + "characterCount": 661, + "nonWhitespaceCharacterCount": 550, + "newlineCount": 34 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "occupational", + "status/incomplete", + "type/task", + "authorship/original" + ], + "title": "Refactor System Scripts" + } + }, + "realism-vs-instrumentalism.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 99, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.33, + "characterCount": 691, + "nonWhitespaceCharacterCount": 579, + "newlineCount": 18, + "readingTimeInMinutes": 0.37358490566037733, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1758562084632, + "modifiedDate": 1761838372097, + "sizeInBytes": 860, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.33, + "wordCount": 99, + "characterCount": 691, + "nonWhitespaceCharacterCount": 579, + "newlineCount": 18 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/draft" + ], + "title": "Realism vs. Instrumentalism" + } + }, + "README.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 78, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.26, + "characterCount": 555, + "nonWhitespaceCharacterCount": 461, + "newlineCount": 26, + "readingTimeInMinutes": 0.2943396226415094, + "linkCount": 3, + "embedCount": 0, + "aliases": [ + "home", + "zmVault" + ], + "createdDate": 1756122472406, + "modifiedDate": 1761143515752, + "sizeInBytes": 790, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.26, + "wordCount": 78, + "characterCount": 555, + "nonWhitespaceCharacterCount": 461, + "newlineCount": 26 + }, + "frontmatter": { + "id": "README", + "aliases": [ + "home", + "zmVault" + ], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/meta", + "type/encyclopedia" + ], + "title": "README" + } + }, + "raceway-terms.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 354, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.18, + "characterCount": 2550, + "nonWhitespaceCharacterCount": 2145, + "newlineCount": 86, + "readingTimeInMinutes": 1.3358490566037735, + "linkCount": 1, + "embedCount": 4, + "aliases": [], + "createdDate": 1756122472504, + "modifiedDate": 1761315659686, + "sizeInBytes": 2743, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.18, + "wordCount": 354, + "characterCount": 2550, + "nonWhitespaceCharacterCount": 2145, + "newlineCount": 86 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia" + ], + "title": "Raceway Terms" + } + }, + "purpose-of-construction-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 198, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.66, + "characterCount": 1396, + "nonWhitespaceCharacterCount": 1156, + "newlineCount": 57, + "readingTimeInMinutes": 0.7471698113207547, + "linkCount": 2, + "embedCount": 0, + "aliases": [], + "createdDate": 1760105479019, + "modifiedDate": 1761838630053, + "sizeInBytes": 1611, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.66, + "wordCount": 198, + "characterCount": 1396, + "nonWhitespaceCharacterCount": 1156, + "newlineCount": 57 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/estimating", + "type/philosophy", + "authorship/original", + "topic/construction" + ], + "title": "The Purpose of Construction Estimating" + } + }, + "pumpkin-coins-estimate.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 186, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.62, + "characterCount": 1753, + "nonWhitespaceCharacterCount": 1160, + "newlineCount": 71, + "readingTimeInMinutes": 0.7018867924528301, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761591240033, + "modifiedDate": 1761676230746, + "sizeInBytes": 1919, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.62, + "wordCount": 186, + "characterCount": 1753, + "nonWhitespaceCharacterCount": 1160, + "newlineCount": 71 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/estimating", + "type/idea", + "status/incomplete" + ], + "title": "Pumpkin Coins Estimate" + } + }, + "project-management-tm.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 557, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.8566666666666667, + "characterCount": 3867, + "nonWhitespaceCharacterCount": 3258, + "newlineCount": 99, + "readingTimeInMinutes": 2.1018867924528304, + "linkCount": 4, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472499, + "modifiedDate": 1761064576873, + "sizeInBytes": 4090, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.8566666666666667, + "wordCount": 557, + "characterCount": 3867, + "nonWhitespaceCharacterCount": 3258, + "newlineCount": 99 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/draft", + "topic/organization", + "type/philosophy" + ], + "title": "Project Management™" + } + }, + "project-setup.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 164, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5466666666666666, + "characterCount": 1466, + "nonWhitespaceCharacterCount": 1229, + "newlineCount": 71, + "readingTimeInMinutes": 0.6188679245283019, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472501, + "modifiedDate": 1761314136941, + "sizeInBytes": 1635, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5466666666666666, + "wordCount": 164, + "characterCount": 1466, + "nonWhitespaceCharacterCount": 1229, + "newlineCount": 71 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/draft", + "type/guide", + "authorship/original" + ], + "next": "setup-accubid", + "title": "Project Setup" + } + }, + "project-start-notification.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 186, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.62, + "characterCount": 3000, + "nonWhitespaceCharacterCount": 1331, + "newlineCount": 41, + "readingTimeInMinutes": 0.7018867924528301, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472502, + "modifiedDate": 1761314143401, + "sizeInBytes": 3168, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.62, + "wordCount": 186, + "characterCount": 3000, + "nonWhitespaceCharacterCount": 1331, + "newlineCount": 41 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/incomplete", + "type/guide", + "authorship/other-for-now" + ], + "title": "Project Start Notification" + } + }, + "project-info.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 200, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6666666666666666, + "characterCount": 1506, + "nonWhitespaceCharacterCount": 1240, + "newlineCount": 51, + "readingTimeInMinutes": 0.7547169811320755, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472497, + "modifiedDate": 1761677015918, + "sizeInBytes": 1678, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6666666666666666, + "wordCount": 200, + "characterCount": 1506, + "nonWhitespaceCharacterCount": 1240, + "newlineCount": 51 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/estimating", + "type/idea" + ], + "title": "Project Info" + } + }, + "professionalism.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 183, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.61, + "characterCount": 1160, + "nonWhitespaceCharacterCount": 946, + "newlineCount": 47, + "readingTimeInMinutes": 0.690566037735849, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1762198829105, + "modifiedDate": 1762206821668, + "sizeInBytes": 1329, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.61, + "wordCount": 183, + "characterCount": 1160, + "nonWhitespaceCharacterCount": 946, + "newlineCount": 47 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/organization" + ], + "title": "Professionalism" + } + }, + "portable-tools.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 46, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.15333333333333332, + "characterCount": 356, + "nonWhitespaceCharacterCount": 293, + "newlineCount": 22, + "readingTimeInMinutes": 0.17358490566037735, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472496, + "modifiedDate": 1761314118863, + "sizeInBytes": 516, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.15333333333333332, + "wordCount": 46, + "characterCount": 356, + "nonWhitespaceCharacterCount": 293, + "newlineCount": 22 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/software", + "type/encyclopedia", + "authorship/original" + ], + "title": "Portable Tools" + } + }, + "pre-takeoff-research.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 430, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.4333333333333333, + "characterCount": 3157, + "nonWhitespaceCharacterCount": 2583, + "newlineCount": 113, + "readingTimeInMinutes": 1.6226415094339623, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1761055024768, + "modifiedDate": 1761742940959, + "sizeInBytes": 3334, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.4333333333333333, + "wordCount": 430, + "characterCount": 3157, + "nonWhitespaceCharacterCount": 2583, + "newlineCount": 113 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/incomplete", + "type/guide", + "authorship/original" + ], + "title": "Pre-Takeoff Research" + } + }, + "pre-takeoff-confirmation.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 195, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.65, + "characterCount": 1451, + "nonWhitespaceCharacterCount": 1181, + "newlineCount": 57, + "readingTimeInMinutes": 0.7358490566037735, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1758205708777, + "modifiedDate": 1761836261589, + "sizeInBytes": 1619, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.65, + "wordCount": 195, + "characterCount": 1451, + "nonWhitespaceCharacterCount": 1181, + "newlineCount": 57 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/draft", + "type/guide", + "authorship/original", + "occupational/takeoff" + ], + "title": "Pre-Takeoff Confirmation" + } + }, + "pdi-market-types.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 110, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.36666666666666664, + "characterCount": 910, + "nonWhitespaceCharacterCount": 702, + "newlineCount": 52, + "readingTimeInMinutes": 0.41509433962264153, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761073664565, + "modifiedDate": 1761314115154, + "sizeInBytes": 1061, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.36666666666666664, + "wordCount": 110, + "characterCount": 910, + "nonWhitespaceCharacterCount": 702, + "newlineCount": 52 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "occupational", + "status/incomplete", + "type/task", + "authorship/original" + ], + "title": "PDI Market Types" + } + }, + "pdi-estimating-systems.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 4, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.013333333333333334, + "characterCount": 61, + "nonWhitespaceCharacterCount": 54, + "newlineCount": 5, + "readingTimeInMinutes": 0.01509433962264151, + "linkCount": 0, + "embedCount": 1, + "aliases": [], + "createdDate": 1760114878290, + "modifiedDate": 1761316590359, + "sizeInBytes": 239, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.013333333333333334, + "wordCount": 4, + "characterCount": 61, + "nonWhitespaceCharacterCount": 54, + "newlineCount": 5 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/incomplete", + "type/encyclopedia" + ], + "title": "PDI Estimating Systems" + } + }, + "pdi-labor-plan.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 298, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.9933333333333333, + "characterCount": 1967, + "nonWhitespaceCharacterCount": 1473, + "newlineCount": 54, + "readingTimeInMinutes": 1.1245283018867924, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761073192968, + "modifiedDate": 1761314089778, + "sizeInBytes": 2125, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.9933333333333333, + "wordCount": 298, + "characterCount": 1967, + "nonWhitespaceCharacterCount": 1473, + "newlineCount": 54 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/incomplete", + "type/guide", + "authorship/other-for-now" + ], + "title": "PDI Labor Plan" + } + }, + "pathfinding.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 24, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.08, + "characterCount": 194, + "nonWhitespaceCharacterCount": 145, + "newlineCount": 21, + "readingTimeInMinutes": 0.09056603773584905, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756223980057, + "modifiedDate": 1761676980214, + "sizeInBytes": 342, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.08, + "wordCount": 24, + "characterCount": 194, + "nonWhitespaceCharacterCount": 145, + "newlineCount": 21 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "topic/software", + "type/idea", + "authorship/original", + "status/incomplete" + ], + "title": "Pathfinding" + } + }, + "pdi-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 32, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.10666666666666667, + "characterCount": 377, + "nonWhitespaceCharacterCount": 318, + "newlineCount": 29, + "readingTimeInMinutes": 0.12075471698113208, + "linkCount": 6, + "embedCount": 0, + "aliases": [], + "createdDate": 1759329652262, + "modifiedDate": 1761826987690, + "sizeInBytes": 559, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.10666666666666667, + "wordCount": 32, + "characterCount": 377, + "nonWhitespaceCharacterCount": 318, + "newlineCount": 29 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "type/encyclopedia", + "authorship/original", + "status/incomplete" + ], + "title": "PDI Estimating" + } + }, + "pdi-breakdowns.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 11, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.03666666666666667, + "characterCount": 102, + "nonWhitespaceCharacterCount": 79, + "newlineCount": 13, + "readingTimeInMinutes": 0.04150943396226415, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761577801015, + "modifiedDate": 1761582320173, + "sizeInBytes": 268, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.03666666666666667, + "wordCount": 11, + "characterCount": 102, + "nonWhitespaceCharacterCount": 79, + "newlineCount": 13 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/incomplete", + "type/encyclopedia" + ], + "title": "PDI Breakdowns" + } + }, + "pdi-building-types.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 142, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.47333333333333333, + "characterCount": 1075, + "nonWhitespaceCharacterCount": 892, + "newlineCount": 49, + "readingTimeInMinutes": 0.5358490566037736, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1761064809366, + "modifiedDate": 1761314050874, + "sizeInBytes": 1241, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.47333333333333333, + "wordCount": 142, + "characterCount": 1075, + "nonWhitespaceCharacterCount": 892, + "newlineCount": 49 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "type/encyclopedia", + "status/incomplete", + "authorship/original" + ], + "title": "PDI Building Types" + } + }, + "owned-models.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 333, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.11, + "characterCount": 2338, + "nonWhitespaceCharacterCount": 1942, + "newlineCount": 82, + "readingTimeInMinutes": 1.2566037735849056, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759751126871, + "modifiedDate": 1761315825603, + "sizeInBytes": 3891, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.11, + "wordCount": 333, + "characterCount": 2338, + "nonWhitespaceCharacterCount": 1942, + "newlineCount": 82 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/complete", + "topic/hobbies", + "type/encyclopedia", + "authorship/original" + ], + "title": "Owned Models" + } + }, + "optimal-estimating-patterns.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 681, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 2.27, + "characterCount": 4530, + "nonWhitespaceCharacterCount": 3773, + "newlineCount": 144, + "readingTimeInMinutes": 2.569811320754717, + "linkCount": 4, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472452, + "modifiedDate": 1761679472364, + "sizeInBytes": 4731, + "sessionStart": { + "noteCount": 1, + "pageCount": 2.27, + "wordCount": 681, + "characterCount": 4530, + "nonWhitespaceCharacterCount": 3773, + "newlineCount": 144 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/estimating", + "topic/software", + "type/idea" + ], + "title": "Optimal Estimating Patterns" + } + }, + "outlets.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 9, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.03, + "characterCount": 210, + "nonWhitespaceCharacterCount": 195, + "newlineCount": 12, + "readingTimeInMinutes": 0.033962264150943396, + "linkCount": 0, + "embedCount": 5, + "aliases": [], + "createdDate": 1761307431897, + "modifiedDate": 1761315659667, + "sizeInBytes": 398, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.03, + "wordCount": 9, + "characterCount": 210, + "nonWhitespaceCharacterCount": 195, + "newlineCount": 12 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "topic/construction/electrical", + "authorship/original", + "destiny/permanent", + "type/encyclopedia", + "status/incomplete" + ], + "title": "Outlets" + } + }, + "ohms-law.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 37, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.12333333333333334, + "characterCount": 224, + "nonWhitespaceCharacterCount": 169, + "newlineCount": 22, + "readingTimeInMinutes": 0.13962264150943396, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761929284317, + "modifiedDate": 1762196986942, + "sizeInBytes": 395, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.12333333333333334, + "wordCount": 37, + "characterCount": 224, + "nonWhitespaceCharacterCount": 169, + "newlineCount": 22 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia" + ], + "title": "Ohm's Law" + } + }, + "nfpa-72_national-fire-alarm-code.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761317317767, + "modifiedDate": 1762291197303, + "sizeInBytes": 7809, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_national-electric-code.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761312125652, + "modifiedDate": 1762291246829, + "sizeInBytes": 10537, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_520_theaters.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760623711790, + "modifiedDate": 1762291253508, + "sizeInBytes": 4181, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_450_transformers.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759841284023, + "modifiedDate": 1762291258341, + "sizeInBytes": 1634, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_430_motors.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759840745945, + "modifiedDate": 1762291262375, + "sizeInBytes": 1498, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_314_boxes.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472405, + "modifiedDate": 1762291266772, + "sizeInBytes": 6301, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_310_conductors_for_general_wiring.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759502544856, + "modifiedDate": 1762291270654, + "sizeInBytes": 9119, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_300_general-requirements.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760979271242, + "modifiedDate": 1762291273413, + "sizeInBytes": 4182, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_220_load-calculations.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759507975768, + "modifiedDate": 1762291276892, + "sizeInBytes": 5581, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_215_feeders.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759514504311, + "modifiedDate": 1762291279886, + "sizeInBytes": 3124, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_110_requirements-for-electrical-installations.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759503634833, + "modifiedDate": 1762291286178, + "sizeInBytes": 12492, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_210_branch-circuits.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759499735030, + "modifiedDate": 1762291283602, + "sizeInBytes": 26696, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "nfpa-70_100_definitions.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761238656183, + "modifiedDate": 1762291290913, + "sizeInBytes": 87046, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "my-occupation.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 13, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.043333333333333335, + "characterCount": 199, + "nonWhitespaceCharacterCount": 171, + "newlineCount": 15, + "readingTimeInMinutes": 0.04905660377358491, + "linkCount": 4, + "embedCount": 0, + "aliases": [], + "createdDate": 1761076768460, + "modifiedDate": 1761077951991, + "sizeInBytes": 373, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.043333333333333335, + "wordCount": 13, + "characterCount": 199, + "nonWhitespaceCharacterCount": 171, + "newlineCount": 15 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational", + "status/incomplete", + "type/encyclopedia" + ], + "title": "My Occupation" + } + }, + "nfpa-101_life-safety-code.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761318343863, + "modifiedDate": 1762291296077, + "sizeInBytes": 11124, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "multi-family-dwellings.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 204, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.68, + "characterCount": 1547, + "nonWhitespaceCharacterCount": 1282, + "newlineCount": 56, + "readingTimeInMinutes": 0.769811320754717, + "linkCount": 1, + "embedCount": 1, + "aliases": [], + "createdDate": 1761587081356, + "modifiedDate": 1761676061215, + "sizeInBytes": 1797, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.68, + "wordCount": 204, + "characterCount": 1547, + "nonWhitespaceCharacterCount": 1282, + "newlineCount": 56 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction", + "type/encyclopedia" + ], + "title": "Multifamily Dwellings" + } + }, + "monte-carlo-methods.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 95, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.31666666666666665, + "characterCount": 632, + "nonWhitespaceCharacterCount": 526, + "newlineCount": 20, + "readingTimeInMinutes": 0.3584905660377358, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472492, + "modifiedDate": 1761314003287, + "sizeInBytes": 886, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.31666666666666665, + "wordCount": 95, + "characterCount": 632, + "nonWhitespaceCharacterCount": 526, + "newlineCount": 20 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/draft", + "topic/math", + "topic/risk", + "type/encyclopedia", + "authorship/original" + ], + "title": "Monte Carlo Methods" + } + }, + "misc-budgets-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 230, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.7666666666666667, + "characterCount": 1954, + "nonWhitespaceCharacterCount": 1578, + "newlineCount": 75, + "readingTimeInMinutes": 0.8679245283018868, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472490, + "modifiedDate": 1762280107978, + "sizeInBytes": 2106, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.7666666666666667, + "wordCount": 230, + "characterCount": 1954, + "nonWhitespaceCharacterCount": 1578, + "newlineCount": 75 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/draft", + "type/guide" + ], + "title": "Misc Budgets" + } + }, + "me.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 391, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.3033333333333332, + "characterCount": 2256, + "nonWhitespaceCharacterCount": 1838, + "newlineCount": 64, + "readingTimeInMinutes": 1.4754716981132074, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472486, + "modifiedDate": 1761313994451, + "sizeInBytes": 2402, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.3033333333333332, + "wordCount": 391, + "characterCount": 2256, + "nonWhitespaceCharacterCount": 1838, + "newlineCount": 64 + }, + "frontmatter": { + "id": "me", + "aliases": [], + "tags": [ + "destiny/permanent", + "status/draft", + "topic/meta", + "type/encyclopedia", + "authorship/original" + ], + "title": "Me" + } + }, + "medium-voltage.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 143, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.4766666666666667, + "characterCount": 1665, + "nonWhitespaceCharacterCount": 873, + "newlineCount": 40, + "readingTimeInMinutes": 0.539622641509434, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761769474247, + "modifiedDate": 1761772426003, + "sizeInBytes": 1818, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.4766666666666667, + "wordCount": 143, + "characterCount": 1665, + "nonWhitespaceCharacterCount": 873, + "newlineCount": 40 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/construction/electrical", + "type/encyclopedia" + ], + "title": "Medium Voltage" + } + }, + "mike-holts-illustrated-guide-to-electrical-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 118, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.3933333333333333, + "characterCount": 852, + "nonWhitespaceCharacterCount": 698, + "newlineCount": 35, + "readingTimeInMinutes": 0.44528301886792454, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472488, + "modifiedDate": 1762288060464, + "sizeInBytes": 1148, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.3933333333333333, + "wordCount": 118, + "characterCount": 852, + "nonWhitespaceCharacterCount": 698, + "newlineCount": 35 + }, + "frontmatter": { + "id": "mike-holts-illustrated-guide-to-electrical-estimating", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/complete", + "topic/construction/electrical", + "topic/estimating", + "type/media-commentary" + ], + "title": "_Mike Holt's Illustrated Guide to Electrical Estimating_" + } + }, + "material-pricing.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 107, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.3566666666666667, + "characterCount": 1050, + "nonWhitespaceCharacterCount": 669, + "newlineCount": 39, + "readingTimeInMinutes": 0.4037735849056604, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472485, + "modifiedDate": 1761313989582, + "sizeInBytes": 1198, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.3566666666666667, + "wordCount": 107, + "characterCount": 1050, + "nonWhitespaceCharacterCount": 669, + "newlineCount": 39 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Material Pricing" + } + }, + "media-to-watch.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 9, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.03, + "characterCount": 61, + "nonWhitespaceCharacterCount": 47, + "newlineCount": 6, + "readingTimeInMinutes": 0.033962264150943396, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761739676326, + "modifiedDate": 1762279767524, + "sizeInBytes": 175, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.03, + "wordCount": 9, + "characterCount": 61, + "nonWhitespaceCharacterCount": 47, + "newlineCount": 6 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "authorship/original", + "topic/hobbies" + ], + "title": "Media to Watch" + } + }, + "low-voltage-raceway-selection.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 22, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.07333333333333333, + "characterCount": 165, + "nonWhitespaceCharacterCount": 131, + "newlineCount": 16, + "readingTimeInMinutes": 0.0830188679245283, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761592020870, + "modifiedDate": 1761592092090, + "sizeInBytes": 346, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.07333333333333333, + "wordCount": 22, + "characterCount": 165, + "nonWhitespaceCharacterCount": 131, + "newlineCount": 16 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "type/encyclopedia", + "status/incomplete" + ], + "title": "Low Voltage Raceway Selection" + } + }, + "low-voltage-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 49, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.16333333333333333, + "characterCount": 466, + "nonWhitespaceCharacterCount": 392, + "newlineCount": 28, + "readingTimeInMinutes": 0.18490566037735848, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472484, + "modifiedDate": 1761758840950, + "sizeInBytes": 657, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.16333333333333333, + "wordCount": 49, + "characterCount": 466, + "nonWhitespaceCharacterCount": 392, + "newlineCount": 28 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/low-voltage", + "status/draft", + "type/guide" + ], + "title": "Low Voltage Takeoff" + } + }, + "low-voltage-systems.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 194, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6466666666666666, + "characterCount": 1579, + "nonWhitespaceCharacterCount": 1329, + "newlineCount": 69, + "readingTimeInMinutes": 0.7320754716981132, + "linkCount": 2, + "embedCount": 0, + "aliases": [], + "createdDate": 1761585257049, + "modifiedDate": 1761676034227, + "sizeInBytes": 1767, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6466666666666666, + "wordCount": 194, + "characterCount": 1579, + "nonWhitespaceCharacterCount": 1329, + "newlineCount": 69 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia" + ], + "title": "Low Voltage Systems" + } + }, + "lighting-controls-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 78, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.26, + "characterCount": 571, + "nonWhitespaceCharacterCount": 478, + "newlineCount": 18, + "readingTimeInMinutes": 0.2943396226415094, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472480, + "modifiedDate": 1761836170960, + "sizeInBytes": 789, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.26, + "wordCount": 78, + "characterCount": 571, + "nonWhitespaceCharacterCount": 478, + "newlineCount": 18 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/electrical", + "status/draft", + "type/guide" + ], + "title": "Lighting Controls Takeoff" + } + }, + "lightning-protection-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 179, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5966666666666667, + "characterCount": 1422, + "nonWhitespaceCharacterCount": 1158, + "newlineCount": 47, + "readingTimeInMinutes": 0.6754716981132075, + "linkCount": 2, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472481, + "modifiedDate": 1761836370055, + "sizeInBytes": 1619, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5966666666666667, + "wordCount": 179, + "characterCount": 1422, + "nonWhitespaceCharacterCount": 1158, + "newlineCount": 47 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational/takeoff/lightning-protection", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Lightning Protection" + } + }, + "lightning-protection.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 6, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.02, + "characterCount": 58, + "nonWhitespaceCharacterCount": 48, + "newlineCount": 5, + "readingTimeInMinutes": 0.022641509433962263, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761584738650, + "modifiedDate": 1761675990526, + "sizeInBytes": 239, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.02, + "wordCount": 6, + "characterCount": 58, + "nonWhitespaceCharacterCount": 48, + "newlineCount": 5 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/construction/electrical", + "status/incomplete", + "type/encyclopedia" + ], + "title": "Lightning Protection" + } + }, + "ibc-construction-types.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 344, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.1466666666666667, + "characterCount": 2831, + "nonWhitespaceCharacterCount": 2407, + "newlineCount": 117, + "readingTimeInMinutes": 1.2981132075471697, + "linkCount": 6, + "embedCount": 0, + "aliases": [], + "createdDate": 1761059670486, + "modifiedDate": 1762271336649, + "sizeInBytes": 3027, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.1466666666666667, + "wordCount": 344, + "characterCount": 2831, + "nonWhitespaceCharacterCount": 2407, + "newlineCount": 117 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "type/encyclopedia", + "status/incomplete", + "authorship/original", + "topic/construction" + ], + "title": "IBC Construction Types" + } + }, + "lighting-controls.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 80, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.26666666666666666, + "characterCount": 570, + "nonWhitespaceCharacterCount": 473, + "newlineCount": 27, + "readingTimeInMinutes": 0.3018867924528302, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761584546426, + "modifiedDate": 1761584718301, + "sizeInBytes": 751, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.26666666666666666, + "wordCount": 80, + "characterCount": 570, + "nonWhitespaceCharacterCount": 473, + "newlineCount": 27 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia" + ], + "title": "Lighting Controls" + } + }, + "individual-ability.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 110, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.36666666666666664, + "characterCount": 759, + "nonWhitespaceCharacterCount": 640, + "newlineCount": 26, + "readingTimeInMinutes": 0.41509433962264153, + "linkCount": 2, + "embedCount": 0, + "aliases": [], + "createdDate": 1762203876287, + "modifiedDate": 1762279750893, + "sizeInBytes": 891, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.36666666666666664, + "wordCount": 110, + "characterCount": 759, + "nonWhitespaceCharacterCount": 640, + "newlineCount": 26 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/organization" + ], + "title": "Individual Ability" + } + }, + "hvac-calculations.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 152, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5066666666666667, + "characterCount": 1225, + "nonWhitespaceCharacterCount": 1011, + "newlineCount": 86, + "readingTimeInMinutes": 0.5735849056603773, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759943460138, + "modifiedDate": 1761315658999, + "sizeInBytes": 1407, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5066666666666667, + "wordCount": 152, + "characterCount": 1225, + "nonWhitespaceCharacterCount": 1011, + "newlineCount": 86 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia", + "authorship/original" + ], + "title": "HVAC Calculations" + } + }, + "homelab.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 209, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6966666666666667, + "characterCount": 1458, + "nonWhitespaceCharacterCount": 1215, + "newlineCount": 50, + "readingTimeInMinutes": 0.7886792452830189, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761739676325, + "modifiedDate": 1762279731920, + "sizeInBytes": 1588, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6966666666666667, + "wordCount": 209, + "characterCount": 1458, + "nonWhitespaceCharacterCount": 1215, + "newlineCount": 50 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/hobbies" + ], + "title": "Homelab" + } + }, + "heating-designations.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 31, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.10333333333333333, + "characterCount": 229, + "nonWhitespaceCharacterCount": 190, + "newlineCount": 8, + "readingTimeInMinutes": 0.1169811320754717, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761583215391, + "modifiedDate": 1761583383309, + "sizeInBytes": 401, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.10333333333333333, + "wordCount": 31, + "characterCount": 229, + "nonWhitespaceCharacterCount": 190, + "newlineCount": 8 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/incomplete", + "type/encyclopedia" + ], + "title": "Heating Designations" + } + }, + "gut-feel.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 61, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.20333333333333334, + "characterCount": 389, + "nonWhitespaceCharacterCount": 323, + "newlineCount": 12, + "readingTimeInMinutes": 0.23018867924528302, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472478, + "modifiedDate": 1761313944945, + "sizeInBytes": 517, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.20333333333333334, + "wordCount": 61, + "characterCount": 389, + "nonWhitespaceCharacterCount": 323, + "newlineCount": 12 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/risk", + "authorship/original" + ], + "title": "Gut Feel" + } + }, + "grounding-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 123, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.41, + "characterCount": 944, + "nonWhitespaceCharacterCount": 780, + "newlineCount": 37, + "readingTimeInMinutes": 0.4641509433962264, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472477, + "modifiedDate": 1761585149467, + "sizeInBytes": 1119, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.41, + "wordCount": 123, + "characterCount": 944, + "nonWhitespaceCharacterCount": 780, + "newlineCount": 37 + }, + "frontmatter": { + "id": "grounding", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/feeders", + "status/draft", + "type/guide" + ], + "title": "Grounding Takeoff" + } + }, + "gold-plating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 187, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6233333333333333, + "characterCount": 1274, + "nonWhitespaceCharacterCount": 1070, + "newlineCount": 33, + "readingTimeInMinutes": 0.7056603773584905, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472475, + "modifiedDate": 1761678953671, + "sizeInBytes": 1486, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6233333333333333, + "wordCount": 187, + "characterCount": 1274, + "nonWhitespaceCharacterCount": 1070, + "newlineCount": 33 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/complete", + "topic/construction", + "topic/construction/electrical", + "topic/risk", + "type/encyclopedia" + ], + "title": "Gold Plating" + } + }, + "getting-historical-pricing.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 11, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.03666666666666667, + "characterCount": 99, + "nonWhitespaceCharacterCount": 85, + "newlineCount": 5, + "readingTimeInMinutes": 0.04150943396226415, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472474, + "modifiedDate": 1761313927829, + "sizeInBytes": 292, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.03666666666666667, + "wordCount": 11, + "characterCount": 99, + "nonWhitespaceCharacterCount": 85, + "newlineCount": 5 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "status/complete", + "topic/automation", + "topic/estimating", + "type/idea", + "authorship/original" + ], + "title": "Getting Historical Material Pricing" + } + }, + "functional-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 508, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.6933333333333334, + "characterCount": 3682, + "nonWhitespaceCharacterCount": 2881, + "newlineCount": 140, + "readingTimeInMinutes": 1.9169811320754717, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1758716291160, + "modifiedDate": 1761313912899, + "sizeInBytes": 4230, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.6933333333333334, + "wordCount": 508, + "characterCount": 3682, + "nonWhitespaceCharacterCount": 2881, + "newlineCount": 140 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "topic/math", + "type/idea", + "authorship/original" + ], + "title": "Functional Estimating" + } + }, + "functional-labor-factoring.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 230, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.7666666666666667, + "characterCount": 1894, + "nonWhitespaceCharacterCount": 1591, + "newlineCount": 62, + "readingTimeInMinutes": 0.8679245283018868, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472472, + "modifiedDate": 1761679213101, + "sizeInBytes": 2099, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.7666666666666667, + "wordCount": 230, + "characterCount": 1894, + "nonWhitespaceCharacterCount": 1591, + "newlineCount": 62 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/estimating", + "topic/software", + "type/idea", + "authorship/original" + ], + "title": "Functional Labor Factoring" + } + }, + "formatting-titles.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 24, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.08, + "characterCount": 201, + "nonWhitespaceCharacterCount": 169, + "newlineCount": 9, + "readingTimeInMinutes": 0.09056603773584905, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761047128950, + "modifiedDate": 1761315881812, + "sizeInBytes": 376, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.08, + "wordCount": 24, + "characterCount": 201, + "nonWhitespaceCharacterCount": 169, + "newlineCount": 9 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "authorship/original", + "topic/other", + "topic/meta", + "type/encyclopedia" + ], + "title": "Formatting Titles" + } + }, + "full-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 49, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.16333333333333333, + "characterCount": 498, + "nonWhitespaceCharacterCount": 428, + "newlineCount": 40, + "readingTimeInMinutes": 0.18490566037735848, + "linkCount": 18, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472471, + "modifiedDate": 1761586446612, + "sizeInBytes": 727, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.16333333333333333, + "wordCount": 49, + "characterCount": 498, + "nonWhitespaceCharacterCount": 428, + "newlineCount": 40 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "type/guide", + "occupational/takeoff" + ], + "title": "Full Takeoff" + } + }, + "fixtures-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 77, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.25666666666666665, + "characterCount": 589, + "nonWhitespaceCharacterCount": 478, + "newlineCount": 31, + "readingTimeInMinutes": 0.29056603773584905, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472467, + "modifiedDate": 1761585133661, + "sizeInBytes": 766, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.25666666666666665, + "wordCount": 77, + "characterCount": 589, + "nonWhitespaceCharacterCount": 478, + "newlineCount": 31 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/fixtures", + "status/draft", + "type/guide" + ], + "title": "Fixtures Takeoff" + } + }, + "fire-alarm-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 590, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.9666666666666666, + "characterCount": 4895, + "nonWhitespaceCharacterCount": 3942, + "newlineCount": 184, + "readingTimeInMinutes": 2.2264150943396226, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472464, + "modifiedDate": 1761743127579, + "sizeInBytes": 5076, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.9666666666666666, + "wordCount": 590, + "characterCount": 4895, + "nonWhitespaceCharacterCount": 3942, + "newlineCount": 184 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/fire-alarm", + "status/draft", + "type/guide" + ], + "title": "Fire Alarm Takeoff" + } + }, + "fixture-designations.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 809, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 2.6966666666666668, + "characterCount": 7993, + "nonWhitespaceCharacterCount": 5704, + "newlineCount": 252, + "readingTimeInMinutes": 3.0528301886792453, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472466, + "modifiedDate": 1761925121521, + "sizeInBytes": 8184, + "sessionStart": { + "noteCount": 1, + "pageCount": 2.6966666666666668, + "wordCount": 809, + "characterCount": 7993, + "nonWhitespaceCharacterCount": 5704, + "newlineCount": 252 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational/takeoff/fixtures", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Fixture Designations" + } + }, + "feeder-verification.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 97, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.3233333333333333, + "characterCount": 655, + "nonWhitespaceCharacterCount": 531, + "newlineCount": 26, + "readingTimeInMinutes": 0.3660377358490566, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472457, + "modifiedDate": 1761676925347, + "sizeInBytes": 831, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.3233333333333333, + "wordCount": 97, + "characterCount": 655, + "nonWhitespaceCharacterCount": 531, + "newlineCount": 26 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "occupational", + "topic/automation", + "type/guide", + "authorship/original", + "status/incomplete" + ], + "title": "Feeder Verification" + } + }, + "fire-alarm.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 80, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.26666666666666666, + "characterCount": 625, + "nonWhitespaceCharacterCount": 516, + "newlineCount": 27, + "readingTimeInMinutes": 0.3018867924528302, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761231488978, + "modifiedDate": 1761659936717, + "sizeInBytes": 789, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.26666666666666666, + "wordCount": 80, + "characterCount": 625, + "nonWhitespaceCharacterCount": 516, + "newlineCount": 27 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "topic/construction/electrical", + "type/guide", + "status/incomplete" + ], + "title": "Fire Alarm" + } + }, + "feeders-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 198, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.66, + "characterCount": 1589, + "nonWhitespaceCharacterCount": 1333, + "newlineCount": 74, + "readingTimeInMinutes": 0.7471698113207547, + "linkCount": 4, + "embedCount": 1, + "aliases": [], + "createdDate": 1756122472457, + "modifiedDate": 1761585115797, + "sizeInBytes": 1780, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.66, + "wordCount": 198, + "characterCount": 1589, + "nonWhitespaceCharacterCount": 1333, + "newlineCount": 74 + }, + "frontmatter": { + "id": "feeders", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/feeders", + "status/draft", + "type/guide" + ], + "title": "Feeders Takeoff" + } + }, + "favorite-quotes.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 280, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.9333333333333333, + "characterCount": 1758, + "nonWhitespaceCharacterCount": 1422, + "newlineCount": 64, + "readingTimeInMinutes": 1.0566037735849056, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1758911985977, + "modifiedDate": 1761676837706, + "sizeInBytes": 1976, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.9333333333333333, + "wordCount": 280, + "characterCount": 1758, + "nonWhitespaceCharacterCount": 1422, + "newlineCount": 64 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/draft" + ], + "title": "Favorite Quotes" + } + }, + "Excalidraw/sigmoid-function-example.excalidraw.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760992401446, + "modifiedDate": 1760992692961, + "sizeInBytes": 4308, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "Excalidraw/location-vs-scope.excalidraw.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1758369450625, + "modifiedDate": 1760092401407, + "sizeInBytes": 6812, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "excel-macros.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 255, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.85, + "characterCount": 1732, + "nonWhitespaceCharacterCount": 1350, + "newlineCount": 77, + "readingTimeInMinutes": 0.9622641509433962, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472457, + "modifiedDate": 1761320865545, + "sizeInBytes": 1894, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.85, + "wordCount": 255, + "characterCount": 1732, + "nonWhitespaceCharacterCount": 1350, + "newlineCount": 77 + }, + "frontmatter": { + "id": "excel-macros", + "aliases": [], + "tags": [ + "destiny/permanent", + "topic/software", + "type/guide", + "authorship/original", + "status/complete" + ], + "title": "Excel Macros" + } + }, + "estimator-calibration.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 830, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 2.7666666666666666, + "characterCount": 5285, + "nonWhitespaceCharacterCount": 4316, + "newlineCount": 169, + "readingTimeInMinutes": 3.1320754716981134, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472431, + "modifiedDate": 1761313759219, + "sizeInBytes": 5474, + "sessionStart": { + "noteCount": 1, + "pageCount": 2.7666666666666666, + "wordCount": 830, + "characterCount": 5285, + "nonWhitespaceCharacterCount": 4316, + "newlineCount": 169 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/estimating", + "topic/risk", + "type/encyclopedia", + "authorship/original" + ], + "title": "Estimator Calibration" + } + }, + "estimator-skills.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472455, + "modifiedDate": 1762291339892, + "sizeInBytes": 21947, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "estimating-thoughts.base": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760098514439, + "modifiedDate": 1761679388487, + "sizeInBytes": 805, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "estimating-philosophy.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 136, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.4533333333333333, + "characterCount": 942, + "nonWhitespaceCharacterCount": 798, + "newlineCount": 23, + "readingTimeInMinutes": 0.5132075471698113, + "linkCount": 4, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472453, + "modifiedDate": 1761313737903, + "sizeInBytes": 1125, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.4533333333333333, + "wordCount": 136, + "characterCount": 942, + "nonWhitespaceCharacterCount": 798, + "newlineCount": 23 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "type/philosophy", + "authorship/original" + ], + "title": "Estimating Philosophy" + } + }, + "estimating-methodologies.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 321, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.07, + "characterCount": 2461, + "nonWhitespaceCharacterCount": 2051, + "newlineCount": 104, + "readingTimeInMinutes": 1.211320754716981, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1758712296129, + "modifiedDate": 1761313732976, + "sizeInBytes": 2626, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.07, + "wordCount": 321, + "characterCount": 2461, + "nonWhitespaceCharacterCount": 2051, + "newlineCount": 104 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/draft", + "topic/estimating", + "type/philosophy", + "authorship/original" + ], + "title": "Estimating Methodologies" + } + }, + "estimating-dimensionality.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 267, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.89, + "characterCount": 1740, + "nonWhitespaceCharacterCount": 1431, + "newlineCount": 73, + "readingTimeInMinutes": 1.0075471698113208, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472451, + "modifiedDate": 1761313729120, + "sizeInBytes": 1947, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.89, + "wordCount": 267, + "characterCount": 1740, + "nonWhitespaceCharacterCount": 1431, + "newlineCount": 73 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "topic/organization", + "topic/software", + "type/idea", + "authorship/original" + ], + "title": "Estimating Dimensionality" + } + }, + "estimating-culture.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 390, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.3, + "characterCount": 2625, + "nonWhitespaceCharacterCount": 2205, + "newlineCount": 73, + "readingTimeInMinutes": 1.471698113207547, + "linkCount": 7, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472447, + "modifiedDate": 1761313719738, + "sizeInBytes": 2911, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.3, + "wordCount": 390, + "characterCount": 2625, + "nonWhitespaceCharacterCount": 2205, + "newlineCount": 73 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/draft", + "topic/estimating", + "topic/organization", + "type/philosophy", + "authorship/original" + ], + "title": "Estimating Culture" + } + }, + "estimating-detail.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 236, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.7866666666666666, + "characterCount": 1581, + "nonWhitespaceCharacterCount": 1320, + "newlineCount": 53, + "readingTimeInMinutes": 0.8905660377358491, + "linkCount": 2, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472449, + "modifiedDate": 1761313723185, + "sizeInBytes": 1757, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.7866666666666666, + "wordCount": 236, + "characterCount": 1581, + "nonWhitespaceCharacterCount": 1320, + "newlineCount": 53 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "type/philosophy", + "authorship/original" + ], + "title": "Estimating Detail" + } + }, + "emergency-systems-research.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 36, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.12, + "characterCount": 353, + "nonWhitespaceCharacterCount": 276, + "newlineCount": 17, + "readingTimeInMinutes": 0.13584905660377358, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1761582618845, + "modifiedDate": 1761662896268, + "sizeInBytes": 543, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.12, + "wordCount": 36, + "characterCount": 353, + "nonWhitespaceCharacterCount": 276, + "newlineCount": 17 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff", + "status/incomplete", + "type/encyclopedia" + ], + "title": "Emergency Systems Research" + } + }, + "electrical-estimators-manual.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 98, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.32666666666666666, + "characterCount": 801, + "nonWhitespaceCharacterCount": 643, + "newlineCount": 43, + "readingTimeInMinutes": 0.36981132075471695, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472444, + "modifiedDate": 1761676815731, + "sizeInBytes": 1007, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.32666666666666666, + "wordCount": 98, + "characterCount": 801, + "nonWhitespaceCharacterCount": 643, + "newlineCount": 43 + }, + "frontmatter": { + "id": "electrical-estimators-manual", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/draft", + "topic/estimating", + "type/media-commentary" + ], + "title": "_Electrical Estimators Manual_" + } + }, + "emergency-communications-systems.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 234, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.78, + "characterCount": 1764, + "nonWhitespaceCharacterCount": 1498, + "newlineCount": 49, + "readingTimeInMinutes": 0.8830188679245283, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1761319269291, + "modifiedDate": 1761586223805, + "sizeInBytes": 2125, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.78, + "wordCount": 234, + "characterCount": 1764, + "nonWhitespaceCharacterCount": 1498, + "newlineCount": 49 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia" + ], + "title": "Emergency Communications Systems (ECS)" + } + }, + "distribution-equipment.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 94, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.31333333333333335, + "characterCount": 699, + "nonWhitespaceCharacterCount": 580, + "newlineCount": 30, + "readingTimeInMinutes": 0.35471698113207545, + "linkCount": 1, + "embedCount": 3, + "aliases": [], + "createdDate": 1761143969834, + "modifiedDate": 1761662733665, + "sizeInBytes": 951, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.31333333333333335, + "wordCount": 94, + "characterCount": 699, + "nonWhitespaceCharacterCount": 580, + "newlineCount": 30 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "type/encyclopedia", + "topic/construction/electrical" + ], + "title": "Distribution Equipment" + } + }, + "electrical-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 181, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.6033333333333334, + "characterCount": 1568, + "nonWhitespaceCharacterCount": 1321, + "newlineCount": 75, + "readingTimeInMinutes": 0.6830188679245283, + "linkCount": 5, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472445, + "modifiedDate": 1761938437754, + "sizeInBytes": 1768, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.6033333333333334, + "wordCount": 181, + "characterCount": 1568, + "nonWhitespaceCharacterCount": 1321, + "newlineCount": 75 + }, + "frontmatter": { + "id": "electrical", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/electrical", + "status/draft", + "type/guide" + ], + "title": "Electrical Takeoff" + } + }, + "electrical-estimating-methods.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 79, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.2633333333333333, + "characterCount": 628, + "nonWhitespaceCharacterCount": 522, + "newlineCount": 30, + "readingTimeInMinutes": 0.2981132075471698, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472443, + "modifiedDate": 1761838581475, + "sizeInBytes": 873, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.2633333333333333, + "wordCount": 79, + "characterCount": 628, + "nonWhitespaceCharacterCount": 522, + "newlineCount": 30 + }, + "frontmatter": { + "id": "electrical-estimating-methods", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/complete", + "topic/construction/electrical", + "topic/estimating", + "type/media-commentary" + ], + "title": "_Electrical Estimating Methods_" + } + }, + "distributed-antenna-systems-takeoff.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 186, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.62, + "characterCount": 1629, + "nonWhitespaceCharacterCount": 1370, + "newlineCount": 61, + "readingTimeInMinutes": 0.7018867924528301, + "linkCount": 3, + "embedCount": 0, + "aliases": [ + "das" + ], + "createdDate": 1756122472441, + "modifiedDate": 1761827130825, + "sizeInBytes": 1876, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.62, + "wordCount": 186, + "characterCount": 1629, + "nonWhitespaceCharacterCount": 1370, + "newlineCount": 61 + }, + "frontmatter": { + "id": null, + "aliases": [ + "das" + ], + "tags": [ + "authorship/original", + "destiny/permanent", + "occupational/takeoff/standalone-systems", + "status/draft", + "type/guide" + ], + "title": "Distributed Antenna Systems (DAS) Takeoff" + } + }, + "default-list.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 247, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.8233333333333334, + "characterCount": 1500, + "nonWhitespaceCharacterCount": 1222, + "newlineCount": 38, + "readingTimeInMinutes": 0.9320754716981132, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1760357912588, + "modifiedDate": 1761315833576, + "sizeInBytes": 1951, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.8233333333333334, + "wordCount": 247, + "characterCount": 1500, + "nonWhitespaceCharacterCount": 1222, + "newlineCount": 38 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "type/encyclopedia", + "authorship/original", + "topic/hobbies" + ], + "title": "Default List" + } + }, + "diagrams.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 9, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.03, + "characterCount": 78, + "nonWhitespaceCharacterCount": 62, + "newlineCount": 10, + "readingTimeInMinutes": 0.033962264150943396, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761580370015, + "modifiedDate": 1762262038728, + "sizeInBytes": 228, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.03, + "wordCount": 9, + "characterCount": 78, + "nonWhitespaceCharacterCount": 62, + "newlineCount": 10 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/uncertain", + "status/incomplete", + "topic/meta", + "type/encyclopedia" + ], + "title": "Diagrams" + } + }, + "design-build-budget.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 94, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.31333333333333335, + "characterCount": 791, + "nonWhitespaceCharacterCount": 654, + "newlineCount": 48, + "readingTimeInMinutes": 0.35471698113207545, + "linkCount": 7, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472440, + "modifiedDate": 1761313647223, + "sizeInBytes": 970, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.31333333333333335, + "wordCount": 94, + "characterCount": 791, + "nonWhitespaceCharacterCount": 654, + "newlineCount": 48 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "occupational", + "status/draft", + "type/guide", + "authorship/original" + ], + "title": "Design Build Budget" + } + }, + "construction-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 268, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.8933333333333333, + "characterCount": 2031, + "nonWhitespaceCharacterCount": 1714, + "newlineCount": 69, + "readingTimeInMinutes": 1.0113207547169811, + "linkCount": 7, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472438, + "modifiedDate": 1762208426289, + "sizeInBytes": 2253, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.8933333333333333, + "wordCount": 268, + "characterCount": 2031, + "nonWhitespaceCharacterCount": 1714, + "newlineCount": 69 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction", + "topic/estimating", + "type/encyclopedia" + ], + "title": "Construction Estimating" + } + }, + "construction-methods.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 256, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.8533333333333334, + "characterCount": 1943, + "nonWhitespaceCharacterCount": 1625, + "newlineCount": 70, + "readingTimeInMinutes": 0.9660377358490566, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761322071772, + "modifiedDate": 1761326904790, + "sizeInBytes": 2416, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.8533333333333334, + "wordCount": 256, + "characterCount": 1943, + "nonWhitespaceCharacterCount": 1625, + "newlineCount": 70 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/incomplete", + "topic/construction", + "type/encyclopedia" + ], + "title": "Construction Methods" + } + }, + "construction-estimating-software.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 161, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5366666666666666, + "characterCount": 1408, + "nonWhitespaceCharacterCount": 1138, + "newlineCount": 74, + "readingTimeInMinutes": 0.6075471698113207, + "linkCount": 3, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472431, + "modifiedDate": 1761325423324, + "sizeInBytes": 1617, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5366666666666666, + "wordCount": 161, + "characterCount": 1408, + "nonWhitespaceCharacterCount": 1138, + "newlineCount": 74 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/uncertain", + "status/incomplete", + "topic/estimating", + "topic/software", + "type/philosophy", + "authorship/original" + ], + "title": "Construction Estimating Software" + } + }, + "consolidate-estimating-thoughts.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 65, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.21666666666666667, + "characterCount": 588, + "nonWhitespaceCharacterCount": 469, + "newlineCount": 23, + "readingTimeInMinutes": 0.24528301886792453, + "linkCount": 0, + "embedCount": 1, + "aliases": [], + "createdDate": 1760106533140, + "modifiedDate": 1761313620242, + "sizeInBytes": 777, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.21666666666666667, + "wordCount": 65, + "characterCount": 588, + "nonWhitespaceCharacterCount": 469, + "newlineCount": 23 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "status/incomplete", + "topic/estimating", + "topic/meta", + "type/task", + "authorship/original" + ], + "title": "Consolidate Estimating Thoughts" + } + }, + "construction-estimating-using-excel.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 114, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.38, + "characterCount": 913, + "nonWhitespaceCharacterCount": 759, + "newlineCount": 37, + "readingTimeInMinutes": 0.43018867924528303, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472436, + "modifiedDate": 1762288074920, + "sizeInBytes": 1169, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.38, + "wordCount": 114, + "characterCount": 913, + "nonWhitespaceCharacterCount": 759, + "newlineCount": 37 + }, + "frontmatter": { + "id": "construction-estimating-using-excel", + "aliases": [], + "tags": [ + "authorship/original", + "destiny/permanent", + "status/complete", + "topic/estimating", + "type/media-commentary", + "topic/construction" + ], + "title": "Review: _Construction Estimating Using Excel_" + } + }, + "consolidate-electrical-info.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 20, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.06666666666666667, + "characterCount": 185, + "nonWhitespaceCharacterCount": 159, + "newlineCount": 9, + "readingTimeInMinutes": 0.07547169811320754, + "linkCount": 1, + "embedCount": 1, + "aliases": [], + "createdDate": 1761314615273, + "modifiedDate": 1761315659964, + "sizeInBytes": 372, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.06666666666666667, + "wordCount": 20, + "characterCount": 185, + "nonWhitespaceCharacterCount": 159, + "newlineCount": 9 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/construction/electrical", + "type/task" + ], + "title": "Consolidate Electrical Info" + } + }, + "conductor-sizing.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 501, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.67, + "characterCount": 3593, + "nonWhitespaceCharacterCount": 2988, + "newlineCount": 136, + "readingTimeInMinutes": 1.890566037735849, + "linkCount": 7, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472457, + "modifiedDate": 1762197387162, + "sizeInBytes": 3907, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.67, + "wordCount": 501, + "characterCount": 3593, + "nonWhitespaceCharacterCount": 2988, + "newlineCount": 136 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "status/incomplete", + "topic/construction/electrical", + "type/encyclopedia", + "authorship/original" + ], + "title": "Conductor Sizing" + } + }, + "burndy-AYP300_pigtail-adaptor.png": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756128903447, + "modifiedDate": 1756129789647, + "sizeInBytes": 186420, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "breakdown-objects.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 104, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.3466666666666667, + "characterCount": 925, + "nonWhitespaceCharacterCount": 745, + "newlineCount": 62, + "readingTimeInMinutes": 0.39245283018867927, + "linkCount": 0, + "embedCount": 1, + "aliases": [], + "createdDate": 1757432900210, + "modifiedDate": 1761676661159, + "sizeInBytes": 1125, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.3466666666666667, + "wordCount": 104, + "characterCount": 925, + "nonWhitespaceCharacterCount": 745, + "newlineCount": 62 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/estimating", + "topic/software", + "type/idea" + ], + "title": "Breakdown Objects" + } + }, + "bpm-award-analysis.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 68, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.22666666666666666, + "characterCount": 630, + "nonWhitespaceCharacterCount": 531, + "newlineCount": 23, + "readingTimeInMinutes": 0.25660377358490566, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472430, + "modifiedDate": 1761676567850, + "sizeInBytes": 804, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.22666666666666666, + "wordCount": 68, + "characterCount": 630, + "nonWhitespaceCharacterCount": 531, + "newlineCount": 23 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "occupational", + "topic/automation", + "type/idea", + "authorship/original", + "status/incomplete" + ], + "title": "BPM Award Analysis" + } + }, + "company-switch.png": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1759262525863, + "modifiedDate": 1759262525865, + "sizeInBytes": 93144, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "birds.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 113, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.37666666666666665, + "characterCount": 1136, + "nonWhitespaceCharacterCount": 913, + "newlineCount": 56, + "readingTimeInMinutes": 0.42641509433962266, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1758886491235, + "modifiedDate": 1762208158937, + "sizeInBytes": 2583, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.37666666666666665, + "wordCount": 113, + "characterCount": 1136, + "nonWhitespaceCharacterCount": 913, + "newlineCount": 56 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "type/encyclopedia", + "authorship/original", + "topic/hobbies" + ], + "title": "Birds I've Seen Around Here" + } + }, + "bid-process-strategy.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 86, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.2866666666666667, + "characterCount": 641, + "nonWhitespaceCharacterCount": 541, + "newlineCount": 26, + "readingTimeInMinutes": 0.32452830188679244, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1760116109020, + "modifiedDate": 1761313598078, + "sizeInBytes": 851, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.2866666666666667, + "wordCount": 86, + "characterCount": 641, + "nonWhitespaceCharacterCount": 541, + "newlineCount": 26 + }, + "frontmatter": { + "id": "risk-oriented-estimating", + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/estimating", + "topic/risk", + "type/philosophy", + "authorship/original" + ], + "title": "Bid Process Strategy" + } + }, + "backlog.base": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760112493010, + "modifiedDate": 1761912783546, + "sizeInBytes": 669, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "bad-bid-practice.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 53, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.17666666666666667, + "characterCount": 405, + "nonWhitespaceCharacterCount": 334, + "newlineCount": 25, + "readingTimeInMinutes": 0.2, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1760544578882, + "modifiedDate": 1761313589998, + "sizeInBytes": 529, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.17666666666666667, + "wordCount": 53, + "characterCount": 405, + "nonWhitespaceCharacterCount": 334, + "newlineCount": 25 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "authorship/original", + "status/incomplete" + ], + "title": "Bad Bid Practice" + } + }, + "automating-pdf-annotation.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 297, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.99, + "characterCount": 2116, + "nonWhitespaceCharacterCount": 1722, + "newlineCount": 103, + "readingTimeInMinutes": 1.120754716981132, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472426, + "modifiedDate": 1761676362671, + "sizeInBytes": 2303, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.99, + "wordCount": 297, + "characterCount": 2116, + "nonWhitespaceCharacterCount": 1722, + "newlineCount": 103 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/software", + "type/idea" + ], + "title": "Automating PDF Annotation" + } + }, + "assembly-objects.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 94, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.31333333333333335, + "characterCount": 1063, + "nonWhitespaceCharacterCount": 760, + "newlineCount": 64, + "readingTimeInMinutes": 0.35471698113207545, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472421, + "modifiedDate": 1761676292613, + "sizeInBytes": 1258, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.31333333333333335, + "wordCount": 94, + "characterCount": 1063, + "nonWhitespaceCharacterCount": 760, + "newlineCount": 64 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/estimating", + "topic/software", + "type/idea" + ], + "title": "Assembly Objects" + } + }, + "automating-estimating-project-creation.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 25, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.08333333333333333, + "characterCount": 392, + "nonWhitespaceCharacterCount": 355, + "newlineCount": 16, + "readingTimeInMinutes": 0.09433962264150944, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472426, + "modifiedDate": 1761676316859, + "sizeInBytes": 597, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.08333333333333333, + "wordCount": 25, + "characterCount": 392, + "nonWhitespaceCharacterCount": 355, + "newlineCount": 16 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/automation", + "topic/organization", + "topic/software" + ], + "title": "Automating Estimating Project Creation" + } + }, + "90-day-performance-review.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1757074872430, + "modifiedDate": 1762291325951, + "sizeInBytes": 5495, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + }, + "assembly-philosophy.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 294, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.98, + "characterCount": 2040, + "nonWhitespaceCharacterCount": 1716, + "newlineCount": 58, + "readingTimeInMinutes": 1.109433962264151, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472423, + "modifiedDate": 1761676307740, + "sizeInBytes": 2208, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.98, + "wordCount": 294, + "characterCount": 2040, + "nonWhitespaceCharacterCount": 1716, + "newlineCount": 58 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "authorship/original", + "destiny/fleeting", + "status/incomplete", + "topic/estimating", + "type/philosophy" + ], + "title": "Assembly Philosophy" + } + }, + "alternating-current.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 472, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 1.5733333333333333, + "characterCount": 3167, + "nonWhitespaceCharacterCount": 2568, + "newlineCount": 120, + "readingTimeInMinutes": 1.7811320754716982, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472400, + "modifiedDate": 1762179394726, + "sizeInBytes": 3422, + "sessionStart": { + "noteCount": 1, + "pageCount": 1.5733333333333333, + "wordCount": 472, + "characterCount": 3167, + "nonWhitespaceCharacterCount": 2568, + "newlineCount": 120 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/fleeting", + "topic/construction/electrical", + "type/encyclopedia", + "authorship/original", + "status/incomplete" + ], + "title": "Alternating Current" + } + }, + "ai-in-estimating.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 164, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.5466666666666666, + "characterCount": 1054, + "nonWhitespaceCharacterCount": 882, + "newlineCount": 22, + "readingTimeInMinutes": 0.6188679245283019, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472418, + "modifiedDate": 1761679798062, + "sizeInBytes": 1235, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.5466666666666666, + "wordCount": 164, + "characterCount": 1054, + "nonWhitespaceCharacterCount": 882, + "newlineCount": 22 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "topic/estimating", + "topic/software", + "type/philosophy", + "authorship/original", + "status/incomplete", + "destiny/permanent" + ], + "title": "AI in Estimating" + } + }, + "2025-07-18_estimating-isnt-engineering.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 114, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.38, + "characterCount": 818, + "nonWhitespaceCharacterCount": 693, + "newlineCount": 26, + "readingTimeInMinutes": 0.43018867924528303, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472399, + "modifiedDate": 1761838667650, + "sizeInBytes": 1052, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.38, + "wordCount": 114, + "characterCount": 818, + "nonWhitespaceCharacterCount": 693, + "newlineCount": 26 + }, + "frontmatter": { + "id": "2025-07-18_estimating-isnt-engineering", + "aliases": [], + "tags": [ + "destiny/permanent", + "status/incomplete", + "topic/estimating", + "type/anecdote", + "authorship/original", + "topic/construction" + ], + "title": "Estimating Isn't Engineering" + } + }, + "accubid-setup.md": { + "isCountable": true, + "targetNodeType": "file", + "noteCount": 1, + "wordCount": 186, + "wordCountTowardGoal": 0, + "wordGoal": null, + "pageCount": 0.62, + "characterCount": 1443, + "nonWhitespaceCharacterCount": 1192, + "newlineCount": 69, + "readingTimeInMinutes": 0.7018867924528301, + "linkCount": 1, + "embedCount": 0, + "aliases": [], + "createdDate": 1756122472416, + "modifiedDate": 1762267226728, + "sizeInBytes": 1627, + "sessionStart": { + "noteCount": 1, + "pageCount": 0.62, + "wordCount": 186, + "characterCount": 1443, + "nonWhitespaceCharacterCount": 1192, + "newlineCount": 69 + }, + "frontmatter": { + "id": null, + "aliases": [], + "tags": [ + "destiny/permanent", + "status/draft", + "occupational", + "type/guide", + "authorship/original" + ], + "title": "Accubid Setup" + } + }, + "1960-04-04_durant-daily-democrat.md": { + "isCountable": false, + "targetNodeType": "file", + "noteCount": 0, + "wordCount": 0, + "wordCountTowardGoal": 0, + "wordGoal": 0, + "pageCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0, + "readingTimeInMinutes": 0, + "linkCount": 0, + "embedCount": 0, + "aliases": [], + "createdDate": 1761143333452, + "modifiedDate": 1762291348920, + "sizeInBytes": 2907, + "sessionStart": { + "noteCount": 0, + "pageCount": 0, + "wordCount": 0, + "characterCount": 0, + "nonWhitespaceCharacterCount": 0, + "newlineCount": 0 + } + } + } +} \ No newline at end of file diff --git a/.obsidian/plugins/novel-word-count/main.js b/.obsidian/plugins/novel-word-count/main.js new file mode 100644 index 0000000..412f063 --- /dev/null +++ b/.obsidian/plugins/novel-word-count/main.js @@ -0,0 +1,2065 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// main.ts +var main_exports = {}; +__export(main_exports, { + default: () => NovelWordCountPlugin +}); +module.exports = __toCommonJS(main_exports); + +// logic/debug.ts +var DebugHelper = class { + constructor() { + this.debugMode = false; + this.idCounter = 0; + } + setDebugMode(debug) { + this.debugMode = debug; + } + debug(...args) { + if (!this.debugMode) { + return; + } + console.log("novel-word-count:", ...args); + } + error(message) { + if (!this.debugMode) { + return; + } + console.error(message); + } + debugStart(name) { + if (!this.debugMode) { + return () => { + }; + } + var qualifiedName = `novel-word-count|${name} (${++this.idCounter})`; + console.time(qualifiedName); + return () => console.timeEnd(qualifiedName); + } +}; + +// logic/event.ts +var import_obsidian = require("obsidian"); + +// logic/cancellation.ts +var CANCEL = Symbol("Cancel"); +var CancellationToken = class { + constructor() { + this._isCancelled = false; + } + get isCancelled() { + return this._isCancelled; + } + [CANCEL]() { + this._isCancelled = true; + } +}; +var CancellationTokenSource = class { + constructor() { + this.token = new CancellationToken(); + } + cancel() { + this.token[CANCEL](); + } +}; + +// logic/event.ts +var EventHelper = class { + constructor(plugin, app, debugHelper, fileHelper) { + this.plugin = plugin; + this.app = app; + this.debugHelper = debugHelper; + this.fileHelper = fileHelper; + this.cancellationSources = []; + } + async handleEvents() { + const debouncedFileModified = (0, import_obsidian.debounce)(async (file) => { + const countToken = this.registerNewCountToken(); + await this.fileHelper.updateFileCounts( + file, + this.plugin.savedData.cachedCounts, + countToken.token + ); + this.cancelToken(countToken); + await this.plugin.updateDisplayedCounts(file); + this.plugin.saveSettingsDebounced(); + }, 500); + this.plugin.registerEvent( + this.app.metadataCache.on("changed", async (file) => { + this.debugHelper.debug( + "[changed] metadataCache hook fired, scheduling file for analysis", + file.path + ); + debouncedFileModified(file); + }) + ); + this.app.workspace.onLayoutReady(() => { + this.plugin.registerEvent( + this.app.vault.on("create", async (file) => { + this.debugHelper.debug( + "[create] vault hook fired, analyzing file", + file.path + ); + const countToken = this.registerNewCountToken(); + await this.fileHelper.updateFileCounts( + file, + this.plugin.savedData.cachedCounts, + countToken.token + ); + this.cancelToken(countToken); + await this.plugin.updateDisplayedCounts(file); + await this.plugin.saveSettings(); + }) + ); + this.plugin.registerEvent( + this.app.vault.on("modify", async (file) => { + this.debugHelper.debug( + "[modify] vault hook fired, scheduling file for analysis", + file.path + ); + debouncedFileModified(file); + }) + ); + }); + this.plugin.registerEvent( + this.app.vault.on("delete", async (file) => { + this.debugHelper.debug( + "[delete] vault hook fired, forgetting file", + file.path + ); + this.fileHelper.removeFileCounts( + file.path, + this.plugin.savedData.cachedCounts + ); + await this.plugin.updateDisplayedCounts(file); + await this.plugin.saveSettings(); + }) + ); + this.plugin.registerEvent( + this.app.vault.on("rename", async (file, oldPath) => { + if (file instanceof import_obsidian.TFolder) { + return; + } + this.debugHelper.debug( + "[rename] vault hook fired, recounting file", + file.path + ); + this.fileHelper.removeFileCounts( + oldPath, + this.plugin.savedData.cachedCounts + ); + const countToken = this.registerNewCountToken(); + await this.fileHelper.updateFileCounts( + file, + this.plugin.savedData.cachedCounts, + countToken.token + ); + this.cancelToken(countToken); + await this.plugin.updateDisplayedCounts(file); + await this.plugin.saveSettings(); + }) + ); + const reshowCountsIfNeeded = async (hookName) => { + this.debugHelper.debug(`[${hookName}] hook fired`); + const fileExplorerLeaf = await this.plugin.getFileExplorerLeaf(); + if (this.isContainerTouched(fileExplorerLeaf)) { + this.debugHelper.debug( + "container already touched, skipping display update" + ); + return; + } + this.debugHelper.debug("container is clean, updating display"); + await this.plugin.updateDisplayedCounts(); + }; + this.plugin.registerEvent( + this.app.workspace.on( + "layout-change", + (0, import_obsidian.debounce)(reshowCountsIfNeeded.bind(this, "layout-change"), 1e3) + ) + ); + } + isContainerTouched(leaf) { + const container = leaf.view.containerEl; + return container.className.includes("novel-word-count--"); + } + async reinitializeAllCounts() { + this.cancelAllCountTokens(); + const countToken = this.registerNewCountToken(); + this.debugHelper.debug("refreshAllCounts"); + this.plugin.savedData.cachedCounts = await this.fileHelper.initializeAllFileCounts( + countToken.token + ); + this.cancelToken(countToken); + await this.plugin.saveSettings(); + } + /* + CANCELLATION HANDLING + */ + registerNewCountToken() { + const cancellationSource = new CancellationTokenSource(); + this.cancellationSources.push(cancellationSource); + return cancellationSource; + } + cancelToken(source) { + source.cancel(); + if (this.cancellationSources.includes(source)) { + this.cancellationSources.splice( + this.cancellationSources.indexOf(source), + 1 + ); + } + } + cancelAllCountTokens() { + for (const source of this.cancellationSources) { + source.cancel(); + } + this.cancellationSources = []; + } +}; + +// logic/file.ts +var import_obsidian2 = require("obsidian"); + +// logic/settings.ts +var $CountType = /* @__PURE__ */ (($CountType2) => { + $CountType2["None"] = "none"; + $CountType2["Word"] = "word"; + $CountType2["Page"] = "page"; + $CountType2["PageDecimal"] = "pagedecimal"; + $CountType2["Linebreak"] = "linebreak"; + $CountType2["ReadTime"] = "readtime"; + $CountType2["PercentGoal"] = "percentgoal"; + $CountType2["Note"] = "note"; + $CountType2["Character"] = "character"; + $CountType2["Link"] = "link"; + $CountType2["Embed"] = "embed"; + $CountType2["Alias"] = "alias"; + $CountType2["Created"] = "created"; + $CountType2["Modified"] = "modified"; + $CountType2["FileSize"] = "filesize"; + $CountType2["FrontmatterKey"] = "frontmatterKey"; + $CountType2["TrackSession"] = "tracksession"; + return $CountType2; +})($CountType || {}); +var COUNT_TYPES = Object.values($CountType); +var SESSION_COUNT_TYPES = [ + "word" /* Word */, + "page" /* Page */, + "pagedecimal" /* PageDecimal */, + "linebreak" /* Linebreak */, + "note" /* Note */, + "character" /* Character */ +]; +var COUNT_TYPE_DISPLAY_STRINGS = { + ["none" /* None */]: "None", + ["word" /* Word */]: "Word Count", + ["page" /* Page */]: "Page Count", + ["pagedecimal" /* PageDecimal */]: "Page Count (decimal)", + ["linebreak" /* Linebreak */]: "Line Break Count", + ["readtime" /* ReadTime */]: "Reading Time", + ["percentgoal" /* PercentGoal */]: "% of Word Goal", + ["note" /* Note */]: "Note Count", + ["character" /* Character */]: "Character Count", + ["link" /* Link */]: "Link Count", + ["embed" /* Embed */]: "Embed Count", + ["alias" /* Alias */]: "First Alias", + ["created" /* Created */]: "Created Date", + ["modified" /* Modified */]: "Last Updated Date", + ["filesize" /* FileSize */]: "File Size", + ["frontmatterKey" /* FrontmatterKey */]: "Frontmatter Key", + ["tracksession" /* TrackSession */]: "Track Session" +}; +var COUNT_TYPE_DESCRIPTIONS = { + ["none" /* None */]: "Hidden.", + ["word" /* Word */]: "Total words.", + ["page" /* Page */]: "Total pages, rounded up.", + ["pagedecimal" /* PageDecimal */]: "Total pages, precise to 2 digits after the decimal.", + ["linebreak" /* Linebreak */]: "Newlines (\xB6), including empty lines.", + ["readtime" /* ReadTime */]: "Estimated time to read the note.", + ["percentgoal" /* PercentGoal */]: "Set a word goal by adding the 'word-goal' property to a note.", + ["note" /* Note */]: "Total notes.", + ["character" /* Character */]: "Total characters (letters, symbols, numbers, and spaces).", + ["link" /* Link */]: "Total links to other notes.", + ["embed" /* Embed */]: "Total embedded images, files, and notes.", + ["alias" /* Alias */]: "The first alias property of each note.", + ["created" /* Created */]: "Creation date. (On folders: earliest creation date of any note.)", + ["modified" /* Modified */]: "Date of last edit. (On folders: latest edit date of any note.)", + ["filesize" /* FileSize */]: "Total size on hard drive.", + ["frontmatterKey" /* FrontmatterKey */]: "Key in the frontmatter block.", + ["tracksession" /* TrackSession */]: "Track progress since last Obsidian startup, plugin init, settings change, or recount" +}; +var UNFORMATTABLE_COUNT_TYPES = [ + "none" /* None */, + "alias" /* Alias */, + "filesize" /* FileSize */, + "readtime" /* ReadTime */ +]; +var COUNT_TYPE_DEFAULT_SHORT_SUFFIXES = { + ["word" /* Word */]: "w", + ["page" /* Page */]: "p", + ["pagedecimal" /* PageDecimal */]: "p", + ["linebreak" /* Linebreak */]: "\xB6", + ["percentgoal" /* PercentGoal */]: "%", + ["note" /* Note */]: "n", + ["character" /* Character */]: "ch", + ["link" /* Link */]: "x", + ["embed" /* Embed */]: "em", + ["created" /* Created */]: "/c", + ["modified" /* Modified */]: "/u", + ["frontmatterKey" /* FrontmatterKey */]: "", + ["tracksession" /* TrackSession */]: "/s" +}; +function getDescription(countType) { + return `[${COUNT_TYPE_DISPLAY_STRINGS[countType]}] ${COUNT_TYPE_DESCRIPTIONS[countType]}`; +} +var ALIGNMENT_TYPES = [ + "inline" /* Inline */, + "right" /* Right */, + "below" /* Below */ +]; +var DEFAULT_SETTINGS = { + // FORMATTING + useAdvancedFormatting: false, + // NOTES + countType: "word" /* Word */, + countConfig: { + customSuffix: "w", + $sessionCountType: "word" /* Word */ + }, + countType2: "none" /* None */, + countConfig2: { + $sessionCountType: "word" /* Word */ + }, + countType3: "none" /* None */, + countConfig3: { + $sessionCountType: "word" /* Word */ + }, + pipeSeparator: "|", + abbreviateDescriptions: false, + alignment: "inline" /* Inline */, + // FOLDERS + showSameCountsOnFolders: true, + folderCountType: "word" /* Word */, + folderCountConfig: { + customSuffix: "w", + $sessionCountType: "word" /* Word */ + }, + folderCountType2: "none" /* None */, + folderCountConfig2: { + $sessionCountType: "word" /* Word */ + }, + folderCountType3: "none" /* None */, + folderCountConfig3: { + $sessionCountType: "word" /* Word */ + }, + folderPipeSeparator: "|", + folderAbbreviateDescriptions: false, + folderAlignment: "inline" /* Inline */, + // ROOT + showSameCountsOnRoot: true, + rootCountType: "word" /* Word */, + rootCountConfig: { + customSuffix: "w", + $sessionCountType: "word" /* Word */ + }, + rootCountType2: "none" /* None */, + rootCountConfig2: { + $sessionCountType: "word" /* Word */ + }, + rootCountType3: "none" /* None */, + rootCountConfig3: { + $sessionCountType: "word" /* Word */ + }, + rootPipeSeparator: "|", + rootAbbreviateDescriptions: false, + // ADVANCED + showAdvanced: false, + labelOpacity: 0.75, + wordsPerMinute: 265, + charsPerMinute: 500, + wordsPerPage: 300, + charsPerPage: 1500, + charsPerPageIncludesWhitespace: false, + characterCountType: "AllCharacters" /* StringLength */, + pageCountType: "ByWords" /* ByWords */, + includeDirectories: "", + excludeComments: false, + excludeCodeBlocks: false, + excludeNonVisibleLinkPortions: false, + excludeFootnotes: false, + momentDateFormat: "", + debugMode: false +}; + +// logic/parser.ts +var cjkRegex = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/gu; +var allSymbolsRegex = /[\p{S}\p{P}]/gu; +function countMarkdown(content, config) { + content = removeNonCountedContent(content, config); + let wordSequences = content.replace(cjkRegex, " ").replace(allSymbolsRegex, "").trim().split(/\s+/); + if (wordSequences.length === 1 && wordSequences[0] === "") { + wordSequences = []; + } + let lineSequences = content.split("\n"); + if (lineSequences.length === 1 && lineSequences[0] === "") { + lineSequences = []; + } + const result = { + charCount: content.length, + nonWhitespaceCharCount: countNonWhitespaceCharacters(content), + spaceDelimitedWordCount: wordSequences.length, + cjkWordCount: (content.match(cjkRegex) || []).length, + newlineCount: lineSequences.length + }; + return result; +} +var whitespaceRegex = /\s/g; +function countNonWhitespaceCharacters(content) { + return content.replace(whitespaceRegex, "").length; +} +function removeNonCountedContent(content, config) { + if (config.excludeCodeBlocks) { + content = content.replace(/(```.+?```)/gims, ""); + } + if (config.excludeComments) { + content = content.replace(/(%%.+?%%|)/gims, ""); + } + if (config.excludeNonVisibleLinkPortions) { + content = content.replace(/\[([^\]]*?)\]\([^\)]*?\)/gim, "$1"); + content = content.replace(/\[\[(.*?)\]\]/gim, (_, $1) => { + return !$1 ? "" : $1.includes("|") ? $1.slice($1.indexOf("|") + 1) : $1; + }); + } + if (config.excludeFootnotes) { + content = content.replace(/\[\^.+?\]: .*/gim, ""); + content = content.replace(/\[\^.+?\]/gim, ""); + } + return content; +} + +// logic/canvas.ts +var CanvasHelper = class { + constructor(debug) { + this.debug = debug; + } + getCanvasText(file, content) { + try { + const canvas = JSON.parse(content); + const texts = canvas.nodes.map((node) => node.text).filter((text) => !!text); + return texts.join("\n"); + } catch (ex) { + this.debug.error(`Unable to parse canvas file [${file.name}]: ${ex}`); + return ""; + } + } +}; + +// logic/file.ts +var FileHelper = class { + constructor(app, plugin) { + this.app = app; + this.plugin = plugin; + this.debugHelper = new DebugHelper(); + this.canvasHelper = new CanvasHelper(this.debugHelper); + this.pathIncludeMatchers = []; + this.pathExcludeMatchers = []; + this.FileTypeAllowlist = /* @__PURE__ */ new Set([ + "", + // Markdown extensions + "markdown", + "md", + "mdml", + "mdown", + "mdtext", + "mdtxt", + "mdwn", + "mkd", + "mkdn", + // Obsidian canvas + "canvas", + // Text files + "txt", + "text", + "rtf", + // MD with embedded code + "qmd", + "rmd", + // MD for screenwriters + "fountain", + // LaTeX files + "tex" + ]); + } + get settings() { + return this.plugin.settings; + } + get vault() { + return this.app.vault; + } + async initializeAllFileCounts(cancellationToken) { + const debugEnd = this.debugHelper.debugStart("getAllFileCounts"); + const files = this.vault.getFiles(); + if (typeof this.plugin.settings.includeDirectories === "string" && this.plugin.settings.includeDirectories.trim() !== "*" && this.plugin.settings.includeDirectories.trim() !== "") { + const allMatchers = this.plugin.settings.includeDirectories.trim().split(",").map((matcher) => matcher.trim()); + const includeMatchers = allMatchers.filter( + (matcher) => !matcher.startsWith("!") + ); + const excludeMatchers = allMatchers.filter((matcher) => matcher.startsWith("!")).map((matcher) => matcher.slice(1)); + const matchedFiles = files.filter( + (file) => (includeMatchers.length === 0 ? true : includeMatchers.some((matcher) => file.path.includes(matcher))) && !excludeMatchers.some((matcher) => file.path.includes(matcher)) + ); + if (matchedFiles.length > 0) { + this.pathIncludeMatchers = includeMatchers; + this.pathExcludeMatchers = excludeMatchers; + } else { + this.pathIncludeMatchers = []; + this.pathExcludeMatchers = []; + this.debugHelper.debug( + "No files matched by includeDirectories setting. Defaulting to all files." + ); + } + } + const counts = {}; + for (const file of files) { + if (cancellationToken.isCancelled) { + break; + } + this.setCounts(counts, file, true); + } + debugEnd(); + return counts; + } + getCachedDataForPath(counts, path) { + if (counts.hasOwnProperty(path)) { + return counts[path]; + } + const childPaths = this.getChildPaths(counts, path); + const directoryDefault = { + isCountable: false, + targetNodeType: this.isRoot(path) ? "root" /* Root */ : "directory" /* Directory */, + noteCount: 0, + wordCount: 0, + wordCountTowardGoal: 0, + wordGoal: 0, + pageCount: 0, + characterCount: 0, + nonWhitespaceCharacterCount: 0, + newlineCount: 0, + readingTimeInMinutes: 0, + linkCount: 0, + embedCount: 0, + aliases: null, + createdDate: 0, + modifiedDate: 0, + sizeInBytes: 0, + sessionStart: { + noteCount: 0, + pageCount: 0, + wordCount: 0, + characterCount: 0, + nonWhitespaceCharacterCount: 0, + newlineCount: 0 + } + }; + return childPaths.reduce((total, childPath) => { + const childCount = this.getCachedDataForPath(counts, childPath); + return { + isCountable: total.isCountable || childCount.isCountable, + targetNodeType: total.targetNodeType, + noteCount: total.noteCount + childCount.noteCount, + linkCount: total.linkCount + childCount.linkCount, + embedCount: total.embedCount + childCount.embedCount, + aliases: [], + wordCount: total.wordCount + childCount.wordCount, + wordCountTowardGoal: total.wordCountTowardGoal + childCount.wordCountTowardGoal, + wordGoal: total.wordGoal + childCount.wordGoal, + pageCount: total.pageCount + childCount.pageCount, + characterCount: total.characterCount + childCount.characterCount, + nonWhitespaceCharacterCount: total.nonWhitespaceCharacterCount + childCount.nonWhitespaceCharacterCount, + newlineCount: total.newlineCount + childCount.newlineCount, + readingTimeInMinutes: total.readingTimeInMinutes + childCount.readingTimeInMinutes, + createdDate: total.createdDate === 0 ? childCount.createdDate : Math.min(total.createdDate, childCount.createdDate), + modifiedDate: Math.max(total.modifiedDate, childCount.modifiedDate), + sizeInBytes: total.sizeInBytes + childCount.sizeInBytes, + sessionStart: { + noteCount: total.sessionStart.noteCount + childCount.sessionStart.noteCount, + pageCount: total.sessionStart.pageCount + childCount.sessionStart.pageCount, + wordCount: total.sessionStart.wordCount + childCount.sessionStart.wordCount, + characterCount: total.sessionStart.characterCount + childCount.sessionStart.characterCount, + nonWhitespaceCharacterCount: total.sessionStart.nonWhitespaceCharacterCount + childCount.sessionStart.nonWhitespaceCharacterCount, + newlineCount: total.sessionStart.newlineCount + childCount.sessionStart.newlineCount + } + }; + }, directoryDefault); + } + setDebugMode(debug) { + this.debugHelper.setDebugMode(debug); + } + removeFileCounts(path, counts) { + this.removeCounts(counts, path); + for (const childPath of this.getChildPaths(counts, path)) { + this.removeCounts(counts, childPath); + } + } + async updateFileCounts(abstractFile, counts, cancellationToken) { + if (abstractFile instanceof import_obsidian2.TFolder) { + for (const child of abstractFile.children) { + await this.updateFileCounts(child, counts, cancellationToken); + } + return; + } + if (abstractFile instanceof import_obsidian2.TFile) { + await this.setCounts(counts, abstractFile, false); + } + } + countEmbeds(metadata) { + var _a, _b; + return (_b = (_a = metadata == null ? void 0 : metadata.embeds) == null ? void 0 : _a.length) != null ? _b : 0; + } + countLinks(metadata) { + var _a, _b; + return (_b = (_a = metadata == null ? void 0 : metadata.links) == null ? void 0 : _a.length) != null ? _b : 0; + } + getChildPaths(counts, path) { + const childPaths = Object.keys(counts).filter( + (countPath) => path === "/" || countPath.startsWith(path + "/") + ); + return childPaths; + } + isRoot(path) { + return !path || path === "/"; + } + removeCounts(counts, path) { + delete counts[path]; + } + async setCounts(counts, file, startNewSession) { + var _a, _b; + const metadata = this.app.metadataCache.getFileCache( + file + ); + const shouldCountFile = this.shouldCountFile(file, metadata); + const existingSession = (_a = counts[file.path]) == null ? void 0 : _a.sessionStart; + counts[file.path] = { + isCountable: shouldCountFile, + targetNodeType: "file" /* File */, + noteCount: 0, + wordCount: 0, + wordCountTowardGoal: 0, + wordGoal: 0, + pageCount: 0, + characterCount: 0, + nonWhitespaceCharacterCount: 0, + newlineCount: 0, + readingTimeInMinutes: 0, + linkCount: 0, + embedCount: 0, + aliases: [], + createdDate: file.stat.ctime, + modifiedDate: file.stat.mtime, + sizeInBytes: file.stat.size, + sessionStart: startNewSession || !existingSession ? { + noteCount: 0, + pageCount: 0, + wordCount: 0, + characterCount: 0, + nonWhitespaceCharacterCount: 0, + newlineCount: 0 + } : existingSession + }; + if (!shouldCountFile) { + return; + } + let content = await this.vault.cachedRead(file); + if (file.extension.toLowerCase() === "canvas") { + content = this.canvasHelper.getCanvasText(file, content); + } else { + content = this.trimFrontmatter(content, metadata); + } + const countResult = countMarkdown(content, { + excludeCodeBlocks: this.settings.excludeCodeBlocks, + excludeComments: this.settings.excludeComments, + excludeNonVisibleLinkPortions: this.settings.excludeNonVisibleLinkPortions, + excludeFootnotes: this.settings.excludeFootnotes + }); + const combinedWordCount = countResult.cjkWordCount + countResult.spaceDelimitedWordCount; + const wordGoal = this.getWordGoal(metadata); + const cjkReadingTime = countResult.cjkWordCount / (this.settings.charsPerMinute || 500); + const spaceDelimitedReadingTime = countResult.spaceDelimitedWordCount / (this.settings.wordsPerMinute || 265); + const readingTimeInMinutes = cjkReadingTime + spaceDelimitedReadingTime; + let pageCount = 0; + if (this.settings.pageCountType === "ByWords" /* ByWords */) { + const wordsPerPage = Number(this.settings.wordsPerPage); + const wordsPerPageValid = !isNaN(wordsPerPage) && wordsPerPage > 0; + pageCount = combinedWordCount / (wordsPerPageValid ? wordsPerPage : 300); + } else if (this.settings.pageCountType === "ByChars" /* ByChars */ && !this.settings.charsPerPageIncludesWhitespace) { + const charsPerPage = Number(this.settings.charsPerPage); + const charsPerPageValid = !isNaN(charsPerPage) && charsPerPage > 0; + pageCount = countResult.nonWhitespaceCharCount / (charsPerPageValid ? charsPerPage : 1500); + } else if (this.settings.pageCountType === "ByChars" /* ByChars */ && this.settings.charsPerPageIncludesWhitespace) { + const charsPerPage = Number(this.settings.charsPerPage); + const charsPerPageValid = !isNaN(charsPerPage) && charsPerPage > 0; + pageCount = countResult.charCount / (charsPerPageValid ? charsPerPage : 1500); + } + Object.assign(counts[file.path], { + noteCount: 1, + wordCount: combinedWordCount, + wordCountTowardGoal: wordGoal !== null ? combinedWordCount : 0, + wordGoal, + pageCount, + characterCount: countResult.charCount, + nonWhitespaceCharacterCount: countResult.nonWhitespaceCharCount, + newlineCount: countResult.newlineCount, + readingTimeInMinutes, + linkCount: this.countLinks(metadata), + embedCount: this.countEmbeds(metadata), + aliases: (0, import_obsidian2.parseFrontMatterAliases)(metadata == null ? void 0 : metadata.frontmatter), + frontmatter: metadata == null ? void 0 : metadata.frontmatter, + sessionStart: { + ...(_b = counts[file.path]) == null ? void 0 : _b.sessionStart, + ...startNewSession ? { + noteCount: 1, + pageCount, + wordCount: combinedWordCount, + characterCount: countResult.charCount, + nonWhitespaceCharacterCount: countResult.nonWhitespaceCharCount, + newlineCount: countResult.newlineCount + } : {} + } + }); + } + getWordGoal(metadata) { + const goal = metadata && metadata.frontmatter && metadata.frontmatter["word-goal"]; + if (!goal || isNaN(Number(goal))) { + return null; + } + return Number(goal); + } + trimFrontmatter(content, metadata) { + let meaningfulContent = content; + const hasFrontmatter = !!metadata && !!metadata.frontmatter; + if (hasFrontmatter) { + const frontmatterPos = metadata.frontmatterPosition || metadata.frontmatter.position; + meaningfulContent = frontmatterPos && frontmatterPos.start && frontmatterPos.end ? meaningfulContent.slice(0, frontmatterPos.start.offset) + meaningfulContent.slice(frontmatterPos.end.offset) : meaningfulContent; + } + return meaningfulContent; + } + shouldCountFile(file, metadata) { + if (this.pathIncludeMatchers.length > 0 && !this.pathIncludeMatchers.some((matcher) => file.path.includes(matcher))) { + return false; + } + if (this.pathExcludeMatchers.length > 0 && this.pathExcludeMatchers.some((matcher) => file.path.includes(matcher))) { + return false; + } + if (!this.FileTypeAllowlist.has(file.extension.toLowerCase())) { + return false; + } + if (!metadata) { + return true; + } + if (metadata.frontmatter && metadata.frontmatter.hasOwnProperty("wordcount") && (metadata.frontmatter.wordcount === null || metadata.frontmatter.wordcount === false || metadata.frontmatter.wordcount === "false")) { + return false; + } + const tags = (0, import_obsidian2.getAllTags)(metadata).map((tag) => tag.toLowerCase()); + if (tags.length && (tags.includes("#excalidraw") || tags.filter((tag) => tag.startsWith("#exclude")).map((tag) => tag.replace(/[-_]/g, "")).includes("#excludefromwordcount"))) { + return false; + } + return true; + } +}; + +// logic/locale_format.ts +var locales = [...navigator.languages, "en-US"]; +var NumberFormatDefault = new Intl.NumberFormat(locales); +var NumberFormatDecimal = new Intl.NumberFormat(locales, { + minimumFractionDigits: 1, + maximumFractionDigits: 2 +}); +var NumberFormatFileSize = new Intl.NumberFormat(locales, { + minimumFractionDigits: 0, + maximumFractionDigits: 2 +}); + +// logic/filesize.ts +var formatThresholds = [{ + suffix: "B", + suffixLong: " B", + divisor: 1 +}, { + suffix: "kB", + suffixLong: " kB", + divisor: 1e3 +}, { + suffix: "MB", + suffixLong: " MB", + divisor: 1e6 +}, { + suffix: "GB", + suffixLong: " GB", + divisor: 1e9 +}, { + suffix: "TB", + suffixLong: " TB", + divisor: 1e12 +}]; +var FileSizeHelper = class { + formatFileSize(bytes, shouldAbbreviate) { + const largestThreshold = formatThresholds.last(); + for (const formatThreshold of formatThresholds) { + if (bytes < formatThreshold.divisor * 1e3 || formatThreshold === largestThreshold) { + const units = bytes / formatThreshold.divisor; + const suffix = shouldAbbreviate ? formatThreshold.suffix : formatThreshold.suffixLong; + return `${NumberFormatFileSize.format(units)}${suffix}`; + } + } + return `?B`; + } +}; + +// logic/readtime.ts +var ReadTimeHelper = class { + formatReadTime(minutes, shouldAbbreviate) { + const final = shouldAbbreviate ? "" : " read"; + if (minutes * 60 < 1) { + return `0m${final}`; + } + if (minutes < 1) { + const seconds = Math.round(minutes * 60); + return `${seconds}s${final}`; + } + if (minutes < 60) { + return `${Math.round(minutes)}m${final}`; + } + const hours = NumberFormatDefault.format(Math.floor(minutes / 60)); + const remainder = Math.floor(minutes) % 60; + return remainder === 0 ? `${hours}h${final}` : `${hours}h${remainder}m${final}`; + } +}; + +// logic/node_label.ts +var import_obsidian3 = require("obsidian"); +var NodeLabelHelper = class { + constructor(plugin) { + this.plugin = plugin; + this.fileSizeHelper = new FileSizeHelper(); + this.readTimeHelper = new ReadTimeHelper(); + this.unconditionalCountTypes = [ + "created" /* Created */, + "filesize" /* FileSize */, + "modified" /* Modified */ + ]; + } + get settings() { + return this.plugin.settings; + } + getNodeLabel(counts) { + let countTypes; + let abbreviateDescriptions; + let separator; + const noteCountTypes = [ + this.getCountTypeWithSuffix( + this.settings.countType, + this.settings.countConfig + ), + this.getCountTypeWithSuffix( + this.settings.countType2, + this.settings.countConfig2 + ), + this.getCountTypeWithSuffix( + this.settings.countType3, + this.settings.countConfig3 + ) + ]; + const noteAbbreviateDescriptions = this.settings.abbreviateDescriptions; + const noteSeparator = this.settings.useAdvancedFormatting ? this.settings.pipeSeparator : "|"; + switch (counts.targetNodeType) { + case "root" /* Root */: + if (this.settings.showSameCountsOnRoot) { + countTypes = noteCountTypes; + abbreviateDescriptions = noteAbbreviateDescriptions; + separator = noteSeparator; + break; + } + countTypes = [ + this.getCountTypeWithSuffix( + this.settings.rootCountType, + this.settings.rootCountConfig + ), + this.getCountTypeWithSuffix( + this.settings.rootCountType2, + this.settings.rootCountConfig2 + ), + this.getCountTypeWithSuffix( + this.settings.rootCountType3, + this.settings.rootCountConfig3 + ) + ]; + abbreviateDescriptions = this.settings.rootAbbreviateDescriptions; + separator = this.settings.useAdvancedFormatting ? this.settings.rootPipeSeparator : noteSeparator; + break; + case "directory" /* Directory */: + if (this.settings.showSameCountsOnFolders) { + countTypes = noteCountTypes; + abbreviateDescriptions = noteAbbreviateDescriptions; + separator = noteSeparator; + break; + } + countTypes = [ + this.getCountTypeWithSuffix( + this.settings.folderCountType, + this.settings.folderCountConfig + ), + this.getCountTypeWithSuffix( + this.settings.folderCountType2, + this.settings.folderCountConfig2 + ), + this.getCountTypeWithSuffix( + this.settings.folderCountType3, + this.settings.folderCountConfig3 + ) + ]; + abbreviateDescriptions = this.settings.folderAbbreviateDescriptions; + separator = this.settings.useAdvancedFormatting ? this.settings.folderPipeSeparator : noteSeparator; + break; + default: + countTypes = noteCountTypes; + abbreviateDescriptions = noteAbbreviateDescriptions; + separator = noteSeparator; + break; + } + return countTypes.filter((ct) => ct.$countType !== "none" /* None */).map( + (ct) => this.getDataTypeLabel( + counts, + ct, + abbreviateDescriptions + ) + ).filter((display) => display !== null).join(` ${separator} `); + } + getCountTypeWithSuffix($countType, countConfig) { + return { + $countType, + customSuffix: this.settings.useAdvancedFormatting ? countConfig.customSuffix : null, + frontmatterKey: countConfig.frontmatterKey, + $sessionCountType: countConfig.$sessionCountType + }; + } + getBasicCountString(config) { + var _a; + const defaultSuffix = config.abbreviateDescriptions ? config.abbreviatedNoun : ` ${config.noun}${config.count == "1" ? "" : "s"}`; + const suffix = (_a = config.customSuffix) != null ? _a : defaultSuffix; + return `${config.count}${suffix}`; + } + getDataTypeLabel(counts, config, abbreviateDescriptions) { + var _a, _b; + if (!counts || typeof counts.wordCount !== "number") { + return null; + } + if (!counts.isCountable && !this.unconditionalCountTypes.includes(config.$countType)) { + return null; + } + switch (config.$countType) { + case "none" /* None */: + return null; + case "word" /* Word */: + return this.getBasicCountString({ + count: NumberFormatDefault.format(Math.ceil(counts.wordCount)), + noun: "word", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["word" /* Word */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "page" /* Page */: + return this.getBasicCountString({ + count: NumberFormatDefault.format(Math.ceil(counts.pageCount)), + noun: "page", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["page" /* Page */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "pagedecimal" /* PageDecimal */: + return this.getBasicCountString({ + count: NumberFormatDecimal.format(counts.pageCount), + noun: "page", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["pagedecimal" /* PageDecimal */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "linebreak" /* Linebreak */: + return this.getBasicCountString({ + count: NumberFormatDefault.format(counts.newlineCount), + noun: "line", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["linebreak" /* Linebreak */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "percentgoal" /* PercentGoal */: { + if (counts.wordGoal <= 0) { + return null; + } + const fraction = counts.wordCountTowardGoal / counts.wordGoal; + const percent = NumberFormatDefault.format(Math.round(fraction * 100)); + const defaultSuffix = abbreviateDescriptions ? "%" : `% of ${NumberFormatDefault.format(counts.wordGoal)}`; + const suffix = (_a = config.customSuffix) != null ? _a : defaultSuffix; + return `${percent}${suffix}`; + } + case "note" /* Note */: + return this.getBasicCountString({ + count: NumberFormatDefault.format(counts.noteCount), + noun: "note", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["note" /* Note */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "character" /* Character */: { + const characterCount = this.settings.characterCountType === "ExcludeWhitespace" /* ExcludeWhitespace */ ? counts.nonWhitespaceCharacterCount : counts.characterCount; + return this.getBasicCountString({ + count: NumberFormatDefault.format(characterCount), + noun: "character", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["character" /* Character */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + } + case "readtime" /* ReadTime */: + return this.readTimeHelper.formatReadTime( + counts.readingTimeInMinutes, + abbreviateDescriptions + ); + case "link" /* Link */: + if (counts.linkCount === 0) { + return null; + } + return this.getBasicCountString({ + count: NumberFormatDefault.format(counts.linkCount), + noun: "link", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["link" /* Link */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "embed" /* Embed */: + if (counts.embedCount === 0) { + return null; + } + return this.getBasicCountString({ + count: NumberFormatDefault.format(counts.embedCount), + noun: "embed", + abbreviatedNoun: COUNT_TYPE_DEFAULT_SHORT_SUFFIXES["embed" /* Embed */], + abbreviateDescriptions, + customSuffix: config.customSuffix + }); + case "alias" /* Alias */: + if (!counts.aliases || !Array.isArray(counts.aliases) || !counts.aliases.length) { + return null; + } + return abbreviateDescriptions ? `${counts.aliases[0]}` : `alias: ${counts.aliases[0]}${counts.aliases.length > 1 ? ` +${counts.aliases.length - 1}` : ""}`; + case "created" /* Created */: { + if (counts.createdDate === 0) { + return null; + } + const cDate = (0, import_obsidian3.moment)(counts.createdDate).format(this.settings.momentDateFormat || "YYYY/MM/DD"); + if (config.customSuffix !== null) { + return `${cDate}${config.customSuffix}`; + } + return abbreviateDescriptions ? `${cDate}/c` : `Created ${cDate}`; + } + case "modified" /* Modified */: { + if (counts.modifiedDate === 0) { + return null; + } + const uDate = (0, import_obsidian3.moment)(counts.modifiedDate).format(this.settings.momentDateFormat || "YYYY/MM/DD"); + if (config.customSuffix !== null) { + return `${uDate}${config.customSuffix}`; + } + return abbreviateDescriptions ? `${uDate}/u` : `Updated ${uDate}`; + } + case "filesize" /* FileSize */: + return this.fileSizeHelper.formatFileSize( + counts.sizeInBytes, + abbreviateDescriptions + ); + case "frontmatterKey" /* FrontmatterKey */: { + if (!config.frontmatterKey) { + return null; + } + const value = (_b = counts == null ? void 0 : counts.frontmatter) == null ? void 0 : _b[config.frontmatterKey]; + if (value === void 0 || value === null) { + return null; + } + if (config.customSuffix !== null) { + return `${value}${config.customSuffix}`; + } + return value; + } + case "tracksession" /* TrackSession */: { + if (!config.$sessionCountType) { + return null; + } + const quantity = this.getSessionQuantity(counts, config.$sessionCountType); + if (config.customSuffix !== null) { + return `${quantity}${config.customSuffix}`; + } + return abbreviateDescriptions ? `${quantity}/s` : `Session: ${quantity}`; + } + } + return null; + } + getSessionQuantity(counts, $countType) { + switch ($countType) { + case "word" /* Word */: + return NumberFormatDefault.format(Math.ceil(counts.wordCount - counts.sessionStart.wordCount)); + case "page" /* Page */: + return NumberFormatDefault.format(Math.ceil(counts.pageCount - counts.sessionStart.pageCount)); + case "pagedecimal" /* PageDecimal */: + return NumberFormatDecimal.format(counts.pageCount - counts.sessionStart.pageCount); + case "linebreak" /* Linebreak */: + return NumberFormatDefault.format(counts.newlineCount - counts.sessionStart.newlineCount); + case "note" /* Note */: + return NumberFormatDefault.format(counts.noteCount - counts.sessionStart.noteCount); + case "character" /* Character */: { + const characterCount = this.settings.characterCountType === "ExcludeWhitespace" /* ExcludeWhitespace */ ? counts.nonWhitespaceCharacterCount : counts.characterCount; + const startingCharacterCount = this.settings.characterCountType === "ExcludeWhitespace" /* ExcludeWhitespace */ ? counts.sessionStart.nonWhitespaceCharacterCount : counts.sessionStart.characterCount; + return NumberFormatDefault.format(characterCount - startingCharacterCount); + } + } + } +}; + +// logic/saved_data.ts +var SavedDataHelper = class { + constructor(plugin) { + this.plugin = plugin; + } + async getSavedData() { + const loaded = await this.plugin.loadData(); + const denulled = Object.assign({}, loaded); + denulled.settings = Object.assign({}, DEFAULT_SETTINGS, denulled.settings); + const migrated = migrateSavedData(denulled); + return migrated; + } +}; +function migrateSavedData(saved) { + const migrations = [ + overwriteInvalidCountTypes, + migrateToCountConfigurationObject + ]; + for (const migrate of migrations) { + saved = migrate(saved); + } + return saved; +} +var overwriteInvalidCountTypes = (saved) => { + var _a; + if (!((_a = saved == null ? void 0 : saved.settings) == null ? void 0 : _a.countType)) { + return; + } + const fieldsToCheck = [ + "countType", + "countType2", + "countType3", + "folderCountType", + "folderCountType2", + "folderCountType3", + "rootCountType", + "rootCountType2", + "rootCountType3" + ]; + for (const field of fieldsToCheck) { + if (!COUNT_TYPES.includes(saved.settings[field])) { + saved.settings[field] = field === "countType" ? "word" /* Word */ : "none" /* None */; + } + } + return saved; +}; +var migrateToCountConfigurationObject = (saved) => { + var _a, _b, _c, _d, _e, _f, _g, _h, _i; + const settings = saved.settings; + const oldSettings = saved.settings; + (_a = settings.countConfig) != null ? _a : settings.countConfig = {}; + if (typeof oldSettings.countTypeSuffix === "string") { + settings.countConfig.customSuffix = oldSettings.countTypeSuffix; + delete oldSettings.countTypeSuffix; + } + if (typeof oldSettings.frontmatterKey === "string") { + settings.countConfig.frontmatterKey = oldSettings.frontmatterKey; + delete oldSettings.frontmatterKey; + } + (_b = settings.countConfig2) != null ? _b : settings.countConfig2 = {}; + if (typeof oldSettings.countType2Suffix === "string") { + settings.countConfig2.customSuffix = oldSettings.countType2Suffix; + delete oldSettings.countType2Suffix; + } + if (typeof oldSettings.frontmatterKey2 === "string") { + settings.countConfig2.frontmatterKey = oldSettings.frontmatterKey2; + delete oldSettings.frontmatterKey2; + } + (_c = settings.countConfig3) != null ? _c : settings.countConfig3 = {}; + if (typeof oldSettings.countType3Suffix === "string") { + settings.countConfig3.customSuffix = oldSettings.countType3Suffix; + delete oldSettings.countType3Suffix; + } + if (typeof oldSettings.frontmatterKey3 === "string") { + settings.countConfig3.frontmatterKey = oldSettings.frontmatterKey3; + delete oldSettings.frontmatterKey3; + } + (_d = settings.folderCountConfig) != null ? _d : settings.folderCountConfig = {}; + if (typeof oldSettings.folderCountTypeSuffix === "string") { + settings.folderCountConfig.customSuffix = oldSettings.folderCountTypeSuffix; + delete oldSettings.folderCountTypeSuffix; + } + (_e = settings.folderCountConfig2) != null ? _e : settings.folderCountConfig2 = {}; + if (typeof oldSettings.folderCountType2Suffix === "string") { + settings.folderCountConfig2.customSuffix = oldSettings.folderCountType2Suffix; + delete oldSettings.folderCountType2Suffix; + } + (_f = settings.folderCountConfig3) != null ? _f : settings.folderCountConfig3 = {}; + if (typeof oldSettings.folderCountType3Suffix === "string") { + settings.folderCountConfig3.customSuffix = oldSettings.folderCountType3Suffix; + delete oldSettings.folderCountType3Suffix; + } + (_g = settings.rootCountConfig) != null ? _g : settings.rootCountConfig = {}; + if (typeof oldSettings.rootCountTypeSuffix === "string") { + settings.rootCountConfig.customSuffix = oldSettings.rootCountTypeSuffix; + delete oldSettings.rootCountTypeSuffix; + } + (_h = settings.rootCountConfig2) != null ? _h : settings.rootCountConfig2 = {}; + if (typeof oldSettings.rootCountType2Suffix === "string") { + settings.rootCountConfig2.customSuffix = oldSettings.rootCountType2Suffix; + delete oldSettings.rootCountType2Suffix; + } + (_i = settings.rootCountConfig3) != null ? _i : settings.rootCountConfig3 = {}; + if (typeof oldSettings.rootCountType3Suffix === "string") { + settings.rootCountConfig3.customSuffix = oldSettings.rootCountType3Suffix; + delete oldSettings.rootCountType3Suffix; + } + return saved; +}; + +// logic/settings.tab.ts +var import_obsidian4 = require("obsidian"); +var NovelWordCountSettingTab = class extends import_obsidian4.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + display() { + const { containerEl } = this; + containerEl.empty(); + this.renderNoteSettings(containerEl); + this.renderFolderSettings(containerEl); + this.renderRootSettings(containerEl); + this.renderAdvancedSettings(containerEl); + this.renderReanalyzeButton(containerEl); + this.renderDonationButton(containerEl); + } + // + // NOTES + // + renderNoteSettings(containerEl) { + const mainHeader = containerEl.createEl("div", { + cls: [ + "setting-item", + "setting-item-heading", + "novel-word-count-settings-header" + ] + }); + mainHeader.createEl("div", { text: "Notes" }); + mainHeader.createEl("div", { + text: "You can display up to three data types side by side.", + cls: "setting-item-description" + }); + new import_obsidian4.Setting(containerEl).setDesc("Use advanced formatting").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.useAdvancedFormatting).onChange(async (value) => { + this.plugin.settings.useAdvancedFormatting = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + this.display(); + }) + ); + this.renderCountTypeSetting(containerEl, { + name: "1st data type to show", + oldCountType: this.plugin.settings.countType, + setNewCountType: (value) => { + this.plugin.settings.countType = value; + this.plugin.settings.countConfig.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.countType]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.countType, + oldCountType: this.plugin.settings.countConfig.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.countConfig.$sessionCountType = value; + } + }); + this.renderFrontmatterKeySetting(containerEl, { + countType: this.plugin.settings.countType, + oldKey: this.plugin.settings.countConfig.frontmatterKey, + setNewKey: (value) => this.plugin.settings.countConfig.frontmatterKey = value + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.countType, + oldSuffix: this.plugin.settings.countConfig.customSuffix, + setNewSuffix: (value) => this.plugin.settings.countConfig.customSuffix = value + }); + this.renderCountTypeSetting(containerEl, { + name: "2nd data type to show", + oldCountType: this.plugin.settings.countType2, + setNewCountType: (value) => { + this.plugin.settings.countType2 = value; + this.plugin.settings.countConfig2.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.countType2]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.countType2, + oldCountType: this.plugin.settings.countConfig2.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.countConfig2.$sessionCountType = value; + } + }); + this.renderFrontmatterKeySetting(containerEl, { + countType: this.plugin.settings.countType2, + oldKey: this.plugin.settings.countConfig2.frontmatterKey, + setNewKey: (value) => this.plugin.settings.countConfig2.frontmatterKey = value + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.countType2, + oldSuffix: this.plugin.settings.countConfig2.customSuffix, + setNewSuffix: (value) => this.plugin.settings.countConfig2.customSuffix = value + }); + this.renderCountTypeSetting(containerEl, { + name: "3rd data type to show", + oldCountType: this.plugin.settings.countType3, + setNewCountType: (value) => { + this.plugin.settings.countType3 = value; + this.plugin.settings.countConfig3.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.countType3]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.countType3, + oldCountType: this.plugin.settings.countConfig3.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.countConfig3.$sessionCountType = value; + } + }); + this.renderFrontmatterKeySetting(containerEl, { + countType: this.plugin.settings.countType3, + oldKey: this.plugin.settings.countConfig3.frontmatterKey, + setNewKey: (value) => this.plugin.settings.countConfig3.frontmatterKey = value + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.countType3, + oldSuffix: this.plugin.settings.countConfig3.customSuffix, + setNewSuffix: (value) => this.plugin.settings.countConfig3.customSuffix = value + }); + if (this.plugin.settings.useAdvancedFormatting) { + new import_obsidian4.Setting(containerEl).setName("Data type separator").addText( + (text) => text.setValue(this.plugin.settings.pipeSeparator).onChange(async (value) => { + this.plugin.settings.pipeSeparator = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + if (!this.plugin.settings.useAdvancedFormatting) { + new import_obsidian4.Setting(containerEl).setName("Abbreviate descriptions").setDesc("E.g. show '120w' instead of '120 words'").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.abbreviateDescriptions).onChange(async (value) => { + this.plugin.settings.abbreviateDescriptions = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + new import_obsidian4.Setting(containerEl).setName("Alignment").setDesc( + "Show data inline with file/folder names, right-aligned, or underneath" + ).addDropdown((drop) => { + drop.addOption("inline" /* Inline */, "Inline").addOption("right" /* Right */, "Right-aligned").addOption("below" /* Below */, "Below").setValue(this.plugin.settings.alignment).onChange(async (value) => { + this.plugin.settings.alignment = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }); + }); + } + renderFolderSettings(containerEl) { + this.renderSeparator(containerEl); + new import_obsidian4.Setting(containerEl).setHeading().setName("Folders: Same data as Notes").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.showSameCountsOnFolders).onChange(async (value) => { + this.plugin.settings.showSameCountsOnFolders = value; + await this.plugin.saveSettings(); + this.display(); + await this.plugin.updateDisplayedCounts(); + }) + ); + if (!this.plugin.settings.showSameCountsOnFolders) { + this.renderCountTypeSetting(containerEl, { + name: "1st data type to show", + oldCountType: this.plugin.settings.folderCountType, + setNewCountType: (value) => { + this.plugin.settings.folderCountType = value; + this.plugin.settings.folderCountConfig.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.folderCountType]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.folderCountType, + oldCountType: this.plugin.settings.folderCountConfig.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.folderCountConfig.$sessionCountType = value; + } + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.folderCountType, + oldSuffix: this.plugin.settings.folderCountConfig.customSuffix, + setNewSuffix: (value) => this.plugin.settings.folderCountConfig.customSuffix = value + }); + this.renderCountTypeSetting(containerEl, { + name: "2nd data type to show", + oldCountType: this.plugin.settings.folderCountType2, + setNewCountType: (value) => { + this.plugin.settings.folderCountType2 = value; + this.plugin.settings.folderCountConfig2.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.folderCountType2]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.folderCountType2, + oldCountType: this.plugin.settings.folderCountConfig2.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.folderCountConfig2.$sessionCountType = value; + } + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.folderCountType2, + oldSuffix: this.plugin.settings.folderCountConfig2.customSuffix, + setNewSuffix: (value) => this.plugin.settings.folderCountConfig2.customSuffix = value + }); + this.renderCountTypeSetting(containerEl, { + name: "3rd data type to show", + oldCountType: this.plugin.settings.folderCountType3, + setNewCountType: (value) => { + this.plugin.settings.folderCountType3 = value; + this.plugin.settings.folderCountConfig3.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.folderCountType3]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.folderCountType3, + oldCountType: this.plugin.settings.folderCountConfig3.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.folderCountConfig3.$sessionCountType = value; + } + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.folderCountType3, + oldSuffix: this.plugin.settings.folderCountConfig3.customSuffix, + setNewSuffix: (value) => this.plugin.settings.folderCountConfig3.customSuffix = value + }); + if (this.plugin.settings.useAdvancedFormatting) { + new import_obsidian4.Setting(containerEl).setName("Data type separator").addText( + (text) => text.setValue(this.plugin.settings.folderPipeSeparator).onChange(async (value) => { + this.plugin.settings.folderPipeSeparator = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + if (!this.plugin.settings.useAdvancedFormatting) { + new import_obsidian4.Setting(containerEl).setName("Abbreviate descriptions").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.folderAbbreviateDescriptions).onChange(async (value) => { + this.plugin.settings.folderAbbreviateDescriptions = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + new import_obsidian4.Setting(containerEl).setName("Alignment").addDropdown((drop) => { + drop.addOption("inline" /* Inline */, "Inline").addOption("right" /* Right */, "Right-aligned").addOption("below" /* Below */, "Below").setValue(this.plugin.settings.folderAlignment).onChange(async (value) => { + this.plugin.settings.folderAlignment = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }); + }); + } + } + renderRootSettings(containerEl) { + this.renderSeparator(containerEl); + new import_obsidian4.Setting(containerEl).setHeading().setName("Root: Same data as Notes").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.showSameCountsOnRoot).onChange(async (value) => { + this.plugin.settings.showSameCountsOnRoot = value; + await this.plugin.saveSettings(); + this.display(); + await this.plugin.updateDisplayedCounts(); + }) + ); + if (!this.plugin.settings.showSameCountsOnRoot) { + this.renderCountTypeSetting(containerEl, { + name: "1st data type to show", + oldCountType: this.plugin.settings.rootCountType, + setNewCountType: (value) => { + this.plugin.settings.rootCountType = value; + this.plugin.settings.rootCountConfig.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.rootCountType]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.rootCountType, + oldCountType: this.plugin.settings.rootCountConfig.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.rootCountConfig.$sessionCountType = value; + } + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.rootCountType, + oldSuffix: this.plugin.settings.rootCountConfig.customSuffix, + setNewSuffix: (value) => this.plugin.settings.rootCountConfig.customSuffix = value + }); + this.renderCountTypeSetting(containerEl, { + name: "2nd data type to show", + oldCountType: this.plugin.settings.rootCountType2, + setNewCountType: (value) => { + this.plugin.settings.rootCountType2 = value; + this.plugin.settings.rootCountConfig2.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.rootCountType2]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.rootCountType2, + oldCountType: this.plugin.settings.rootCountConfig2.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.rootCountConfig2.$sessionCountType = value; + } + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.rootCountType2, + oldSuffix: this.plugin.settings.rootCountConfig2.customSuffix, + setNewSuffix: (value) => this.plugin.settings.rootCountConfig2.customSuffix = value + }); + this.renderCountTypeSetting(containerEl, { + name: "3rd data type to show", + oldCountType: this.plugin.settings.rootCountType3, + setNewCountType: (value) => { + this.plugin.settings.rootCountType3 = value; + this.plugin.settings.rootCountConfig3.customSuffix = COUNT_TYPE_DEFAULT_SHORT_SUFFIXES[this.plugin.settings.rootCountType3]; + } + }); + this.renderSessionCountTypeSetting(containerEl, { + parentCountType: this.plugin.settings.rootCountType3, + oldCountType: this.plugin.settings.rootCountConfig3.$sessionCountType, + setNewCountType: (value) => { + this.plugin.settings.rootCountConfig3.$sessionCountType = value; + } + }); + this.renderCustomFormatSetting(containerEl, { + countType: this.plugin.settings.rootCountType3, + oldSuffix: this.plugin.settings.rootCountConfig3.customSuffix, + setNewSuffix: (value) => this.plugin.settings.rootCountConfig3.customSuffix = value + }); + if (this.plugin.settings.useAdvancedFormatting) { + new import_obsidian4.Setting(containerEl).setName("Data type separator").addText( + (text) => text.setValue(this.plugin.settings.rootPipeSeparator).onChange(async (value) => { + this.plugin.settings.rootPipeSeparator = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + if (!this.plugin.settings.useAdvancedFormatting) { + new import_obsidian4.Setting(containerEl).setName("Abbreviate descriptions").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.rootAbbreviateDescriptions).onChange(async (value) => { + this.plugin.settings.rootAbbreviateDescriptions = value; + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + } + } + renderAdvancedSettings(containerEl) { + this.renderSeparator(containerEl); + new import_obsidian4.Setting(containerEl).setHeading().setName("Show advanced options").setDesc("Language compatibility and fine-tuning").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.showAdvanced).onChange(async (value) => { + this.plugin.settings.showAdvanced = value; + await this.plugin.saveSettings(); + this.display(); + }) + ); + if (this.plugin.settings.showAdvanced) { + const opacityChanged = async (value) => { + this.plugin.settings.labelOpacity = Math.clamp(value, 0, 1); + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }; + new import_obsidian4.Setting(containerEl).setName("Label opacity").setDesc("Increase this value to make all count labels in the File Explorer more visible.").addSlider((slider) => { + slider.setLimits(0, 1, 0.05).setDynamicTooltip().setValue(this.plugin.settings.labelOpacity).onChange((0, import_obsidian4.debounce)(opacityChanged.bind(this), 500)); + }); + const includePathsChanged = async (txt, value) => { + this.plugin.settings.includeDirectories = value; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }; + new import_obsidian4.Setting(containerEl).setName("Include file/folder names").setDesc( + "Only count paths matching the indicated term(s). Case-sensitive, comma-separated. Defaults to all files. Any term starting with ! will be excluded instead of included." + ).addText((txt) => { + txt.setPlaceholder("").setValue(this.plugin.settings.includeDirectories).onChange((0, import_obsidian4.debounce)(includePathsChanged.bind(this, txt), 1e3)); + }); + new import_obsidian4.Setting(containerEl).setName("Exclude comments").setDesc( + "Exclude %%Obsidian%% and comments from counts. May affect performance on large vaults." + ).addToggle( + (toggle) => toggle.setValue(this.plugin.settings.excludeComments).onChange(async (value) => { + this.plugin.settings.excludeComments = value; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }) + ); + new import_obsidian4.Setting(containerEl).setName("Exclude code blocks").setDesc( + "Exclude ```code blocks``` (e.g. DataView snippets) from all counts. May affect performance on large vaults." + ).addToggle( + (toggle) => toggle.setValue(this.plugin.settings.excludeCodeBlocks).onChange(async (value) => { + this.plugin.settings.excludeCodeBlocks = value; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }) + ); + new import_obsidian4.Setting(containerEl).setName("Exclude non-visible portions of links").setDesc( + "For external links, exclude the URI from all counts. For internal links with aliases, only count the alias. May affect performance on large vaults." + ).addToggle( + (toggle) => toggle.setValue(this.plugin.settings.excludeNonVisibleLinkPortions).onChange(async (value) => { + this.plugin.settings.excludeNonVisibleLinkPortions = value; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }) + ); + new import_obsidian4.Setting(containerEl).setName("Exclude footnotes").setDesc( + "Exclude footnotes[^1] from counts. May affect performance on large vaults." + ).addToggle( + (toggle) => toggle.setValue(this.plugin.settings.excludeFootnotes).onChange(async (value) => { + this.plugin.settings.excludeFootnotes = value; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }) + ); + new import_obsidian4.Setting(containerEl).setName("Character count method").setDesc("For language compatibility").addDropdown((drop) => { + drop.addOption("AllCharacters" /* StringLength */, "All characters").addOption( + "ExcludeWhitespace" /* ExcludeWhitespace */, + "Exclude whitespace" + ).setValue(this.plugin.settings.characterCountType).onChange(async (value) => { + this.plugin.settings.characterCountType = value; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }); + }); + new import_obsidian4.Setting(containerEl).setName("Page count method").setDesc("For language compatibility").addDropdown((drop) => { + drop.addOption("ByWords" /* ByWords */, "Words per page").addOption("ByChars" /* ByChars */, "Characters per page").setValue(this.plugin.settings.pageCountType).onChange(async (value) => { + this.plugin.settings.pageCountType = value; + await this.plugin.saveSettings(); + this.display(); + await this.plugin.updateDisplayedCounts(); + }); + }); + const wordsPerMinuteChanged = async (txt, value) => { + const asNumber = Number(value); + const isValid = !isNaN(asNumber) && asNumber > 0; + txt.inputEl.style.borderColor = isValid ? null : "red"; + this.plugin.settings.wordsPerMinute = isValid ? Number(value) : 265; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }; + new import_obsidian4.Setting(containerEl).setName("Words per minute").setDesc( + "Used to calculate Reading Time. 265 is the average speed of an English-speaking adult." + ).addText((txt) => { + txt.setPlaceholder("265").setValue(this.plugin.settings.wordsPerMinute.toString()).onChange((0, import_obsidian4.debounce)(wordsPerMinuteChanged.bind(this, txt), 1e3)); + }); + const charsPerMinuteChanged = async (txt, value) => { + const asNumber = Number(value); + const isValid = !isNaN(asNumber) && asNumber > 0; + txt.inputEl.style.borderColor = isValid ? null : "red"; + this.plugin.settings.charsPerMinute = isValid ? Number(value) : 500; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }; + new import_obsidian4.Setting(containerEl).setName("CJK characters per minute").setDesc( + "Used to calculate Reading Time. 500 is the average speed for CJK texts." + ).addText((txt) => { + txt.setPlaceholder("500").setValue(this.plugin.settings.charsPerMinute.toString()).onChange((0, import_obsidian4.debounce)(charsPerMinuteChanged.bind(this, txt), 1e3)); + }); + if (this.plugin.settings.pageCountType === "ByWords" /* ByWords */) { + const wordsPerPageChanged = async (txt, value) => { + const asNumber = Number(value); + const isValid = !isNaN(asNumber) && asNumber > 0; + txt.inputEl.style.borderColor = isValid ? null : "red"; + this.plugin.settings.wordsPerPage = isValid ? Number(value) : 300; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }; + new import_obsidian4.Setting(containerEl).setName("Words per page").setDesc( + "Used for page count. 300 is standard in English language publishing." + ).addText((txt) => { + txt.setPlaceholder("300").setValue(this.plugin.settings.wordsPerPage.toString()).onChange((0, import_obsidian4.debounce)(wordsPerPageChanged.bind(this, txt), 1e3)); + }); + } + if (this.plugin.settings.pageCountType === "ByChars" /* ByChars */) { + new import_obsidian4.Setting(containerEl).setName("Include whitespace characters in page count").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.charsPerPageIncludesWhitespace).onChange(async (value) => { + this.plugin.settings.charsPerPageIncludesWhitespace = value; + await this.plugin.saveSettings(); + this.display(); + await this.plugin.initialize(); + }) + ); + const charsPerPageChanged = async (txt, value) => { + const asNumber = Number(value); + const isValid = !isNaN(asNumber) && asNumber > 0; + txt.inputEl.style.borderColor = isValid ? null : "red"; + const defaultCharsPerPage = 1500; + this.plugin.settings.charsPerPage = isValid ? Number(value) : defaultCharsPerPage; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }; + new import_obsidian4.Setting(containerEl).setName("Characters per page").setDesc( + `Used for page count. ${this.plugin.settings.charsPerPageIncludesWhitespace ? "2400 is common in Danish." : "1500 is common in German (Normseite)."}` + ).addText((txt) => { + txt.setPlaceholder("1500").setValue(this.plugin.settings.charsPerPage.toString()).onChange((0, import_obsidian4.debounce)(charsPerPageChanged.bind(this, txt), 1e3)); + }); + } + const dateFormatChanged = async (txt, value) => { + const isValid = typeof value === "string" && !!value.trim(); + this.plugin.settings.momentDateFormat = isValid ? value : ""; + await this.plugin.saveSettings(); + await this.plugin.initialize(); + }; + new import_obsidian4.Setting(containerEl).setName("Date format").setDesc("MomentJS date format to use for date strings").addText((txt) => { + txt.setPlaceholder("YYYY/MM/DD").setValue(this.plugin.settings.momentDateFormat).onChange((0, import_obsidian4.debounce)(dateFormatChanged.bind(this, txt), 1e3)); + }); + new import_obsidian4.Setting(containerEl).setName("Debug mode").setDesc("Log debugging information to the developer console").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.debugMode).onChange(async (value) => { + this.plugin.settings.debugMode = value; + this.plugin.debugHelper.setDebugMode(value); + this.plugin.fileHelper.setDebugMode(value); + await this.plugin.saveSettings(); + }) + ); + } + } + renderReanalyzeButton(containerEl) { + this.renderSeparator(containerEl); + new import_obsidian4.Setting(containerEl).setHeading().setName("Recount all documents").setDesc( + "If changes have occurred outside of Obsidian, you may need to trigger a manual recount" + ).addButton( + (button) => button.setButtonText("Recount").setCta().onClick(async () => { + button.disabled = true; + await this.plugin.initialize(); + button.setButtonText("Done"); + button.removeCta(); + setTimeout(() => { + button.setButtonText("Recount"); + button.setCta(); + button.disabled = false; + }, 1e3); + }) + ); + } + renderDonationButton(containerEl) { + this.renderSeparator(containerEl); + const label = containerEl.createEl("div", { + cls: [ + "setting-item", + "setting-item-heading", + "novel-word-count-settings-header", + "novel-word-count-donation-line" + ] + }); + label.createEl("div", { + text: "Enjoying this plugin? Want more features?" + }); + const button = label.createEl("div"); + button.innerHTML = `Buy Me a Coffee at ko-fi.com`; + } + renderCountTypeSetting(containerEl, config) { + new import_obsidian4.Setting(containerEl).setName(config.name).setDesc(getDescription(config.oldCountType)).addDropdown((drop) => { + for (const countType of COUNT_TYPES) { + drop.addOption(countType, COUNT_TYPE_DISPLAY_STRINGS[countType]); + } + drop.setValue(config.oldCountType).onChange(async (value) => { + config.setNewCountType(value); + await this.plugin.saveSettings(); + this.display(); + await this.plugin.updateDisplayedCounts(); + }); + }); + } + renderSessionCountTypeSetting(containerEl, config) { + if (config.parentCountType !== "tracksession" /* TrackSession */) { + return; + } + new import_obsidian4.Setting(containerEl).setDesc("[Track Session] Session count type").addDropdown((drop) => { + for (const countType of SESSION_COUNT_TYPES) { + drop.addOption(countType, COUNT_TYPE_DISPLAY_STRINGS[countType]); + } + drop.setValue(config.oldCountType).onChange(async (value) => { + config.setNewCountType(value); + await this.plugin.saveSettings(); + this.display(); + await this.plugin.updateDisplayedCounts(); + }); + }); + } + renderCustomFormatSetting(containerEl, config) { + if (!this.plugin.settings.useAdvancedFormatting || config.countType === "none" /* None */) { + return; + } + if (UNFORMATTABLE_COUNT_TYPES.includes(config.countType)) { + new import_obsidian4.Setting(containerEl).setDesc( + `[${COUNT_TYPE_DISPLAY_STRINGS[config.countType]}] can't be formatted.` + ); + } else { + new import_obsidian4.Setting(containerEl).setDesc( + `[${COUNT_TYPE_DISPLAY_STRINGS[config.countType]}] Custom suffix` + ).addText( + (text) => text.setValue(config.oldSuffix).onChange(async (value) => { + config.setNewSuffix(value); + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + } + renderFrontmatterKeySetting(containerEl, config) { + if (config.countType !== "frontmatterKey" /* FrontmatterKey */) { + return; + } + new import_obsidian4.Setting(containerEl).setDesc( + `[${COUNT_TYPE_DISPLAY_STRINGS["frontmatterKey" /* FrontmatterKey */]}] Key name` + ).addText( + (text) => text.setValue(config.oldKey).onChange(async (value) => { + config.setNewKey(value); + await this.plugin.saveSettings(); + await this.plugin.updateDisplayedCounts(); + }) + ); + } + renderSeparator(containerEl) { + containerEl.createEl("hr", { + cls: "novel-word-count-hr" + }); + } +}; + +// main.ts +var import_obsidian5 = require("obsidian"); +var NovelWordCountPlugin = class extends import_obsidian5.Plugin { + constructor(app, manifest) { + super(app, manifest); + this.debugHelper = new DebugHelper(); + this.FIVE_MINUTES = 5 * 60 * 1e3; + this.saveSettingsDebounced = (0, import_obsidian5.debounce)(this.saveSettings, this.FIVE_MINUTES, false); + this.fileHelper = new FileHelper(this.app, this); + this.eventHelper = new EventHelper( + this, + app, + this.debugHelper, + this.fileHelper + ); + this.nodeLabelHelper = new NodeLabelHelper(this); + this.savedDataHelper = new SavedDataHelper(this); + } + get settings() { + return this.savedData.settings; + } + // LIFECYCLE + async onload() { + this.savedData = await this.savedDataHelper.getSavedData(); + this.fileHelper.setDebugMode(this.savedData.settings.debugMode); + this.debugHelper.setDebugMode(this.savedData.settings.debugMode); + this.debugHelper.debug(`Detected locales: [${navigator.languages}]`); + this.debugHelper.debug("onload lifecycle hook"); + this.addSettingTab(new NovelWordCountSettingTab(this.app, this)); + this.addCommand({ + id: "recount-vault", + name: "Recount all notes / Reset session", + callback: async () => { + this.debugHelper.debug("[Recount] command triggered"); + await this.initialize(); + } + }); + this.addCommand({ + id: "cycle-count-type", + name: "Show next data type (1st position)", + callback: async () => { + this.debugHelper.debug("[Cycle next data type] command triggered"); + this.settings.countType = COUNT_TYPES[(COUNT_TYPES.indexOf(this.settings.countType) + 1) % COUNT_TYPES.length]; + await this.saveSettings(); + this.updateDisplayedCounts(); + } + }); + this.addCommand({ + id: "toggle-abbreviate", + name: "Toggle abbreviation on Notes", + callback: async () => { + this.debugHelper.debug( + "[Toggle abbrevation - Notes] command triggered" + ); + this.settings.abbreviateDescriptions = !this.settings.abbreviateDescriptions; + await this.saveSettings(); + this.updateDisplayedCounts(); + } + }); + for (const countType of COUNT_TYPES) { + this.addCommand({ + id: `set-count-type-${countType}`, + name: `Show ${COUNT_TYPE_DISPLAY_STRINGS[countType]} (1st position)`, + callback: async () => { + this.debugHelper.debug( + `[Set count type to ${countType}] command triggered` + ); + this.settings.countType = countType; + await this.saveSettings(); + this.updateDisplayedCounts(); + } + }); + } + this.eventHelper.handleEvents(); + this.initialize(); + } + async onunload() { + await this.saveSettings(); + } + // SETTINGS + async saveSettings() { + this.debugHelper.debug("Saving to data.json."); + await this.saveData(this.savedData); + } + // PUBLIC + /** + Called with (true) when the plugin initializes or the user clicks Reanalyze. + Called with (false) every second while waiting for the file explorer to load. + */ + async initialize(reinitializeAllCounts = true) { + this.debugHelper.debug("initialize"); + this.app.workspace.onLayoutReady(async () => { + if (reinitializeAllCounts) { + await this.eventHelper.reinitializeAllCounts(); + } + try { + await this.getFileExplorerLeaf(); + await this.updateDisplayedCounts(); + } catch (err) { + this.debugHelper.debug("Error while updating displayed counts"); + this.debugHelper.error(err); + setTimeout(() => { + this.initialize(false); + }, 1e3); + } + }); + } + async updateDisplayedCounts(file = null) { + var _a, _b; + const debugEnd = this.debugHelper.debugStart( + `updateDisplayedCounts [${file == null ? "ALL" : file.path}]` + ); + if (!Object.keys(this.savedData.cachedCounts).length) { + this.debugHelper.debug("No cached data found; skipping update."); + return; + } + let fileExplorerLeaf; + try { + fileExplorerLeaf = await this.getFileExplorerLeaf(); + } catch (err) { + this.debugHelper.debug("File explorer leaf not found; skipping update."); + return; + } + this.setContainerClass(fileExplorerLeaf); + const fileExplorerView = fileExplorerLeaf.view; + const fileItems = fileExplorerView.fileItems; + if ((_a = fileExplorerView == null ? void 0 : fileExplorerView.headerDom) == null ? void 0 : _a.navButtonsEl) { + const counts = this.fileHelper.getCachedDataForPath( + this.savedData.cachedCounts, + "/" + ); + fileExplorerView.headerDom.navButtonsEl.setAttribute( + "data-novel-word-count-plugin", + this.nodeLabelHelper.getNodeLabel(counts) + ); + document.documentElement.style.setProperty("--novel-word-count-opacity", `${this.settings.labelOpacity}`); + } + if (file) { + const relevantItems = Object.keys(fileItems).filter( + (path) => file.path.includes(path) + ); + this.debugHelper.debug( + "Setting display counts for", + relevantItems.length, + "fileItems matching path", + file.path + ); + } else { + this.debugHelper.debug( + `Setting display counts for ${Object.keys(fileItems).length} fileItems` + ); + } + for (const path in fileItems) { + if (file && (!file.path.includes(path) || file.path === "/")) { + continue; + } + const counts = this.fileHelper.getCachedDataForPath( + this.savedData.cachedCounts, + path + ); + const item = fileItems[path]; + ((_b = item.titleEl) != null ? _b : item.selfEl).setAttribute( + "data-novel-word-count-plugin", + this.nodeLabelHelper.getNodeLabel(counts) + ); + } + debugEnd(); + } + // FUNCTIONALITY + async getFileExplorerLeaf() { + return new Promise((resolve, reject) => { + let foundLeaf = null; + this.app.workspace.iterateAllLeaves((leaf) => { + if (foundLeaf) { + return; + } + const view = leaf.view; + if (!view || !view.fileItems) { + return; + } + foundLeaf = leaf; + resolve(foundLeaf); + }); + if (!foundLeaf) { + reject(Error("Could not find file explorer leaf.")); + } + }); + } + setContainerClass(leaf) { + const container = leaf.view.containerEl; + container.toggleClass(`novel-word-count--active`, true); + const notePrefix = `novel-word-count--note-`; + const folderPrefix = `novel-word-count--folder-`; + const alignmentClasses = ALIGNMENT_TYPES.map((at) => notePrefix + at).concat(ALIGNMENT_TYPES.map((at) => folderPrefix + at)); + for (const ac of alignmentClasses) { + container.toggleClass(ac, false); + } + container.toggleClass(notePrefix + this.settings.alignment, true); + const folderAlignment = this.settings.showSameCountsOnFolders ? this.settings.alignment : this.settings.folderAlignment; + container.toggleClass(folderPrefix + folderAlignment, true); + } +}; + + +/* nosourcemap */ \ No newline at end of file diff --git a/.obsidian/plugins/novel-word-count/manifest.json b/.obsidian/plugins/novel-word-count/manifest.json new file mode 100644 index 0000000..999859c --- /dev/null +++ b/.obsidian/plugins/novel-word-count/manifest.json @@ -0,0 +1,11 @@ +{ + "id": "novel-word-count", + "name": "Novel word count", + "version": "4.6.0", + "minAppVersion": "0.13.31", + "description": "Displays a word count (and more!) for each file, folder and vault in the File Explorer pane.", + "author": "Isaac Lyman", + "authorUrl": "https://isaaclyman.com", + "isDesktopOnly": false, + "fundingUrl": "https://ko-fi.com/isaaclyman" +} \ No newline at end of file diff --git a/.obsidian/plugins/novel-word-count/styles.css b/.obsidian/plugins/novel-word-count/styles.css new file mode 100644 index 0000000..e70a345 --- /dev/null +++ b/.obsidian/plugins/novel-word-count/styles.css @@ -0,0 +1,129 @@ +.novel-word-count--active .nav-header .nav-buttons-container { + flex-wrap: wrap !important; +} +.novel-word-count--active .nav-header .nav-buttons-container::after { + content: attr(data-novel-word-count-plugin); + display: block; + font-size: 0.8em; + max-width: calc(100% - 20px); + min-width: 0; + opacity: var(--novel-word-count-opacity); + overflow: hidden; + padding: 0 4px; + position: relative; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; +} + +.novel-word-count--active .nav-files-container .nav-file-title { + align-items: baseline; + unicode-bidi: isolate; +} +.novel-word-count--active .nav-files-container .nav-file-title::after { + content: attr(data-novel-word-count-plugin); + flex: 1 0 auto; + font-size: 0.8em; + max-width: calc(100% - 20px); + min-width: 0; + opacity: var(--novel-word-count-opacity); + order: 1; + overflow: hidden; + padding: 0 4px; + position: relative; + text-overflow: ellipsis; + white-space: nowrap; + unicode-bidi: isolate; + direction: ltr; +} +.novel-word-count--active .nav-files-container .nav-file-title-content { + min-width: 20px; + unicode-bidi: isolate; +} +.novel-word-count--note-right .nav-files-container .nav-file-title-content { + flex: 1 1 0; +} +.novel-word-count--note-right .nav-files-container .nav-file-title::after { + flex: none; + order: 6; + overflow: hidden; +} +.novel-word-count--note-below .nav-files-container .nav-file-title { + flex-wrap: wrap; +} +.novel-word-count--note-below .nav-files-container .nav-file-title-content { + flex: 100%; +} +.novel-word-count--note-below .nav-files-container .nav-file-title::after { + display: inline-block; + margin-top: -2px; + max-width: 100%; + overflow: hidden; + padding: 0; + text-overflow: ellipsis; + white-space: nowrap; +} +.novel-word-count--active .nav-files-container .nav-folder-title { + align-items: baseline; + unicode-bidi: isolate; +} +.novel-word-count--active .nav-files-container .nav-folder-title::after { + content: attr(data-novel-word-count-plugin); + flex: 1 0 auto; + font-size: 0.8em; + max-width: calc(100% - 20px); + min-width: 0; + opacity: var(--novel-word-count-opacity); + order: 1; + overflow: hidden; + padding: 0 4px; + position: relative; + text-overflow: ellipsis; + white-space: nowrap; + unicode-bidi: isolate; + direction: ltr; +} +.novel-word-count--active .nav-files-container .nav-folder-title-content { + min-width: 20px; + unicode-bidi: isolate; +} +.novel-word-count--folder-right .nav-files-container .nav-folder-title-content { + flex: 1 1 0; +} +.novel-word-count--folder-right .nav-files-container .nav-folder-title::after { + flex: none; + order: 6; + overflow: hidden; +} +.novel-word-count--folder-below .nav-files-container .nav-folder-title { + flex-wrap: wrap; +} +.novel-word-count--folder-below .nav-files-container .nav-folder-title-content { + flex: 100%; +} +.novel-word-count--folder-below .nav-files-container .nav-folder-title::after { + display: inline-block; + margin-top: -2px; + max-width: 100%; + overflow: hidden; + padding: 0; + text-overflow: ellipsis; + white-space: nowrap; +} + +.novel-word-count-settings-header { + align-items: baseline; +} + +.novel-word-count-donation-line { + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.novel-word-count-hr { + border-color: #ccc; + margin: 1rem 0; +} diff --git a/1960-04-04_durant-daily-democrat.md b/1960-04-04_durant-daily-democrat.md index e8456ce..4d2679e 100644 --- a/1960-04-04_durant-daily-democrat.md +++ b/1960-04-04_durant-daily-democrat.md @@ -5,6 +5,7 @@ tags: - authorship/other - destiny/uncertain - status/complete + - exclude-from-word-count title: Rev. William Alexander And Wife Killed In Airplane Crash url: https://gateway.okhistory.org/ark:/67531/metadc2193346/ source: Durant Daily Democrat (Durant, Okla.), Vol. 59, No. 172, Ed. 1 Monday, April 4, 1960 diff --git a/2025-11-04_belle-meade-director-review.md b/2025-11-04_belle-meade-director-review.md new file mode 100644 index 0000000..4c57f26 --- /dev/null +++ b/2025-11-04_belle-meade-director-review.md @@ -0,0 +1,99 @@ +--- +id: +aliases: [] +tags: + - authorship/original + - destiny/permanent + - status/complete + - type/minutes +title: 2025-11-04 Belle Meade Director Review +--- +# 2025-11-04 Belle Meade Director Review + +## Takeoff Review + +Reviewed takeoff by system. + +### Retail Village Temporary Power + +Joel changed square foot budgets to temporary pole budgets only +due to minimal scope (warm shell). + +### Generator Scope + +Confirmed generator quotes include furnishing docking station. + +### Feeder Lengths + +Confirmed validity of longer feeder lengths: +Generator to Tower B + +### Grounding + +Takeoff appears to be missing some or all grounding. +To be added if necessary. + +### Subfeed Sizing + +Based on ampacity, subfeeds are oversized. +Sizing was per feeder schedule. +Takeoff approved unchanged. + +### Undercabinet Wiremold + +Multi-outlet assemblies above unit kitchen countertops were not taken off, +nor was branch wiring for the same. +Joel to confirm takeoff requirement with bid. + +### Amenity Homeruns + +No homeruns for amenity lighting or electrical were taken off. +Joel to add these. + +> [!info] Circuits per Raceway +> Corwin stated that--assuming no overriding specification-- +> up to 6 circuits in a raceway are permissible. + +### Lighting Control + +Lighting control takeoff was reviewed, +no changes were recommended. + +> [!info] Lighting Control Pre-Work +> Corwin stated that with the imminent changes to lighting control takeoff, +> it will be necessary for estimators to more intently consider the design: +> noting quantities of lighting zones and controllers, +> even where not explicitly shown. + +### Telecom + +Confirmed unit telecom requirements. + +Backbone was mistakenly taken off in Telecom. + +### Retail Fire Alarm + +Retail village fire alarm devices were taken off free-air, +Joel to substitute for EMT. + +## Extension Review + +Reviewed extension quantities and costs. +Of particular note were: + +* conduit +* wire +* cable +* wiring devices + +## Labor Plan Review + +Hours per square foot was lower than expected, +this was rationalized as being due +to the relatively high portion of garage and shell retail space. + +%% +"Openings per unit" was another metric considered-- +higher than expected in this case-- +however I didn't catch the significance of this. +%% diff --git a/90-day-performance-review.md b/90-day-performance-review.md index 67a7a93..b4468f1 100644 --- a/90-day-performance-review.md +++ b/90-day-performance-review.md @@ -6,6 +6,7 @@ tags: - occupational - status/complete - authorship/other + - exclude-from-word-count title: 90-Day Performance Review --- # 90-Day Performance Review diff --git a/accubid-setup.md b/accubid-setup.md index 6425b85..8a6a473 100644 --- a/accubid-setup.md +++ b/accubid-setup.md @@ -62,5 +62,17 @@ Upload extracted drawings to LiveCount ### Setup Breakdowns +Replace the `Area`s with those created in [[project-setup#Setup WBS]] + > [!important] > Do not copy Systems from WBS Accubid Setup. + +#### Create Typicals + +##### Create Unit Typicals + + + +##### Create Helper Typicals + +1. "Building X All Stairwells All Levels" diff --git a/construction-estimating-using-excel.md b/construction-estimating-using-excel.md index d17c780..8e8a82e 100644 --- a/construction-estimating-using-excel.md +++ b/construction-estimating-using-excel.md @@ -3,7 +3,7 @@ id: construction-estimating-using-excel aliases: [] tags: - authorship/original - - destiny/uncertain + - destiny/permanent - status/complete - topic/estimating - type/media-commentary diff --git a/convex-hull.md b/convex-hull.md new file mode 100644 index 0000000..4a2c678 --- /dev/null +++ b/convex-hull.md @@ -0,0 +1,72 @@ +--- +id: +aliases: [] +tags: [] +title: Convex Hull +--- +# Convex Hull + +[Convex Hull](https://en.wikipedia.org/wiki/Convex_hull) + +```tikz +\usepackage{pgfplots} +\pgfplotsset{compat=1.16} + +\begin{document} +\begin{tikzpicture} + \begin{axis}[ + axis equal, + xmin=0, xmax=3.5, + ymin=0, ymax=3.4, + grid=both, + xlabel={$x$}, ylabel={$y$}, + tick style={black!60}, + title={Convex Hull of a Point Set} + ] + % Point cloud + \addplot[ + only marks, + mark=*, + mark size=1.8pt + ] coordinates { + (0.5,0.5) + (1.0,2.0) + (2.0,1.0) + (2.5,2.2) + (3.0,0.5) + (1.8,3.0) + (0.2,2.5) + (3.2,1.5) + }; + + % Convex hull (listed in counterclockwise order) + \addplot[ + thick, + fill opacity=0.15, + fill=blue + ] coordinates { + (0.5,0.5) + (3.0,0.5) + (3.2,1.5) + (1.8,3.0) + (0.2,2.5) + } -- cycle; + + % (Optional) label hull vertices + \addplot[only marks, mark=*, mark size=2.2pt] coordinates { + (0.5,0.5) + (3.0,0.5) + (3.2,1.5) + (1.8,3.0) + (0.2,2.5) + }; + \node[anchor=north west] at (axis cs:0.5,0.5) {$H_1$}; + \node[anchor=north east] at (axis cs:3.0,0.5) {$H_2$}; + \node[anchor=west] at (axis cs:3.2,1.5) {$H_3$}; + \node[anchor=south] at (axis cs:1.8,3.0) {$H_4$}; + \node[anchor=east] at (axis cs:0.2,2.5) {$H_5$}; + \end{axis} +\end{tikzpicture} +\end{document} + +``` diff --git a/estimator-skills.md b/estimator-skills.md index 3611988..c6a4aeb 100644 --- a/estimator-skills.md +++ b/estimator-skills.md @@ -6,6 +6,7 @@ tags: - destiny/uncertain - occupational - status/incomplete + - exclude-from-word-count title: Estimator Skills --- # Estimator Skills diff --git a/ibc-construction-types.md b/ibc-construction-types.md index 0c5cbad..7abb67a 100644 --- a/ibc-construction-types.md +++ b/ibc-construction-types.md @@ -11,7 +11,7 @@ title: IBC Construction Types --- # IBC Construction Types -The International Building Code (IBC) +International Building Code (IBC) Section 602: Construction Classification lists 5 major construction types based on fire ratings/materials. ## 5-Over-1 Construction diff --git a/ibc-occupancy-classifications.md b/ibc-occupancy-classifications.md new file mode 100644 index 0000000..3cf1bcf --- /dev/null +++ b/ibc-occupancy-classifications.md @@ -0,0 +1,24 @@ +--- +id: +aliases: [] +tags: + - authorship/other-for-now + - destiny/permanent + - status/incomplete + - topic/construction + - type/encyclopedia +title: IBC Occupancy Classifications +--- +# IBC Occupancy Classifications + +International Building Code (IBC) Section 302: Occupancy Classification and Use Designation + +1. Assembly (see Section 303): Groups A-1, A-2, A-3, A-4 and A-5. +2. Business (see Section 304): Group B. +3. Educational (see Section 305): Group E. +4. Factory and Industrial (see Section 306): Groups F-1 and F-2. +5. High Hazard (see Section 307): Groups H-1, H-2, H-3, H-4 and H-5. +6. Institutional (see Section 308): Groups I-1, I-2, I-3 and I-4. +7. Mercantile (see Section 309): Group M. +8. Residential (see Section 310): Groups R-1, R-2, R-3 and R-4. +9. Storage (see Section 311): Groups S-1 and S-2. diff --git a/mike-holts-illustrated-guide-to-electrical-estimating.md b/mike-holts-illustrated-guide-to-electrical-estimating.md index af9f007..ce6b920 100644 --- a/mike-holts-illustrated-guide-to-electrical-estimating.md +++ b/mike-holts-illustrated-guide-to-electrical-estimating.md @@ -3,7 +3,7 @@ id: mike-holts-illustrated-guide-to-electrical-estimating aliases: [] tags: - authorship/original - - destiny/uncertain + - destiny/permanent - status/complete - topic/construction/electrical - topic/estimating diff --git a/misc-budgets-takeoff.md b/misc-budgets-takeoff.md index 77b096d..7902691 100644 --- a/misc-budgets-takeoff.md +++ b/misc-budgets-takeoff.md @@ -2,97 +2,83 @@ id: aliases: [] tags: + - authorship/original - destiny/permanent - occupational/takeoff - status/draft - type/guide - - authorship/original title: Misc Budgets --- # Misc Budgets ## Slab Deck -``` -Drawing = "N/A" -Area = "Typical - ..." -System = "EL - Electrical" -``` +* `Drawing` = "N/A" +* `Area` = "Typical - ..." +* `System` = "EL - Electrical" Create `Area` Typicals for every concrete slab floor: * 'All Building' * 1 each level except roof - * **HD:** 1 per Section + * _High Density:_ 1 per Section -``` -Phase = "Building - BOH, Storage & Common" -``` +`Phase` = "Building - BOH, Storage & Common" * 'All Garage' * 1 each level -``` -Phase = "Garage" -``` +`Phase` = "Garage" In each Typical: * Takeoff: `ITEM DATABASE`/`MISC PDI PRODUCT`/`MISC MATERIAL - SLAB/DECK & FEEDER`/`MISC MATERIAL - SLAB/DECK (NAILS, PAINT, TAPE, ETC = $250)` * 1 Takeoff each Typical - * _Count_ = 1 + * **Count** = 1 ## Temporary Power & Lighting ### Temp Power -``` -Area = "2 - Site" -Phase = "Temp Power" -System = "TPS - Temp Power Service (Site)" -BidItem = "1 - Site" -``` +* `Area` = "2 - Site" +* `Phase` = "Temp Power" +* `System` = "TPS - Temp Power Service (Site)" +* `BidItem` = "1 - Site" * Takeoff: `ITEM DATABASE`/`TEMPORARY POWER`/`TEMPORARY POWER - ... SERVICE` ### Temp Lighting (Building) -``` -Area = "01 - Temp Power Distribution Building" -Phase = "Temp Power" -System = "TPD - Temp Power Distribution (Gag. & Bldg.)" -BidItem = "3 - Building" -``` +* `Area` = "01 - Temp Power Distribution Building" +* `Phase` = "Temp Power" +* `System` = "TPD - Temp Power Distribution (Gag. & Bldg.)" +* `BidItem` = "3 - Building" Garden Styles: * Takeoff: `ITEM DATABASE`/`TEMPORARY POWER`/`TEMPORARY POWER - T POLE (EACH)` - * _Count_ = 1 per 150ft per building + * **Count** = 1 per 150ft per building All others: * Takeoff: `ITEM DATABASE`/`TEMPORARY POWER`/`* - TEMPORARY LIGHTING / PWR PNL (PER BLDG AREA SFT)` - * _Count_ = Building GSF = Total GSF - Garage GSF + * **Count** = Building GSF = Total GSF - Garage GSF ### Temp Lighting (Garage) -``` -Area = "01 - Temp Power Distribution Garage" -Phase = "Temp Power" -System = "TPD - Temp Power Distribution (Gag. & Bldg.)" -BidItem = "2 - Garage" -``` +* `Area` = "01 - Temp Power Distribution Garage" +* `Phase` = "Temp Power" +* `System` = "TPD - Temp Power Distribution (Gag. & Bldg.)" +* `BidItem` = "2 - Garage" * Takeoff: `ITEM DATABASE`/`TEMPORARY POWER`/`* - TEMPORARY LIGHTING / PWR PNL (PER BLDG AREA SFT)` - * _Count_ = Garage GSF + * **Count** = Garage GSF ## Irrigation Pumps -``` -Area = "2 - Site" -Phase = "Temp Power" -System = "MISC - Site Miscellaneous" -BidItem = "1 - Site" -``` +* `Area` = "2 - Site" +* `Phase` = "Temp Power" +* `System` = "MISC - Site Miscellaneous" +* `BidItem` = "1 - Site" Takeoff: `COMMON ASSEMBLIES`/`MECHANICAL CONNECTIONS (UP TO 100A)`/`PVC - LT NM FLEX (CARFLEX)`/`30A 3PH MECH CONN (200') 3/4" PVC 4#10 - CARFLEX` -* _Count_ = 3 +* **Count** = 3 * Prepend to name: "Irrigation Pumps - " diff --git a/nfpa-101_life-safety-code.md b/nfpa-101_life-safety-code.md index d11adce..f9b76d6 100644 --- a/nfpa-101_life-safety-code.md +++ b/nfpa-101_life-safety-code.md @@ -7,6 +7,7 @@ tags: - status/incomplete - topic/construction - type/media + - exclude-from-word-count title: "NFPA 101: Life Safety Code (2018)" --- # NFPA 101: Life Safety Code (2018) diff --git a/nfpa-70_100_definitions.md b/nfpa-70_100_definitions.md index 842b953..7afe58d 100644 --- a/nfpa-70_100_definitions.md +++ b/nfpa-70_100_definitions.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "NEC Article 100: Definitions" --- # NEC Article 100: Definitions diff --git a/nfpa-70_110_requirements-for-electrical-installations.md b/nfpa-70_110_requirements-for-electrical-installations.md index 27e88df..7c16ddf 100644 --- a/nfpa-70_110_requirements-for-electrical-installations.md +++ b/nfpa-70_110_requirements-for-electrical-installations.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "NEC Article 110: Requirements for Electrical Installations" --- # NEC Article 110: Requirements for Electrical Installations diff --git a/nfpa-70_210_branch-circuits.md b/nfpa-70_210_branch-circuits.md index eea1276..c476c9c 100644 --- a/nfpa-70_210_branch-circuits.md +++ b/nfpa-70_210_branch-circuits.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "NEC Article 210: Branch Circuits" --- # NEC Article 210: Branch Circuits diff --git a/nfpa-70_215_feeders.md b/nfpa-70_215_feeders.md index b2c21f1..00ffe22 100644 --- a/nfpa-70_215_feeders.md +++ b/nfpa-70_215_feeders.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: Article 215 Feeders --- # Article 215 Feeders diff --git a/nfpa-70_220_load-calculations.md b/nfpa-70_220_load-calculations.md index 97a0d5e..eba3a02 100644 --- a/nfpa-70_220_load-calculations.md +++ b/nfpa-70_220_load-calculations.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: Article 220 Branch-Circuit, Feeder, and Service Load Calculations --- # Article 220 Branch-Circuit, Feeder, and Service Load Calculations diff --git a/nfpa-70_300_general-requirements.md b/nfpa-70_300_general-requirements.md index 4f564e3..f842672 100644 --- a/nfpa-70_300_general-requirements.md +++ b/nfpa-70_300_general-requirements.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: --- # Article 300: General Requirements for Wiring Methods and Materials diff --git a/nfpa-70_310_conductors_for_general_wiring.md b/nfpa-70_310_conductors_for_general_wiring.md index 3ab0871..2c1f75a 100644 --- a/nfpa-70_310_conductors_for_general_wiring.md +++ b/nfpa-70_310_conductors_for_general_wiring.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: Article 310 Conductors for General Wiring --- # Article 310: Conductors for General Wiring diff --git a/nfpa-70_314_boxes.md b/nfpa-70_314_boxes.md index c27c80c..f911595 100644 --- a/nfpa-70_314_boxes.md +++ b/nfpa-70_314_boxes.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "Article 314: Outlet, Device, Pull, and Junction Boxes; Conduit Bodies; Fittings; and Handhole Enclosures" --- # Article 314: Outlet, Device, Pull, and Junction Boxes; Conduit Bodies; Fittings; and Handhole Enclosures diff --git a/nfpa-70_430_motors.md b/nfpa-70_430_motors.md index bc9c7c5..3f56504 100644 --- a/nfpa-70_430_motors.md +++ b/nfpa-70_430_motors.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "Article 430: Motors, Motor Circuits, and Controllers" --- # Article 430: Motors, Motor Circuits, and Controllers diff --git a/nfpa-70_450_transformers.md b/nfpa-70_450_transformers.md index f285495..ad72f2f 100644 --- a/nfpa-70_450_transformers.md +++ b/nfpa-70_450_transformers.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "Article 450: Transformers and Transformer Vaults (Including Secondary Ties)" --- # Article 450: Transformers and Transformer Vaults (Including Secondary Ties) diff --git a/nfpa-70_520_theaters.md b/nfpa-70_520_theaters.md index 1d526e5..c240a96 100644 --- a/nfpa-70_520_theaters.md +++ b/nfpa-70_520_theaters.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "Article 520: Theaters, Audience Areas of Motion Picture and Television Studios, Performance Areas, and Similar Locations" --- # Article 520: Theaters, Audience Areas of Motion Picture and Television Studios, Performance Areas, and Similar Locations diff --git a/nfpa-70_national-electric-code.md b/nfpa-70_national-electric-code.md index 91e464b..7367c94 100644 --- a/nfpa-70_national-electric-code.md +++ b/nfpa-70_national-electric-code.md @@ -8,6 +8,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "NFPA 70: National Electric Code" --- # NFPA 70: National Electric Code diff --git a/nfpa-72_national-fire-alarm-code.md b/nfpa-72_national-fire-alarm-code.md index 31a0b1c..5d44512 100644 --- a/nfpa-72_national-fire-alarm-code.md +++ b/nfpa-72_national-fire-alarm-code.md @@ -7,6 +7,7 @@ tags: - status/incomplete - topic/construction/electrical - type/media + - exclude-from-word-count title: "NFPA 72: National Fire Alarm and Signaling Code (2019)" --- # NFPA 72: National Fire Alarm and Signaling Code (2019) diff --git a/note-taking.md b/note-taking.md index 9dae4e0..5589fe1 100644 --- a/note-taking.md +++ b/note-taking.md @@ -16,6 +16,7 @@ title: Note-Taking Some say they take notes to remember now, that by writing the thing down they commit it to memory, and the note itself is ancillary. + That's not me at all. I don't remember writing half of what's in [[this-notebook]]. My notes allow me to forget things I _know_ @@ -24,8 +25,13 @@ to make room for ideas I'm not decided on. ## Properties of Good Notes Good notes are _legible_ and their meaning is clear. +It is not enough to know what you mean now, +you must write with clarity sufficient for an outsider to understand, +because eventually it will be you. -## `TALK` +%% + +## TALK This note is intended for @@ -36,7 +42,11 @@ There are bad media for note-taking * print +*** + Opinion, possibly industry dependent: good notes are _text-first_. It can be difficult to explain certain concepts without visuals and that's all the more reason to try. + +%% \ No newline at end of file diff --git a/sleeving-takeoff.md b/sleeving-takeoff.md index 411a649..44e9f8d 100644 --- a/sleeving-takeoff.md +++ b/sleeving-takeoff.md @@ -15,5 +15,14 @@ Provide sleeves for all conduits passing through floors. `ITEM DATABASE`/`HILTI`/`CAST-IN DEVICE CP 680-...` -* Slab Deck => P (Plastic - Combustible) -* Wood Frame => M (Metal - Non-Combustible) +* _Slab Deck:_ P (Plastic - Combustible) +* _Wood Frame:_ M (Metal - Non-Combustible) + +> [!important] +> The term "sleeve" may refer to +> * a short length of conduit +> * a Hilti-type firestop sleeve assembly +> * a short length of conduit +> _in_ a Hilti-type firestop sleeve assembly +> +> Seek additional clarification. diff --git a/the-failure-of-risk-management.md b/the-failure-of-risk-management.md index 0af85d6..c25a324 100644 --- a/the-failure-of-risk-management.md +++ b/the-failure-of-risk-management.md @@ -2,11 +2,11 @@ id: the-failure-of-risk-management aliases: [] tags: + - authorship/original - destiny/permanent - status/complete - topic/risk - type/media-commentary - - authorship/original title: _The Failure of Risk Management_ --- # _The Failure of Risk Management_ @@ -45,30 +45,33 @@ Qualitative risk analysis (i.e. risk matrices, scoring charts) departs from legitimate statistical methodology and has no robust evidence to suggest its efficacy. -There is good reason to believe that such methods -are deleterious to their intended purpose -in contradiction to the common response +In fact, there is good reason to believe that such methods +are _deleterious_ to their intended purpose, +in contradiction to the common refrain that they are "better than nothing". ### Utility as a Measure of Value Expected Value (Probability × Magnitude) -alone can not predict or inform risky decisions, +alone cannot predict or inform risky decisions, except for risk-neutral parties, -but people and organizations are risk-averse. +and people and organizations are risk-averse. Game 1: Which would you pick? * Option 1: a 100% chance to receive $10,000 * Option 2: a 10% chance to receive $100,000 Most people, being risk-averse, will pick option 1. -Suppose the prize of option 1 were lowered + +Suppose the payout of option 1 were lowered until you would pick option 2. That value is your **Certain Monetary Equivalent (CME)** for a 10% chance of $100,000. -For risk-neutral parties, expected value = CME +For risk-neutral parties, expected value would equal CME + +*** Another factor at play here is that utility is not proportional to monetary value. @@ -103,10 +106,22 @@ where $Pr$ is the probability of Payoff. ### Expert Opinion Must Be ~~Adjusted~~ -Expert opinion is valuable despite its flaws. +Expert opinion is valuable, but its weaknesses must be compensated for. +Experts tend to be good at creating heuristics, +but do not apply them consistently in practice. + +> [!example] +> Chapter 7 describes a study where individual experts +> were shown to estimate risk differently for identical cases. + +> [!example] p. 198 +> Models based on expert opinion consistently outperform the same experts. + +#### Estimator Calibration + The book details the statistically observable tendency for people to underestimate risk and to be overconfident in their beliefs. It describes the process of "calibration" @@ -115,19 +130,9 @@ and make predictions far more accurately. See [[estimator-calibration]] for more. -Experts tend to be good at creating heuristics, -but do not apply them consistently in practice. - -> [!example] -> Chapter 7 describes a study where individual experts -> were shown to estimate risk differently for identical cases. - Chapter 13 introduces the [Brier Score](https://en.wikipedia.org/wiki/Brier_score) as a method of evaluating the performance of an estimator, -evaluated as the mean squared error of their forecasts. - -> [!example] p. 198 -> Models based on expert opinion consistently outperform the same experts. +equal to the mean squared error of their forecasts. ### Luck Looks Like Skill @@ -142,19 +147,21 @@ to overvalue competence and undervalue luck in the role of achieving improbable accomplishments as the "Red Baron effect". -This the unstated other half of the **law of large numbers**, -that improbable events become likely with increased sampling. +This the unstated other half of the **law of large numbers**: +improbable events become likely with increased sampling. -How many success stories are simply cases of winning a coin flipping tournament? +> How many success stories +> are simply cases of winning a coin flipping tournament? ### Qualitative Labels are Problematic > [!example] p. 170 (pp.) -> Experts do not agree on the bounds of terms expressing probability. -> "Likely" vs. "Very Likely" +> Experts do not agree on the bounds of terms expressing probability +> (e.g. "Likely" vs. "Very Likely"). > [!example] p. 182 (pp.) -> risk matrix type bucketing tends to inflate the significance of small risks. +> risk matrix type bucketing +> tends to inflate the significance of small risks. ### There's Always Enough Data @@ -169,7 +176,7 @@ that any industry is so niche that data sufficient for quantitative models does not exist. -> [!quote] Fallacy of Close Analogy - p.236 +> [!quote] Fallacy of Close Analogy (p.236) > ...the belief that unless two things are identical in every way, > nothing learned from one can be applied to the other. @@ -212,17 +219,26 @@ to dismiss quantitative methods as inappropriate for their industry-specific ris > and therefore chooses Car B. > The buyer is committing the _exsupero ursus_ fallacy. -Based on this strawman it is clear Hubbard believes his detractors are _correct_ +This and the other false equivalence analogy +that is the namesake of the fallacy show that, +while Hubbard believes his detractors are _correct_ that qualitative methods can not capture the entire nuance of risk probability, -but that they are failing to acknowledge that their preferred alternatives +he believes they are failing to acknowledge that their preferred alternatives are not demonstrably more effective at doing so. -The nuance Hubbard dismisses without addressing -is the possibility of model _improvement_. +There is an obvious reason why a decision-maker +might prefer a human expert over a heuristic algorithm, +even if the algorithm is demonstrated +to outperform the human in all relevant metrics: +_Adaptability_. + +It's likely that this preference is demonstrably unreasonable in many or most cases, +but that it isn't acknowledged severely weakens Hubbard's argument. + A most competent detractor would be aware of the apparent contradiction but argue that their methods will eventually surpass quantitative methods if they are further developed. -Such a position would additionally contextualize Hubbard's observations +Such a position would also contextualize Hubbard's observations that detractors become emotional in their defense. To them, Hubbard's methods represent an attractive short-term gain that would exclude a long-term payoff. diff --git a/the-story-of-ymar.md b/the-story-of-ymar.md index ba9dc8b..49d2725 100644 --- a/the-story-of-ymar.md +++ b/the-story-of-ymar.md @@ -6,6 +6,7 @@ tags: - authorship/other - status/incomplete - topic/hobbies + - exclude-from-word-count title: The Story of Ymar description: | An excerpt from Chapter 17 of _The Shadow of the Torturer_ by Gene Wolfe, diff --git a/topics-to-revisit.md b/topics-to-revisit.md index 2d5d24f..621290d 100644 --- a/topics-to-revisit.md +++ b/topics-to-revisit.md @@ -13,10 +13,6 @@ that I think may be relevant later. [Topological Sorting](https://en.wikipedia.org/wiki/Topological_sorting) -## Convex Hull - -[Convex Hull](https://en.wikipedia.org/wiki/Convex_hull) - ## Quantities A **quantity** has a **value** and a **unit of measure** (e.g. 20ft) diff --git a/wiring-method-selection.md b/wiring-method-selection.md index 283e48d..acf01dc 100644 --- a/wiring-method-selection.md +++ b/wiring-method-selection.md @@ -59,12 +59,19 @@ See [[ibc-construction-types]] for more info. Cable type wiring methods (MC, NM, SE) may only be used where they will be concealed from view. -### PVC in Slab +### PVC In-Slab May require rigid stub-ups in certain cases, which could make EMT more cost-effective. Consult with the Senior Construction Estimator in this case. +> [!important] +> Be careful of ambiguous terminology in specifications and PDI proposals: +> "underground" and "below grade" are sometimes used inappropriately +> to describe PVC in-slab. +> It may be that rigid stub-ups are only necessary when emerging from grade (dirt), +> but not when emerging from the slab. + #### Garage Slab _Conventional Slab_: PVC in Slab