Files
FixIt/layouts/_partials/base/assets.html
T
Cell 658f03d1e5 refactor(params)!: flatten [params.page] to [params], snake_case keys, more page-level params support (#805)
* refactor(params)!: snake_case config + eliminate params.page + use .Param

BREAKING CHANGE: All params keys renamed from camelCase to snake_case,
[params.page] section eliminated (moved to [params] level), and users
must update their hugo.toml and front matter accordingly.

Key changes:
- All camelCase config keys → snake_case (e.g., defaultTheme → default_theme)
- [params.page] flat keys and sub-sections moved to [params] level
- Removed function/params.html (manual merge), replaced with Hugo .Param
- New function/param.html partial for page-level section params with
  shorthand boolean support and site defaults merging
- New function/camel-case.html for string conversion
- snake2camel.html renamed to camel-case-keys.html
- New function/get-cover.html for cover image resolution
- Deprecation warnings in detection-deprecated.html for old config keys
- Front matter only params (subtitle, featured_image, password, repost,
  weight, message) use .Params.xxx instead of .Param
- Page-level sections use param.html partial
- Simplified patch.html (siteTime only) and init/index.html

Refs: camel-case-keys.html#29 (planned v1.0 breaking change)

* refactor(params)!: move params.link to page-level, simplify link guard

- Move [params.link] and [params.link.guard] to page-level section
- link.html: .Page optional, use param.html when available for
  page-level override, fall back to site config without .Page
- Remove $guardConfig variable, use $config.guard directly
- Remove unnecessary .Page from callers that don't need page override
- friends.html: use param.html for link guard instead of link_guard

* refactor(params)!: move image/codeblock/json_viewer/filetree to page-level

- Move [params.image], [params.codeblock], [params.json_viewer],
  [params.filetree] to page-level sub-sections
- Templates use param.html for merged config (page override + site defaults)
- image.html: .Page optional, falls back to site config without .Page
- Add v1- prefix to all deprecation warnidf IDs
- Fix camelCase key access in image.html (blackList, cacheRemote)
- Fix Hugo-lowered camelCase keys in code-block-wrapper.html
- Add deprecation warnings for codeblock camelCase Markdown attributes
- Add deprecation warnings for file-tree camelCase Markdown attributes
- Update render-codeblock-toggle.html for snake_case attribute names

* style: standardize @param comment style across all HTML templates

- PascalCase types: {string} → {String}, {boolean} → {Boolean},
  {int} → {Int}, {map} → {Map}, {array} → {Array}
- Add missing ` - ` separator between param name and description
- Remove extra alignment spaces between type and param name

* refactor(params)!: move params.mermaid to page-level, extract gen/ templates

- Move [params.mermaid] to page-level sub-sections
- Mermaid config injected into window.config (per-page override support)
- mermaid.ts reads config from window.config.mermaid instead of parameter
- Create _partials/gen/ directory for JS content generators
- Move mermaid-bootstrap.html from plugin/ to gen/
- Extract window.config JS generation into gen/config.html
- mermaid.html uses param.html for wrapper config

* refactor(params)!: consolidate link_to_* into params.post_link section

- Move link_to_markdown/source/edit/report/vscode into [params.post_link]
- Rename keys: markdown, source, edit, report (bool), editor (string)
- editor defaults to "vscode", supports "trae" etc. via protocol template
- footer.html uses .Param "post_link" for all link toggles
- Remove link_to_* from deprecated keys list

* fix: add fallback for deprecated camelCase attributes and expand deprecation warnings

- render-codeblock-file-tree.html: folderSlash attribute fallback
- render-codeblock-toggle.html: lineNosToggler/lineWrapToggler fallback + warnings
- code-block-wrapper.html: maxShownLines/wrapperClass fallback
- detection-deprecated.html: add nested key warnings for 13 sections
  (header, breadcrumb, navigation, watermark, busuanzi, image, mermaid,
  codeblock, filetree, math.katex, math.mathjax.options, post_summary, footer)
- detection-deprecated.html: add link_guard front matter deprecation warning

* fix(mermaid): fix rendering in hidden tab panels and neutral layer scheduling

- isRenderContextActive: check tab-panel visibility via getBoundingClientRect
  instead of panel.hidden (tab-container uses slot-based hiding, not hidden attr)
- bindTabContainerChanged: render neutral layers when switching tabs so
  print/fallback scenarios work correctly
2026-07-01 22:27:08 +08:00

411 lines
24 KiB
HTML

{{- /*
Assets Partial - Asset orchestration for page scripts and styles
This partial collects feature flags and page/site params, then registers
required CSS/JS resources through store/style.html and store/script.html.
Key responsibilities:
- Resolve optional third-party libraries and plugin integrations
- Build per-page runtime config and emit window.config
- Build and register core bundles (file-tree, mermaid, main, custom)
- Append page-injected style/script arrays and analytics hooks
Called from: layouts/baseof.html
*/ -}}
{{- $noop := .WordCount -}}
{{- $cdn := .Site.Store.Get "cdn" | default dict -}}
{{- $fingerprint := .Site.Store.Get "fingerprint" -}}
{{- $config := (.Store.Get "this").config -}}
{{- $config = dict "version" (hugo.Store.Get "version") | merge $config -}}
{{- $author := partial "function/get-author-map.html" .Params.author -}}
{{- $isArchivesOrOffline := (eq .Kind "home") | and (in .RelPermalink "archives") | or (in .RelPermalink "offline") -}}
{{- $uniqueFileId := "" -}}
{{- $languagePrefix := .Site.LanguagePrefix -}}
{{- with .File -}}
{{- $uniqueFileId = .UniqueID -}}
{{- end -}}
{{- /* Search */ -}}
{{- if .Site.Params.search | and .Site.Params.search.enable -}}
{{- $search := .Site.Params.search -}}
{{- $source := $cdn.autocompleteJS | default "lib/autocomplete-js/index.production.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $placeholder := $search.placeholder | default (T "assets.searchPlaceholder") -}}
{{- $config = dict "maxResultLength" $search.max_result_length "snippetLength" $search.snippet_length "highlightTag" $search.highlight_tag "noResultsFound" (T "assets.noResultsFound") "placeholder" $placeholder "clearText" (T "assets.clear") | dict "search" | merge $config -}}
{{- if eq $search.type "algolia" -}}
{{- $source := $cdn.algoliasearchJS | default "lib/algoliasearch/browser.umd.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "type" "algolia" "algoliaIndex" $search.algolia.index "algoliaAppID" $search.algolia.app_id "algoliaSearchKey" $search.algolia.search_key | dict "search" | merge $config -}}
{{- else if eq $search.type "fuse" -}}
{{- with .Site.Home.OutputFormats.Get "search" -}}
{{- $config = dict "type" "fuse" "fuseIndexURL" .RelPermalink | dict "search" | merge $config -}}
{{- end -}}
{{- dict "Source" "js/lib/fuse.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "isCaseSensitive" $search.fuse.is_case_sensitive "minMatchCharLength" $search.fuse.min_match_char_length "findAllMatches" $search.fuse.find_all_matches "location" $search.fuse.location "threshold" $search.fuse.threshold "distance" $search.fuse.distance "ignoreLocation" $search.fuse.ignore_location "useExtendedSearch" $search.fuse.use_extended_search "ignoreFieldNorm" $search.fuse.ignore_field_norm | dict "search" | merge $config -}}
{{- else if eq $search.type "pagefind" -}}
{{- $config = dict "type" "pagefind" | dict "search" | merge $config -}}
{{- $pagefind := $search.pagefind | default dict -}}
{{- $bundlePath := relURL ($pagefind.bundle_path | default "pagefind/") -}}
{{- if not (hasSuffix $bundlePath "/") -}}
{{- $bundlePath = printf "%v/" $bundlePath -}}
{{- end -}}
{{- $config = dict
"bundlePath" $bundlePath
"debounceTimeoutMs" ($pagefind.debounce_timeout_ms | default 300)
"useBuiltInFilters" ($pagefind.use_built_in_filters | default true)
"sortBy" ($pagefind.sort_by | default "")
"sortOrder" ($pagefind.sort_order | default "desc")
| dict "pagefind" | merge $config
-}}
{{- else if eq $search.type "cse" -}}
{{- $config = dict "type" "cse" | dict "search" | merge $config -}}
{{- $cse := .Site.Params.cse -}}
{{- $resultsPage := $cse.results_page -}}
{{- if not (hasPrefix $resultsPage (relURL "")) -}}
{{- $resultsPage = path.Join (relURL "") $resultsPage -}}
{{- end -}}
{{- $config = dict "resultsPage" $resultsPage "gotoResultsPage" (T "assets.gotoResultsPage") | dict "cse" | merge $config -}}
{{- if (eq $cse.engine "google") | and $cse.google.cx -}}
{{- $config = dict "engine" "google" "cx" $cse.google.cx "searchIn" (T "assets.searchIn" "Google") | dict "cse" | merge $config -}}
{{- end -}}
{{- if eq $cse.engine "bing" | and $cse.bing.cx -}}
{{- $config = dict "engine" "bing" "cx" $cse.bing.cx "searchIn" (T "assets.searchIn" "Bing") | dict "cse" | merge $config -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- /* instant.page */ -}}
{{- if .Param "instant_page" -}}
{{- $source := $cdn.instantPage | default "lib/instant-page/instantpage.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Attr" `type="module"` "Async" true "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* JSON Viewer */ -}}
{{- if .Store.Get "hasJsonViewer" | and (not $isArchivesOrOffline) -}}
{{- $source := $cdn.jsonViewerElementJS | default "lib/json-viewer-element/json-viewer-element.umd.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- dict "Source" "js/lib/json-viewer.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Mermaid */ -}}
{{- if .Store.Get "hasMermaid" | and (not $isArchivesOrOffline) -}}
{{- if .Store.Get "hasPanzoom" -}}
{{- $source := $cdn.panzoomJS | default "lib/panzoom/panzoom.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" $ "Data" | partial "store/script.html" -}}
{{- end -}}
{{- $mermaid := dict "Page" . "Key" "mermaid" "ToCamel" true | partial "function/param.html" -}}
{{- $config = dict "mermaid" $mermaid | merge $config -}}
{{- end -}}
{{- /* twemoji */ -}}
{{- if .Param "twemoji" -}}
{{- $source := $cdn.twemojiJS | default "lib/twemoji/twemoji.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "twemoji" true | merge $config -}}
{{- dict "Source" "js/lib/twemoji.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* lightgallery */ -}}
{{- if (.Param "lightgallery") | or (eq (.Param "lightgallery") "force") -}}
{{- $source := $cdn.lightgalleryCSS | default "lib/lightgallery/css/lightgallery-bundle.min.css" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- $source := $cdn.lightgalleryJS | default "lib/lightgallery/lightgallery.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $source := $cdn.lightgalleryThumbnailJS | default "lib/lightgallery/plugins/thumbnail/lg-thumbnail.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $source := $cdn.lightgalleryZoomJS | default "lib/lightgallery/plugins/zoom/lg-zoom.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "lightgallery" true | merge $config -}}
{{- dict "Source" "js/lib/lightgallery.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Sharer.js */ -}}
{{- if .Store.Get "hasSharer" -}}
{{- $source := $cdn.sharerJS | default "lib/sharer/sharer.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Async" true "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* TypeIt */ -}}
{{- if .Store.Get "hasTyped" -}}
{{- $typeit := partial "function/camel-case-keys.html" .Site.Params.typeit -}}
{{- $source := $cdn.typeitJS | default "lib/typeit/index.umd.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "typeit" $typeit | merge $config -}}
{{- dict "Source" "js/lib/typeit.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* KaTeX */ -}}
{{- $math := dict "Page" . "Key" "math" "ToCamel" true | partial "function/param.html" -}}
{{- if .Store.Get "hasKaTeX" | and (not $isArchivesOrOffline) -}}
{{- $source := $cdn.katexCSS | default "lib/katex/katex.min.css" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- /* Copy-tex extension */ -}}
{{- if $math.katex.copyTex -}}
{{- $source := $cdn.katexCopyTexJS | default "lib/katex/copy-tex.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- end -}}
{{- /* MathJax */ -}}
{{- if .Store.Get "hasMathJax" | and (not $isArchivesOrOffline) -}}
{{- dict "Source" "js/lib/mathjax.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $mathjax := $math.mathjax -}}
{{- $mjoc := $mathjax.options | default dict -}}
{{- $mjo := dict -}}
{{- if eq $mjoc.enableMenu false -}}
{{- $mjo = dict "enableMenu" false | merge $mjo -}}
{{- end -}}
{{- with $mjoc.ignoreHtmlClass -}}
{{- $mjo = dict "ignoreHtmlClass" . | merge $mjo -}}
{{- end -}}
{{- with $mjoc.skipHtmlTags -}}
{{- $mjo = dict "skipHtmlTags" . | merge $mjo -}}
{{- end -}}
{{- with $mjoc.includeHtmlTags -}}
{{- $mjo = dict "includeHtmlTags" . | merge $mjo -}}
{{- end -}}
{{- $config = dict
"cdn" $mathjax.cdn
"tex" ($mathjax.tex | default dict)
"packages" ($mathjax.packages | default dict)
"macros" ($mathjax.macros | default dict)
"loader" ($mathjax.loader | default dict)
"options" $mjo
| dict "mathjax"
| merge $config
-}}
{{- end -}}
{{- /* ECharts */ -}}
{{- if .Store.Get "hasEcharts" | and (not $isArchivesOrOffline) -}}
{{- $source := $cdn.echartsJS | default "lib/echarts/echarts.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $lightTheme := resources.Get "lib/echarts/theme/light.yml" | transform.Unmarshal -}}
{{- $darkTheme := resources.Get "lib/echarts/theme/dark.yml" | transform.Unmarshal -}}
{{- $config = dict "lightTheme" $lightTheme "darkTheme" $darkTheme | dict "echarts" | merge $config -}}
{{- dict "Source" "js/lib/echarts.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Mapbox GL */ -}}
{{- if .Store.Get "hasMapbox" -}}
{{- $source := $cdn.mapboxGLCSS | default "lib/mapbox-gl/mapbox-gl.css" -}}
{{- dict "Source" $source "Minify" hugo.IsProduction "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- $source = $cdn.mapboxGLJS | default "lib/mapbox-gl/mapbox-gl.js" -}}
{{- dict "Source" $source "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- dict "Source" "lib/mapbox-gl/mapbox-gl-language.js" "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $mapbox := dict "Page" . "Key" "mapbox" | partial "function/param.html" -}}
{{- $config = dict "accessToken" $mapbox.access_token "RTLTextPlugin" "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.0/mapbox-gl-rtl-text.js" | dict "mapbox" | merge $config -}}
{{- dict "Source" "js/lib/mapbox.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Music (APlayer / MetingJS) */ -}}
{{- if (.Store.Get "hasAplayer") | or (.Store.Get "hasMusic") -}}
{{- /* APlayer */ -}}
{{- $source := $cdn.aplayerCSS | default "lib/aplayer/APlayer.min.css" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- dict "Source" "lib/aplayer/dark.scss" "ToCSS" true "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- $source := $cdn.aplayerJS | default "lib/aplayer/APlayer.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- if .Store.Get "hasAplayer" -}}
{{- dict "Source" "js/lib/aplayer.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- if .Store.Get "hasMusic" -}}
{{- /* MetingJS */ -}}
{{- $source := $cdn.metingJS | default "lib/meting/Meting.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- end -}}
{{- /* Tabs */ -}}
{{- if .Store.Get "hasTabs" | and (not $isArchivesOrOffline) -}}
{{- $source := $cdn.tabContainerElementJS | default "lib/tab-container-element/bundle.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Attr" `type="module"` "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Cookie Consent */ -}}
{{- if .Site.Params.cookieconsent | and .Site.Params.cookieconsent.enable -}}
{{- $source := $cdn.cookieconsentCSS | default "lib/cookieconsent/cookieconsent.min.css" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- $source := $cdn.cookieconsentJS | default "lib/cookieconsent/cookieconsent.min.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $cookieconsentConfig := dict "popup" (dict "background" "#1aa3ff") "button" (dict "background" "#f0f0f0") | dict "theme" "edgeless" "palette" -}}
{{- $cookieconsentConfig = .Site.Params.cookieconsent | merge $cookieconsentConfig -}}
{{- $cookieconsentConfig = dict "message" ($cookieconsentConfig.content.message | default (T "assets.cookieconsentMessage")) "dismiss" ($cookieconsentConfig.content.dismiss | default (T "assets.cookieconsentDismiss")) "link" ($cookieconsentConfig.content.link | default (T "assets.cookieconsentLink")) | dict "content" | merge $cookieconsentConfig -}}
{{- $config = $cookieconsentConfig | dict "cookieconsent" | merge $config -}}
{{- dict "Source" "js/lib/cookieconsent.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* PanguJS */ -}}
{{- if eq .Site.Params.pangu.enable true -}}
{{- $source := $cdn.panguJS | default "lib/pangu/pangu.umd.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "pangu" .Site.Params.pangu | merge $config -}}
{{- dict "Source" "js/lib/pangu.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Cell Tooltip */ -}}
{{- if eq .Site.Params.tooltip true -}}
{{- /* [TODO] Temporary feasibility check; replace with a more stable alternative (Floating UI). */ -}}
{{- $source := $cdn.cellTooltipJS | default "lib/cell-tooltip/cell-tooltip.umd.js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "tooltip" true | merge $config -}}
{{- end -}}
{{- /* Watermark */ -}}
{{- $watermarkConfig := partial "function/camel-case-keys.html" .Site.Params.watermark | default dict -}}
{{- if $watermarkConfig.enable -}}
{{- $source := $cdn.cellWatermarkJS | default "lib/cell-watermark/watermark.js" -}}
{{- dict "Source" $source "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $watermarkConfig = dict
"appendTo" ".widgets"
"content" ($watermarkConfig.content | default $author.name | default .Site.Title)
| merge $watermarkConfig
-}}
{{- $config = dict "watermark" $watermarkConfig | merge $config -}}
{{- dict "Source" "js/lib/watermark.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Content Decryption */ -}}
{{- $encryptPartial := .Store.Get "hasEncryptor" -}}
{{- if .Params.password | or $encryptPartial -}}
{{- $cryptoCoreJS := $cdn.cryptoCoreJS | default "lib/crypto-js/core.js" -}}
{{- $cryptoEncBase64JS := $cdn.cryptoEncBase64JS | default "lib/crypto-js/enc-base64.js" -}}
{{- $cryptoSha256JS := $cdn.cryptoSha256JS | default "lib/crypto-js/sha256.js" -}}
{{- $xxhashWasmJS := $cdn.xxhashWasmJS | default "lib/xxhash-wasm/xxhash-wasm.js" -}}
{{- dict "Source" $cryptoCoreJS "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- dict "Source" $cryptoEncBase64JS "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- dict "Source" $cryptoSha256JS "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- dict "Source" $xxhashWasmJS "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- /* Decryption script */ -}}
{{- dict "Source" "js/lib/fixit-decryptor.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- $config = dict "all" (.Params.password | not | not) "shortcode" ($encryptPartial | default false) | dict "encryption" | merge $config -}}
{{- end -}}
{{- /* Busuanzi visitor counter */ -}}
{{- if .Site.Params.busuanzi.enable | and hugo.IsProduction -}}
{{- $source := .Site.Params.busuanzi.source | default "https://vercount.one/js" -}}
{{- dict "Source" $source "Fingerprint" $fingerprint "Async" true "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Site creation time */ -}}
{{- $siteTime := .Site.Params.footer.site_time -}}
{{- if $siteTime.enable -}}
{{- with $siteTime.value -}}
{{- $config = dict "siteTime" . | merge $config -}}
{{- end -}}
{{- end -}}
{{- /* PWA */ -}}
{{- if not hugo.IsServer | and hugo.IsProduction | and .Site.Params.app.pwa -}}
{{- $offlineURL := "" -}}
{{- with .Site.Home.OutputFormats.Get "offline" -}}
{{- $offlineURL = .RelPermalink -}}
{{- end -}}
{{- $mainCSS := .Site.Store.Get "mainCSS" -}}
{{- $mainJS := .Site.Store.Get "mainJS" -}}
{{- $swBuildCtx := dict "mainCSSURL" $mainCSS.RelPermalink "mainJSURL" $mainJS.RelPermalink "offlineURL" $offlineURL "relURL" (relURL "") "version" (hugo.Store.Get "version") "Page" . -}}
{{- $serviceWorker := resources.Get "js/service-worker.template.js" | resources.ExecuteAsTemplate "js/service-worker.template.js" $swBuildCtx -}}
{{- $serviceWorker = dict "Resource" $serviceWorker "Build" (dict "targetPath" "sw.js") "Fingerprint" $fingerprint | partial "function/js-build.html" -}}
{{- $config = dict "PWA" (dict "enable" .Site.Params.app.pwa "serviceWorkerURL" $serviceWorker.RelPermalink) | merge $config -}}
{{- end -}}
{{- /* Auto Bookmark */ -}}
{{- if eq .Kind "page" -}}
{{- with .Param "auto_bookmark" -}}
{{- $config = dict "autoBookmark" . | merge $config -}}
{{- end -}}
{{- end -}}
{{- /* PACE */ -}}
{{- if eq .Site.Params.pace.enable true -}}
{{- $paceJS := "" -}}
{{- $paceCSS := "" -}}
{{- with ($cdn.paceJS | default "lib/pace") -}}
{{- $paceJS = printf "%v/pace.min.js" . -}}
{{- if $.Site.Params.pace.color | and $.Site.Params.pace.theme -}}
{{- $paceCSS = printf "%v/themes/%v/pace-theme-%v.css" . $.Site.Params.pace.color $.Site.Params.pace.theme -}}
{{- else -}}
{{- $paceCSS = printf "%v/pace-theme-default.min.css" . -}}
{{- end -}}
{{- end -}}
{{- dict "Source" $paceJS "Fingerprint" $fingerprint "Async" true "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- dict "Source" $paceCSS "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- /* To patch pace theme flat-top z-index error */ -}}
{{- if eq $.Site.Params.pace.theme "flat-top" -}}
{{- dict "Source" "lib/pace/pace-patch-flat-top.css" "Fingerprint" $fingerprint | dict "Page" . "Data" | partial "store/style.html" -}}
{{- end -}}
{{- end -}}
{{- /* Print */ -}}
{{- $config = partial "function/camel-case-keys.html" .Site.Params.print | dict "print" | merge $config -}}
{{- /* PostChat */ -}}
{{- partial "plugin/post-chat-ai.html" . -}}
{{- $library := dict "Page" . "Key" "library" | partial "function/param.html" -}}
{{- range $library.css -}}
{{- dict "Source" . "Fingerprint" $fingerprint | dict "Page" $ "Data" | partial "store/style.html" -}}
{{- end -}}
{{- range $library.js -}}
{{- dict "Source" . "Fingerprint" $fingerprint "Defer" true | dict "Page" $ "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Runtime config script */ -}}
{{- $configJS := dict "Config" $config | partial "gen/config.html" -}}
{{- $configPath := "" -}}
{{- if $uniqueFileId | and (not .IsHome) -}}
{{- $configPath = printf "%s/js/config/%s.js" $languagePrefix $uniqueFileId -}}
{{- end -}}
{{- dict "Content" $configJS "Path" $configPath "Minify" hugo.IsProduction "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- /* File-tree plugin */ -}}
{{- dict "Source" "js/lib/file-tree.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- /* Mermaid module */ -}}
{{- if .Store.Get "hasMermaid" | and (not $isArchivesOrOffline) -}}
{{- $options := dict "format" "esm" -}}
{{- $mermaidModule := dict "Resource" (resources.Get "js/lib/mermaid.ts") "Build" $options "Fingerprint" $fingerprint | partial "function/js-build.html" -}}
{{- $bootstrapJS := dict
"MermaidModuleURL" $mermaidModule.RelPermalink
| partial "gen/mermaid-bootstrap.html"
| htmlUnescape
-}}
{{- dict "Content" $bootstrapJS "Path" "js/lib/mermaid-bootstrap.js" "Minify" hugo.IsProduction "Attr" `type="module"` "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- end -}}
{{- /* Theme main bundle (built once in head/index.html) */ -}}
{{- dict "Resource" (.Site.Store.Get "mainJS") "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
{{- /* Custom assets block */ -}}
{{- block "custom-assets" . }}{{ end -}}
{{- /* Custom script (custom.ts takes priority over custom.js) */ -}}
{{- with resources.Get "js/custom.ts" | default (resources.Get "js/custom.js") -}}
{{- dict "Source" . "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" $ "Data" | partial "store/script.html" -}}
{{- end -}}
{{- with .Store.Get "styleArr" -}}
{{- $content := delimit . " " -}}
{{- $path := printf "%s/scss/pages/%s.scss" $languagePrefix $uniqueFileId -}}
{{- dict "Content" $content "Path" $path "ToCSS" (dict "enableSourceMap" false) | dict "Page" $ "Data" | partial "store/style.html" -}}
{{- end -}}
{{- with .Store.Get "scriptArr" -}}
{{- $content := delimit . "\n" -}}
{{- $targetPath := printf "%s/js/pages/%s.js" $languagePrefix $uniqueFileId -}}
{{- dict "Content" $content "Path" $targetPath "Minify" hugo.IsProduction "Defer" true | dict "Page" $ "Data" | partial "store/script.html" -}}
{{- end -}}
{{- range (.Store.Get "this").style -}}
{{- partial "plugin/style.html" . -}}
{{- end -}}
{{- range (.Store.Get "this").script -}}
{{- partial "plugin/script.html" . -}}
{{- end -}}
{{- partial "plugin/analytics.html" . -}}