hexo-theme-gnix 7.0.0 → 9.0.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 (53) hide show
  1. package/README.md +6 -2
  2. package/include/hexo/encrypt.js +42 -0
  3. package/include/hexo/feed.js +330 -0
  4. package/include/util/common.js +7 -16
  5. package/languages/en.yml +5 -2
  6. package/languages/zh-CN.yml +5 -2
  7. package/layout/archive.jsx +8 -204
  8. package/layout/comment/twikoo.jsx +2 -11
  9. package/layout/common/article.jsx +45 -32
  10. package/layout/common/article_cover.jsx +11 -1
  11. package/layout/common/article_media.jsx +2 -4
  12. package/layout/common/footer.jsx +10 -14
  13. package/layout/common/head.jsx +7 -15
  14. package/layout/common/navbar.jsx +3 -18
  15. package/layout/common/scripts.jsx +6 -5
  16. package/layout/common/theme_selector.jsx +5 -6
  17. package/layout/common/toc.jsx +8 -14
  18. package/layout/index.jsx +2 -4
  19. package/layout/misc/open_graph.jsx +4 -4
  20. package/layout/misc/paginator.jsx +10 -4
  21. package/layout/misc/structured_data.jsx +3 -4
  22. package/layout/plugin/busuanzi.jsx +1 -1
  23. package/layout/plugin/cookie_consent.jsx +40 -31
  24. package/layout/plugin/swup.jsx +2 -22
  25. package/layout/search/insight.jsx +16 -3
  26. package/package.json +12 -8
  27. package/scripts/hot-reload.js +92 -0
  28. package/scripts/index.js +2 -0
  29. package/source/css/archive.css +251 -0
  30. package/source/css/default.css +300 -309
  31. package/source/css/encrypt.css +55 -0
  32. package/source/css/responsive/desktop.css +0 -119
  33. package/source/css/responsive/mobile.css +2 -22
  34. package/source/css/responsive/touch.css +9 -103
  35. package/source/css/twikoo.css +265 -249
  36. package/source/img/og_image.webp +0 -0
  37. package/source/js/archive-breadcrumb.js +1 -5
  38. package/source/js/busuanzi.js +1 -12
  39. package/source/js/components/chat.js +239 -0
  40. package/source/js/components/image-carousel.js +410 -0
  41. package/source/js/components/text-image-section.js +180 -0
  42. package/source/js/components/theme-stacked.js +165 -246
  43. package/source/js/components/tree.js +437 -0
  44. package/source/js/decrypt.js +112 -0
  45. package/source/js/insight.js +75 -65
  46. package/source/js/main.js +48 -31
  47. package/source/js/mdit/mermaid.js +12 -4
  48. package/source/js/swup.bundle.js +1 -0
  49. package/source/js/theme-selector.js +94 -113
  50. package/source/img/og_image.png +0 -0
  51. package/source/js/host/swup/Swup.umd.min.js +0 -1
  52. package/source/js/host/swup/head-plugin.umd.min.js +0 -1
  53. package/source/js/host/swup/scripts-plugin.umd.min.js +0 -2
@@ -1,6 +1,6 @@
1
1
  // biome-ignore lint/correctness/noUnusedVariables: Called in other files
2
2
  function loadInsight(config, translation) {
3
- const main = document.querySelector(".searchbox");
3
+ const main = document.querySelector("#searchbox");
4
4
  if (!main) return;
5
5
 
6
6
  const input = main.querySelector(".searchbox-input");
@@ -10,6 +10,7 @@ function loadInsight(config, translation) {
10
10
  let dataset = null; // 缓存 JSON 数据
11
11
  let isLoading = false; // 加载锁
12
12
  let searchTimer = null; // 防抖定时器
13
+ const keywordRegexCache = new Map();
13
14
 
14
15
  // 辅助:创建 DOM
15
16
  function createElement(tag, className, text) {
@@ -29,17 +30,15 @@ function loadInsight(config, translation) {
29
30
  // --- 核心逻辑优化区 ---
30
31
 
31
32
  // HTML 转义函数,防止 XSS 攻击和标签渲染异常
33
+ const _escapeMap = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#039;" };
34
+ const _escapeRe = /[&<>"']/g;
32
35
  function escapeHTML(str) {
33
- const map = {
34
- "&": "&amp;",
35
- "<": "&lt;",
36
- ">": "&gt;",
37
- '"': "&quot;",
38
- "'": "&#039;",
39
- };
40
- return str.replace(/[&<>"']/g, (m) => map[m]);
36
+ return str.replace(_escapeRe, (m) => _escapeMap[m]);
41
37
  }
42
38
 
39
+ // 字段名 → 预计算小写字段名的映射
40
+ const _lowerFields = { title: "_lowerTitle", text: "_lowerText", name: "_lowerName", slug: "_lowerSlug" };
41
+
43
42
  // 优化点:合并 ranges 的逻辑保持不变,这是高亮的核心算法
44
43
  function merge(ranges) {
45
44
  let last;
@@ -74,7 +73,7 @@ function loadInsight(config, translation) {
74
73
 
75
74
  if (!indices.length) return maxlen ? escapeHTML(text.slice(0, maxlen)) : escapeHTML(text);
76
75
 
77
- let result = "";
76
+ const parts = [];
78
77
  let last = 0;
79
78
  const ranges = merge(indices);
80
79
  const sumRange = [ranges[0][0], ranges[ranges.length - 1][1]];
@@ -85,21 +84,21 @@ function loadInsight(config, translation) {
85
84
 
86
85
  for (let i = 0; i < ranges.length; i++) {
87
86
  const range = ranges[i];
88
- result += escapeHTML(text.slice(last, Math.min(range[0], sumRange[0] + maxlen)));
87
+ parts.push(escapeHTML(text.slice(last, Math.min(range[0], sumRange[0] + maxlen))));
89
88
  if (maxlen && range[0] >= sumRange[0] + maxlen) break;
90
89
 
91
- result += `<span style="color: var(--mauve)">${escapeHTML(text.slice(range[0], range[1]))}</span>`;
90
+ parts.push(`<span style="color: var(--mauve)">${escapeHTML(text.slice(range[0], range[1]))}</span>`);
92
91
  last = range[1];
93
92
 
94
93
  if (i === ranges.length - 1) {
95
94
  if (maxlen) {
96
- result += escapeHTML(text.slice(range[1], Math.min(text.length, sumRange[0] + maxlen + 1)));
95
+ parts.push(escapeHTML(text.slice(range[1], Math.min(text.length, sumRange[0] + maxlen + 1))));
97
96
  } else {
98
- result += escapeHTML(text.slice(range[1]));
97
+ parts.push(escapeHTML(text.slice(range[1])));
99
98
  }
100
99
  }
101
100
  }
102
- return result;
101
+ return parts.join("");
103
102
  }
104
103
 
105
104
  function searchItem(title, preview, url) {
@@ -156,9 +155,14 @@ function loadInsight(config, translation) {
156
155
  const keywords = parseKeywords(keywordsStr);
157
156
  if (keywords.length === 0) return {};
158
157
 
159
- // keywords中的特殊字符转义, 将转移后的关键词编译为正则表达式(忽略大小写,全局,多行)
160
- // 后续在文章内容匹配时使用
161
- const keywordRegexes = keywords.map((k) => new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "img"));
158
+ const keywordRegexes = keywords.map((k) => {
159
+ let regex = keywordRegexCache.get(k);
160
+ if (!regex) {
161
+ regex = new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "img");
162
+ keywordRegexCache.set(k, regex);
163
+ }
164
+ return regex;
165
+ });
162
166
 
163
167
  const calculateWeight = (obj, fields, weights) => {
164
168
  let value = 0;
@@ -174,7 +178,8 @@ function loadInsight(config, translation) {
174
178
  if (!obj[field]) continue;
175
179
 
176
180
  // 1. 快速检查:如果都不包含这个词,直接跳过正则
177
- if (obj[field].toLowerCase().indexOf(keyword) === -1) continue;
181
+ const lowerVal = obj[_lowerFields[field]] ?? obj[field].toLowerCase();
182
+ if (lowerVal.indexOf(keyword) === -1) continue;
178
183
 
179
184
  // 2. 权重计算
180
185
  const matches = obj[field].match(regex);
@@ -221,6 +226,18 @@ function loadInsight(config, translation) {
221
226
  }
222
227
  }
223
228
  container.appendChild(fragment);
229
+
230
+ // 为动态生成的结果项补充 ARIA 属性
231
+ const items = container.querySelectorAll(".searchbox-result-item");
232
+ items.forEach((item, i) => {
233
+ item.id = `searchbox-result-${i}`;
234
+ item.role = "option";
235
+ item.setAttribute("aria-selected", "false");
236
+ item.tabIndex = -1;
237
+ });
238
+
239
+ input.removeAttribute("aria-activedescendant");
240
+ input.setAttribute("aria-expanded", items.length > 0 ? "true" : "false");
224
241
  }
225
242
 
226
243
  function scrollTo(item) {
@@ -252,10 +269,15 @@ function loadInsight(config, translation) {
252
269
  const nextPosition = (items.length + prevPosition + value) % items.length;
253
270
  const finalPosition = nextPosition < 0 ? nextPosition + items.length : nextPosition;
254
271
 
255
- if (prevPosition !== -1) items[prevPosition].classList.remove("active");
272
+ if (prevPosition !== -1) {
273
+ items[prevPosition].classList.remove("active");
274
+ items[prevPosition].setAttribute("aria-selected", "false");
275
+ }
256
276
 
257
277
  const nextItem = items[finalPosition];
258
278
  nextItem.classList.add("active");
279
+ nextItem.setAttribute("aria-selected", "true");
280
+ input.setAttribute("aria-activedescendant", nextItem.id);
259
281
  scrollTo(nextItem);
260
282
  }
261
283
 
@@ -269,6 +291,14 @@ function loadInsight(config, translation) {
269
291
  fetch(config.contentUrl)
270
292
  .then((response) => response.json())
271
293
  .then((json) => {
294
+ for (const post of json.posts) {
295
+ post._lowerTitle = post.title ? post.title.toLowerCase() : "";
296
+ post._lowerText = post.text ? post.text.toLowerCase() : "";
297
+ }
298
+ for (const tag of json.tags) {
299
+ tag._lowerName = tag.name ? tag.name.toLowerCase() : "";
300
+ tag._lowerSlug = tag.slug ? tag.slug.toLowerCase() : "";
301
+ }
272
302
  dataset = json;
273
303
  isLoading = false;
274
304
  // 如果加载完之后输入框里有字,立即触发一次搜索
@@ -294,64 +324,44 @@ function loadInsight(config, translation) {
294
324
  return;
295
325
  }
296
326
 
297
- // 优化点:防抖 (Debounce) 300ms
298
327
  searchTimer = setTimeout(() => {
299
328
  searchResultToDOM(keywords, search(dataset, keywords));
300
- }, 200);
329
+ }, 150);
301
330
  });
302
331
 
303
- main.addEventListener("focusout", (e) => {
304
- if (main.contains(e.relatedTarget)) {
305
- return;
332
+ // 键盘导航
333
+ input.addEventListener("keydown", (e) => {
334
+ if (e.key === "ArrowDown") {
335
+ e.preventDefault();
336
+ selectItemByDiff(1);
337
+ } else if (e.key === "ArrowUp") {
338
+ e.preventDefault();
339
+ selectItemByDiff(-1);
340
+ } else if (e.key === "Enter") {
341
+ const active = container.querySelector(".searchbox-result-item.active");
342
+ if (active) {
343
+ active.click();
344
+ }
306
345
  }
307
- main.classList.remove("show");
308
346
  });
309
347
 
310
348
  main.addEventListener("click", (e) => {
311
- const resultItem = e.target.closest(".searchbox-result-item");
312
- if (resultItem) {
313
- main.classList.remove("show");
349
+ if (e.target === main || e.target.closest(".searchbox-result-item")) {
350
+ main.hidePopover();
314
351
  }
315
352
  });
316
353
 
317
- document.addEventListener("click", (e) => {
318
- if (e.target.closest(".navbar-main .search")) {
319
- main.classList.add("show");
320
- const inp = main.querySelector(".searchbox-input");
321
- inp.focus();
354
+ if (location.hash.trim() === "#insight-search") {
355
+ main.showPopover();
356
+ }
322
357
 
323
- // Lazy Load - 打开时再请求数据
358
+ // Popover 打开时 focus input 并预加载数据
359
+ main.addEventListener("toggle", (e) => {
360
+ if (e.newState === "open") {
324
361
  fetchData();
362
+ input.focus();
363
+ } else {
364
+ input.setAttribute("aria-expanded", "false");
325
365
  }
326
366
  });
327
-
328
- document.addEventListener("keydown", (e) => {
329
- if (!main.classList.contains("show")) return;
330
- switch (e.key) {
331
- case "ArrowUp":
332
- selectItemByDiff(-1);
333
- break;
334
- case "ArrowDown":
335
- selectItemByDiff(1);
336
- break;
337
- case "Enter": {
338
- const activeItem = container.querySelector(".searchbox-result-item.active");
339
- if (activeItem) location.href = activeItem.getAttribute("href");
340
- break;
341
- }
342
- }
343
- });
344
-
345
- document.addEventListener("touchstart", () => {
346
- touch = true;
347
- });
348
- document.addEventListener("touchmove", () => {
349
- touch = false;
350
- });
351
-
352
- // 处理 location.hash 自动打开的情况
353
- if (location.hash.trim() === "#insight-search") {
354
- main.classList.add("show");
355
- fetchData();
356
- }
357
367
  }
package/source/js/main.js CHANGED
@@ -15,27 +15,21 @@ function tableWrapFix() {
15
15
  }
16
16
 
17
17
  function twikoo_handler() {
18
- const twikooContainer = document.getElementById("tko");
19
- if (!twikooContainer) return;
20
- const initTwikoo = () => {
21
- if (window.twikoo?.init && window.twikooConfig) {
22
- window.twikoo.init(window.twikooConfig);
23
- }
24
- };
18
+ const el = document.getElementById("tko");
19
+ if (!el) return;
25
20
 
26
- // 简化判断逻辑:直接检查twikoo库是否加载完成
27
- if (window.twikoo && typeof twikoo.init === "function") {
28
- initTwikoo();
29
- } else {
30
- // 监听Twikoo脚本加载(保留SPA兼容逻辑)
31
- const script = document.querySelector('script[src*="twikoo.all.min.js"]');
32
- if (script) {
33
- script.addEventListener("load", initTwikoo);
34
- if (script.readyState === "complete" || script.readyState === "loaded") {
35
- setTimeout(initTwikoo, 0);
36
- }
37
- }
21
+ const { envId, region, lang, jsUrl, cssUrl } = el.dataset;
22
+
23
+ if (cssUrl) loadCSSOnce(cssUrl);
24
+
25
+ const config = { envId, region, lang, el: "#tko" };
26
+
27
+ if (typeof window.twikoo?.init === "function") {
28
+ window.twikoo.init(config);
29
+ return;
38
30
  }
31
+
32
+ loadScriptOnce(jsUrl, () => window.twikoo.init(config));
39
33
  }
40
34
  // #region mdit@tab-plugin
41
35
  /**
@@ -220,19 +214,32 @@ function handleKeyDown(e) {
220
214
  if (["INPUT", "TEXTAREA"].includes(tag) || e.target.isContentEditable) return;
221
215
 
222
216
  switch (e.code) {
217
+ case "KeyT":
218
+ e.preventDefault();
219
+ document.getElementById("toc-body")?.togglePopover();
220
+ break;
223
221
  case "KeyK":
224
222
  e.preventDefault();
225
- document.querySelector(".navbar-main .search")?.click();
223
+ document.querySelector("#searchbox")?.showPopover();
226
224
  break;
227
225
  case "KeyP":
228
226
  if (!e.shiftKey) {
229
227
  e.preventDefault();
230
- window.openThemeModal?.();
228
+ document.querySelector("#theme-selector-popover")?.showPopover();
231
229
  }
232
230
  break;
233
231
  }
234
232
  }
235
233
 
234
+ function loadCSSOnce(url) {
235
+ if (!document.querySelector(`link[href="${url}"]`)) {
236
+ const link = document.createElement("link");
237
+ link.rel = "stylesheet";
238
+ link.href = url;
239
+ document.head.appendChild(link);
240
+ }
241
+ }
242
+
236
243
  /**
237
244
  * 加载脚本一次,如果已存在则监听 load 事件
238
245
  */
@@ -255,12 +262,7 @@ function handleMermaid() {
255
262
  const cssUrl = "/css/optional/mermaid.css";
256
263
  const adapterUrl = "/js/mdit/mermaid.js";
257
264
 
258
- if (!document.querySelector(`link[href="${cssUrl}"]`)) {
259
- const link = document.createElement("link");
260
- link.rel = "stylesheet";
261
- link.href = cssUrl;
262
- document.head.appendChild(link);
263
- }
265
+ loadCSSOnce(cssUrl);
264
266
 
265
267
  const runInit = () => {
266
268
  const isNight = document.documentElement.classList.contains("night");
@@ -287,14 +289,14 @@ function handleMermaid() {
287
289
  // #endregion
288
290
 
289
291
  function initPage() {
290
- console.log("Page initialized");
291
292
  tableWrapFix();
292
293
  initializeTabs();
293
294
  handleMermaid();
294
295
  addHighlightTool();
295
- mediumZoom(".article img", {
296
- background: "hsla(from var(--mantle) / 0.9)",
297
- });
296
+ const zoomOpts = { background: "hsla(from var(--mantle) / 0.9)" };
297
+ const zoomImgs = new Set();
298
+ document.querySelectorAll(".content img").forEach((img) => zoomImgs.add(img));
299
+ mediumZoom([...zoomImgs], zoomOpts);
298
300
  twikoo_handler();
299
301
  }
300
302
 
@@ -309,3 +311,18 @@ document.addEventListener("keydown", handleKeyDown, {
309
311
  capture: true, // 捕获阶段监听,优先于浏览器默认处理
310
312
  passive: false, // 允许调用 preventDefault
311
313
  });
314
+
315
+ function toggleNav(event) {
316
+ const container = event.currentTarget;
317
+ const burger = container.querySelector(".navbar-burger");
318
+ const menu = container.querySelector(".navbar-menu");
319
+ const target = event.target;
320
+
321
+ if (target.closest(".navbar-burger")) {
322
+ burger.classList.toggle("is-active");
323
+ menu.classList.toggle("is-active");
324
+ } else if (target.closest(".navbar-item")) {
325
+ burger.classList.remove("is-active");
326
+ menu.classList.remove("is-active");
327
+ }
328
+ }
@@ -1,6 +1,8 @@
1
1
  (() => {
2
2
  const instances = new Map();
3
3
  let mermaidPromise = null;
4
+ let renderSeq = 0;
5
+
4
6
  const loadMermaid = (jsUrl) => {
5
7
  if (mermaidPromise) return mermaidPromise;
6
8
  if (window.mermaid) {
@@ -21,11 +23,15 @@
21
23
  const mermaid = await mermaidPromise;
22
24
  if (!content || !mermaid) return;
23
25
 
24
- // Initialize with current theme
26
+ const instance = instances.get(id);
27
+ if (!instance) return;
28
+ const version = (instance.renderVersion = ++renderSeq);
29
+
30
+ const isNight = document.documentElement.classList.contains("night");
25
31
  mermaid.initialize({
26
32
  startOnLoad: false,
27
- theme: document.documentElement.classList.contains("night") ? "dark" : "default",
28
- darkMode: document.documentElement.classList.contains("night"),
33
+ theme: isNight ? "dark" : "default",
34
+ darkMode: isNight,
29
35
  themeVariables,
30
36
  securityLevel: "strict",
31
37
  fontSize: 16,
@@ -33,9 +39,11 @@
33
39
 
34
40
  try {
35
41
  content.innerHTML = "";
36
- const { svg } = await mermaid.render(`${id}-svg`, code);
42
+ const { svg } = await mermaid.render(`${id}-svg-${version}`, code);
43
+ if (instance.renderVersion !== version) return;
37
44
  content.insertAdjacentHTML("beforeend", svg);
38
45
  } catch (error) {
46
+ if (instance.renderVersion !== version) return;
39
47
  console.error("Mermaid rendering error:", error);
40
48
  content.innerHTML = `<p style="color: red;">Failed to render diagram: ${error.message}</p>`;
41
49
  }
@@ -0,0 +1 @@
1
+ var y=new WeakMap;function k(f,S,z,G){if(!f&&!y.has(S))return!1;let J=y.get(S)??new WeakMap;y.set(S,J);let K=J.get(z)??new Set;J.set(z,K);let Y=K.has(G);if(f)K.add(G);else K.delete(G);return Y&&f}function Gf(f,S){let z=f.target;if(z instanceof Text)z=z.parentElement;if(z instanceof Element&&f.currentTarget instanceof Node){let G=z.closest(S);if(G&&f.currentTarget.contains(G))return G}}function Jf(f,S,z,G={}){let{signal:J,base:K=document}=G;if(J?.aborted)return;let{once:Y,...Z}=G,X=K instanceof Document?K.documentElement:K,Q=Boolean(typeof G==="object"?G.capture:G),q=(D)=>{let W=Gf(D,String(f));if(W){let V=Object.assign(D,{delegateTarget:W});if(z.call(X,V),Y)X.removeEventListener(S,q,Z),k(!1,X,z,B)}},B=JSON.stringify({selector:f,type:S,capture:Q});if(!k(!0,X,z,B))X.addEventListener(S,q,Z);J?.addEventListener("abort",()=>{k(!1,X,z,B)})}var w=Jf;function $(){return $=Object.assign?Object.assign.bind():function(f){for(var S=1;S<arguments.length;S++){var z=arguments[S];for(var G in z)({}).hasOwnProperty.call(z,G)&&(f[G]=z[G])}return f},$.apply(null,arguments)}var o=(f,S)=>String(f).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||S||"",T=({hash:f}={})=>window.location.pathname+window.location.search+(f?window.location.hash:""),Kf=(f,S={})=>{let z=$({url:f=f||T({hash:!0}),random:Math.random(),source:"swup"},S);window.history.pushState(z,"",f)},O=(f=null,S={})=>{f=f||T({hash:!0});let z=$({},window.history.state||{},{url:f,random:Math.random(),source:"swup"},S);window.history.replaceState(z,"",f)},Qf=(f,S,z,G)=>{let J=new AbortController;return G=$({},G,{signal:J.signal}),w(f,S,z,G),{destroy:()=>J.abort()}};class F extends URL{constructor(f,S=document.baseURI){super(f.toString(),S),Object.setPrototypeOf(this,F.prototype)}get url(){return this.pathname+this.search}static fromElement(f){let S=f.getAttribute("href")||f.getAttribute("xlink:href")||"";return new F(S)}static fromUrl(f){return new F(f)}}class _ extends Error{constructor(f,S){super(f),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=S.url,this.status=S.status,this.aborted=S.aborted||!1,this.timedOut=S.timedOut||!1}}async function Xf(f,S={}){var z;f=F.fromUrl(f).url;let{visit:G=this.visit}=S,J=$({},this.options.requestHeaders,S.headers),K=(z=S.timeout)!=null?z:this.options.timeout,Y=new AbortController,{signal:Z}=Y;S=$({},S,{headers:J,signal:Z});let X,Q=!1,q=null;K&&K>0&&(q=setTimeout(()=>{Q=!0,Y.abort("timeout")},K));try{X=await this.hooks.call("fetch:request",G,{url:f,options:S},(P,{url:C,options:N})=>fetch(C,N)),q&&clearTimeout(q)}catch(P){if(Q)throw this.hooks.call("fetch:timeout",G,{url:f}),new _(`Request timed out: ${f}`,{url:f,timedOut:Q});if((P==null?void 0:P.name)==="AbortError"||Z.aborted)throw new _(`Request aborted: ${f}`,{url:f,aborted:!0});throw P}let{status:B,url:I}=X,D=await X.text();if(B===500)throw this.hooks.call("fetch:error",G,{status:B,response:X,url:I}),new _(`Server error: ${I}`,{status:B,url:I});if(!D)throw new _(`Empty response: ${I}`,{status:B,url:I});let{url:W}=F.fromUrl(I),V={url:W,html:D};return!G.cache.write||S.method&&S.method!=="GET"||f!==W||this.cache.set(V.url,V),V}class l{constructor(f){this.swup=void 0,this.pages=new Map,this.swup=f}get size(){return this.pages.size}get all(){let f=new Map;return this.pages.forEach((S,z)=>{f.set(z,$({},S))}),f}has(f){return this.pages.has(this.resolve(f))}get(f){let S=this.pages.get(this.resolve(f));return S?$({},S):S}set(f,S){S=$({},S,{url:f=this.resolve(f)}),this.pages.set(f,S),this.swup.hooks.callSync("cache:set",void 0,{page:S})}update(f,S){f=this.resolve(f);let z=$({},this.get(f),S,{url:f});this.pages.set(f,z)}delete(f){this.pages.delete(this.resolve(f))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0,void 0)}prune(f){this.pages.forEach((S,z)=>{f(z,S)&&this.delete(z)})}resolve(f){let{url:S}=F.fromUrl(f);return this.swup.resolveUrl(S)}}var h=(f,S=document)=>S.querySelector(f),m=(f,S=document)=>Array.from(S.querySelectorAll(f)),r=()=>new Promise((f)=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{f()})})});function i(f){return!!f&&(typeof f=="object"||typeof f=="function")&&typeof f.then=="function"}function Yf(f,S=[]){return new Promise((z,G)=>{let J=f(...S);i(J)?J.then(z,G):z(J)})}function p(f,S){let z=f==null?void 0:f.closest(`[${S}]`);return z!=null&&z.hasAttribute(S)?(z==null?void 0:z.getAttribute(S))||!0:void 0}class n{constructor(f){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating","is-leaving"],this.swup=f}get selectors(){let{scope:f}=this.swup.visit.animation;return f==="containers"?this.swup.visit.containers:f==="html"?["html"]:Array.isArray(f)?f:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?m(this.selector):[]}add(...f){this.targets.forEach((S)=>S.classList.add(...f))}remove(...f){this.targets.forEach((S)=>S.classList.remove(...f))}clear(){this.targets.forEach((f)=>{let S=f.className.split(" ").filter((z)=>this.isSwupClass(z));f.classList.remove(...S)})}isSwupClass(f){return this.swupClasses.some((S)=>f.startsWith(S))}}class v{constructor(f,S){this.id=void 0,this.state=void 0,this.from=void 0,this.to=void 0,this.containers=void 0,this.animation=void 0,this.trigger=void 0,this.cache=void 0,this.history=void 0,this.scroll=void 0,this.meta=void 0;let{to:z,from:G,hash:J,el:K,event:Y}=S;this.id=Math.random(),this.state=1,this.from={url:G!=null?G:f.location.url,hash:f.location.hash},this.to={url:z,hash:J},this.containers=f.options.containers,this.animation={animate:!0,wait:!1,name:void 0,native:f.options.native,scope:f.options.animationScope,selector:f.options.animationSelector},this.trigger={el:K,event:Y},this.cache={read:f.options.cache,write:f.options.cache},this.history={action:"push",popstate:!1,direction:void 0},this.scroll={reset:!0,target:void 0},this.meta={}}advance(f){this.state<f&&(this.state=f)}abort(){this.state=8}get done(){return this.state>=7}}function Zf(f){return new v(this,f)}class s{constructor(f){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:abort","visit:end"],this.swup=f,this.init()}init(){this.hooks.forEach((f)=>this.create(f))}create(f){this.registry.has(f)||this.registry.set(f,new Map)}exists(f){return this.registry.has(f)}get(f){let S=this.registry.get(f);if(S)return S;console.error(`Unknown hook '${f}'`)}clear(){this.registry.forEach((f)=>f.clear())}on(f,S,z={}){let G=this.get(f);if(!G)return console.warn(`Hook '${f}' not found.`),()=>{};let J=$({},z,{id:G.size+1,hook:f,handler:S});return G.set(S,J),()=>this.off(f,S)}before(f,S,z={}){return this.on(f,S,$({},z,{before:!0}))}replace(f,S,z={}){return this.on(f,S,$({},z,{replace:!0}))}once(f,S,z={}){return this.on(f,S,$({},z,{once:!0}))}off(f,S){let z=this.get(f);z&&S?z.delete(S)||console.warn(`Handler for hook '${f}' not found.`):z&&z.clear()}async call(f,S,z,G){let[J,K,Y]=this.parseCallArgs(f,S,z,G),{before:Z,handler:X,after:Q}=this.getHandlers(f,Y);await this.run(Z,J,K);let[q]=await this.run(X,J,K,!0);return await this.run(Q,J,K),this.dispatchDomEvent(f,J,K),q}callSync(f,S,z,G){let[J,K,Y]=this.parseCallArgs(f,S,z,G),{before:Z,handler:X,after:Q}=this.getHandlers(f,Y);this.runSync(Z,J,K);let[q]=this.runSync(X,J,K,!0);return this.runSync(Q,J,K),this.dispatchDomEvent(f,J,K),q}parseCallArgs(f,S,z,G){return S instanceof v||typeof S!="object"&&typeof z!="function"?[S,z,G]:[void 0,S,z]}async run(f,S=this.swup.visit,z,G=!1){let J=[];for(let{hook:K,handler:Y,defaultHandler:Z,once:X}of f)if(S==null||!S.done){X&&this.off(K,Y);try{let Q=await Yf(Y,[S,z,Z]);J.push(Q)}catch(Q){if(G)throw Q;console.error(`Error in hook '${K}':`,Q)}}return J}runSync(f,S=this.swup.visit,z,G=!1){let J=[];for(let{hook:K,handler:Y,defaultHandler:Z,once:X}of f)if(S==null||!S.done){X&&this.off(K,Y);try{let Q=Y(S,z,Z);J.push(Q),i(Q)&&console.warn(`Swup will not await Promises in handler for synchronous hook '${K}'.`)}catch(Q){if(G)throw Q;console.error(`Error in hook '${K}':`,Q)}}return J}getHandlers(f,S){let z=this.get(f);if(!z)return{found:!1,before:[],handler:[],after:[],replaced:!1};let G=Array.from(z.values()),J=this.sortRegistrations,K=G.filter(({before:q,replace:B})=>q&&!B).sort(J),Y=G.filter(({replace:q})=>q).filter((q)=>!0).sort(J),Z=G.filter(({before:q,replace:B})=>!q&&!B).sort(J),X=Y.length>0,Q=[];if(S&&(Q=[{id:0,hook:f,handler:S}],X)){let q=Y.length-1,{handler:B,once:I}=Y[q],D=(W)=>{let V=Y[W-1];return V?(P,C)=>V.handler(P,C,D(W-1)):S};Q=[{id:0,hook:f,once:I,handler:B,defaultHandler:D(q)}]}return{found:!0,before:K,handler:Q,after:Z,replaced:X}}sortRegistrations(f,S){var z,G;return((z=f.priority)!=null?z:0)-((G=S.priority)!=null?G:0)||f.id-S.id||0}dispatchDomEvent(f,S,z){if(S!=null&&S.done)return;let G={hook:f,args:z,visit:S||this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:G,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${f}`,{detail:G,bubbles:!0}))}parseName(f){let[S,...z]=f.split(".");return[S,z.reduce((G,J)=>$({},G,{[J]:!0}),{})]}}var qf=(f)=>{if(f&&f.charAt(0)==="#"&&(f=f.substring(1)),!f)return null;let S=decodeURIComponent(f),z=document.getElementById(f)||document.getElementById(S)||h(`a[name='${CSS.escape(f)}']`)||h(`a[name='${CSS.escape(S)}']`);return z||f!=="top"||(z=document.body),z},M="transition",E="animation";async function Bf({selector:f,elements:S}){if(f===!1&&!S)return;let z=[];if(S)z=Array.from(S);else if(f&&(z=m(f,document.body),!z.length))return void console.warn(`[swup] No elements found matching animationSelector \`${f}\``);let G=z.map((J)=>function(K){let{type:Y,timeout:Z,propCount:X}=function(Q){let q=window.getComputedStyle(Q),B=U(q,`${M}Delay`),I=U(q,`${M}Duration`),D=c(B,I),W=U(q,`${E}Delay`),V=U(q,`${E}Duration`),P=c(W,V),C=Math.max(D,P),N=C>0?D>P?M:E:null;return{type:N,timeout:C,propCount:N?N===M?I.length:V.length:0}}(K);return!(!Y||!Z)&&new Promise((Q)=>{let q=`${Y}end`,B=performance.now(),I=0,D=()=>{K.removeEventListener(q,W),Q()},W=(V)=>{V.target===K&&((performance.now()-B)/1000<V.elapsedTime||++I>=X&&D())};setTimeout(()=>{I<X&&D()},Z+1),K.addEventListener(q,W)})}(J));G.filter(Boolean).length>0?await Promise.all(G):f&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${f}\``)}function U(f,S){return(f[S]||"").split(", ")}function c(f,S){for(;f.length<S.length;)f=f.concat(f);return Math.max(...S.map((z,G)=>a(z)+a(f[G])))}function a(f){return 1000*parseFloat(f)}function Df(f,S={},z={}){if(typeof f!="string")throw Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(f,{el:z.el,event:z.event}))return void window.location.assign(f);let{url:G,hash:J}=F.fromUrl(f),K=this.createVisit($({},z,{to:G,hash:J}));this.performNavigation(K,S)}async function If(f,S={}){if(this.navigating){if(this.visit.state>=6)return f.state=2,void(this.onVisitEnd=()=>this.performNavigation(f,S));await this.hooks.call("visit:abort",this.visit,void 0),delete this.visit.to.document,this.visit.state=8}this.navigating=!0,this.visit=f;let{el:z}=f.trigger;S.referrer=S.referrer||this.location.url,S.animate===!1&&(f.animation.animate=!1),f.animation.animate||this.classes.clear();let G=S.history||p(z,"data-swup-history");typeof G=="string"&&["push","replace"].includes(G)&&(f.history.action=G);let J=S.animation||p(z,"data-swup-animation");var K,Y;typeof J=="string"&&(f.animation.name=J),f.meta=S.meta||{},typeof S.cache=="object"?(f.cache.read=(K=S.cache.read)!=null?K:f.cache.read,f.cache.write=(Y=S.cache.write)!=null?Y:f.cache.write):S.cache!==void 0&&(f.cache={read:!!S.cache,write:!!S.cache}),delete S.cache;try{await this.hooks.call("visit:start",f,void 0),f.state=3;let Z=this.hooks.call("page:load",f,{options:S},async(Q,q)=>{let B;return Q.cache.read&&(B=this.cache.get(Q.to.url)),q.page=B||await this.fetchPage(Q.to.url,q.options),q.cache=!!B,q.page});Z.then(({html:Q})=>{f.advance(5),f.to.html=Q,f.to.document=new DOMParser().parseFromString(Q,"text/html")});let X=f.to.url+f.to.hash;if(f.history.popstate||(f.history.action==="replace"||f.to.url===this.location.url?O(X):(this.currentHistoryIndex++,Kf(X,{index:this.currentHistoryIndex}))),this.location=F.fromUrl(X),f.history.popstate&&this.classes.add("is-popstate"),f.animation.name&&this.classes.add(`to-${o(f.animation.name)}`),f.animation.wait&&await Z,f.done)return;if(await this.hooks.call("visit:transition",f,void 0,async()=>{if(!f.animation.animate)return await this.hooks.call("animation:skip",void 0),void await this.renderPage(f,await Z);f.advance(4),await this.animatePageOut(f),f.animation.native&&document.startViewTransition?await document.startViewTransition(async()=>await this.renderPage(f,await Z)).finished:await this.renderPage(f,await Z),await this.animatePageIn(f)}),f.done)return;await this.hooks.call("visit:end",f,void 0,()=>this.classes.clear()),f.state=7,this.navigating=!1,this.onVisitEnd&&(this.onVisitEnd(),this.onVisitEnd=void 0)}catch(Z){if(!Z||Z!=null&&Z.aborted)return void(f.state=8);f.state=9,console.error(Z),this.options.skipPopStateHandling=()=>(window.location.assign(f.to.url+f.to.hash),!0),window.history.back()}finally{delete f.to.document}}var Nf=async function(f){await this.hooks.call("animation:out:start",f,void 0,()=>{this.classes.add("is-changing","is-animating","is-leaving")}),await this.hooks.call("animation:out:await",f,{skip:!1},(S,{skip:z})=>{if(!z)return this.awaitAnimations({selector:S.animation.selector})}),await this.hooks.call("animation:out:end",f,void 0)},Pf=function(f){var S;let z=f.to.document;if(!z)return!1;let G=((S=z.querySelector("title"))==null?void 0:S.innerText)||"";document.title=G;let J=m('[data-swup-persist]:not([data-swup-persist=""])'),K=f.containers.map((Y)=>{let Z=document.querySelector(Y),X=z.querySelector(Y);return Z&&X?(Z.replaceWith(X.cloneNode(!0)),!0):(Z||console.warn(`[swup] Container missing in current document: ${Y}`),X||console.warn(`[swup] Container missing in incoming document: ${Y}`),!1)}).filter(Boolean);return J.forEach((Y)=>{let Z=Y.getAttribute("data-swup-persist"),X=h(`[data-swup-persist="${Z}"]`);X&&X!==Y&&X.replaceWith(Y)}),K.length===f.containers.length},Vf=function(f){let S={behavior:"auto"},{target:z,reset:G}=f.scroll,J=z!=null?z:f.to.hash,K=!1;return J&&(K=this.hooks.callSync("scroll:anchor",f,{hash:J,options:S},(Y,{hash:Z,options:X})=>{let Q=this.getAnchorElement(Z);return Q&&Q.scrollIntoView(X),!!Q})),G&&!K&&(K=this.hooks.callSync("scroll:top",f,{options:S},(Y,{options:Z})=>(window.scrollTo($({top:0,left:0},Z)),!0))),K},Wf=async function(f){if(f.done)return;let S=this.hooks.call("animation:in:await",f,{skip:!1},(z,{skip:G})=>{if(!G)return this.awaitAnimations({selector:z.animation.selector})});await r(),await this.hooks.call("animation:in:start",f,void 0,()=>{this.classes.remove("is-animating")}),await S,await this.hooks.call("animation:in:end",f,void 0)},$f=async function(f,S){if(f.done)return;f.advance(6);let{url:z}=S;this.isSameResolvedUrl(T(),z)||(O(z),this.location=F.fromUrl(z),f.to.url=this.location.url,f.to.hash=this.location.hash),await this.hooks.call("content:replace",f,{page:S},(G,{})=>{if(this.classes.remove("is-leaving"),G.animation.animate&&this.classes.add("is-rendering"),!this.replaceContent(G))throw Error("[swup] Container mismatch, aborting");G.animation.animate&&(this.classes.add("is-changing","is-animating","is-rendering"),G.animation.name&&this.classes.add(`to-${o(G.animation.name)}`))}),await this.hooks.call("content:scroll",f,void 0,()=>this.scrollToContent(f)),await this.hooks.call("page:view",f,{url:this.location.url,title:document.title})},Cf=function(f){var S;if(S=f,Boolean(S==null?void 0:S.isSwupPlugin)){if(f.swup=this,!f._checkRequirements||f._checkRequirements())return f._beforeMount&&f._beforeMount(),f.mount(),this.plugins.push(f),this.plugins}else console.error("Not a swup plugin instance",f)};function Ff(f){let S=this.findPlugin(f);if(S)return S.unmount(),S._afterUnmount&&S._afterUnmount(),this.plugins=this.plugins.filter((z)=>z!==S),this.plugins;console.error("No such plugin",S)}function Hf(f){return this.plugins.find((S)=>S===f||S.name===f||S.name===`Swup${String(f)}`)}function _f(f){if(typeof this.options.resolveUrl!="function")return console.warn("[swup] options.resolveUrl expects a callback function."),f;let S=this.options.resolveUrl(f);return S&&typeof S=="string"?S.startsWith("//")||S.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),f):S:(console.warn("[swup] options.resolveUrl needs to return a url"),f)}function Of(f,S){return this.resolveUrl(f)===this.resolveUrl(S)}var Tf={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],hooks:{},ignoreVisit:(f,{el:S}={})=>!(S==null||!S.closest("[data-no-swup]")),linkSelector:"a[href]",linkToSelf:"scroll",native:!1,plugins:[],resolveUrl:(f)=>f,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:(f)=>{var S;return((S=f.state)==null?void 0:S.source)!=="swup"},timeout:0};class u{get currentPageUrl(){return this.location.url}constructor(f={}){var S,z;this.version="4.8.3",this.options=void 0,this.defaults=Tf,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.location=F.fromUrl(window.location.href),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.onVisitEnd=void 0,this.use=Cf,this.unuse=Ff,this.findPlugin=Hf,this.log=()=>{},this.navigate=Df,this.performNavigation=If,this.createVisit=Zf,this.delegateEvent=Qf,this.fetchPage=Xf,this.awaitAnimations=Bf,this.renderPage=$f,this.replaceContent=Pf,this.animatePageIn=Wf,this.animatePageOut=Nf,this.scrollToContent=Vf,this.getAnchorElement=qf,this.getCurrentUrl=T,this.resolveUrl=_f,this.isSameResolvedUrl=Of,this.options=$({},this.defaults,f),this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new l(this),this.classes=new n(this),this.hooks=new s(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=(S=(z=window.history.state)==null?void 0:z.index)!=null?S:1,this.enable()}async enable(){var f;let{linkSelector:S}=this.options;this.clickDelegate=this.delegateEvent(S,"click",this.handleLinkClick),window.addEventListener("popstate",this.handlePopState),this.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),this.options.native=this.options.native&&!!document.startViewTransition,this.options.plugins.forEach((z)=>this.use(z));for(let[z,G]of Object.entries(this.options.hooks)){let[J,K]=this.hooks.parseName(z);this.hooks.on(J,G,K)}((f=window.history.state)==null?void 0:f.source)!=="swup"&&O(null,{index:this.currentHistoryIndex}),await r(),await this.hooks.call("enable",void 0,void 0,()=>{let z=document.documentElement;z.classList.add("swup-enabled"),z.classList.toggle("swup-native",this.options.native)})}async destroy(){this.clickDelegate.destroy(),window.removeEventListener("popstate",this.handlePopState),this.cache.clear(),this.options.plugins.forEach((f)=>this.unuse(f)),await this.hooks.call("disable",void 0,void 0,()=>{let f=document.documentElement;f.classList.remove("swup-enabled"),f.classList.remove("swup-native")}),this.hooks.clear()}shouldIgnoreVisit(f,{el:S,event:z}={}){let{origin:G,url:J,hash:K}=F.fromUrl(f);return G!==window.location.origin||!(!S||!this.triggerWillOpenNewWindow(S))||!!this.options.ignoreVisit(J+K,{el:S,event:z})}handleLinkClick(f){let S=f.delegateTarget,{href:z,url:G,hash:J}=F.fromElement(S);if(this.shouldIgnoreVisit(z,{el:S,event:f}))return;if(this.navigating&&G===this.visit.to.url)return void f.preventDefault();let K=this.createVisit({to:G,hash:J,el:S,event:f});f.metaKey||f.ctrlKey||f.shiftKey||f.altKey?this.hooks.callSync("link:newtab",K,{href:z}):f.button===0&&this.hooks.callSync("link:click",K,{el:S,event:f},()=>{var Y;let Z=(Y=K.from.url)!=null?Y:"";f.preventDefault(),G&&G!==Z?this.isSameResolvedUrl(G,Z)||this.performNavigation(K):J?this.hooks.callSync("link:anchor",K,{hash:J},()=>{O(G+J),this.scrollToContent(K)}):this.hooks.callSync("link:self",K,void 0,()=>{this.options.linkToSelf==="navigate"?this.performNavigation(K):(O(G),this.scrollToContent(K))})})}handlePopState(f){var S,z,G,J;let K=(S=(z=f.state)==null?void 0:z.url)!=null?S:window.location.href;if(this.options.skipPopStateHandling(f))return;if(this.isSameResolvedUrl(T(),this.location.url))return;let{url:Y,hash:Z}=F.fromUrl(K),X=this.createVisit({to:Y,hash:Z,event:f});X.history.popstate=!0;let Q=(G=(J=f.state)==null?void 0:J.index)!=null?G:0;Q&&Q!==this.currentHistoryIndex&&(X.history.direction=Q-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=Q),X.animation.animate=!1,X.scroll.reset=!1,X.scroll.target=!1,this.options.animateHistoryBrowsing&&(X.animation.animate=!0,X.scroll.reset=!0),this.hooks.callSync("history:popstate",X,{event:f},()=>{this.performNavigation(X)})}triggerWillOpenNewWindow(f){return!!f.matches('[download], [target="_blank"]')}}function A(){return A=Object.assign?Object.assign.bind():function(f){for(var S=1;S<arguments.length;S++){var z=arguments[S];for(var G in z)Object.prototype.hasOwnProperty.call(z,G)&&(f[G]=z[G])}return f},A.apply(this,arguments)}var e=(f)=>String(f).split(".").map((S)=>String(parseInt(S||"0",10))).concat(["0","0"]).slice(0,3).join(".");class x{constructor(){this.isSwupPlugin=!0,this.swup=void 0,this.version=void 0,this.requires={},this.handlersToUnregister=[]}mount(){}unmount(){this.handlersToUnregister.forEach((f)=>f()),this.handlersToUnregister=[]}_beforeMount(){if(!this.name)throw Error("You must define a name of plugin when creating a class.")}_afterUnmount(){}_checkRequirements(){return typeof this.requires!="object"||Object.entries(this.requires).forEach(([f,S])=>{if(!function(z,G,J){let K=function(Y,Z){var X;if(Y==="swup")return(X=Z.version)!=null?X:"";{var Q;let q=Z.findPlugin(Y);return(Q=q==null?void 0:q.version)!=null?Q:""}}(z,J);return!!K&&((Y,Z)=>Z.every((X)=>{let[,Q,q]=X.match(/^([\D]+)?(.*)$/)||[];var B,I;return((D,W)=>{let V={"":(P)=>P===0,">":(P)=>P>0,">=":(P)=>P>=0,"<":(P)=>P<0,"<=":(P)=>P<=0};return(V[W]||V[""])(D)})((I=q,B=e(B=Y),I=e(I),B.localeCompare(I,void 0,{numeric:!0})),Q||">=")}))(K,G)}(f,S=Array.isArray(S)?S:[S],this.swup)){let z=`${f} ${S.join(", ")}`;throw Error(`Plugin version mismatch: ${this.name} requires ${z}`)}}),!0}on(f,S,z={}){var G;S=!(G=S).name.startsWith("bound ")||G.hasOwnProperty("prototype")?S.bind(this):S;let J=this.swup.hooks.on(f,S,z);return this.handlersToUnregister.push(J),J}once(f,S,z={}){return this.on(f,S,A({},z,{once:!0}))}before(f,S,z={}){return this.on(f,S,A({},z,{before:!0}))}replace(f,S,z={}){return this.on(f,S,A({},z,{replace:!0}))}off(f,S){return this.swup.hooks.off(f,S)}}function L(){return L=Object.assign?Object.assign.bind():function(f){for(var S=1;S<arguments.length;S++){var z=arguments[S];for(var G in z)({}).hasOwnProperty.call(z,G)&&(f[G]=z[G])}return f},L.apply(null,arguments)}function t(f){return f.localName!=="title"&&!f.matches("[data-swup-theme]")}function ff(f,S){return f.outerHTML===S.outerHTML}function Sf(f,S=[]){let z=Array.from(f.attributes);return S.length?z.filter(({name:G})=>S.some((J)=>J instanceof RegExp?J.test(G):G===J)):z}function Af(f){return f.matches("link[rel=stylesheet][href]")}class g extends x{constructor(f={}){var S;super(),S=this,this.name="SwupHeadPlugin",this.requires={swup:">=4.6"},this.defaults={persistTags:!1,persistAssets:!1,awaitAssets:!1,attributes:["lang","dir"],timeout:3000},this.options=void 0,this.updateHead=async function(z,{page:{}}){let{awaitAssets:G,attributes:J,timeout:K}=S.options,Y=z.to.document,{removed:Z,added:X}=function(Q,q,{shouldPersist:B=()=>!1}={}){let I=Array.from(Q.children),D=Array.from(q.children),W=(V=I,D.reduce((N,H,R)=>(V.some((j)=>ff(H,j))||N.push({el:H,index:R}),N),[]));var V;let P=function(N,H){return N.reduce((R,j)=>(H.some((zf)=>ff(j,zf))||R.push({el:j}),R),[])}(I,D);P.reverse().filter(({el:N})=>t(N)).filter(({el:N})=>!B(N)).forEach(({el:N})=>Q.removeChild(N));let C=W.filter(({el:N})=>t(N)).map((N)=>{let H=N.el.cloneNode(!0);return Q.insertBefore(H,Q.children[(N.index||0)+1]||null),L({},N,{el:H})});return{removed:P.map(({el:N})=>N),added:C.map(({el:N})=>N)}}(document.head,Y.head,{shouldPersist:(Q)=>S.isPersistentTag(Q)});if(S.swup.log(`Removed ${Z.length} / added ${X.length} tags in head`),J!=null&&J.length&&function(Q,q,B=[]){let I=new Set;for(let{name:D,value:W}of Sf(q,B))Q.setAttribute(D,W),I.add(D);for(let{name:D}of Sf(Q,B))I.has(D)||Q.removeAttribute(D)}(document.documentElement,Y.documentElement,J),G){let Q=function(q,B=0){return q.filter(Af).map((I)=>function(D,W=0){let V,P=(C)=>{D.sheet?C():V=setTimeout(()=>P(C),10)};return new Promise((C)=>{P(()=>C(D)),W>0&&setTimeout(()=>{V&&clearTimeout(V),C(D)},W)})}(I,B))}(X,K);Q.length&&(S.swup.log(`Waiting for ${Q.length} assets to load`),await Promise.all(Q))}},this.options=L({},this.defaults,f),this.options.persistAssets&&!this.options.persistTags&&(this.options.persistTags="link[rel=stylesheet], script[src], style")}mount(){this.before("content:replace",this.updateHead)}isPersistentTag(f){let{persistTags:S}=this.options;return typeof S=="function"?S(f):typeof S=="string"&&S.length>0?f.matches(S):Boolean(S)}}function b(){return b=Object.assign?Object.assign.bind():function(f){for(var S=1;S<arguments.length;S++){var z=arguments[S];for(var G in z)Object.prototype.hasOwnProperty.call(z,G)&&(f[G]=z[G])}return f},b.apply(this,arguments)}class d extends x{constructor(f={}){super(),this.name="SwupScriptsPlugin",this.requires={swup:">=4"},this.defaults={head:!0,body:!0,optin:!1},this.options=void 0,this.options=b({},this.defaults,f)}mount(){this.on("content:replace",this.runScripts)}runScripts(){let{head:f,body:S,optin:z}=this.options,G=this.getScope({head:f,body:S});if(!G)return;let J=Array.from(G.querySelectorAll(z?"script[data-swup-reload-script]":"script:not([data-swup-ignore-script])"));J.forEach((K)=>this.runScript(K)),this.swup.log(`Executed ${J.length} scripts.`)}runScript(f){let S=document.createElement("script");for(let{name:z,value:G}of f.attributes)S.setAttribute(z,G);return S.textContent=f.textContent,f.replaceWith(S),S}getScope({head:f,body:S}){return f&&S?document:f?document.head:S?document.body:null}}var xf=new u({containers:["#swup"],cache:!0,native:!0,animationSelector:!1,plugins:[new g({persistTags:!0}),new d({optin:!0})]});window.swup=xf;