datalog-theme 0.7.0 → 0.9.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.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +188 -0
  3. data/CITATION.cff +2 -2
  4. data/README.md +25 -17
  5. data/_data/cdn-integrity.yml +0 -30
  6. data/_data/i18n/en.yml +297 -0
  7. data/_data/i18n/es.yml +297 -0
  8. data/_data/i18n/pt.yml +297 -0
  9. data/_data/js_manifest.json +16 -0
  10. data/_includes/analytics/dashboard.html +3 -1
  11. data/_includes/components/api-function.html +20 -1
  12. data/_includes/components/author-bio.html +21 -11
  13. data/_includes/components/author-list.html +32 -0
  14. data/_includes/components/citation-tools.html +33 -25
  15. data/_includes/components/comments-thread.html +90 -0
  16. data/_includes/components/contact-form.html +120 -0
  17. data/_includes/components/correction-report.html +82 -0
  18. data/_includes/components/enhanced-code-block.html +1 -1
  19. data/_includes/components/enhanced-toc.html +6 -7
  20. data/_includes/components/license-link.html +13 -0
  21. data/_includes/components/license-notice.html +28 -0
  22. data/_includes/components/moderation-inbox.html +139 -0
  23. data/_includes/components/reactions.html +49 -0
  24. data/_includes/components/reading-list.html +31 -0
  25. data/_includes/components/reading-mode-toggle.html +65 -0
  26. data/_includes/components/reading-state-bookmark.html +27 -0
  27. data/_includes/components/reading-state-panel.html +71 -0
  28. data/_includes/components/reproducibility.html +61 -0
  29. data/_includes/components/responsive-image.html +3 -3
  30. data/_includes/components/revision-history.html +39 -0
  31. data/_includes/components/revision-notice.html +35 -0
  32. data/_includes/components/series-nav.html +64 -0
  33. data/_includes/components/subscribe-form.html +88 -0
  34. data/_includes/components/subscription-manage.html +68 -0
  35. data/_includes/components/webmentions.html +48 -0
  36. data/_includes/csp-meta.html +135 -11
  37. data/_includes/footer.html +22 -20
  38. data/_includes/head.html +111 -63
  39. data/_includes/header/navigation.html +12 -15
  40. data/_includes/header.html +28 -19
  41. data/_includes/layouts/default/article.html +9 -7
  42. data/_includes/meta/dynamic-services-config.html +14 -0
  43. data/_includes/meta/math-config.html +18 -10
  44. data/_includes/meta/person-json.html +27 -0
  45. data/_includes/meta/publisher.html +45 -0
  46. data/_includes/meta/schema.html +67 -30
  47. data/_includes/meta/scholarly.html +121 -0
  48. data/_includes/meta/scripts-loader.html +18 -32
  49. data/_includes/meta/webmention-discovery.html +14 -0
  50. data/_includes/post/related-posts.html +4 -7
  51. data/_includes/scripts.html +57 -0
  52. data/_includes/search/index-data.json +9 -34
  53. data/_layouts/dataset.html +5 -3
  54. data/_layouts/default.html +16 -8
  55. data/_layouts/notebook.html +1 -0
  56. data/_layouts/package.html +4 -2
  57. data/_layouts/page.html +15 -0
  58. data/_layouts/portfolio.html +1 -0
  59. data/_layouts/post.html +102 -23
  60. data/_layouts/project.html +4 -3
  61. data/_layouts/research.html +20 -8
  62. data/_plugins/analytics_dashboard.rb +9 -3
  63. data/_plugins/authors.rb +133 -0
  64. data/_plugins/config_validator.rb +231 -23
  65. data/_plugins/critical_css_check.rb +42 -0
  66. data/_plugins/csp_generator.rb +18 -28
  67. data/_plugins/datalog_bibliography.rb +9 -7
  68. data/_plugins/datalog_comments.rb +8 -5
  69. data/_plugins/datalog_slides.rb +9 -8
  70. data/_plugins/i18n.rb +13 -12
  71. data/_plugins/image_optimizer.rb +241 -178
  72. data/_plugins/licenses.rb +135 -0
  73. data/_plugins/math_preprocessor.rb +59 -7
  74. data/_plugins/notebook_converter.rb +23 -4
  75. data/_plugins/plugin_loader.rb +3 -1
  76. data/_plugins/publications_generator.rb +8 -2
  77. data/_plugins/references.rb +238 -0
  78. data/_plugins/reproducibility.rb +150 -0
  79. data/_plugins/revisions.rb +101 -0
  80. data/_plugins/rouge_highlight_filter.rb +42 -0
  81. data/_plugins/scholarly.rb +50 -0
  82. data/_plugins/search_code_blocks.rb +30 -0
  83. data/_plugins/search_normalizer.rb +15 -53
  84. data/_plugins/search_pages.rb +3 -4
  85. data/_plugins/series.rb +104 -0
  86. data/_plugins/statements.rb +87 -0
  87. data/_sass/_academic-dashboard.scss +262 -0
  88. data/_sass/_base.scss +20 -1
  89. data/_sass/_comments-thread.scss +159 -0
  90. data/_sass/_components.scss +64 -1153
  91. data/_sass/_features.scss +17 -0
  92. data/_sass/_layout.scss +385 -1
  93. data/_sass/_mathematical.scss +27 -0
  94. data/_sass/_moderation.scss +222 -0
  95. data/_sass/_notebooks.scss +322 -0
  96. data/_sass/_open-science-badges.scss +56 -0
  97. data/_sass/{_phase1-enhancements.scss → _post-components.scss} +5 -3
  98. data/_sass/_print.scss +291 -0
  99. data/_sass/_reactions.scss +89 -0
  100. data/_sass/_reading-state.scss +290 -0
  101. data/_sass/_search-page.scss +530 -0
  102. data/_sass/_search.scss +46 -0
  103. data/_sass/_service-forms.scss +204 -0
  104. data/_sass/_subscriptions.scss +140 -0
  105. data/_sass/_syntax-highlighting.scss +212 -97
  106. data/_sass/_theme.scss +40 -19
  107. data/_sass/_typography.scss +130 -0
  108. data/_sass/_utilities.scss +5 -0
  109. data/_sass/_variables.scss +6 -0
  110. data/_sass/_webmentions.scss +125 -0
  111. data/assets/css/main.scss +14 -0
  112. data/assets/js/dist/academic.js +1 -1
  113. data/assets/js/dist/analytics-dashboard.js +1 -1
  114. data/assets/js/dist/chunks/chunk-2DYDWUFX.js +1 -0
  115. data/assets/js/dist/chunks/chunk-PATLC23F.js +1 -0
  116. data/assets/js/dist/chunks/chunk-V7734B2G.js +1 -0
  117. data/assets/js/dist/comments.js +2 -0
  118. data/assets/js/dist/contact.js +1 -0
  119. data/assets/js/dist/core.js +1 -1
  120. data/assets/js/dist/corrections.js +1 -0
  121. data/assets/js/dist/loader.js +1 -1
  122. data/assets/js/dist/math.js +1 -1
  123. data/assets/js/dist/moderation.js +1 -0
  124. data/assets/js/dist/notebook.js +1 -1
  125. data/assets/js/dist/reactions.js +1 -0
  126. data/assets/js/dist/reading-state.js +1 -0
  127. data/assets/js/dist/search.js +1 -1
  128. data/assets/js/dist/sources.json +52 -0
  129. data/assets/js/dist/subscriptions.js +1 -0
  130. data/assets/js/dist/visualizations.js +11 -2
  131. data/assets/js/dist/webmentions.js +1 -0
  132. data/assets/js/loader.js +37 -1
  133. data/datalog-theme.gemspec +35 -23
  134. data/lib/datalog/cli.rb +43 -15
  135. data/lib/datalog/critical_css.rb +168 -0
  136. data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
  137. data/lib/datalog/plugins/comments.rb +33 -3
  138. data/lib/datalog/theme/installed_files.rb +113 -0
  139. data/lib/datalog/theme/package.rb +57 -0
  140. data/lib/datalog/theme/repository_checkout.rb +94 -0
  141. data/lib/datalog/theme/version.rb +5 -1
  142. data/lib/datalog/warning_filter.rb +5 -11
  143. data/lib/datalog-theme.rb +6 -0
  144. metadata +96 -147
  145. data/_data/academic.yml +0 -217
  146. data/_data/config/author.yml +0 -121
  147. data/_data/datasets.yml +0 -28
  148. data/_data/js_meta.json +0 -371
  149. data/_data/navigation.yml +0 -145
  150. data/_data/projects.yml +0 -41
  151. data/_data/publications.yml +0 -28
  152. data/_data/social.yml +0 -73
  153. data/_data/visualizations.yml +0 -51
  154. data/_includes/components/advanced-search.html +0 -682
  155. data/_includes/components/bookmark-system.html +0 -96
  156. data/_includes/components/comments.html +0 -244
  157. data/_includes/components/content-recommendations.html +0 -228
  158. data/_includes/components/email-preferences.html +0 -200
  159. data/_includes/components/enhanced-metadata.html +0 -228
  160. data/_includes/components/language-switcher.html +0 -396
  161. data/_includes/components/navigation-enhancements.html +0 -454
  162. data/_includes/components/newsletter-signup.html +0 -178
  163. data/_includes/components/popular-posts.html +0 -233
  164. data/_includes/components/reading-progress.html +0 -133
  165. data/_includes/components/reading-time.html +0 -121
  166. data/_includes/components/series-navigation.html +0 -124
  167. data/_includes/components/social-proof.html +0 -34
  168. data/_includes/components/user-preferences.html +0 -566
  169. data/_includes/meta/syntax-config.html +0 -19
  170. data/_layouts/archive.html +0 -282
  171. data/_layouts/post-sidebar.html +0 -183
  172. data/_sass/_phase3-enhancements.scss +0 -874
  173. data/_sass/_phase4-enhancements.scss +0 -1214
  174. data/_sass/_phase5-enhancements.scss +0 -414
  175. data/assets/js/academic.js +0 -262
  176. data/assets/js/analytics-dashboard.js +0 -382
  177. data/assets/js/core/dark-mode.js +0 -79
  178. data/assets/js/core/github-cards.js +0 -123
  179. data/assets/js/core/language-filter.js +0 -69
  180. data/assets/js/core/navigation.js +0 -184
  181. data/assets/js/core/scroll-progress.js +0 -45
  182. data/assets/js/core/search-hotkeys.js +0 -62
  183. data/assets/js/core/skip-links.js +0 -62
  184. data/assets/js/dist/manifest.json +0 -22
  185. data/assets/js/dist/meta.json +0 -371
  186. data/assets/js/main.js +0 -23
  187. data/assets/js/math.js +0 -818
  188. data/assets/js/notebook.js +0 -158
  189. data/assets/js/search/analytics.js +0 -91
  190. data/assets/js/search/app.js +0 -271
  191. data/assets/js/search/autocomplete.js +0 -120
  192. data/assets/js/search/engine.js +0 -260
  193. data/assets/js/search/filters.js +0 -45
  194. data/assets/js/search/render.js +0 -217
  195. data/assets/js/search/utils.js +0 -99
  196. data/assets/js/search.js +0 -354
  197. data/assets/js/visualizations.js +0 -816
  198. data/assets/publications/datalog-publications.bib +0 -8
  199. data/assets/publications/datalog-publications.ris +0 -9
  200. data/assets/publications/publications.bib +0 -30
  201. data/assets/templates/diogo-ribeiro-cv.md +0 -31
  202. data/assets/templates/diogo-ribeiro-cv.tex +0 -32
  203. data/lib/datalog/theme/theme.rb +0 -18
data/_sass/_theme.scss CHANGED
@@ -1,31 +1,50 @@
1
1
  // Primary manifest for the DataLog theme.
2
2
  // Provides CSS custom properties and composes the Sass partials.
3
3
  @use "sass:color";
4
+ @use "sass:meta";
4
5
  // 1) Modules FIRST (no CSS before these)
5
6
  @use 'variables' as *; // gives access to Sass tokens here
6
7
  @use 'mixins' as *;
8
+ @use 'features';
7
9
 
8
10
  // Each partial below MUST import its own tokens if it references them.
9
- // `@use` here does NOT leak variables into those files' scopes.
10
- @use 'font-fallbacks';
11
- @use 'base';
12
- @use 'typography';
13
- @use 'layout';
14
- @use 'header';
15
- @use 'components';
16
- @use 'utilities';
17
- @use 'syntax-highlighting';
18
- @use 'mathematical';
19
- @use 'interactive';
20
- @use 'search';
21
- @use 'visualizations';
22
- @use 'phase1-enhancements';
23
- @use 'phase3-enhancements';
24
- @use 'phase4-enhancements';
25
- @use 'phase5-enhancements';
26
- @use 'package-docs';
11
+ // Loading it here does NOT leak variables into that file's scope.
12
+ // meta.load-css emits a partial's CSS at the point it is included, in this
13
+ // order, and unlike @use it may sit inside @if: the partials for optional
14
+ // features load only when their flag in _features.scss is on.
15
+ @include meta.load-css('font-fallbacks');
16
+ @include meta.load-css('base');
17
+ @include meta.load-css('typography');
18
+ @include meta.load-css('layout');
19
+ @include meta.load-css('header');
20
+ @include meta.load-css('components');
21
+ @include meta.load-css('utilities');
22
+ @include meta.load-css('syntax-highlighting');
23
+ @include meta.load-css('mathematical');
24
+ @if features.$visualizations {
25
+ @include meta.load-css('interactive');
26
+ }
27
+ @if features.$search {
28
+ @include meta.load-css('search');
29
+ }
30
+ @if features.$visualizations {
31
+ @include meta.load-css('visualizations');
32
+ }
33
+ @include meta.load-css('post-components');
34
+ @if features.$packages {
35
+ @include meta.load-css('package-docs');
36
+ }
37
+ @include meta.load-css('reading-state');
38
+ @include meta.load-css('service-forms');
39
+ @include meta.load-css('comments-thread');
40
+ @include meta.load-css('reactions');
41
+ @include meta.load-css('webmentions');
42
+ @include meta.load-css('subscriptions');
43
+ @include meta.load-css('moderation');
44
+ // Reading mode and print come last, so their rules win.
45
+ @include meta.load-css('print');
27
46
 
28
- // 2) CSS rules AFTER all @use/@forward
47
+ // 2) CSS rules AFTER the partials
29
48
  :root {
30
49
  // Surface/background colors
31
50
  --color-surface: #{$color-surface-50};
@@ -42,6 +61,7 @@
42
61
 
43
62
  // Accent colors
44
63
  --color-accent: #{$color-accent-primary};
64
+ --color-accent-text: #{$color-accent-primary-text};
45
65
  --color-accent-secondary: #{$color-accent-secondary};
46
66
  --color-accent-dark: #{color.adjust($color-accent-primary, $lightness: -10%)};
47
67
 
@@ -80,6 +100,7 @@ body.dark-mode {
80
100
 
81
101
  // Accent colors
82
102
  --color-accent: #{$dark-accent-primary};
103
+ --color-accent-text: #{$dark-accent-primary};
83
104
  --color-accent-secondary: #{$dark-accent-secondary};
84
105
  --color-accent-dark: #{color.adjust($dark-accent-primary, $lightness: -10%)};
85
106
 
@@ -95,6 +95,122 @@ figcaption {
95
95
  margin-top: map.get($spacing, 2);
96
96
  }
97
97
 
98
+ // Numbered figures and tables, and the references to them (_plugins/references.rb).
99
+ .datalog-figure img {
100
+ display: block;
101
+ max-width: 100%;
102
+ height: auto;
103
+ margin: 0 auto;
104
+ }
105
+
106
+ table > caption {
107
+ caption-side: top;
108
+ text-align: left;
109
+ font-size: map.get($font-size-scale, sm);
110
+ color: $color-ink-500;
111
+ margin-bottom: map.get($spacing, 2);
112
+ }
113
+
114
+ body.dark-mode table > caption {
115
+ color: rgba($dark-ink-500, 0.85);
116
+ }
117
+
118
+ .datalog-ref-label {
119
+ font-weight: 600;
120
+ }
121
+
122
+ // A reference scrolls its target clear of the sticky header.
123
+ [data-ref-target] {
124
+ scroll-margin-top: calc(var(--header-height, 96px) + #{map.get($spacing, 4)});
125
+ }
126
+
127
+ @media print {
128
+ [data-ref-target] {
129
+ break-inside: avoid;
130
+ }
131
+ }
132
+
133
+ // Theorems, definitions and the other statements, and proofs (_plugins/statements.rb).
134
+ .datalog-statement {
135
+ @include callout($color-accent-primary);
136
+ margin: map.get($spacing, 5) 0;
137
+ max-width: $max-width-reading;
138
+ }
139
+
140
+ .datalog-statement--definition,
141
+ .datalog-statement--assumption {
142
+ @include callout($color-accent-secondary);
143
+ }
144
+
145
+ .datalog-statement--example,
146
+ .datalog-statement--remark {
147
+ @include callout($color-neutral-500);
148
+ }
149
+
150
+ .datalog-statement__heading,
151
+ .datalog-proof__heading {
152
+ margin: 0 0 map.get($spacing, 2);
153
+ }
154
+
155
+ .datalog-statement__body > :last-child,
156
+ .datalog-proof__body > :last-child {
157
+ margin-bottom: 0;
158
+ }
159
+
160
+ .datalog-proof {
161
+ margin: map.get($spacing, 5) 0;
162
+ max-width: $max-width-reading;
163
+ }
164
+
165
+ .datalog-proof__heading {
166
+ font-style: italic;
167
+ }
168
+
169
+ .datalog-proof__end {
170
+ margin: 0;
171
+ text-align: right;
172
+ }
173
+
174
+ // On the tinted background, a link is a shade darker to keep its contrast, and
175
+ // a code block sits on the page background, which the highlighter's colours
176
+ // are set for.
177
+ .datalog-statement a {
178
+ color: $color-accent-primary-text;
179
+
180
+ &:hover,
181
+ &:focus {
182
+ color: $color-accent-secondary-text;
183
+ }
184
+ }
185
+
186
+ .datalog-statement pre.highlight,
187
+ .datalog-statement pre[class*='language-'] {
188
+ background: $color-surface-50;
189
+ }
190
+
191
+ body.dark-mode {
192
+ .datalog-statement {
193
+ border-left-color: $dark-accent-primary;
194
+ }
195
+
196
+ .datalog-statement--definition,
197
+ .datalog-statement--assumption {
198
+ border-left-color: $dark-accent-secondary;
199
+ }
200
+
201
+ .datalog-statement--example,
202
+ .datalog-statement--remark {
203
+ border-left-color: $dark-ink-500;
204
+ }
205
+ }
206
+
207
+ @media print {
208
+ .datalog-statement {
209
+ border-left-color: currentColor;
210
+ background: none;
211
+ }
212
+ }
213
+
98
214
  body.dark-mode figcaption {
99
215
  color: rgba($dark-ink-500, 0.85);
100
216
  }
@@ -146,3 +262,17 @@ pre code {
146
262
  text-transform: uppercase;
147
263
  letter-spacing: 0.08em;
148
264
  }
265
+
266
+ // Keyboard keys, such as the shortcut hints on the search page.
267
+ kbd {
268
+ display: inline-block;
269
+ padding: 0.25rem 0.5rem;
270
+ background: var(--color-background-secondary, #f7fafc);
271
+ border: 1px solid var(--color-border, #cbd5e0);
272
+ border-radius: 4px;
273
+ font-family: var(--font-mono, monospace);
274
+ font-size: 0.8125rem;
275
+ font-weight: 600;
276
+ color: var(--color-text-primary, #1a202c);
277
+ box-shadow: 0 2px 0 var(--color-border, #cbd5e0);
278
+ }
@@ -328,6 +328,11 @@ body.dark-mode .analytics-alert {
328
328
  background: rgba($color-surface, 0.65);
329
329
  }
330
330
 
331
+ // The intro's colour is the light ink; on the dark background it was invisible (1.02:1).
332
+ body.dark-mode .post-comments-intro {
333
+ color: $dark-ink-700;
334
+ }
335
+
331
336
  body.dark-mode .datalog-comments {
332
337
  background: rgba($color-surface-dark, 0.35);
333
338
  border-color: rgba($color-border-dark, 0.6);
@@ -45,9 +45,15 @@ $color-accent-secondary: #0d9488; // teal — fills, borders and other non-text
45
45
  // #0d9488 reaches only 3.1:1 to 3.7:1 against white and against its own
46
46
  // tinted backgrounds, so it fails WCAG AA wherever it is used as text.
47
47
  $color-accent-secondary-text: #115e59; // teal — the same accent as readable text
48
+ // #2563eb reaches only 4.4:1 against its own 8% tint on the page background,
49
+ // where a theorem's links sit.
50
+ $color-accent-primary-text: #1d4ed8; // blue — links on a tinted background
48
51
  $color-accent-tertiary: #7c3aed; // purple — charts, visual accents
49
52
  $color-success: #16a34a;
53
+ $color-success-text: #166534; // green — the success colour as readable text
50
54
  $color-warning: #d97706;
55
+ $color-warning-text: #92400e; // amber — the warning colour as readable text
56
+ $dark-warning: #fbbf24; // lighter amber for dark bg
51
57
  $color-critical: #dc2626;
52
58
  $color-neutral-50: #fafaf9 !default;
53
59
  $color-neutral-100: #f5f5f4;
@@ -0,0 +1,125 @@
1
+ @use 'sass:map';
2
+
3
+ @use 'variables' as *;
4
+
5
+ // "Mentioned elsewhere" (components/webmentions.html, assets/js/webmentions/list.js):
6
+ // what other websites said about the article, apart from the comments hosted here.
7
+
8
+ .webmentions {
9
+ max-width: $max-width-reading;
10
+ margin-top: map.get($spacing, 6);
11
+ padding-top: map.get($spacing, 4);
12
+ border-top: 1px solid rgba($color-neutral-500, 0.25);
13
+ }
14
+
15
+ .webmentions__heading {
16
+ margin: 0 0 map.get($spacing, 2);
17
+ font-size: map.get($font-size-scale, lg);
18
+ }
19
+
20
+ .webmentions__intro,
21
+ .webmentions__status {
22
+ margin: 0 0 map.get($spacing, 3);
23
+ font-size: map.get($font-size-scale, sm);
24
+ color: $color-ink-500;
25
+ }
26
+
27
+ .webmentions[data-state='error'] .webmentions__status {
28
+ color: $color-danger-700;
29
+ }
30
+
31
+ .webmentions__list {
32
+ list-style: none;
33
+ margin: 0;
34
+ padding: 0;
35
+ display: grid;
36
+ gap: map.get($spacing, 3);
37
+ }
38
+
39
+ // display: grid would override the hidden attribute.
40
+ .webmentions__list[hidden] {
41
+ display: none;
42
+ }
43
+
44
+ .webmention {
45
+ padding-left: map.get($spacing, 4);
46
+ border-left: 3px solid rgba($color-neutral-500, 0.35);
47
+ font-size: map.get($font-size-scale, sm);
48
+ }
49
+
50
+ .webmention--reply {
51
+ border-left-color: $color-accent-secondary;
52
+ }
53
+
54
+ .webmention__type {
55
+ display: inline-block;
56
+ margin-right: map.get($spacing, 2);
57
+ padding: 0 map.get($spacing, 2);
58
+ border-radius: map.get($radius, sm);
59
+ background: rgba($color-neutral-500, 0.15);
60
+ color: $color-ink-700;
61
+ font-size: map.get($font-size-scale, xs);
62
+ text-transform: uppercase;
63
+ letter-spacing: 0.04em;
64
+ }
65
+
66
+ .webmention__title {
67
+ font-weight: 600;
68
+ overflow-wrap: anywhere;
69
+ }
70
+
71
+ .webmention__meta {
72
+ display: block;
73
+ margin-top: map.get($spacing, 1);
74
+ color: $color-ink-500;
75
+
76
+ > * + *::before {
77
+ content: '·';
78
+ margin: 0 map.get($spacing, 1);
79
+ }
80
+ }
81
+
82
+ .webmention__excerpt {
83
+ margin: map.get($spacing, 2) 0 0;
84
+ color: $color-ink-700;
85
+ overflow-wrap: anywhere;
86
+ }
87
+
88
+ body.dark-mode {
89
+ .webmentions {
90
+ border-top-color: rgba($dark-ink-500, 0.35);
91
+ }
92
+
93
+ .webmentions__intro,
94
+ .webmentions__status,
95
+ .webmention__meta {
96
+ color: $dark-ink-500;
97
+ }
98
+
99
+ .webmentions[data-state='error'] .webmentions__status {
100
+ color: $color-danger-300;
101
+ }
102
+
103
+ .webmention {
104
+ border-left-color: rgba($dark-ink-500, 0.45);
105
+ }
106
+
107
+ .webmention--reply {
108
+ border-left-color: $dark-accent-secondary;
109
+ }
110
+
111
+ .webmention__type {
112
+ background: rgba($dark-ink-500, 0.2);
113
+ color: $dark-ink-700;
114
+ }
115
+
116
+ .webmention__excerpt {
117
+ color: $dark-ink-700;
118
+ }
119
+ }
120
+
121
+ @media print {
122
+ .webmentions {
123
+ display: none !important;
124
+ }
125
+ }
data/assets/css/main.scss CHANGED
@@ -1,4 +1,18 @@
1
1
  ---
2
2
  # Only front matter so Jekyll processes this file
3
3
  ---
4
+ {%- comment -%}
5
+ Configures _sass/_features.scss before the theme loads it, so the stylesheet
6
+ carries the styles of an optional feature only when this site uses it. A site
7
+ that copies this file to add its own rules keeps these lines.
8
+ {%- endcomment -%}
9
+ {%- assign notebook_pages = site.pages | where: "layout", "notebook" -%}
10
+ @use "features" with (
11
+ $search: {% if site.features.search %}true{% else %}false{% endif %},
12
+ $visualizations: {% if site.features.visualizations %}true{% else %}false{% endif %},
13
+ $notebooks: {% if notebook_pages.size > 0 %}true{% else %}false{% endif %},
14
+ $packages: {% if site.packages.size > 0 %}true{% else %}false{% endif %},
15
+ $academic-dashboard: {% if site.features.academic_dashboard %}true{% else %}false{% endif %},
16
+ $open-science-badges: {% if site.data.academic.badges.size > 0 %}true{% else %}false{% endif %}
17
+ );
4
18
  @use "theme";
@@ -1 +1 @@
1
- function u(){let e=window.DatalogAcademic||{},a=window.DatalogPublications||{},t=a.metrics||(e.citations?e.citations.metrics:{})||{},o=a.yearly_totals||(e.citations?e.citations.yearly_totals:{})||{};document.querySelectorAll("[data-citation-metric]").forEach(i=>{let c=i.getAttribute("data-citation-metric");if(!c)return;let n;switch(c){case"total":n=t.total;break;case"h_index":case"h-index":n=t.h_index;break;case"i10_index":case"i10-index":n=t.i10_index;break;case"since_total":n=t.since_2019?t.since_2019.total:void 0;break;case"since_h_index":n=t.since_2019?t.since_2019.h_index:void 0;break;case"since_i10":n=t.since_2019?t.since_2019.i10_index:void 0;break;default:if(c.startsWith("year_")){let s=c.replace("year_","");n=o[s]}break}typeof n=="number"?i.textContent=n.toLocaleString():n&&(i.textContent=n)})}function f(){let e=window.DatalogAcademic||{},t=(window.DatalogPublications||{}).citation_totals||(e.citations?e.citations.per_publication:{})||{};document.querySelectorAll("[data-publication-citations]").forEach(o=>{let i=o.getAttribute("data-publication-citations");if(!i)return;let c=i.toLowerCase(),n;t[i]?n=t[i].total||t[i]:t[c]&&(n=t[c].total||t[c]),typeof n=="number"&&(o.textContent=n.toLocaleString())})}function p(){let e=window.DatalogAcademic||{},t=(window.DatalogPublications||{}).yearly_totals||(e.citations?e.citations.yearly_totals:{})||{},o=document.querySelector("[data-citation-timeline]");o&&t&&o.querySelectorAll("li[data-year]").forEach(c=>{let n=c.getAttribute("data-year");if(!n)return;let s=c.querySelector("[data-year-total]"),r=t[n];s&&typeof r!="undefined"&&(s.textContent=Number(r).toLocaleString(),c.style.setProperty("--timeline-value",Math.min(Number(r)/5,100)))})}function l(e,a){document.querySelectorAll(e).forEach(t=>{t.addEventListener("click",()=>{let o=typeof a=="function"?a(t):a;o&&navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(o).then(()=>{t.dataset.copied="true",t.textContent="Copied!",setTimeout(()=>{t.dataset.copied="false",t.textContent=t.dataset.originalText||"Copy"},2e3)}).catch(()=>{t.dataset.copied="error",t.textContent="Error"})}),t.dataset.originalText=t.textContent})}function y(){l("[data-copy-citation]",e=>{let a=e.getAttribute("data-target");if(!a)return"";let t=document.getElementById(a);return t?t.value:""}),l("[data-copy-bibliography]",e=>{let a=e.getAttribute("data-target");if(!a)return"";let t=document.getElementById(a);return t?t.value:""})}function b(){let e=document.querySelector("[data-submission-filter]");if(e){let a=document.querySelectorAll(".submission-card"),t=()=>{let o=e.value;a.forEach(i=>{if(!o){i.hidden=!1;return}let c=i.getAttribute("data-submission-status");i.hidden=c!==o})};e.addEventListener("change",t),t()}}function m(){let e=document.querySelector("[data-calendar-filter]"),a=document.querySelector("[data-academic-calendar]");if(e&&a){let t=a.querySelectorAll("li[data-event-type]"),o=()=>{let i=e.value;t.forEach(c=>{if(!i){c.hidden=!1;return}let n=c.getAttribute("data-event-type");c.hidden=n!==i})};e.addEventListener("change",o),o()}}function x(){document.querySelectorAll(".open-science-badge").forEach(a=>{let t=a.querySelector(".open-science-badge__description"),o=a.querySelector(".open-science-badge__criteria"),i=[];t&&i.push(t.textContent.trim()),o&&i.push(o.textContent.trim()),i.length&&a.setAttribute("title",i.join(" \u2022 "))})}function d(){u(),f(),p(),y(),b(),m(),x()}typeof window!="undefined"&&document.readyState!=="loading"?d():typeof window!="undefined"&&document.addEventListener("DOMContentLoaded",d);export{l as attachCopyHandler,d as initAcademicFeatures,m as initCalendarFilter,y as initCopyHandlers,x as initOpenScienceBadges,b as initSubmissionFilter,u as populateCitationMetrics,p as populateCitationTimeline,f as populatePublicationCitations};
1
+ import"./chunks/chunk-PATLC23F.js";function d(){let a=window.DatalogAcademic||{},c=window.DatalogPublications||{},t=c.metrics||(a.citations?a.citations.metrics:{})||{},o=c.yearly_totals||(a.citations?a.citations.yearly_totals:{})||{};document.querySelectorAll("[data-citation-metric]").forEach(e=>{let n=e.getAttribute("data-citation-metric");if(!n)return;let i;switch(n){case"total":i=t.total;break;case"h_index":case"h-index":i=t.h_index;break;case"i10_index":case"i10-index":i=t.i10_index;break;case"since_total":i=t.since_2019?t.since_2019.total:void 0;break;case"since_h_index":i=t.since_2019?t.since_2019.h_index:void 0;break;case"since_i10":i=t.since_2019?t.since_2019.i10_index:void 0;break;default:if(n.startsWith("year_")){let s=n.replace("year_","");i=o[s]}break}typeof i=="number"?e.textContent=i.toLocaleString():i&&(e.textContent=i)})}function u(){let a=window.DatalogAcademic||{},t=(window.DatalogPublications||{}).citation_totals||(a.citations?a.citations.per_publication:{})||{};document.querySelectorAll("[data-publication-citations]").forEach(o=>{let e=o.getAttribute("data-publication-citations");if(!e)return;let n=e.toLowerCase(),i;t[e]?i=t[e].total||t[e]:t[n]&&(i=t[n].total||t[n]),typeof i=="number"&&(o.textContent=i.toLocaleString())})}function f(){let a=window.DatalogAcademic||{},t=(window.DatalogPublications||{}).yearly_totals||(a.citations?a.citations.yearly_totals:{})||{},o=document.querySelector("[data-citation-timeline]");o&&t&&o.querySelectorAll("li[data-year]").forEach(n=>{let i=n.getAttribute("data-year");if(!i)return;let s=n.querySelector("[data-year-total]"),r=t[i];s&&typeof r!="undefined"&&(s.textContent=Number(r).toLocaleString(),n.style.setProperty("--timeline-value",Math.min(Number(r)/5,100)))})}function y(){let a=document.querySelector("[data-submission-filter]");if(a){let c=document.querySelectorAll(".submission-card"),t=()=>{let o=a.value;c.forEach(e=>{if(!o){e.hidden=!1;return}let n=e.getAttribute("data-submission-status");e.hidden=n!==o})};a.addEventListener("change",t),t()}}function p(){let a=document.querySelector("[data-calendar-filter]"),c=document.querySelector("[data-academic-calendar]");if(a&&c){let t=c.querySelectorAll("li[data-event-type]"),o=()=>{let e=a.value;t.forEach(n=>{if(!e){n.hidden=!1;return}let i=n.getAttribute("data-event-type");n.hidden=i!==e})};a.addEventListener("change",o),o()}}function b(){document.querySelectorAll(".open-science-badge").forEach(c=>{let t=c.querySelector(".open-science-badge__description"),o=c.querySelector(".open-science-badge__criteria"),e=[];t&&e.push(t.textContent.trim()),o&&e.push(o.textContent.trim()),e.length&&c.setAttribute("title",e.join(" \u2022 "))})}function l(){d(),u(),f(),y(),p(),b()}typeof window!="undefined"&&document.readyState!=="loading"?l():typeof window!="undefined"&&document.addEventListener("DOMContentLoaded",l);export{l as initAcademicFeatures,p as initCalendarFilter,b as initOpenScienceBadges,y as initSubmissionFilter,d as populateCitationMetrics,f as populateCitationTimeline,u as populatePublicationCitations};
@@ -1 +1 @@
1
- function m(){return window.__DATALOG_ANALYTICS__||{}}function E(e){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e,{once:!0}):e()}function f(e){return!e||!Array.isArray(e.rows)?[]:e.rows}function d(e,a){return new Intl.NumberFormat(void 0,a||{maximumFractionDigits:0}).format(e||0)}function h(e,a,n){var r;if(!e)return;let c=n||((r=e.closest("table"))==null?void 0:r.querySelectorAll("th").length)||1,i=document.createElement("tr");i.className="placeholder";let s=document.createElement("td");s.setAttribute("colspan",c),s.textContent=a,i.appendChild(s),e.replaceChildren(i)}function v(){let e=document.getElementById("analytics-top-posts"),a=f(m().top_posts);if(e){if(!a.length){h(e,e.dataset.emptyMessage||"No data available",3);return}e.replaceChildren(),a.forEach(n=>{var b,y,C;let c=n.dimensionValues||[],i=n.metricValues||[],s=((b=c[0])==null?void 0:b.value)||"",r=Number(((y=i[0])==null?void 0:y.value)||0),t=Number(((C=i[1])==null?void 0:C.value)||0),o=document.createElement("tr"),l=document.createElement("a");l.href=s.startsWith("/")?s:`/${s}`,l.textContent=s||"\u2014",l.rel="noopener",l.className="analytics-link";let u=document.createElement("td");u.appendChild(l);let p=document.createElement("td");p.textContent=d(r);let g=document.createElement("td");g.textContent=d(t,{maximumFractionDigits:0}),o.append(u,p,g),e.appendChild(o)})}}function w(){let e=document.getElementById("analytics-search-terms");if(!e)return;let a=f(m().search_terms);if(!a.length){h(e,e.dataset.emptyMessage||"No search queries recorded",2);return}e.replaceChildren(),a.forEach(n=>{var u,p;let c=n.dimensionValues||[],i=n.metricValues||[],s=((u=c[0])==null?void 0:u.value)||"(not provided)",r=Number(((p=i[0])==null?void 0:p.value)||0),t=document.createElement("tr"),o=document.createElement("td");o.textContent=s;let l=document.createElement("td");l.textContent=d(r),t.append(o,l),e.appendChild(t)})}function N(e){return!e||e.includes("-")?e:e.length===8?`${e.slice(0,4)}-${e.slice(4,6)}-${e.slice(6,8)}`:e}function _(){let e=document.getElementById("analytics-visitors-chart");if(!e||typeof Chart=="undefined")return;let a=f(m().visitor_trends);if(!a.length)return;let n=a.map(t=>{var o,l;return N((l=(o=t.dimensionValues)==null?void 0:o[0])==null?void 0:l.value)}),c=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[0])==null?void 0:l.value)||0)}),i=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[1])==null?void 0:l.value)||0)}),s=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[2])==null?void 0:l.value)||0)}),r=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[3])==null?void 0:l.value)||0)});new Chart(e,{type:"line",data:{labels:n,datasets:[{label:"Total users",data:c,borderColor:"#2563eb",backgroundColor:"rgba(37, 99, 235, 0.15)",tension:.35,fill:!0},{label:"New users",data:i,borderColor:"#10b981",backgroundColor:"rgba(16, 185, 129, 0.12)",tension:.35,fill:!1},{label:"Sessions",data:s,borderColor:"#9333ea",backgroundColor:"rgba(147, 51, 234, 0.1)",tension:.35,fill:!1},{label:"Page views",data:r,borderColor:"#f97316",backgroundColor:"rgba(249, 115, 22, 0.1)",borderDash:[6,6],tension:.35,fill:!1}]},options:{responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},scales:{y:{beginAtZero:!0,ticks:{callback:t=>d(t)}}},plugins:{legend:{position:"top"}}}})}function A(){let e=document.getElementById("analytics-engagement-chart");if(!e||typeof Chart=="undefined")return;let a=f(m().engagement_by_page).slice(0,10);if(!a.length)return;let n=a.map(s=>{var r,t;return((t=(r=s.dimensionValues)==null?void 0:r[0])==null?void 0:t.value)||"\u2014"}),c=a.map(s=>{var r,t;return Number(((t=(r=s.metricValues)==null?void 0:r[2])==null?void 0:t.value)||0)}),i=a.map(s=>{var r,t;return Number(((t=(r=s.metricValues)==null?void 0:r[0])==null?void 0:t.value)||0)});new Chart(e,{type:"bar",data:{labels:n,datasets:[{label:"Engaged sessions",data:c,backgroundColor:"rgba(59, 130, 246, 0.7)"},{label:"Page views",data:i,backgroundColor:"rgba(14, 165, 233, 0.5)"}]},options:{responsive:!0,maintainAspectRatio:!1,indexAxis:"y",scales:{x:{beginAtZero:!0,ticks:{callback:s=>d(s)}}},plugins:{legend:{position:"top"}}}})}function k(){let e=document.getElementById("analytics-key-events");if(!e)return;let a=f(m().key_events);if(!a.length){let n=document.createElement("li");n.className="placeholder",n.textContent="No tracked events in the selected window.",e.replaceChildren(n);return}e.replaceChildren(),a.forEach(n=>{var t,o,l,u;let c=((o=(t=n.dimensionValues)==null?void 0:t[0])==null?void 0:o.value)||"event",i=Number(((u=(l=n.metricValues)==null?void 0:l[0])==null?void 0:u.value)||0),s=document.createElement("li"),r=document.createElement("strong");r.textContent=d(i),s.appendChild(r),s.appendChild(document.createTextNode(` ${c.replace(/_/g," ")}`)),e.appendChild(s)})}function x(){let e=m().scholar||{},a=document.querySelector('[data-field="scholar-total"]'),n=document.querySelector('[data-field="scholar-h-index"]'),c=document.querySelector('[data-field="scholar-i10-index"]');a&&(a.textContent=e.total?d(Number(e.total)):"\u2014"),n&&(n.textContent=e.h_index?d(Number(e.h_index)):"\u2014"),c&&(c.textContent=e.i10_index?d(Number(e.i10_index)):"\u2014");let i=document.getElementById("analytics-scholar-chart");if(!i||typeof Chart=="undefined")return;let s=e.yearly_totals||{},r=Object.entries(s).map(([t,o])=>[Number(t),Number(o)]).sort((t,o)=>t[0]-o[0]);r.length&&new Chart(i,{type:"bar",data:{labels:r.map(t=>t[0]),datasets:[{label:"Citations",data:r.map(t=>t[1]),backgroundColor:"rgba(99, 102, 241, 0.8)"}]},options:{responsive:!0,maintainAspectRatio:!1,scales:{y:{beginAtZero:!0,ticks:{callback:t=>d(t)}}}}})}function V(){let e=document.getElementById("analytics-monthly-reports");if(!e)return;let a=Array.isArray(m().monthly_reports)?m().monthly_reports:[];if(!a.length){h(e,e.dataset.emptyMessage||"No monthly reports available",5);return}e.replaceChildren(),a.forEach(n=>{let c=document.createElement("tr"),i=document.createElement("td");i.textContent=n.month||"\u2014";let s=document.createElement("td");s.textContent=d(n.total_users||0);let r=document.createElement("td");r.textContent=d(n.new_users||0);let t=document.createElement("td");t.textContent=d(n.sessions||0);let o=document.createElement("td");o.textContent=d(n.page_views||0),c.append(i,s,r,t,o),e.appendChild(c)})}function I(){if(m().status!=="ok"){["analytics-top-posts","analytics-search-terms","analytics-monthly-reports"].forEach(n=>{let c=document.getElementById(n);c&&h(c,m().message||"Analytics data unavailable.")});let a=document.getElementById("analytics-key-events");if(a){let n=document.createElement("li");n.className="placeholder",n.textContent=m().message||"Analytics data unavailable.",a.replaceChildren(n)}x();return}v(),w(),_(),A(),k(),x(),V()}typeof window!="undefined"&&!window.__VITEST__&&E(I);export{h as ensurePlaceholder,N as formatDateLabel,d as formatNumber,E as onReady,f as parseRows,I as render,A as renderEngagementChart,k as renderKeyEvents,V as renderMonthlyReports,x as renderScholar,w as renderSearchTerms,v as renderTopPosts,_ as renderVisitorChart};
1
+ import"./chunks/chunk-PATLC23F.js";function m(){return window.__DATALOG_ANALYTICS__||{}}function E(e){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e,{once:!0}):e()}function f(e){return!e||!Array.isArray(e.rows)?[]:e.rows}function d(e,a){return new Intl.NumberFormat(void 0,a||{maximumFractionDigits:0}).format(e||0)}function h(e,a,n){var r;if(!e)return;let c=n||((r=e.closest("table"))==null?void 0:r.querySelectorAll("th").length)||1,i=document.createElement("tr");i.className="placeholder";let s=document.createElement("td");s.setAttribute("colspan",c),s.textContent=a,i.appendChild(s),e.replaceChildren(i)}function v(){let e=document.getElementById("analytics-top-posts"),a=f(m().top_posts);if(e){if(!a.length){h(e,e.dataset.emptyMessage||"No data available",3);return}e.replaceChildren(),a.forEach(n=>{var b,y,C;let c=n.dimensionValues||[],i=n.metricValues||[],s=((b=c[0])==null?void 0:b.value)||"",r=Number(((y=i[0])==null?void 0:y.value)||0),t=Number(((C=i[1])==null?void 0:C.value)||0),o=document.createElement("tr"),l=document.createElement("a");l.href=s.startsWith("/")?s:`/${s}`,l.textContent=s||"\u2014",l.rel="noopener",l.className="analytics-link";let u=document.createElement("td");u.appendChild(l);let p=document.createElement("td");p.textContent=d(r);let g=document.createElement("td");g.textContent=d(t,{maximumFractionDigits:0}),o.append(u,p,g),e.appendChild(o)})}}function w(){let e=document.getElementById("analytics-search-terms");if(!e)return;let a=f(m().search_terms);if(!a.length){h(e,e.dataset.emptyMessage||"No search queries recorded",2);return}e.replaceChildren(),a.forEach(n=>{var u,p;let c=n.dimensionValues||[],i=n.metricValues||[],s=((u=c[0])==null?void 0:u.value)||"(not provided)",r=Number(((p=i[0])==null?void 0:p.value)||0),t=document.createElement("tr"),o=document.createElement("td");o.textContent=s;let l=document.createElement("td");l.textContent=d(r),t.append(o,l),e.appendChild(t)})}function N(e){return!e||e.includes("-")?e:e.length===8?`${e.slice(0,4)}-${e.slice(4,6)}-${e.slice(6,8)}`:e}function _(){let e=document.getElementById("analytics-visitors-chart");if(!e||typeof Chart=="undefined")return;let a=f(m().visitor_trends);if(!a.length)return;let n=a.map(t=>{var o,l;return N((l=(o=t.dimensionValues)==null?void 0:o[0])==null?void 0:l.value)}),c=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[0])==null?void 0:l.value)||0)}),i=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[1])==null?void 0:l.value)||0)}),s=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[2])==null?void 0:l.value)||0)}),r=a.map(t=>{var o,l;return Number(((l=(o=t.metricValues)==null?void 0:o[3])==null?void 0:l.value)||0)});new Chart(e,{type:"line",data:{labels:n,datasets:[{label:"Total users",data:c,borderColor:"#2563eb",backgroundColor:"rgba(37, 99, 235, 0.15)",tension:.35,fill:!0},{label:"New users",data:i,borderColor:"#10b981",backgroundColor:"rgba(16, 185, 129, 0.12)",tension:.35,fill:!1},{label:"Sessions",data:s,borderColor:"#9333ea",backgroundColor:"rgba(147, 51, 234, 0.1)",tension:.35,fill:!1},{label:"Page views",data:r,borderColor:"#f97316",backgroundColor:"rgba(249, 115, 22, 0.1)",borderDash:[6,6],tension:.35,fill:!1}]},options:{responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},scales:{y:{beginAtZero:!0,ticks:{callback:t=>d(t)}}},plugins:{legend:{position:"top"}}}})}function A(){let e=document.getElementById("analytics-engagement-chart");if(!e||typeof Chart=="undefined")return;let a=f(m().engagement_by_page).slice(0,10);if(!a.length)return;let n=a.map(s=>{var r,t;return((t=(r=s.dimensionValues)==null?void 0:r[0])==null?void 0:t.value)||"\u2014"}),c=a.map(s=>{var r,t;return Number(((t=(r=s.metricValues)==null?void 0:r[2])==null?void 0:t.value)||0)}),i=a.map(s=>{var r,t;return Number(((t=(r=s.metricValues)==null?void 0:r[0])==null?void 0:t.value)||0)});new Chart(e,{type:"bar",data:{labels:n,datasets:[{label:"Engaged sessions",data:c,backgroundColor:"rgba(59, 130, 246, 0.7)"},{label:"Page views",data:i,backgroundColor:"rgba(14, 165, 233, 0.5)"}]},options:{responsive:!0,maintainAspectRatio:!1,indexAxis:"y",scales:{x:{beginAtZero:!0,ticks:{callback:s=>d(s)}}},plugins:{legend:{position:"top"}}}})}function k(){let e=document.getElementById("analytics-key-events");if(!e)return;let a=f(m().key_events);if(!a.length){let n=document.createElement("li");n.className="placeholder",n.textContent="No tracked events in the selected window.",e.replaceChildren(n);return}e.replaceChildren(),a.forEach(n=>{var t,o,l,u;let c=((o=(t=n.dimensionValues)==null?void 0:t[0])==null?void 0:o.value)||"event",i=Number(((u=(l=n.metricValues)==null?void 0:l[0])==null?void 0:u.value)||0),s=document.createElement("li"),r=document.createElement("strong");r.textContent=d(i),s.appendChild(r),s.appendChild(document.createTextNode(` ${c.replace(/_/g," ")}`)),e.appendChild(s)})}function x(){let e=m().scholar||{},a=document.querySelector('[data-field="scholar-total"]'),n=document.querySelector('[data-field="scholar-h-index"]'),c=document.querySelector('[data-field="scholar-i10-index"]');a&&(a.textContent=e.total?d(Number(e.total)):"\u2014"),n&&(n.textContent=e.h_index?d(Number(e.h_index)):"\u2014"),c&&(c.textContent=e.i10_index?d(Number(e.i10_index)):"\u2014");let i=document.getElementById("analytics-scholar-chart");if(!i||typeof Chart=="undefined")return;let s=e.yearly_totals||{},r=Object.entries(s).map(([t,o])=>[Number(t),Number(o)]).sort((t,o)=>t[0]-o[0]);r.length&&new Chart(i,{type:"bar",data:{labels:r.map(t=>t[0]),datasets:[{label:"Citations",data:r.map(t=>t[1]),backgroundColor:"rgba(99, 102, 241, 0.8)"}]},options:{responsive:!0,maintainAspectRatio:!1,scales:{y:{beginAtZero:!0,ticks:{callback:t=>d(t)}}}}})}function V(){let e=document.getElementById("analytics-monthly-reports");if(!e)return;let a=Array.isArray(m().monthly_reports)?m().monthly_reports:[];if(!a.length){h(e,e.dataset.emptyMessage||"No monthly reports available",5);return}e.replaceChildren(),a.forEach(n=>{let c=document.createElement("tr"),i=document.createElement("td");i.textContent=n.month||"\u2014";let s=document.createElement("td");s.textContent=d(n.total_users||0);let r=document.createElement("td");r.textContent=d(n.new_users||0);let t=document.createElement("td");t.textContent=d(n.sessions||0);let o=document.createElement("td");o.textContent=d(n.page_views||0),c.append(i,s,r,t,o),e.appendChild(c)})}function I(){if(m().status!=="ok"){["analytics-top-posts","analytics-search-terms","analytics-monthly-reports"].forEach(n=>{let c=document.getElementById(n);c&&h(c,m().message||"Analytics data unavailable.")});let a=document.getElementById("analytics-key-events");if(a){let n=document.createElement("li");n.className="placeholder",n.textContent=m().message||"Analytics data unavailable.",a.replaceChildren(n)}x();return}v(),w(),_(),A(),k(),x(),V()}typeof window!="undefined"&&!window.__VITEST__&&E(I);export{h as ensurePlaceholder,N as formatDateLabel,d as formatNumber,E as onReady,f as parseRows,I as render,A as renderEngagementChart,k as renderKeyEvents,V as renderMonthlyReports,x as renderScholar,w as renderSearchTerms,v as renderTopPosts,_ as renderVisitorChart};
@@ -0,0 +1 @@
1
+ import{a as x,b as $}from"./chunk-PATLC23F.js";var O="/capabilities",M="/health",U={401:"unauthorized",403:"forbidden",404:"not_found",409:"conflict",422:"invalid",429:"rate_limited"},j=new Set(["timeout","network","rate_limited","server"]),q=new Set(["GET","HEAD","OPTIONS"]),N={disabled:"This feature is not set up on this site.",unsupported:"The service behind this site does not offer this feature.",version:"This site and its service expect different API versions.",timeout:"The service took too long to answer. Try again in a moment.",network:"The service could not be reached. Check your connection and try again.",malformed:"The service answered in a way this site could not read.",unauthorized:"You need to sign in for this.",forbidden:"You are not allowed to do this.",not_found:"The service has nothing at that address.",conflict:"This was already done, or something changed in the meantime.",invalid:"Some of what you entered needs a correction.",rate_limited:"Too many requests for now. Please wait a little and try again.",server:"The service ran into a problem. Try again later.",http:"The service refused the request.",aborted:"The request was cancelled.",reference:"Reference: {{id}}"},c=class extends Error{constructor(r,i,n={}){var h,a,f,T,b,v,A,m;super(i),this.name="ServiceError",this.kind=r,this.status=(h=n.status)!=null?h:null,this.code=(a=n.code)!=null?a:null,this.requestId=(f=n.requestId)!=null?f:null,this.retryAfter=(T=n.retryAfter)!=null?T:null,this.errors=(b=n.errors)!=null?b:null,this.expected=(v=n.expected)!=null?v:null,this.actual=(A=n.actual)!=null?A:null,this.retryable=(m=n.retryable)!=null?m:j.has(r)}};function H(e=globalThis){let r=e.DatalogDynamicServices;return r&&typeof r=="object"?r:{}}function Y(e){let r=String(e!=null?e:"1").trim()||"1";return/^v/i.test(r)?`v${r.slice(1)}`:`v${r}`}function G(e,r=Date.now()){if(!e)return null;let i=Number(e);if(Number.isFinite(i))return Math.max(0,i);let n=Date.parse(e);return Number.isNaN(n)?null:Math.max(0,Math.round((n-r)/1e3))}function K(e,r){if(!e||typeof e.cookie!="string")return null;let i=e.cookie.split(";").map(n=>n.trim()).find(n=>n.startsWith(`${r}=`));return i?decodeURIComponent(i.slice(r.length+1)):null}function B(e,r,i){let n=e.status,h=U[n]||(n>=500?"server":"http"),a=r&&typeof r=="object"?r.error||r:{},f=a&&(a.message||a.title)||`The service answered ${n}`;return new c(h,f,{status:n,code:a&&a.code||null,requestId:i,retryAfter:G(e.headers.get("Retry-After")),errors:a&&a.errors||null})}function X(e,r={}){let i=e&&e.kind?e.kind:"http",n=r[i]||N[i]||r.http||N.http;if(e&&e.requestId){let h=r.reference||N.reference;return`${n} ${h.split("{{id}}").join(e.requestId)}`}return n}function J(e=H(),r={}){let i=r.fetch||((...t)=>globalThis.fetch(...t)),n=r.delay||(t=>new Promise(s=>setTimeout(s,t))),h=r.document===void 0?globalThis.document:r.document,a=String(e.base_url||"").replace(/\/+$/,""),f=Y(e.api_version),T=Number(e.timeout_ms)>0?Number(e.timeout_ms):8e3,b=["omit","same-origin","include"].includes(e.credentials)?e.credentials:"omit",v=e.features&&typeof e.features=="object"?e.features:{},A=e.paths&&typeof e.paths=="object"?e.paths:{},m=a!=="",E=null;function R(t){return/^https?:\/\//i.test(t)?t:`${a}/${f}${t.startsWith("/")?t:`/${t}`}`}function L(t){let s=A[t];return typeof s=="string"&&s!==""?s:`/${t}`}async function P(t,s,o){let u=new AbortController,_=setTimeout(()=>u.abort(),T),w=!1;o.signal&&o.signal.addEventListener("abort",()=>{w=!0,u.abort()});let p=x({Accept:"application/json"},o.headers||{}),d={method:t,headers:p,credentials:b,signal:u.signal};if(o.body!==void 0&&(p["Content-Type"]="application/json",d.body=JSON.stringify(o.body)),o.idempotencyKey&&(p["Idempotency-Key"]=o.idempotencyKey),!q.has(t)&&e.csrf_header&&e.csrf_cookie){let g=K(h,e.csrf_cookie);g&&(p[e.csrf_header]=g)}let l,k;try{l=await i(R(s),d),k=await l.text()}catch(g){throw w?new c("aborted","The request was cancelled",{retryable:!1}):u.signal.aborted?new c("timeout",`No answer within ${T} ms`):new c("network","The service could not be reached")}finally{clearTimeout(_)}let I=l.headers.get("X-Request-Id")||null,S=null;if(k)try{S=JSON.parse(k)}catch(g){if(l.ok)throw new c("malformed","The service did not answer with JSON",{status:l.status,requestId:I,retryable:!1})}if(!l.ok)throw B(l,S,I);return{data:S,status:l.status,requestId:I,headers:l.headers}}async function y(t,s,o={}){var p;if(!m)throw new c("disabled","Dynamic services are not configured for this site",{retryable:!1});let u=String(t).toUpperCase(),_=(p=o.retries)!=null?p:q.has(u)?2:0,w=0;for(;;)try{return await P(u,s,o)}catch(d){let l=d.retryAfter!==null&&d.retryAfter>10;if(!(d instanceof c)||!d.retryable||w>=_||l)throw d;w+=1,await n(d.retryAfter!==null?d.retryAfter*1e3:300*w)}}function C(){return E||(E=y("GET",O).then(({data:t})=>{var u;let s=String((u=t&&t.api_version)!=null?u:"").replace(/^v/i,""),o=f.slice(1);if(s!==o)throw new c("version",`The service speaks API version ${s||"unknown"}; this site expects ${o}`,{expected:o,actual:s,retryable:!1});return t}).catch(t=>{throw E=null,t})),E}async function F(t){if(!m)throw new c("disabled","Dynamic services are not configured for this site",{retryable:!1});if(v[t]===!1)throw new c("disabled",`${t} is off in this site's settings`,{retryable:!1});let s=await C();if(!s||!s.features||!s.features[t])throw new c("unsupported",`The service does not offer ${t}`,{retryable:!1});return!0}return{enabled:m,base:a,version:f,timeout:T,credentials:b,urlFor:R,pathFor:L,request:y,get:(t,s)=>y("GET",t,s),post:(t,s,o={})=>y("POST",t,$(x({},o),{body:s})),patch:(t,s,o={})=>y("PATCH",t,$(x({},o),{body:s})),delete:(t,s)=>y("DELETE",t,s),capabilities:C,feature:F,health:()=>y("GET",M).then(({data:t})=>t)}}var D=null;function z(){return D||(D=J()),D}export{X as a,J as b,z as c};
@@ -0,0 +1 @@
1
+ var f=Object.defineProperty,g=Object.defineProperties;var h=Object.getOwnPropertyDescriptors;var d=Object.getOwnPropertySymbols;var i=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var e=(c,a,b)=>a in c?f(c,a,{enumerable:!0,configurable:!0,writable:!0,value:b}):c[a]=b,k=(c,a)=>{for(var b in a||(a={}))i.call(a,b)&&e(c,b,a[b]);if(d)for(var b of d(a))j.call(a,b)&&e(c,b,a[b]);return c},l=(c,a)=>g(c,h(a));export{k as a,l as b};
@@ -0,0 +1 @@
1
+ import{a as l}from"./chunk-2DYDWUFX.js";var u=["idle","pending","success","invalid","error","disabled"];function b(e,t){let i=e.elements.namedItem(t);return i?typeof i.setAttribute=="function"?[i]:Array.from(i):[]}function f(e){e.querySelectorAll("[aria-invalid]").forEach(t=>{t.removeAttribute("aria-invalid");let i=(t.getAttribute("aria-describedby")||"").split(/\s+/).filter(r=>r&&!r.endsWith("-error")).join(" ");i?t.setAttribute("aria-describedby",i):t.removeAttribute("aria-describedby")}),e.querySelectorAll("[data-error-for]").forEach(t=>{t.textContent="",t.hidden=!0})}function y(e,t){let i=0,r=null;return Object.keys(t||{}).forEach(n=>{let o=Array.isArray(t[n])?t[n].join(" "):String(t[n]),s=e.querySelector(`[data-error-for="${n}"]`);s&&(s.textContent=o,s.hidden=!1,s.id||(s.id=`${e.id||"form"}-${n}-error`)),b(e,n).forEach(d=>{if(d.setAttribute("aria-invalid","true"),s){let a=(d.getAttribute("aria-describedby")||"").split(/\s+/).filter(Boolean);a.includes(s.id)||a.push(s.id),d.setAttribute("aria-describedby",a.join(" "))}r=r||d,i+=1})}),r&&typeof r.focus=="function"&&r.focus(),i}function c(e,t,i="",r=null){e.dataset.state=u.includes(t)?t:"idle";let n=t==="pending";e.setAttribute("aria-busy",n?"true":"false"),e.querySelectorAll("button[type=submit], [data-form-submit]").forEach(s=>{s.disabled=n||t==="disabled"}),e.querySelectorAll("fieldset").forEach(s=>{s.disabled=t==="disabled"});let o=e.querySelector("[data-form-status]");o&&(o.setAttribute("role",t==="error"||t==="invalid"?"alert":"status"),o.textContent=i,o.hidden=i===""),f(e),t==="invalid"&&r&&y(e,r)}function A(e){let t={};return new FormData(e).forEach((i,r)=>{let n=typeof i=="string"?i.trim():i;r in t?t[r]=[].concat(t[r],n):t[r]=n}),t}function h(e,t,i={}){let r=l(t,i);t&&t.kind==="invalid"?c(e,"invalid",r,t.errors||null):c(e,"error",r)}export{c as a,A as b,h as c};
@@ -0,0 +1,2 @@
1
+ import{a as v,b as K,c as B}from"./chunks/chunk-V7734B2G.js";import{a as I,b as U,c as M}from"./chunks/chunk-2DYDWUFX.js";import{a as T,b as q}from"./chunks/chunk-PATLC23F.js";var O="comments",Q=3,J=/^https?:\/\//i,W=new Set(["disabled","unsupported","version"]);function X(e,t){let n=e.querySelector(t);if(!n)return{};try{return JSON.parse(n.textContent)||{}}catch(a){return{}}}function Z(){let e=globalThis.crypto;return e&&typeof e.randomUUID=="function"?e.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function ee(e,t){return Object.keys(t).reduce((n,a)=>n.split(`{{${a}}}`).join(t[a]),e)}function te(e,t){let n=new Date(e);if(Number.isNaN(n.getTime()))return String(e||"");try{return n.toLocaleString(t||void 0,{dateStyle:"medium",timeStyle:"short"})}catch(a){return n.toISOString()}}function ne(e,t=!0){let n=Array.isArray(e)?e.filter(i=>i&&typeof i=="object"):[],a=new Map;n.forEach(i=>a.set(String(i.id),{comment:i,replies:[]}));let f=[];a.forEach(i=>{let o=i.comment.parent_id,u=t&&o!==null&&o!==void 0?a.get(String(o)):null;u&&u!==i?u.replies.push(i):f.push(i)});let p=(i,o)=>String(i.comment.created_at||"").localeCompare(String(o.comment.created_at||"")),y=i=>(i.sort(p),i.forEach(o=>y(o.replies)),i);return y(f)}function P(e,t,n={}){let{labels:a={},lang:f,replies:p=!1,onReply:y}=n,i=t.status==="pending",o=e.createElement("li");o.className=i?"comment comment--pending":"comment",t.id!==null&&t.id!==void 0&&(o.id=`comment-${t.id}`);let u=e.createElement("article");u.className="comment__card";let S=e.createElement("header");S.className="comment__meta";let h=t.author&&typeof t.author=="object"?t.author:{},g=String(h.name||"").trim()||a.anonymous||"Anonymous",s;if(J.test(String(h.url||""))?(s=e.createElement("a"),s.href=h.url,s.rel="nofollow noopener ugc"):s=e.createElement("span"),s.className="comment__author",s.textContent=g,S.appendChild(s),t.created_at){let l=e.createElement("time");l.className="comment__time",l.dateTime=String(t.created_at),l.textContent=te(t.created_at,f),S.appendChild(l)}if(i){let l=e.createElement("span");l.className="comment__pending",l.textContent=a.pending||"Awaiting moderation",S.appendChild(l)}u.appendChild(S);let b=e.createElement("div");if(b.className="comment__body",String(t.body||"").split(/\n{2,}/).forEach(l=>{let _=e.createElement("p");l.split(`
2
+ `).forEach((C,w)=>{w>0&&_.appendChild(e.createElement("br")),_.appendChild(e.createTextNode(C))}),b.appendChild(_)}),u.appendChild(b),p&&y&&!i&&t.id!==null&&t.id!==void 0){let l=e.createElement("button");l.type="button",l.className="comment__reply post-tool",l.textContent=a.reply||"Reply",l.addEventListener("click",()=>y(t)),u.appendChild(l)}return o.appendChild(u),o}function V(e,t){let n=t.querySelector(":scope > .comments-thread__replies");return n||(n=e.createElement("ol"),n.className="comments-thread__replies",t.appendChild(n)),n}function Y(e,t,n,a){n.forEach(f=>{let p=P(e,f.comment,a);f.replies.length>0&&Y(e,V(e,p),f.replies,a),t.appendChild(p)})}function re(e,t){let n={name:e.name||""};return e.email&&(n.email=e.email),e.url&&(n.url=e.url),{path:t,parent_id:e.parent_id||null,author:n,body:e.body||""}}function ae(e,t,n={}){let a={};return e.author.name||(a.name=n.name_required||"Say who you are."),e.author.email&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e.author.email)&&(a.email=n.email_invalid||"That does not look like an email address."),e.author.url&&!J.test(e.author.url)&&(a.url=n.url_invalid||"A website address starts with http:// or https://."),e.body.trim().length<Q&&(a.body=n.body_short||"Say a little more."),t.website&&(a.website="spam"),Object.keys(a).length>0?a:null}function oe(e,t={}){let n=e.ownerDocument,a=t.window||n.defaultView,f=e.dataset.commentsEndpoint||"",p=t.client||(f?U(q(T({},a&&a.DatalogDynamicServices||{}),{base_url:f})):M()),y=e.dataset.commentsPath||"/",i=e.dataset.commentsReplies!=="false",o=X(e,"[data-comments-labels]"),u=o.errors||{},S=n.documentElement.lang||void 0,h=e.querySelector("[data-comments-status]"),g=e.querySelector("[data-comments-list]"),s=e.querySelector("form"),b=s?s.elements.namedItem("parent_id"):null,l=e.querySelector("[data-comments-replying]"),_=e.querySelector("[data-comments-replying-to]"),C=null,w=!1,F=!1,x=(r,c="",d={})=>{if(e.dataset.state=r,!!h&&(h.textContent=c,h.hidden=c==="",h.setAttribute("role",d.alert?"alert":"status"),d.retry)){let m=n.createElement("button");m.type="button",m.className="post-tool",m.setAttribute("data-comments-retry",""),m.textContent=o.retry||"Try again",m.addEventListener("click",()=>N.load()),h.appendChild(n.createTextNode(" ")),h.appendChild(m)}},L=()=>(C||(C=p.feature(O).catch(r=>{throw C=null,r})),C),R=r=>{if(!b)return;if(b.value=String(r.id),_){let d=r.author&&r.author.name?r.author.name:o.anonymous||"Anonymous";_.textContent=ee(o.replying_to||"Replying to {{name}}",{name:d})}l&&(l.hidden=!1);let c=s.elements.namedItem("body");c&&typeof c.focus=="function"&&c.focus()},D=()=>{b&&(b.value=""),l&&(l.hidden=!0)},j={labels:o,lang:S,replies:i,onReply:R},H=(r,c)=>{let d=i&&c!==null&&c!==void 0?g.querySelector(`#comment-${CSS.escape(String(c))}`):null;(d?V(n,d):g).appendChild(r),g.hidden=!1,e.dataset.state==="empty"&&x("loaded")},N={root:e,form:s,reply:R,cancelReply:D,async load(){if(w)return null;w=!0,x("loading",o.loading||"");try{await L();let r=await p.get(`${p.pathFor(O)}?path=${encodeURIComponent(y)}`),c=r&&r.data&&Array.isArray(r.data.comments)?r.data.comments:[];g.textContent="";let d=ne(c,i);return Y(n,g,d,j),g.hidden=d.length===0,x(d.length>0?"loaded":"empty",d.length>0?"":o.empty||""),F=!0,c}catch(r){return r&&W.has(r.kind)?(x("disabled",I(r,u)),s&&(s.hidden=!0)):x("error",I(r,u),{alert:!0,retry:!0}),null}finally{w=!1}},async submit(){let r=K(s),c=re(r,y),d=ae(c,r,o);if(d)return d.website?(v(s,"success",o.posted_pending||""),null):(v(s,"invalid",u.invalid||"",d),null);v(s,"pending",o.sending||"");try{await L();let m=await p.post(p.pathFor(O),c,{idempotencyKey:Z()}),A=m&&m.data&&typeof m.data=="object"?m.data:{},E=A.comment&&typeof A.comment=="object"?A.comment:null,k=A.status==="pending"||E!==null&&E.status==="pending";return E&&H(P(n,k?q(T({},E),{status:"pending"}):E,j),E.parent_id),s.reset(),D(),v(s,"success",k?o.posted_pending||"":o.posted||""),m}catch(m){return B(s,m,u),null}}};s&&(s.addEventListener("submit",r=>{r.preventDefault(),N.submit()}),e.querySelectorAll("[data-comments-cancel-reply]").forEach(r=>{r.addEventListener("click",D)}));let $=()=>{F||N.load()};if(t.immediate||!a||typeof a.IntersectionObserver!="function")$();else{let r=new a.IntersectionObserver(c=>{c.some(d=>d.isIntersecting)&&(r.disconnect(),$())},{rootMargin:"400px 0px"});r.observe(e)}return N}function z(e=document){return Array.from(e.querySelectorAll("[data-comments-thread]")).map(t=>oe(t))}function G(){z(document)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",G,{once:!0}):G();
@@ -0,0 +1 @@
1
+ import{a as o,b as v,c as y}from"./chunks/chunk-V7734B2G.js";import{c as g}from"./chunks/chunk-2DYDWUFX.js";import"./chunks/chunk-PATLC23F.js";var S="contact",w=20;function j(t,r){let n=t.querySelector(r);if(!n)return{};try{return JSON.parse(n.textContent)||{}}catch(e){return{}}}function U(){let t=globalThis.crypto;return t&&typeof t.randomUUID=="function"?t.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function A(t,r){let n={category:t.category||"other",name:t.name||"",email:t.email||"",subject:t.subject||"",message:t.message||"",source_url:r};return t.affiliation&&(n.affiliation=t.affiliation),n}function L(t,r,n={}){let e={};return t.name||(e.name=n.name_required||"Say who you are."),/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.email)||(e.email=n.email_invalid||"That does not look like an email address."),t.subject||(e.subject=n.subject_required||"Give the message a subject."),t.message.length<w&&(e.message=(n.message_short||"Say a little more: at least {{min}} characters.").split("{{min}}").join(String(w))),r.website&&(e.website="spam"),Object.keys(e).length>0?e:null}function _(t,r={}){let n=r.client||g(),e=t.querySelector("form"),s=j(t,"[data-contact-labels]"),C=j(t,"[data-contact-prompts]"),c=s.errors||{},F=t.dataset.sourceUrl||"",i=e.elements.namedItem("category"),l=t.querySelector("[data-contact-hint]"),q=l?l.textContent:"",u=null,f=()=>{l&&(l.textContent=i&&C[i.value]||q)};if(i&&(i.addEventListener("change",f),f()),!n.enabled)return o(e,"disabled",c.disabled||""),{form:e,available:!1,submit:async()=>null};let b=()=>(u||(u=n.feature(S).catch(a=>{throw u=null,y(e,a,c),e.dataset.state="disabled",e.querySelectorAll("button[type=submit]").forEach(m=>{m.disabled=!0}),a})),u);e.addEventListener("focusin",()=>b().catch(()=>{}),{once:!0});let h={form:e,available:!0,async submit(){let a=v(e),m=A(a,F),p=L(m,a,s);if(p)return p.website?(o(e,"success",s.success||""),null):(o(e,"invalid",c.invalid||"",p),null);o(e,"pending",s.pending||"");try{await b()}catch(d){return null}try{let d=await n.post(n.pathFor(S),m,{idempotencyKey:U()});return e.reset(),f(),o(e,"success",s.success||""),d}catch(d){return y(e,d,c),null}}};return e.addEventListener("submit",a=>{a.preventDefault(),h.submit()}),h}function x(t=document){return Array.from(t.querySelectorAll("[data-contact-form]")).map(r=>_(r))}function E(){x(document)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",E,{once:!0}):E();
@@ -1 +1 @@
1
- var f="datalog-color-mode",u="dark-mode";function I(e){let t=localStorage.getItem(f);return t==="dark"?!0:t==="light"?!1:e.matches}function h(){let e=document.querySelector("[data-toggle-dark-mode]"),t=document.body,n=window.matchMedia("(prefers-color-scheme: dark)");I(n)&&t.classList.add(u);let r=()=>{let i=t.classList.contains(u)?"dark":"light";t.dataset.theme=i,document.documentElement.dataset.theme=i},o=()=>{r(),e&&e.setAttribute("aria-pressed",t.classList.contains(u))};o(),e&&e.addEventListener("click",()=>{let i=t.classList.toggle(u);e.setAttribute("aria-pressed",String(i)),localStorage.setItem(f,i?"dark":"light"),r()}),n.addEventListener("change",i=>{localStorage.getItem(f)||(i.matches?t.classList.add(u):t.classList.remove(u),o())})}var C="datalog-github-";function m(e,t){return`${C}${e}-${t}`}function N(e,t,n){try{let r=localStorage.getItem(m(e,t));if(!r)return null;let o=JSON.parse(r);return!o||typeof o!="object"?null:Date.now()-o.timestamp>n?(localStorage.removeItem(m(e,t)),null):o.data}catch(r){return null}}function P(e,t,n){try{localStorage.setItem(m(e,t),JSON.stringify({timestamp:Date.now(),data:n}))}catch(r){}}async function D(e,t,n,r){let o=N(e,t,r);if(o)return o;try{let i=await fetch(`${n}/${e}/${t}`);if(!i.ok)throw new Error(`GitHub API error: ${i.status}`);let c=await i.json();return P(e,t,c),c}catch(i){return null}}function G(e,t){e.querySelectorAll("[data-github-stat]").forEach(r=>{let o=r.getAttribute("data-github-stat");if(!o)return;let i=t[o];typeof i=="number"?r.textContent=i.toLocaleString():typeof i=="string"&&i.length>0&&(r.textContent=i)})}function p(){let e=document.querySelectorAll("[data-github-owner][data-github-repo]");if(!e.length)return Promise.resolve();let n=(window.DatalogIntegrations||{}).github||{};if(n.enabled===!1)return Promise.resolve();let r=n.api_base||"https://api.github.com/repos",o=Number(n.cache_ttl||43200)*1e3,i=Array.from(e).map(c=>{let l=c.getAttribute("data-github-owner"),d=c.getAttribute("data-github-repo");return!l||!d?Promise.resolve():D(l,d,r,o).then(a=>{a&&G(c,a)})});return Promise.all(i)}var H="[data-language-filter], [data-navigate-on-change]";function $(e){if(typeof e!="string")return null;let t=Array.from(e).filter(r=>{let o=r.codePointAt(0);return o>31&&o!==127}).join("").trim();if(!t)return null;let n=/^[a-z][a-z0-9+.-]*:/i.exec(t);return n&&!/^https?:$/i.test(n[0])?null:t}function y(){let e=document.querySelectorAll(H);e.length!==0&&e.forEach(t=>{t.addEventListener("change",n=>{let r=$(n.target&&n.target.value);r&&(window.location.href=r)})})}var q="(min-width: 48rem)",b="#site-nav",L=".nav-toggle",g="nav-open";function S(e){return e.replace(/index\.html$/,"").replace(/\/$/,"")}function O(e){let t=e.getAttribute("href");if(!t)return null;try{let n=new URL(t,window.location.origin);if(!n.hash)return null;let r=new URL(window.location.href);return S(n.pathname)!==S(r.pathname)?null:n.hash.replace("#","")}catch(n){return null}}function R(e){if(!e)return!1;let t=document.getElementById(e);return t?(t.scrollIntoView({behavior:"smooth",block:"start"}),!0):!1}function v(){let e=document.querySelector(b);if(!e)return;let t=document.querySelector(L),n=document.body,r=window.matchMedia(q),o=a=>{if(a){e.dataset.open="true",n.classList.remove(g),t&&(t.setAttribute("aria-expanded","false"),t.classList.remove("is-active"));return}let s=e.dataset.open==="true";s||(e.dataset.open="false"),t&&(t.setAttribute("aria-expanded",String(s)),t.classList.toggle("is-active",s))},i=({focusToggle:a=!1}={})=>{r.matches||(e.dataset.open="false",n.classList.remove(g),t&&(t.setAttribute("aria-expanded","false"),t.classList.remove("is-active"),a&&t.focus()))},c=()=>{r.matches||(e.dataset.open="true",n.classList.add(g),t&&(t.setAttribute("aria-expanded","true"),t.classList.add("is-active")))},l=()=>{r.matches||(e.dataset.open==="true"?i():c())};r.matches||(e.dataset.open="false"),o(r.matches),r.addEventListener("change",a=>{a.matches?o(!0):(i(),e.dataset.open="false",o(!1))}),e.querySelectorAll(".nav-link").forEach(a=>{let s=O(a);a.addEventListener("click",x=>{r.matches||i(),s&&R(s)&&x.preventDefault()})}),t&&t.addEventListener("click",()=>{l()}),document.addEventListener("keydown",a=>{a.key==="Escape"&&i({focusToggle:!0})}),document.addEventListener("click",a=>{if(r.matches||e.dataset.open!=="true")return;let s=a.target;!s||typeof s.closest!="function"||s.closest(b)||t&&s.closest(L)||i()})}function _(e,t){let n=window.pageYOffset||document.documentElement.scrollTop,r=document.documentElement.scrollHeight-window.innerHeight,o=r>0?Math.min(n/r*100,100):0;e.tagName==="PROGRESS"?e.setAttribute("value",String(o)):e.style.setProperty("--progress",`${o}%`),t&&(t.textContent=Math.round(o))}function E(){let e=document.querySelector("[data-scroll-progress]");if(!e)return;let t=document.querySelector("[data-scroll-progress-value]"),n=()=>_(e,t);n(),window.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",n)}function k(e){if(!e)return;let t=e.querySelector("input[type='search']"),n=e.getAttribute("action");t?(t.focus(),t.select()):n&&(window.location.href=n)}function K(e){if(!e)return!1;if(e.isContentEditable)return!0;let t=e.tagName;return t==="INPUT"||t==="TEXTAREA"||t==="SELECT"}function w(){let e=document.querySelector(".site-search");e&&document.addEventListener("keydown",t=>{K(document.activeElement)||(t.key==="/"&&!t.ctrlKey&&!t.metaKey&&!t.altKey&&(t.preventDefault(),k(e)),(t.key==="k"||t.key==="K")&&(t.ctrlKey||t.metaKey)&&(t.preventDefault(),k(e)))})}function M(e){if(!e)return;e.getAttribute("tabindex")===null&&(e.setAttribute("tabindex","-1"),e.dataset.skipLinkTempTabindex="true"),e.addEventListener("blur",()=>{e.dataset.skipLinkTempTabindex&&(e.removeAttribute("tabindex"),delete e.dataset.skipLinkTempTabindex)},{once:!0}),e.focus()}function A(){let e=document.querySelectorAll(".skip-link[href^='#']");e.length&&e.forEach(t=>{t.addEventListener("click",n=>{let o=(t.getAttribute("href")||"").slice(1);if(!o)return;let i=document.getElementById(o);i&&(n.preventDefault(),M(i))})})}function T(){A(),v(),h(),y(),E(),w(),p()}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",T):T();export{T as initializeCore};
1
+ import{a as p}from"./chunks/chunk-PATLC23F.js";var _="[data-copy-citation], [data-copy-bibliography]";var g=!1;function G(t){let e=t.getAttribute("data-target"),n=e?document.getElementById(e):null;return n?"value"in n?n.value:n.textContent||"":""}async function O(t){let e=G(t);if(!(!e||!navigator.clipboard||!navigator.clipboard.writeText)){t.dataset.originalText===void 0&&(t.dataset.originalText=t.textContent);try{await navigator.clipboard.writeText(e),t.dataset.copied="true",t.textContent="Copied!",setTimeout(()=>{t.dataset.copied="false",t.textContent=t.dataset.originalText},2e3)}catch(n){t.dataset.copied="error",t.textContent="Error"}}}function h(){g||(g=!0,document.addEventListener("click",t=>{let e=t.target instanceof Element?t.target.closest(_):null;e&&O(e)}))}var y="datalog-color-mode",l="dark-mode";function b(){try{return localStorage.getItem(y)}catch(t){return null}}function $(t){try{localStorage.setItem(y,t)}catch(e){}}function q(t){let e=b();return e==="dark"?!0:e==="light"?!1:t.matches}function E(){let t=document.querySelector("[data-toggle-dark-mode]"),e=document.body,n=window.matchMedia("(prefers-color-scheme: dark)");q(n)&&e.classList.add(l);let r=()=>{let a=e.classList.contains(l)?"dark":"light";e.dataset.theme=a,document.documentElement.dataset.theme=a},o=()=>{r(),t&&t.setAttribute("aria-pressed",e.classList.contains(l))};o(),t&&t.addEventListener("click",()=>{let a=e.classList.toggle(l);t.setAttribute("aria-pressed",String(a)),$(a?"dark":"light"),r()}),n.addEventListener("change",a=>{b()||(a.matches?e.classList.add(l):e.classList.remove(l),o())})}var H="datalog-github-";var S=Symbol("recently-failed");function f(t,e){return`${H}${t}-${e}`}function K(t,e,n){try{let r=localStorage.getItem(f(t,e));if(!r)return null;let o=JSON.parse(r);if(!o||typeof o!="object")return null;let a=o.failed?6e5:n;return Date.now()-o.timestamp>a?(localStorage.removeItem(f(t,e)),null):o.failed?S:o.data}catch(r){return null}}function L(t,e,n){try{localStorage.setItem(f(t,e),JSON.stringify(p({timestamp:Date.now()},n)))}catch(r){}}async function M(t,e,n,r){let o=K(t,e,r);if(o===S)return null;if(o)return o;try{let a=await fetch(`${n}/${t}/${e}`);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let s=await a.json();return L(t,e,{data:s}),s}catch(a){return L(t,e,{failed:!0}),null}}function B(t,e){t.querySelectorAll("[data-github-stat]").forEach(r=>{let o=r.getAttribute("data-github-stat");if(!o)return;let a=e[o];typeof a=="number"?r.textContent=a.toLocaleString():typeof a=="string"&&a.length>0&&(r.textContent=a)})}function F(t){t.dataset.githubState="error";let e=t.getAttribute("data-github-unavailable");e&&t.querySelectorAll("[data-github-stat]").forEach(n=>{n.textContent=e})}function v(){let t=document.querySelectorAll("[data-github-owner][data-github-repo]");if(!t.length)return Promise.resolve();let n=(window.DatalogIntegrations||{}).github||{};if(n.enabled===!1)return Promise.resolve();let r=n.api_base||"https://api.github.com/repos",o=Number(n.cache_ttl||43200)*1e3,a=Array.from(t).map(s=>{let u=s.getAttribute("data-github-owner"),d=s.getAttribute("data-github-repo");return!u||!d?Promise.resolve():(s.dataset.githubState="loading",M(u,d,r,o).then(i=>{if(!i){F(s);return}B(s,i),s.dataset.githubState="ready"}))});return Promise.all(a)}var z="[data-language-filter], [data-navigate-on-change]";function U(t){if(typeof t!="string")return null;let e=Array.from(t).filter(r=>{let o=r.codePointAt(0);return o>31&&o!==127}).join("").trim();if(!e)return null;let n=/^[a-z][a-z0-9+.-]*:/i.exec(e);return n&&!/^https?:$/i.test(n[0])?null:e}function A(){let t=document.querySelectorAll(z);t.length!==0&&t.forEach(e=>{e.addEventListener("change",n=>{let r=U(n.target&&n.target.value);r&&(window.location.href=r)})})}var V="(min-width: 48rem)",T="#site-nav",k=".nav-toggle",m="nav-open";function w(t){return t.replace(/index\.html$/,"").replace(/\/$/,"")}function j(t){let e=t.getAttribute("href");if(!e)return null;try{let n=new URL(e,window.location.origin);if(!n.hash)return null;let r=new URL(window.location.href);return w(n.pathname)!==w(r.pathname)?null:n.hash.replace("#","")}catch(n){return null}}function Y(t){if(!t)return!1;let e=document.getElementById(t);return e?(e.scrollIntoView({block:"start"}),!0):!1}function x(){let t=document.querySelector(T);if(!t)return;let e=document.querySelector(k),n=document.body,r=window.matchMedia(V),o=i=>{if(i){t.dataset.open="true",n.classList.remove(m),e&&(e.setAttribute("aria-expanded","false"),e.classList.remove("is-active"));return}let c=t.dataset.open==="true";c||(t.dataset.open="false"),e&&(e.setAttribute("aria-expanded",String(c)),e.classList.toggle("is-active",c))},a=({focusToggle:i=!1}={})=>{r.matches||(t.dataset.open="false",n.classList.remove(m),e&&(e.setAttribute("aria-expanded","false"),e.classList.remove("is-active"),i&&e.focus()))},s=()=>{r.matches||(t.dataset.open="true",n.classList.add(m),e&&(e.setAttribute("aria-expanded","true"),e.classList.add("is-active")))},u=()=>{r.matches||(t.dataset.open==="true"?a():s())};r.matches||(t.dataset.open="false"),o(r.matches),r.addEventListener("change",i=>{i.matches?o(!0):(a(),t.dataset.open="false",o(!1))}),t.querySelectorAll(".nav-link").forEach(i=>{let c=j(i);i.addEventListener("click",R=>{r.matches||a(),c&&Y(c)&&R.preventDefault()})}),e&&e.addEventListener("click",()=>{u()}),document.addEventListener("keydown",i=>{i.key==="Escape"&&t.dataset.open==="true"&&a({focusToggle:!0})}),document.addEventListener("click",i=>{if(r.matches||t.dataset.open!=="true")return;let c=i.target;!c||typeof c.closest!="function"||c.closest(T)||e&&c.closest(k)||a()})}function J(t,e){let n=window.pageYOffset||document.documentElement.scrollTop,r=document.documentElement.scrollHeight-window.innerHeight,o=r>0?Math.min(n/r*100,100):0;t.tagName==="PROGRESS"?t.setAttribute("value",String(o)):t.style.setProperty("--progress",`${o}%`),e&&(e.textContent=Math.round(o))}function C(){let t=document.querySelector("[data-scroll-progress]");if(!t)return;let e=document.querySelector("[data-scroll-progress-value]"),n=()=>J(t,e);n(),window.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",n)}function I(t){if(!t)return;let e=t.querySelector("input[type='search']"),n=t.getAttribute("action");e?(e.focus(),e.select()):n&&(window.location.href=n)}function X(t){if(!t)return!1;if(t.isContentEditable)return!0;let e=t.tagName;return e==="INPUT"||e==="TEXTAREA"||e==="SELECT"}function N(){let t=document.querySelector(".site-search");t&&document.addEventListener("keydown",e=>{X(document.activeElement)||(e.key==="/"&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&(e.preventDefault(),I(t)),(e.key==="k"||e.key==="K")&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),I(t)))})}function Q(t){if(!t)return;t.getAttribute("tabindex")===null&&(t.setAttribute("tabindex","-1"),t.dataset.skipLinkTempTabindex="true"),t.addEventListener("blur",()=>{t.dataset.skipLinkTempTabindex&&(t.removeAttribute("tabindex"),delete t.dataset.skipLinkTempTabindex)},{once:!0}),t.focus()}function P(){let t=document.querySelectorAll(".skip-link[href^='#']");t.length&&t.forEach(e=>{e.addEventListener("click",n=>{let o=(e.getAttribute("href")||"").slice(1);if(!o)return;let a=document.getElementById(o);a&&(n.preventDefault(),Q(a))})})}var Z=[P,x,E,A,C,N,v,h];function D(t=Z){t.forEach(e=>{try{e()}catch(n){}})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>D()):D();export{D as initializeCore};
@@ -0,0 +1 @@
1
+ import{a,b as x,c as b}from"./chunks/chunk-V7734B2G.js";import{c as v}from"./chunks/chunk-2DYDWUFX.js";import"./chunks/chunk-PATLC23F.js";var C="corrections",E=20,_=500;function D(t){let e=t.querySelector("[data-correction-labels]");if(!e)return{};try{return JSON.parse(e.textContent)||{}}catch(n){return{}}}function U(){let t=globalThis.crypto;return t&&typeof t.randomUUID=="function"?t.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function F(t,e){!t||!e||e.querySelectorAll("h2[id], h3[id]").forEach(n=>{let o=t.ownerDocument.createElement("option");o.value=n.id,o.textContent=n.textContent.trim(),t.appendChild(o)})}function I(t,e){let n=t.getSelection&&t.getSelection();if(!n||n.isCollapsed||n.rangeCount===0||!e)return"";let o=n.getRangeAt(0);return e.contains(o.commonAncestorContainer)?n.toString().trim().slice(0,_):""}function L(t,e){let n={category:t.category||"other",message:t.message||"",article:{url:e.url,title:e.title}};return t.section&&(n.section=t.section),t.contact_email&&(n.contact_email=t.contact_email),t.quote&&(n.quote=t.quote),n}function R(t,e,n={}){let o={};return t.message.length<E&&(o.message=(n.message_short||"Say a little more: at least {{min}} characters.").split("{{min}}").join(String(E))),t.contact_email&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.contact_email)&&(o.contact_email=n.email_invalid||"That does not look like an email address."),e.website&&(o.website="spam"),Object.keys(o).length>0?o:null}function T(t,e={}){let n=t.ownerDocument,o=e.window||n.defaultView,l=e.client||v(),S=e.content===void 0?n.querySelector(".post-content"):e.content,r=t.querySelector("form"),c=D(t),u=c.errors||{},A={url:t.dataset.articleUrl||"",title:t.dataset.articleTitle||""},p=r.elements.namedItem("quote"),s=t.querySelector("[data-correction-quote]"),d=null;if(F(r.elements.namedItem("section"),S),!l.enabled)return a(r,"disabled",u.disabled||""),{form:r,available:!1,submit:async()=>null};let w=()=>(d||(d=l.feature(C).catch(i=>{throw d=null,b(r,i,u),r.dataset.state="disabled",r.querySelectorAll("button[type=submit]").forEach(m=>{m.disabled=!0}),i})),d),y=t.tagName==="DETAILS"?t:t.querySelector("details");y&&y.addEventListener("toggle",()=>{if(!y.open)return;let i=I(o,S);p&&i&&!p.value&&(p.value=i,s&&(s.textContent=i,s.hidden=!1)),w().catch(()=>{})});let q={form:r,available:!0,async submit(){let i=x(r),m=L(i,A),g=R(m,i,c);if(g)return g.website?(a(r,"success",c.success||""),null):(a(r,"invalid",u.invalid||"",g),null);a(r,"pending",c.pending||"");try{await w()}catch(f){return null}try{let f=await l.post(l.pathFor(C),m,{idempotencyKey:U()});return r.reset(),s&&(s.hidden=!0),a(r,"success",c.success||""),f}catch(f){return b(r,f,u),null}}};return r.addEventListener("submit",i=>{i.preventDefault(),q.submit()}),q}function h(t=document){return Array.from(t.querySelectorAll("[data-correction-report]")).map(e=>T(e))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>h()):h();export{h as initCorrectionReports};
@@ -1 +1 @@
1
- function y(){let e=document.getElementById("datalog-js-manifest");if(!e||!e.textContent)return{};try{return JSON.parse(e.textContent)}catch(n){return{}}}function l(e){return`feature${e.replace(/(^|-)([a-z])/g,(n,o,s)=>s.toUpperCase())}`}function r(e,n){let o=document.body;if(!o)return;let s=`${l(e)}State`;o.dataset[s]=n}async function d(e){return import(e)}var p=[{name:"search",test:()=>document.querySelector("[data-search-app]")||document.querySelector(".site-search")},{name:"visualizations",test:()=>document.querySelector("[data-viz-type]")},{name:"math",test:()=>{var e;return((e=document.body)==null?void 0:e.dataset.featureMath)==="true"}},{name:"academic",test:()=>document.querySelector("[data-citation-metric], [data-citation-table], [data-citation-chart]")},{name:"notebook",test:()=>{var e;return((e=document.body)==null?void 0:e.dataset.featureNotebook)==="true"||document.querySelector(".notebook-output")}}];async function i(e){let n=e||y(),{core:o,features:s={}}=n;if(!o)return;try{r("core","loading"),await d(o),r("core","ready")}catch(t){r("core","error");return}let u=document.body;if(!u)return;let m=p.filter(t=>{let c=l(t.name),a=u.dataset[c];return a==="true"||a==="auto"?a==="auto"&&typeof t.test=="function"?!!t.test():!0:!1}).map(async({name:t,test:c})=>{let a=s[t];if(a){r(t,"loading");try{if(typeof c=="function"&&!c()){r(t,"skipped");return}await d(a),r(t,"ready")}catch(f){r(t,"error")}}});await Promise.all(m)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>i()):i();export{i as bootstrapFeatures};
1
+ import"./chunks/chunk-PATLC23F.js";function f(){let e=document.getElementById("datalog-js-manifest");if(!e||!e.textContent)return{};try{return JSON.parse(e.textContent)}catch(n){return{}}}function m(e){return`feature${e.replace(/(^|-)([a-z])/g,(n,r,c)=>c.toUpperCase())}`}function o(e,n){let r=document.body;if(!r)return;let c=`${m(e)}State`;r.dataset[c]=n}async function u(e){return import(e)}var b=[{name:"search",test:()=>document.querySelector("[data-search-app]")},{name:"visualizations",test:()=>document.querySelector("[data-viz-type]")},{name:"math",test:()=>{var e;return((e=document.body)==null?void 0:e.dataset.featureMath)==="true"}},{name:"academic",test:()=>document.querySelector("[data-citation-metric], [data-citation-table], [data-citation-chart]")},{name:"notebook",test:()=>{var e;return((e=document.body)==null?void 0:e.dataset.featureNotebook)==="true"||document.querySelector(".notebook-output")}},{name:"reading-state",test:()=>document.querySelector("[data-reading-state], [data-reading-list]")},{name:"corrections",test:()=>document.querySelector("[data-correction-report]")},{name:"contact",test:()=>document.querySelector("[data-contact-form]")},{name:"comments",test:()=>document.querySelector("[data-comments-thread]")},{name:"reactions",test:()=>document.querySelector("[data-reactions]")},{name:"webmentions",test:()=>document.querySelector("[data-webmentions]")},{name:"subscriptions",test:()=>document.querySelector("[data-subscribe], [data-subscription-manage]")},{name:"moderation",test:()=>document.querySelector("[data-moderation-inbox]")}];async function i(e){let n=e||f(),{core:r,features:c={}}=n;if(!r)return;try{o("core","loading"),await u(r),o("core","ready")}catch(t){o("core","error");return}let d=document.body;if(!d)return;let l=b.filter(t=>{let s=m(t.name),a=d.dataset[s];return a==="true"||a==="auto"?a==="auto"&&typeof t.test=="function"?!!t.test():!0:!1}).map(async({name:t,test:s})=>{let a=c[t];if(a){o(t,"loading");try{if(typeof s=="function"&&!s()){o(t,"skipped");return}await u(a),o(t,"ready")}catch(y){o(t,"error")}}});await Promise.all(l)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>i()):i();export{i as bootstrapFeatures};