jekyll-theme-zer0 1.29.0 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +715 -2
- data/_data/README.md +2 -0
- data/_data/ai.yml +5 -3
- data/_data/ai_pricing.yml +36 -0
- data/_data/backlog.yml +169 -18
- data/_data/consumers.yml +48 -5
- data/_data/features.yml +146 -20
- data/_data/feedback_types.yml +17 -12
- data/_data/landing.yml +5 -2
- data/_data/navigation/quickstart.yml +4 -0
- data/_data/site_builder.yml +874 -0
- data/_data/theme-manifest.yml +122 -114
- data/_data/ui-text.yml +18 -0
- data/_includes/README.md +11 -1
- data/_includes/analytics/posthog.html +2 -2
- data/_includes/components/admin-links.html +2 -2
- data/_includes/components/admin-tabs.html +2 -2
- data/_includes/components/ai-chat.html +14 -11
- data/_includes/components/analytics-dashboard.html +8 -8
- data/_includes/components/author-bio.html +1 -1
- data/_includes/components/author-card.html +10 -2
- data/_includes/components/author-eeat.html +4 -4
- data/_includes/components/background-customizer.html +8 -8
- data/_includes/components/background-image.html +114 -0
- data/_includes/components/background-settings.html +28 -15
- data/_includes/components/collection-manager.html +5 -5
- data/_includes/components/component-showcase.html +13 -13
- data/_includes/components/config-editor.html +12 -12
- data/_includes/components/config-viewer.html +8 -8
- data/_includes/components/cookie-consent.html +11 -11
- data/_includes/components/cta-button.html +7 -2
- data/_includes/components/dev-shortcuts.html +7 -7
- data/_includes/components/env-dashboard.html +8 -8
- data/_includes/components/env-switcher.html +9 -9
- data/_includes/components/feature-card.html +2 -2
- data/_includes/components/halfmoon.html +2 -2
- data/_includes/components/info-section.html +36 -36
- data/_includes/components/js-cdn.html +15 -15
- data/_includes/components/language-toggle.html +4 -4
- data/_includes/components/mermaid.html +72 -435
- data/_includes/components/nanobar.html +5 -5
- data/_includes/components/nav-editor.html +2 -2
- data/_includes/components/nav-export.html +2 -2
- data/_includes/components/nav-overview.html +2 -2
- data/_includes/components/page-feedback.html +45 -30
- data/_includes/components/page-views-init.html +1 -1
- data/_includes/components/post-card.html +22 -22
- data/_includes/components/post-type-badge.html +2 -2
- data/_includes/components/powered-by.html +2 -2
- data/_includes/components/preview-image.html +6 -0
- data/_includes/components/quick-index.html +2 -2
- data/_includes/components/search-modal.html +27 -2
- data/_includes/components/searchbar.html +2 -2
- data/_includes/components/svg-background.html +2 -2
- data/_includes/components/theme-customizer.html +2 -2
- data/_includes/components/theme-info.html +6 -6
- data/_includes/components/theme-preview-gallery.html +22 -22
- data/_includes/content/giscus.html +2 -2
- data/_includes/content/intro.html +8 -8
- data/_includes/content/jsonld-faq.html +2 -2
- data/_includes/content/jsonld-software.html +2 -2
- data/_includes/content/seo.html +4 -4
- data/_includes/content/sitemap.html +27 -27
- data/_includes/content/toc.html +183 -183
- data/_includes/core/branding.html +6 -6
- data/_includes/core/console-capture.html +32 -74
- data/_includes/core/favicon.html +49 -7
- data/_includes/core/footer-fabs.html +17 -3
- data/_includes/core/footer.html +31 -18
- data/_includes/core/head.html +102 -90
- data/_includes/core/header.html +71 -52
- data/_includes/docs/bootstrap-docs.html +8 -8
- data/_includes/landing/landing-install-cards.html +2 -2
- data/_includes/landing/landing-quick-links.html +1 -1
- data/_includes/navigation/admin-nav.html +2 -2
- data/_includes/navigation/nav-tree.html +8 -8
- data/_includes/navigation/navbar.html +12 -12
- data/_includes/navigation/section-sidebar.html +16 -16
- data/_includes/navigation/sidebar-config.html +36 -2
- data/_includes/navigation/sidebar-left.html +15 -15
- data/_includes/navigation/sidebar-right.html +6 -6
- data/_includes/obsidian/full-graph.html +2 -2
- data/_includes/setup/claude-session.html +72 -0
- data/_includes/setup/prereq-checklist.html +90 -0
- data/_includes/setup/wizard.html +906 -291
- data/_includes/stats/stats-categories.html +8 -8
- data/_includes/stats/stats-header.html +14 -14
- data/_includes/stats/stats-metrics.html +12 -12
- data/_includes/stats/stats-no-data.html +12 -12
- data/_includes/stats/stats-overview.html +6 -6
- data/_includes/stats/stats-tags.html +8 -8
- data/_layouts/404.html +38 -24
- data/_layouts/admin.html +22 -22
- data/_layouts/article.html +39 -34
- data/_layouts/author.html +20 -20
- data/_layouts/authors.html +2 -2
- data/_layouts/book-abc.html +12 -12
- data/_layouts/book-story.html +15 -15
- data/_layouts/book.html +12 -12
- data/_layouts/collection.html +33 -33
- data/_layouts/cookbook.html +12 -12
- data/_layouts/default.html +27 -24
- data/_layouts/home.html +23 -23
- data/_layouts/index.html +10 -10
- data/_layouts/landing.html +17 -17
- data/_layouts/news.html +44 -44
- data/_layouts/note.html +38 -38
- data/_layouts/notebook.html +34 -34
- data/_layouts/recipe.html +24 -24
- data/_layouts/root.html +73 -55
- data/_layouts/section.html +23 -23
- data/_layouts/setup.html +3 -3
- data/_layouts/sitemap-collection.html +49 -49
- data/_layouts/stats.html +40 -40
- data/_layouts/tag.html +12 -12
- data/_layouts/welcome.html +21 -21
- data/_sass/components/_mermaid.scss +375 -0
- data/_sass/components/_setup-wizard.scss +569 -40
- data/_sass/core/_navbar.scss +11 -31
- data/_sass/layouts/_navbar-extras.scss +14 -4
- data/assets/css/main.scss +1 -0
- data/assets/js/ai-chat.js +47 -5
- data/assets/js/fleet-feedback-capture.js +124 -0
- data/assets/js/fleet-feedback.js +853 -0
- data/assets/js/mermaid-diagrams.js +1267 -0
- data/assets/js/modules/navigation/config.js +9 -6
- data/assets/js/modules/navigation/scroll-spy.js +315 -80
- data/assets/js/modules/theme/appearance.js +8 -2
- data/assets/js/obsidian-wiki-links.js +8 -3
- data/assets/js/page-feedback.js +125 -192
- data/assets/js/search-modal.js +26 -0
- data/assets/js/setup-wizard.js +2112 -361
- data/assets/js/site-builder.js +1834 -0
- data/assets/js/ui-enhancements.js +11 -3
- data/scripts/README.md +15 -0
- data/scripts/ai/README.md +38 -0
- data/scripts/ai/api_call.rb +124 -0
- data/scripts/ai/usage.rb +314 -0
- data/scripts/ai/usage_report.rb +225 -0
- data/scripts/ci/test_visual_evidence_autogen.py +341 -0
- data/scripts/ci/visual_evidence_autogen.py +1060 -0
- data/scripts/content-review.rb +20 -1
- data/scripts/test/integration/mermaid +22 -8
- data/scripts/test/lib/run_tests.sh +1 -0
- data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
- data/scripts/translate.rb +23 -1
- metadata +19 -2
data/_includes/content/toc.html
CHANGED
|
@@ -1,183 +1,183 @@
|
|
|
1
|
-
{% comment %} Feature: ZER0-037 {% endcomment %}
|
|
2
|
-
{% capture tocWorkspace %}
|
|
3
|
-
{% comment %}
|
|
4
|
-
Copyright (c) 2017 Vladimir "allejo" Jimenez
|
|
5
|
-
|
|
6
|
-
Permission is hereby granted, free of charge, to any person
|
|
7
|
-
obtaining a copy of this software and associated documentation
|
|
8
|
-
files (the "Software"), to deal in the Software without
|
|
9
|
-
restriction, including without limitation the rights to use,
|
|
10
|
-
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
-
copies of the Software, and to permit persons to whom the
|
|
12
|
-
Software is furnished to do so, subject to the following
|
|
13
|
-
conditions:
|
|
14
|
-
|
|
15
|
-
The above copyright notice and this permission notice shall be
|
|
16
|
-
included in all copies or substantial portions of the Software.
|
|
17
|
-
|
|
18
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
20
|
-
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
22
|
-
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
23
|
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
24
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
25
|
-
OTHER DEALINGS IN THE SOFTWARE.
|
|
26
|
-
{% endcomment %}
|
|
27
|
-
{% comment %}
|
|
28
|
-
Version 1.1.0
|
|
29
|
-
https://github.com/allejo/jekyll-toc
|
|
30
|
-
|
|
31
|
-
"...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way" ~jaybe
|
|
32
|
-
|
|
33
|
-
Usage:
|
|
34
|
-
{% include content/toc.html html=content sanitize=true class="inline_toc" id="my_toc" h_min=2 h_max=3 %}
|
|
35
|
-
|
|
36
|
-
Parameters:
|
|
37
|
-
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll
|
|
38
|
-
|
|
39
|
-
Optional Parameters:
|
|
40
|
-
* sanitize (bool) : false - when set to true, the headers will be stripped of any HTML in the TOC
|
|
41
|
-
* class (string) : '' - a CSS class assigned to the TOC
|
|
42
|
-
* id (string) : '' - an ID to assigned to the TOC
|
|
43
|
-
* h_min (int) : 1 - the minimum TOC header level to use; any header lower than this value will be ignored
|
|
44
|
-
* h_max (int) : 6 - the maximum TOC header level to use; any header greater than this value will be ignored
|
|
45
|
-
* ordered (bool) : false - when set to true, an ordered list will be outputted instead of an unordered list
|
|
46
|
-
* item_class (string) : '' - add custom class(es) for each list item; has support for '%level%' placeholder, which is the current heading level
|
|
47
|
-
* submenu_class (string) : '' - add custom class(es) for each child group of headings; has support for '%level%' placeholder which is the current "submenu" heading level
|
|
48
|
-
* base_url (string) : '' - add a base url to the TOC links for when your TOC is on another page than the actual content
|
|
49
|
-
* anchor_class (string) : '' - add custom class(es) for each anchor element
|
|
50
|
-
* skip_no_ids (bool) : false - skip headers that do not have an `id` attribute
|
|
51
|
-
|
|
52
|
-
Output:
|
|
53
|
-
An ordered or unordered list representing the table of contents of a markdown block. This snippet will only
|
|
54
|
-
generate the table of contents and will NOT output the markdown given to it
|
|
55
|
-
{% endcomment %}
|
|
56
|
-
|
|
57
|
-
{% capture newline %}
|
|
58
|
-
{% endcapture %}
|
|
59
|
-
{% assign newline = newline | rstrip %}
|
|
60
|
-
|
|
61
|
-
{% capture deprecation_warnings %}{% endcapture %}
|
|
62
|
-
|
|
63
|
-
{% if include.baseurl %}
|
|
64
|
-
{% capture deprecation_warnings %}{{ deprecation_warnings }}
|
|
65
|
-
{% endif %}
|
|
66
|
-
|
|
67
|
-
{% if include.skipNoIDs %}
|
|
68
|
-
{% capture deprecation_warnings %}{{ deprecation_warnings }}
|
|
69
|
-
{% endif %}
|
|
70
|
-
|
|
71
|
-
{% capture jekyll_toc %}{% endcapture %}
|
|
72
|
-
{% assign orderedList = include.ordered | default: false %}
|
|
73
|
-
{% assign baseURL = include.base_url | default: include.baseurl | default: '' %}
|
|
74
|
-
{% assign skipNoIDs = include.skip_no_ids | default: include.skipNoIDs | default: false %}
|
|
75
|
-
{% assign minHeader = include.h_min | default: 1 %}
|
|
76
|
-
{% assign maxHeader = include.h_max | default: 6 %}
|
|
77
|
-
{% assign nodes = include.html | strip | split: '<h' %}
|
|
78
|
-
|
|
79
|
-
{% assign firstHeader = true %}
|
|
80
|
-
{% assign currLevel = 0 %}
|
|
81
|
-
{% assign lastLevel = 0 %}
|
|
82
|
-
|
|
83
|
-
{% capture listModifier %}{% if orderedList %}ol{% else %}ul{% endif %}{% endcapture %}
|
|
84
|
-
|
|
85
|
-
{% for node in nodes %}
|
|
86
|
-
{% if node == "" %}
|
|
87
|
-
{% continue %}
|
|
88
|
-
{% endif %}
|
|
89
|
-
|
|
90
|
-
{% assign currLevel = node | replace: '"', '' | slice: 0, 1 | times: 1 %}
|
|
91
|
-
|
|
92
|
-
{% if currLevel < minHeader or currLevel > maxHeader %}
|
|
93
|
-
{% continue %}
|
|
94
|
-
{% endif %}
|
|
95
|
-
|
|
96
|
-
{% assign _workspace = node | split: '</h' %}
|
|
97
|
-
|
|
98
|
-
{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
|
|
99
|
-
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
|
|
100
|
-
{% assign htmlID = _idWorkspace[0] %}
|
|
101
|
-
|
|
102
|
-
{% assign _classWorkspace = _workspace[0] | split: 'class="' %}
|
|
103
|
-
{% assign _classWorkspace = _classWorkspace[1] | split: '"' %}
|
|
104
|
-
{% assign htmlClass = _classWorkspace[0] %}
|
|
105
|
-
|
|
106
|
-
{% if htmlClass contains "no_toc" %}
|
|
107
|
-
{% continue %}
|
|
108
|
-
{% endif %}
|
|
109
|
-
|
|
110
|
-
{% if firstHeader %}
|
|
111
|
-
{% assign minHeader = currLevel %}
|
|
112
|
-
{% endif %}
|
|
113
|
-
|
|
114
|
-
{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
|
|
115
|
-
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
|
|
116
|
-
|
|
117
|
-
{% if include.item_class and include.item_class != blank %}
|
|
118
|
-
{% capture listItemClass %} class="{{ include.item_class | replace: '%level%', currLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
|
119
|
-
{% endif %}
|
|
120
|
-
|
|
121
|
-
{% if include.submenu_class and include.submenu_class != blank %}
|
|
122
|
-
{% assign subMenuLevel = currLevel | minus: 1 %}
|
|
123
|
-
{% capture subMenuClass %} class="{{ include.submenu_class | replace: '%level%', subMenuLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
|
124
|
-
{% endif %}
|
|
125
|
-
|
|
126
|
-
{% capture anchorBody %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %}
|
|
127
|
-
|
|
128
|
-
{% if htmlID %}
|
|
129
|
-
{% capture anchorAttributes %} href="{% if baseURL %}{{ baseURL }}{% endif %}#{{ htmlID }}"{% endcapture %}
|
|
130
|
-
|
|
131
|
-
{% if include.anchor_class %}
|
|
132
|
-
{% capture anchorAttributes %}{{ anchorAttributes }} class="{{ include.anchor_class | split: '.' | join: ' ' }}"{% endcapture %}
|
|
133
|
-
{% endif %}
|
|
134
|
-
|
|
135
|
-
{% capture listItem %}<a{{ anchorAttributes }}>{{ anchorBody }}</a>{% endcapture %}
|
|
136
|
-
{% elsif skipNoIDs == true %}
|
|
137
|
-
{% continue %}
|
|
138
|
-
{% else %}
|
|
139
|
-
{% capture listItem %}{{ anchorBody }}{% endcapture %}
|
|
140
|
-
{% endif %}
|
|
141
|
-
|
|
142
|
-
{% if currLevel > lastLevel %}
|
|
143
|
-
{% capture jekyll_toc %}{{ jekyll_toc }}<{{ listModifier }}{{ subMenuClass }}>{% endcapture %}
|
|
144
|
-
{% elsif currLevel < lastLevel %}
|
|
145
|
-
{% assign repeatCount = lastLevel | minus: currLevel %}
|
|
146
|
-
|
|
147
|
-
{% for i in (1..repeatCount) %}
|
|
148
|
-
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
|
149
|
-
{% endfor %}
|
|
150
|
-
|
|
151
|
-
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
|
152
|
-
{% else %}
|
|
153
|
-
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
|
154
|
-
{% endif %}
|
|
155
|
-
|
|
156
|
-
{% capture jekyll_toc %}{{ jekyll_toc }}<li{{ listItemClass }}>{{ listItem }}{% endcapture %}
|
|
157
|
-
|
|
158
|
-
{% assign lastLevel = currLevel %}
|
|
159
|
-
{% assign firstHeader = false %}
|
|
160
|
-
{% endfor %}
|
|
161
|
-
|
|
162
|
-
{% assign repeatCount = minHeader | minus: 1 %}
|
|
163
|
-
{% assign repeatCount = lastLevel | minus: repeatCount %}
|
|
164
|
-
{% for i in (1..repeatCount) %}
|
|
165
|
-
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
|
166
|
-
{% endfor %}
|
|
167
|
-
|
|
168
|
-
{% if jekyll_toc != '' %}
|
|
169
|
-
{% assign rootAttributes = '' %}
|
|
170
|
-
{% if include.class and include.class != blank %}
|
|
171
|
-
{% capture rootAttributes %} class="{{ include.class | split: '.' | join: ' ' }}"{% endcapture %}
|
|
172
|
-
{% endif %}
|
|
173
|
-
|
|
174
|
-
{% if include.id and include.id != blank %}
|
|
175
|
-
{% capture rootAttributes %}{{ rootAttributes }} id="{{ include.id }}"{% endcapture %}
|
|
176
|
-
{% endif %}
|
|
177
|
-
|
|
178
|
-
{% if rootAttributes %}
|
|
179
|
-
{% assign nodes = jekyll_toc | split: '>' %}
|
|
180
|
-
{% capture jekyll_toc %}<{{ listModifier }}{{ rootAttributes }}>{{ nodes | shift | join: '>' }}>{% endcapture %}
|
|
181
|
-
{% endif %}
|
|
182
|
-
{% endif %}
|
|
183
|
-
{% endcapture %}{% assign tocWorkspace = '' %}{{ deprecation_warnings }}{{ jekyll_toc }}
|
|
1
|
+
{% comment %} Feature: ZER0-037 {% endcomment %}
|
|
2
|
+
{% capture tocWorkspace %}
|
|
3
|
+
{% comment %}
|
|
4
|
+
Copyright (c) 2017 Vladimir "allejo" Jimenez
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person
|
|
7
|
+
obtaining a copy of this software and associated documentation
|
|
8
|
+
files (the "Software"), to deal in the Software without
|
|
9
|
+
restriction, including without limitation the rights to use,
|
|
10
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the
|
|
12
|
+
Software is furnished to do so, subject to the following
|
|
13
|
+
conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be
|
|
16
|
+
included in all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
20
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
22
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
23
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
24
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
25
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
26
|
+
{% endcomment %}
|
|
27
|
+
{% comment %}
|
|
28
|
+
Version 1.1.0
|
|
29
|
+
https://github.com/allejo/jekyll-toc
|
|
30
|
+
|
|
31
|
+
"...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way" ~jaybe
|
|
32
|
+
|
|
33
|
+
Usage:
|
|
34
|
+
{% include content/toc.html html=content sanitize=true class="inline_toc" id="my_toc" h_min=2 h_max=3 %}
|
|
35
|
+
|
|
36
|
+
Parameters:
|
|
37
|
+
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll
|
|
38
|
+
|
|
39
|
+
Optional Parameters:
|
|
40
|
+
* sanitize (bool) : false - when set to true, the headers will be stripped of any HTML in the TOC
|
|
41
|
+
* class (string) : '' - a CSS class assigned to the TOC
|
|
42
|
+
* id (string) : '' - an ID to assigned to the TOC
|
|
43
|
+
* h_min (int) : 1 - the minimum TOC header level to use; any header lower than this value will be ignored
|
|
44
|
+
* h_max (int) : 6 - the maximum TOC header level to use; any header greater than this value will be ignored
|
|
45
|
+
* ordered (bool) : false - when set to true, an ordered list will be outputted instead of an unordered list
|
|
46
|
+
* item_class (string) : '' - add custom class(es) for each list item; has support for '%level%' placeholder, which is the current heading level
|
|
47
|
+
* submenu_class (string) : '' - add custom class(es) for each child group of headings; has support for '%level%' placeholder which is the current "submenu" heading level
|
|
48
|
+
* base_url (string) : '' - add a base url to the TOC links for when your TOC is on another page than the actual content
|
|
49
|
+
* anchor_class (string) : '' - add custom class(es) for each anchor element
|
|
50
|
+
* skip_no_ids (bool) : false - skip headers that do not have an `id` attribute
|
|
51
|
+
|
|
52
|
+
Output:
|
|
53
|
+
An ordered or unordered list representing the table of contents of a markdown block. This snippet will only
|
|
54
|
+
generate the table of contents and will NOT output the markdown given to it
|
|
55
|
+
{% endcomment %}
|
|
56
|
+
|
|
57
|
+
{% capture newline %}
|
|
58
|
+
{% endcapture %}
|
|
59
|
+
{% assign newline = newline | rstrip %} {% comment %} Remove the extra spacing but preserve the newline {% endcomment %}
|
|
60
|
+
|
|
61
|
+
{% capture deprecation_warnings %}{% endcapture %}
|
|
62
|
+
|
|
63
|
+
{% if include.baseurl %}
|
|
64
|
+
{% capture deprecation_warnings %}{{ deprecation_warnings }}{% comment %} jekyll-toc :: "baseurl" has been deprecated, use "base_url" instead {% endcomment %}{{ newline }}{% endcapture %}
|
|
65
|
+
{% endif %}
|
|
66
|
+
|
|
67
|
+
{% if include.skipNoIDs %}
|
|
68
|
+
{% capture deprecation_warnings %}{{ deprecation_warnings }}{% comment %} jekyll-toc :: "skipNoIDs" has been deprecated, use "skip_no_ids" instead {% endcomment %}{{ newline }}{% endcapture %}
|
|
69
|
+
{% endif %}
|
|
70
|
+
|
|
71
|
+
{% capture jekyll_toc %}{% endcapture %}
|
|
72
|
+
{% assign orderedList = include.ordered | default: false %}
|
|
73
|
+
{% assign baseURL = include.base_url | default: include.baseurl | default: '' %}
|
|
74
|
+
{% assign skipNoIDs = include.skip_no_ids | default: include.skipNoIDs | default: false %}
|
|
75
|
+
{% assign minHeader = include.h_min | default: 1 %}
|
|
76
|
+
{% assign maxHeader = include.h_max | default: 6 %}
|
|
77
|
+
{% assign nodes = include.html | strip | split: '<h' %}
|
|
78
|
+
|
|
79
|
+
{% assign firstHeader = true %}
|
|
80
|
+
{% assign currLevel = 0 %}
|
|
81
|
+
{% assign lastLevel = 0 %}
|
|
82
|
+
|
|
83
|
+
{% capture listModifier %}{% if orderedList %}ol{% else %}ul{% endif %}{% endcapture %}
|
|
84
|
+
|
|
85
|
+
{% for node in nodes %}
|
|
86
|
+
{% if node == "" %}
|
|
87
|
+
{% continue %}
|
|
88
|
+
{% endif %}
|
|
89
|
+
|
|
90
|
+
{% assign currLevel = node | replace: '"', '' | slice: 0, 1 | times: 1 %}
|
|
91
|
+
|
|
92
|
+
{% if currLevel < minHeader or currLevel > maxHeader %}
|
|
93
|
+
{% continue %}
|
|
94
|
+
{% endif %}
|
|
95
|
+
|
|
96
|
+
{% assign _workspace = node | split: '</h' %}
|
|
97
|
+
|
|
98
|
+
{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
|
|
99
|
+
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
|
|
100
|
+
{% assign htmlID = _idWorkspace[0] %}
|
|
101
|
+
|
|
102
|
+
{% assign _classWorkspace = _workspace[0] | split: 'class="' %}
|
|
103
|
+
{% assign _classWorkspace = _classWorkspace[1] | split: '"' %}
|
|
104
|
+
{% assign htmlClass = _classWorkspace[0] %}
|
|
105
|
+
|
|
106
|
+
{% if htmlClass contains "no_toc" %}
|
|
107
|
+
{% continue %}
|
|
108
|
+
{% endif %}
|
|
109
|
+
|
|
110
|
+
{% if firstHeader %}
|
|
111
|
+
{% assign minHeader = currLevel %}
|
|
112
|
+
{% endif %}
|
|
113
|
+
|
|
114
|
+
{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
|
|
115
|
+
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
|
|
116
|
+
|
|
117
|
+
{% if include.item_class and include.item_class != blank %}
|
|
118
|
+
{% capture listItemClass %} class="{{ include.item_class | replace: '%level%', currLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
|
119
|
+
{% endif %}
|
|
120
|
+
|
|
121
|
+
{% if include.submenu_class and include.submenu_class != blank %}
|
|
122
|
+
{% assign subMenuLevel = currLevel | minus: 1 %}
|
|
123
|
+
{% capture subMenuClass %} class="{{ include.submenu_class | replace: '%level%', subMenuLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
|
124
|
+
{% endif %}
|
|
125
|
+
|
|
126
|
+
{% capture anchorBody %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %}
|
|
127
|
+
|
|
128
|
+
{% if htmlID %}
|
|
129
|
+
{% capture anchorAttributes %} href="{% if baseURL %}{{ baseURL }}{% endif %}#{{ htmlID }}"{% endcapture %}
|
|
130
|
+
|
|
131
|
+
{% if include.anchor_class %}
|
|
132
|
+
{% capture anchorAttributes %}{{ anchorAttributes }} class="{{ include.anchor_class | split: '.' | join: ' ' }}"{% endcapture %}
|
|
133
|
+
{% endif %}
|
|
134
|
+
|
|
135
|
+
{% capture listItem %}<a{{ anchorAttributes }}>{{ anchorBody }}</a>{% endcapture %}
|
|
136
|
+
{% elsif skipNoIDs == true %}
|
|
137
|
+
{% continue %}
|
|
138
|
+
{% else %}
|
|
139
|
+
{% capture listItem %}{{ anchorBody }}{% endcapture %}
|
|
140
|
+
{% endif %}
|
|
141
|
+
|
|
142
|
+
{% if currLevel > lastLevel %}
|
|
143
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}<{{ listModifier }}{{ subMenuClass }}>{% endcapture %}
|
|
144
|
+
{% elsif currLevel < lastLevel %}
|
|
145
|
+
{% assign repeatCount = lastLevel | minus: currLevel %}
|
|
146
|
+
|
|
147
|
+
{% for i in (1..repeatCount) %}
|
|
148
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
|
149
|
+
{% endfor %}
|
|
150
|
+
|
|
151
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
|
152
|
+
{% else %}
|
|
153
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
|
154
|
+
{% endif %}
|
|
155
|
+
|
|
156
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}<li{{ listItemClass }}>{{ listItem }}{% endcapture %}
|
|
157
|
+
|
|
158
|
+
{% assign lastLevel = currLevel %}
|
|
159
|
+
{% assign firstHeader = false %}
|
|
160
|
+
{% endfor %}
|
|
161
|
+
|
|
162
|
+
{% assign repeatCount = minHeader | minus: 1 %}
|
|
163
|
+
{% assign repeatCount = lastLevel | minus: repeatCount %}
|
|
164
|
+
{% for i in (1..repeatCount) %}
|
|
165
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
|
166
|
+
{% endfor %}
|
|
167
|
+
|
|
168
|
+
{% if jekyll_toc != '' %}
|
|
169
|
+
{% assign rootAttributes = '' %}
|
|
170
|
+
{% if include.class and include.class != blank %}
|
|
171
|
+
{% capture rootAttributes %} class="{{ include.class | split: '.' | join: ' ' }}"{% endcapture %}
|
|
172
|
+
{% endif %}
|
|
173
|
+
|
|
174
|
+
{% if include.id and include.id != blank %}
|
|
175
|
+
{% capture rootAttributes %}{{ rootAttributes }} id="{{ include.id }}"{% endcapture %}
|
|
176
|
+
{% endif %}
|
|
177
|
+
|
|
178
|
+
{% if rootAttributes %}
|
|
179
|
+
{% assign nodes = jekyll_toc | split: '>' %}
|
|
180
|
+
{% capture jekyll_toc %}<{{ listModifier }}{{ rootAttributes }}>{{ nodes | shift | join: '>' }}>{% endcapture %}
|
|
181
|
+
{% endif %}
|
|
182
|
+
{% endif %}
|
|
183
|
+
{% endcapture %}{% assign tocWorkspace = '' %}{{ deprecation_warnings }}{{ jekyll_toc }}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
{% comment %}
|
|
2
2
|
===================================================================
|
|
3
3
|
BRANDING - Site Title and Subtitle Display
|
|
4
4
|
===================================================================
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
- site.title_icon: Icon for title display
|
|
15
15
|
- site.subtitle_icon: Icon for subtitle display
|
|
16
16
|
===================================================================
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
{% endcomment %}
|
|
18
|
+
{% comment %} Color Schema Override
|
|
19
19
|
TODO: Add a poline plug-in to generate color scheme
|
|
20
20
|
https://meodai.github.io/poline/
|
|
21
21
|
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
Yellow - #ffe900
|
|
29
29
|
Teal - #376986
|
|
30
30
|
Blue - #007bff
|
|
31
|
-
|
|
31
|
+
{% endcomment %}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
{% comment %} Title Section {% endcomment %}
|
|
34
34
|
|
|
35
35
|
<div class="navbar-brand site-title mb-0 py-0 me-0 min-w-0 flex-grow-1">
|
|
36
36
|
<a
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</a>
|
|
44
44
|
</div>
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
{% comment %} If a subtitle exists {% endcomment %}
|
|
47
47
|
{%- assign _subtitle = site.subtitle | strip -%}
|
|
48
48
|
{%- if _subtitle != "" -%}
|
|
49
49
|
<div class="navbar-brand site-subtitle d-none d-lg-inline">
|
|
@@ -1,89 +1,47 @@
|
|
|
1
1
|
{%- comment -%}
|
|
2
2
|
===================================================================
|
|
3
|
-
CONSOLE CAPTURE — early
|
|
3
|
+
CONSOLE CAPTURE — early console/error ring buffer
|
|
4
4
|
===================================================================
|
|
5
5
|
|
|
6
6
|
File: console-capture.html
|
|
7
7
|
Path: _includes/core/console-capture.html
|
|
8
|
-
Purpose:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
(assets/js/page-feedback.js) can attach the logs and JS
|
|
12
|
-
errors that led up to a report.
|
|
8
|
+
Purpose: Load the fleet feedback kit's capture buffer HIGH in <head> —
|
|
9
|
+
before the theme's deferred scripts run — so the page-feedback
|
|
10
|
+
widget can attach the logs and JS errors that led up to a report.
|
|
13
11
|
|
|
14
12
|
Renders: only when page_feedback.enabled AND page_feedback.capture_logs.
|
|
15
13
|
|
|
14
|
+
This used to be ~60 lines of inline ES5 maintained here. It is now the
|
|
15
|
+
fleet kit's capture.js, VENDORED to assets/js/fleet-feedback-capture.js
|
|
16
|
+
(bamr87/bamr87 templates/feedback/capture.js — drift check (i) holds the
|
|
17
|
+
copy to the hub's). Two things came with the move: the buffer shape is
|
|
18
|
+
now the one FleetFeedbackCore reads, so the theme's widget and the fleet's
|
|
19
|
+
web component file byte-identical issues; and every captured line is
|
|
20
|
+
REDACTED before it enters the ring (bearer/API keys, JWTs, GitHub tokens,
|
|
21
|
+
email addresses), so a secret cannot be previewed, copied, or filed.
|
|
22
|
+
|
|
23
|
+
Loaded blocking rather than deferred, and that is the point: a buffer
|
|
24
|
+
installed after parsing misses exactly the load-time failures worth
|
|
25
|
+
reporting. It is ~4 KB, and it REPLACED ~3.7 KB of inline script, so the
|
|
26
|
+
head got smaller — which also buys back room for the charset meta that
|
|
27
|
+
has to land in the first 1024 bytes (issue #372).
|
|
28
|
+
|
|
16
29
|
Privacy: in-memory only, never persisted, never sent anywhere until the
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
reader opens the modal, reviews the captured lines, and submits.
|
|
31
|
+
Any single entry is truncated; the buffer is a fixed-size ring
|
|
32
|
+
(page_feedback.log_limit, default 40).
|
|
20
33
|
|
|
21
|
-
Depends on:
|
|
34
|
+
Depends on: assets/js/fleet-feedback-capture.js (vendored, no CDN).
|
|
22
35
|
===================================================================
|
|
23
36
|
{%- endcomment -%}
|
|
24
37
|
{%- if site.page_feedback.enabled and site.page_feedback.capture_logs -%}
|
|
25
|
-
<script>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
var buffer = [];
|
|
36
|
-
function now() { return start === null ? Math.round(performance.now()) : (Date.now() - start); }
|
|
37
|
-
|
|
38
|
-
function stringify(value) {
|
|
39
|
-
if (typeof value === "string") { return value; }
|
|
40
|
-
if (value instanceof Error) {
|
|
41
|
-
return (value.name || "Error") + ": " + (value.message || "") + (value.stack ? "\n" + value.stack : "");
|
|
42
|
-
}
|
|
43
|
-
try { return JSON.stringify(value); } catch (e) { return String(value); }
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function push(level, args) {
|
|
47
|
-
try {
|
|
48
|
-
var parts = [];
|
|
49
|
-
for (var i = 0; i < args.length; i++) { parts.push(stringify(args[i])); }
|
|
50
|
-
var text = parts.join(" ");
|
|
51
|
-
if (text.length > MAX_ENTRY) { text = text.slice(0, MAX_ENTRY) + "…"; }
|
|
52
|
-
buffer.push({ t: now(), level: level, text: text });
|
|
53
|
-
while (buffer.length > LIMIT) { buffer.shift(); }
|
|
54
|
-
} catch (e) { /* logging must never break the page */ }
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Wrap console methods, preserving passthrough to the real console.
|
|
58
|
-
if (window.console) {
|
|
59
|
-
["log", "info", "warn", "error", "debug"].forEach(function (level) {
|
|
60
|
-
var original = console[level] ? console[level].bind(console) : null;
|
|
61
|
-
console[level] = function () {
|
|
62
|
-
push(level, arguments);
|
|
63
|
-
if (original) { original.apply(null, arguments); }
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Uncaught errors and unhandled promise rejections.
|
|
69
|
-
window.addEventListener("error", function (e) {
|
|
70
|
-
if (!e) { return; }
|
|
71
|
-
var where = e.filename ? " (" + e.filename + ":" + (e.lineno || 0) + ":" + (e.colno || 0) + ")" : "";
|
|
72
|
-
push("error", [(e.message || "Script error") + where]);
|
|
73
|
-
});
|
|
74
|
-
window.addEventListener("unhandledrejection", function (e) {
|
|
75
|
-
var reason = e && e.reason;
|
|
76
|
-
var msg = reason && reason.message ? reason.message : stringify(reason);
|
|
77
|
-
push("error", ["Unhandled promise rejection: " + msg]);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
window.__zer0Feedback = {
|
|
81
|
-
installed: true,
|
|
82
|
-
logs: buffer,
|
|
83
|
-
/** Snapshot the buffer (newest last) for the widget to read. */
|
|
84
|
-
snapshot: function () { return buffer.slice(); },
|
|
85
|
-
clear: function () { buffer.length = 0; }
|
|
86
|
-
};
|
|
87
|
-
})();
|
|
88
|
-
</script>
|
|
38
|
+
<script src="{{ '/assets/js/fleet-feedback-capture.js' | relative_url }}"></script>
|
|
39
|
+
{%- comment -%}
|
|
40
|
+
The ring size is site configuration, so it is applied after the buffer
|
|
41
|
+
installs rather than baked into the vendored file (which must stay
|
|
42
|
+
byte-identical to the hub's).
|
|
43
|
+
{%- endcomment -%}
|
|
44
|
+
{%- if site.page_feedback.log_limit -%}
|
|
45
|
+
<script>if(window.__fleetFeedback){window.__fleetFeedback.limit={{ site.page_feedback.log_limit | jsonify }};}</script>
|
|
46
|
+
{%- endif -%}
|
|
89
47
|
{%- endif -%}
|
data/_includes/core/favicon.html
CHANGED
|
@@ -16,12 +16,17 @@
|
|
|
16
16
|
png_size : 32x32 # sizes attr for png (optional)
|
|
17
17
|
apple_touch : /assets/images/apple-touch.png # iOS home-screen icon (optional)
|
|
18
18
|
manifest : /site.webmanifest # PWA manifest (optional)
|
|
19
|
-
theme_color
|
|
19
|
+
theme_color : "#0d1117" # pin ONE chrome color (optional)
|
|
20
|
+
theme_color_light : "#ffffff" # light-scheme chrome (optional)
|
|
21
|
+
theme_color_dark : "#212529" # dark-scheme chrome (optional)
|
|
20
22
|
|
|
21
23
|
With NO config at all this still emits the explicit
|
|
22
|
-
/favicon.ico link (every consumer site carries one at root)
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
/favicon.ico link (every consumer site carries one at root)
|
|
25
|
+
AND both theme-color tags. That last part is the point of the
|
|
26
|
+
fallbacks below: a remote_theme consumer does not inherit this
|
|
27
|
+
repo's _config.yml (see remote-theme-checklist.md), so a
|
|
28
|
+
config-gated tag emitted nothing at all on exactly the sites
|
|
29
|
+
this include exists to serve (issue #281).
|
|
25
30
|
Notes: Page-invariant — safe to render via include_cached. All paths
|
|
26
31
|
run through relative_url so baseurl deployments resolve.
|
|
27
32
|
{%- endcomment -%}
|
|
@@ -40,7 +45,44 @@
|
|
|
40
45
|
{%- if _fav.manifest %}
|
|
41
46
|
<link rel="manifest" href="{{ _fav.manifest | relative_url }}">
|
|
42
47
|
{%- endif %}
|
|
43
|
-
{%-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
{%- comment -%}
|
|
49
|
+
theme-color drives mobile browser chrome (iOS Safari address/status bar,
|
|
50
|
+
the Chrome/Android task-switcher card). It must track the page SURFACE.
|
|
51
|
+
|
|
52
|
+
It used to fall back to site.theme_color.main, which is the brand ACCENT --
|
|
53
|
+
#007bff on this site -- so a dark-first theme advertised a bright blue
|
|
54
|
+
address bar. The defaults below are Bootstrap 5.3.3's own --bs-body-bg for
|
|
55
|
+
each scheme (:root #fff, [data-bs-theme=dark] #212529); the theme adds no
|
|
56
|
+
dark override of that variable, so they are the real computed surface.
|
|
57
|
+
|
|
58
|
+
WHICH SHAPE TO EMIT depends on how the mode is decided, because
|
|
59
|
+
`media="(prefers-color-scheme: ...)"` keys off the OS and nothing else:
|
|
60
|
+
|
|
61
|
+
- mode is pinned (color_mode_lock, or a non-auto color_mode_default)
|
|
62
|
+
-> ONE unconditional tag. A media pair would hand light chrome to an
|
|
63
|
+
OS-light visitor looking at a page this site renders dark.
|
|
64
|
+
- mode is `auto` -> the media pair, which is exactly what `auto` means.
|
|
65
|
+
|
|
66
|
+
A locked `auto` resolves to dark here, matching core/color-mode-init.html.
|
|
67
|
+
|
|
68
|
+
Known limitation, deliberately not solved here: an unlocked site lets a
|
|
69
|
+
visitor override the mode from the Appearance panel via localStorage, which
|
|
70
|
+
no static meta can follow. Keeping chrome in sync with the panel needs a
|
|
71
|
+
runtime hook in the toggle path -- tracked separately.
|
|
72
|
+
{%- endcomment -%}
|
|
73
|
+
{%- assign _tc_light = _fav.theme_color_light | default: '#ffffff' -%}
|
|
74
|
+
{%- assign _tc_dark = _fav.theme_color_dark | default: '#212529' -%}
|
|
75
|
+
{%- assign _tc_mode = site.color_mode_default | default: 'auto' -%}
|
|
76
|
+
{%- if _fav.theme_color %}
|
|
77
|
+
{%- comment -%} Back-compat: a consumer that pinned one colour keeps it. {%- endcomment %}
|
|
78
|
+
<meta name="theme-color" content="{{ _fav.theme_color }}">
|
|
79
|
+
{%- elsif site.color_mode_lock and _tc_mode == 'light' %}
|
|
80
|
+
<meta name="theme-color" content="{{ _tc_light }}">
|
|
81
|
+
{%- elsif site.color_mode_lock or _tc_mode == 'dark' %}
|
|
82
|
+
<meta name="theme-color" content="{{ _tc_dark }}">
|
|
83
|
+
{%- elsif _tc_mode == 'light' %}
|
|
84
|
+
<meta name="theme-color" content="{{ _tc_light }}">
|
|
85
|
+
{%- else %}
|
|
86
|
+
<meta name="theme-color" media="(prefers-color-scheme: light)" content="{{ _tc_light }}">
|
|
87
|
+
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="{{ _tc_dark }}">
|
|
46
88
|
{%- endif %}
|
|
@@ -20,12 +20,26 @@
|
|
|
20
20
|
after </footer> is visually identical to the previous nesting.
|
|
21
21
|
===================================================================
|
|
22
22
|
{%- endcomment -%}
|
|
23
|
-
{%-
|
|
24
|
-
|
|
23
|
+
{%- comment -%}
|
|
24
|
+
The TOC FAB controls `#tocContents`, which navigation/sidebar-right.html
|
|
25
|
+
emits — and only _layouts/default.html includes that. This used to be a
|
|
26
|
+
DENYLIST of layouts to skip, which fails open: any layout not on the list got
|
|
27
|
+
the FAB whether or not it rendered the panel, and the list had already fallen
|
|
28
|
+
behind (404 and the book-* layouts were missing, so those pages shipped a FAB
|
|
29
|
+
pointing at nothing — issue #373).
|
|
30
|
+
|
|
31
|
+
Replaced with the positive gate from navigation/sidebar-config.html, which
|
|
32
|
+
fails safe: a new layout gets no FAB until it is declared as one that renders
|
|
33
|
+
the offcanvas. sidebar-config is included here rather than relied upon from
|
|
34
|
+
header.html because Liquid assigns propagate to the INCLUDING template, and
|
|
35
|
+
these are two sibling includes of root.html.
|
|
36
|
+
{%- endcomment -%}
|
|
37
|
+
{% include navigation/sidebar-config.html %}
|
|
38
|
+
{%- if sidebar_offcanvas_rendered -%}
|
|
25
39
|
{% include navigation/toc-fab.html %}
|
|
26
40
|
{%- comment -%} Local-graph FAB/panel are part of the Obsidian feature. {%- endcomment -%}
|
|
27
41
|
{%- if site.obsidian.enabled != false -%}
|
|
28
42
|
{% include navigation/local-graph-fab.html %}
|
|
29
43
|
{% include navigation/local-graph.html %}
|
|
30
44
|
{%- endif -%}
|
|
31
|
-
{%-
|
|
45
|
+
{%- endif -%}
|