rustfava 0.1.0__py3-none-any.whl
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.
- rustfava/__init__.py +30 -0
- rustfava/_ctx_globals_class.py +55 -0
- rustfava/api_models.py +36 -0
- rustfava/application.py +534 -0
- rustfava/beans/__init__.py +6 -0
- rustfava/beans/abc.py +327 -0
- rustfava/beans/account.py +79 -0
- rustfava/beans/create.py +377 -0
- rustfava/beans/flags.py +20 -0
- rustfava/beans/funcs.py +38 -0
- rustfava/beans/helpers.py +52 -0
- rustfava/beans/ingest.py +75 -0
- rustfava/beans/load.py +31 -0
- rustfava/beans/prices.py +151 -0
- rustfava/beans/protocols.py +82 -0
- rustfava/beans/str.py +454 -0
- rustfava/beans/types.py +63 -0
- rustfava/cli.py +187 -0
- rustfava/context.py +13 -0
- rustfava/core/__init__.py +729 -0
- rustfava/core/accounts.py +161 -0
- rustfava/core/attributes.py +145 -0
- rustfava/core/budgets.py +207 -0
- rustfava/core/charts.py +301 -0
- rustfava/core/commodities.py +37 -0
- rustfava/core/conversion.py +229 -0
- rustfava/core/documents.py +87 -0
- rustfava/core/extensions.py +132 -0
- rustfava/core/fava_options.py +255 -0
- rustfava/core/file.py +542 -0
- rustfava/core/filters.py +484 -0
- rustfava/core/group_entries.py +97 -0
- rustfava/core/ingest.py +509 -0
- rustfava/core/inventory.py +167 -0
- rustfava/core/misc.py +105 -0
- rustfava/core/module_base.py +18 -0
- rustfava/core/number.py +106 -0
- rustfava/core/query.py +180 -0
- rustfava/core/query_shell.py +301 -0
- rustfava/core/tree.py +265 -0
- rustfava/core/watcher.py +219 -0
- rustfava/ext/__init__.py +232 -0
- rustfava/ext/auto_commit.py +61 -0
- rustfava/ext/portfolio_list/PortfolioList.js +34 -0
- rustfava/ext/portfolio_list/__init__.py +29 -0
- rustfava/ext/portfolio_list/templates/PortfolioList.html +15 -0
- rustfava/ext/rustfava_ext_test/RustfavaExtTest.js +42 -0
- rustfava/ext/rustfava_ext_test/__init__.py +207 -0
- rustfava/ext/rustfava_ext_test/templates/RustfavaExtTest.html +45 -0
- rustfava/ext/rustfava_ext_test/templates/RustfavaExtTestInclude.html +1 -0
- rustfava/help/__init__.py +15 -0
- rustfava/help/_index.md +29 -0
- rustfava/help/beancount_syntax.md +156 -0
- rustfava/help/budgets.md +31 -0
- rustfava/help/conversion.md +29 -0
- rustfava/help/extensions.md +111 -0
- rustfava/help/features.md +179 -0
- rustfava/help/filters.md +103 -0
- rustfava/help/import.md +27 -0
- rustfava/help/options.md +289 -0
- rustfava/helpers.py +30 -0
- rustfava/internal_api.py +221 -0
- rustfava/json_api.py +952 -0
- rustfava/plugins/__init__.py +3 -0
- rustfava/plugins/link_documents.py +107 -0
- rustfava/plugins/tag_discovered_documents.py +44 -0
- rustfava/py.typed +0 -0
- rustfava/rustledger/__init__.py +31 -0
- rustfava/rustledger/constants.py +76 -0
- rustfava/rustledger/engine.py +485 -0
- rustfava/rustledger/loader.py +273 -0
- rustfava/rustledger/options.py +202 -0
- rustfava/rustledger/query.py +331 -0
- rustfava/rustledger/types.py +830 -0
- rustfava/serialisation.py +220 -0
- rustfava/static/app.css +2988 -0
- rustfava/static/app.css.map +7 -0
- rustfava/static/app.js +12854 -0
- rustfava/static/app.js.map +7 -0
- rustfava/static/beancount-JFV44ZVZ.css +5 -0
- rustfava/static/beancount-JFV44ZVZ.css.map +7 -0
- rustfava/static/beancount-VTTKRGSK.js +4642 -0
- rustfava/static/beancount-VTTKRGSK.js.map +7 -0
- rustfava/static/bql-MGFRUMBP.js +333 -0
- rustfava/static/bql-MGFRUMBP.js.map +7 -0
- rustfava/static/chunk-E7ZF4ASL.js +23061 -0
- rustfava/static/chunk-E7ZF4ASL.js.map +7 -0
- rustfava/static/chunk-V24TLQHT.js +12673 -0
- rustfava/static/chunk-V24TLQHT.js.map +7 -0
- rustfava/static/favicon.ico +0 -0
- rustfava/static/fira-mono-cyrillic-400-normal-BLAGXRCE.woff2 +0 -0
- rustfava/static/fira-mono-cyrillic-500-normal-EN7JUAAW.woff2 +0 -0
- rustfava/static/fira-mono-cyrillic-ext-400-normal-EX7VARTS.woff2 +0 -0
- rustfava/static/fira-mono-cyrillic-ext-500-normal-ZDPTUPRR.woff2 +0 -0
- rustfava/static/fira-mono-greek-400-normal-COGHKMOA.woff2 +0 -0
- rustfava/static/fira-mono-greek-500-normal-4EN2PKZT.woff2 +0 -0
- rustfava/static/fira-mono-greek-ext-400-normal-DYEQIJH7.woff2 +0 -0
- rustfava/static/fira-mono-greek-ext-500-normal-SG73CVKQ.woff2 +0 -0
- rustfava/static/fira-mono-latin-400-normal-NA3VLV7E.woff2 +0 -0
- rustfava/static/fira-mono-latin-500-normal-YC77GFWD.woff2 +0 -0
- rustfava/static/fira-mono-latin-ext-400-normal-DIKTZ5PW.woff2 +0 -0
- rustfava/static/fira-mono-latin-ext-500-normal-ZWY4UO4V.woff2 +0 -0
- rustfava/static/fira-mono-symbols2-400-normal-UITXT77Q.woff2 +0 -0
- rustfava/static/fira-mono-symbols2-500-normal-VWPC2EFN.woff2 +0 -0
- rustfava/static/fira-sans-cyrillic-400-normal-KLQMBCA6.woff2 +0 -0
- rustfava/static/fira-sans-cyrillic-500-normal-NFG7UD6J.woff2 +0 -0
- rustfava/static/fira-sans-cyrillic-ext-400-normal-GWO44OPC.woff2 +0 -0
- rustfava/static/fira-sans-cyrillic-ext-500-normal-SP47E5SC.woff2 +0 -0
- rustfava/static/fira-sans-greek-400-normal-UMQBTLC3.woff2 +0 -0
- rustfava/static/fira-sans-greek-500-normal-4ZKHN4FQ.woff2 +0 -0
- rustfava/static/fira-sans-greek-ext-400-normal-O2DVJAJZ.woff2 +0 -0
- rustfava/static/fira-sans-greek-ext-500-normal-SK6GNWGO.woff2 +0 -0
- rustfava/static/fira-sans-latin-400-normal-OYYTPMAV.woff2 +0 -0
- rustfava/static/fira-sans-latin-500-normal-SMQPZW5A.woff2 +0 -0
- rustfava/static/fira-sans-latin-ext-400-normal-OAUP3WK5.woff2 +0 -0
- rustfava/static/fira-sans-latin-ext-500-normal-LY3YDR5Y.woff2 +0 -0
- rustfava/static/fira-sans-vietnamese-400-normal-OBMQ72MR.woff2 +0 -0
- rustfava/static/fira-sans-vietnamese-500-normal-Y4NZR5EU.woff2 +0 -0
- rustfava/static/source-code-pro-cyrillic-400-normal-TO22V6M3.woff2 +0 -0
- rustfava/static/source-code-pro-cyrillic-500-normal-OGBWWWYW.woff2 +0 -0
- rustfava/static/source-code-pro-cyrillic-ext-400-normal-XH44UCIA.woff2 +0 -0
- rustfava/static/source-code-pro-cyrillic-ext-500-normal-3Z6MMVM6.woff2 +0 -0
- rustfava/static/source-code-pro-greek-400-normal-OUXXUQWK.woff2 +0 -0
- rustfava/static/source-code-pro-greek-500-normal-JA2Z5UXO.woff2 +0 -0
- rustfava/static/source-code-pro-greek-ext-400-normal-WCDKMX7U.woff2 +0 -0
- rustfava/static/source-code-pro-greek-ext-500-normal-ZHVI4VKW.woff2 +0 -0
- rustfava/static/source-code-pro-latin-400-normal-QOGTXED5.woff2 +0 -0
- rustfava/static/source-code-pro-latin-500-normal-X57QEOLQ.woff2 +0 -0
- rustfava/static/source-code-pro-latin-ext-400-normal-QXC74NBF.woff2 +0 -0
- rustfava/static/source-code-pro-latin-ext-500-normal-QGOY7MTT.woff2 +0 -0
- rustfava/static/source-code-pro-vietnamese-400-normal-NPDCDTBA.woff2 +0 -0
- rustfava/static/source-code-pro-vietnamese-500-normal-M6PJKTR5.woff2 +0 -0
- rustfava/static/tree-sitter-beancount-MLXFQBZ5.wasm +0 -0
- rustfava/static/web-tree-sitter-RNOQ6E74.wasm +0 -0
- rustfava/template_filters.py +64 -0
- rustfava/templates/_journal_table.html +156 -0
- rustfava/templates/_layout.html +26 -0
- rustfava/templates/_query_table.html +88 -0
- rustfava/templates/beancount_file +18 -0
- rustfava/templates/help.html +23 -0
- rustfava/templates/macros/_account_macros.html +5 -0
- rustfava/templates/macros/_commodity_macros.html +13 -0
- rustfava/translations/bg/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/bg/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/ca/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/ca/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/de/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/de/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/es/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/es/LC_MESSAGES/messages.po +619 -0
- rustfava/translations/fa/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/fa/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/fr/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/fr/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/ja/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/ja/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/nl/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/nl/LC_MESSAGES/messages.po +617 -0
- rustfava/translations/pt/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/pt/LC_MESSAGES/messages.po +617 -0
- rustfava/translations/pt_BR/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/pt_BR/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/ru/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/ru/LC_MESSAGES/messages.po +617 -0
- rustfava/translations/sk/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/sk/LC_MESSAGES/messages.po +623 -0
- rustfava/translations/sv/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/sv/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/uk/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/uk/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/zh/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/zh/LC_MESSAGES/messages.po +618 -0
- rustfava/translations/zh_Hant_TW/LC_MESSAGES/messages.mo +0 -0
- rustfava/translations/zh_Hant_TW/LC_MESSAGES/messages.po +618 -0
- rustfava/util/__init__.py +157 -0
- rustfava/util/date.py +576 -0
- rustfava/util/excel.py +118 -0
- rustfava/util/ranking.py +79 -0
- rustfava/util/sets.py +18 -0
- rustfava/util/unreachable.py +20 -0
- rustfava-0.1.0.dist-info/METADATA +102 -0
- rustfava-0.1.0.dist-info/RECORD +187 -0
- rustfava-0.1.0.dist-info/WHEEL +5 -0
- rustfava-0.1.0.dist-info/entry_points.txt +2 -0
- rustfava-0.1.0.dist-info/licenses/AUTHORS +11 -0
- rustfava-0.1.0.dist-info/licenses/LICENSE +21 -0
- rustfava-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../frontend/css/style.css", "../../../frontend/css/base.css", "../../../frontend/css/layout.css", "../../../frontend/css/charts.css", "../../../frontend/css/components.css", "../../../frontend/css/editor.css", "../../../frontend/css/grid.css", "../../../frontend/node_modules/@fontsource/source-code-pro/400.css", "../../../frontend/node_modules/@fontsource/source-code-pro/500.css", "../../../frontend/node_modules/@fontsource/fira-mono/400.css", "../../../frontend/node_modules/@fontsource/fira-mono/500.css", "../../../frontend/node_modules/@fontsource/fira-sans/400.css", "../../../frontend/node_modules/@fontsource/fira-sans/500.css", "../../../frontend/css/help.css", "../../../frontend/css/journal-table.css", "../../../frontend/css/notifications.css", "../../../frontend/css/tree-table.css", "ReportLoadError.svelte", "Axis.svelte", "BarChart.svelte", "ChartLegend.svelte", "Icicle.svelte", "Sunburst.svelte", "Treemap.svelte", "LineChart.svelte", "ModeSwitch.svelte", "ScatterPlot.svelte", "Chart.svelte", "SelectCombobox.svelte", "ChartSwitcher.svelte", "AccountCellHeader.svelte", "AccountIndicator.svelte", "AccountCell.svelte", "Diff.svelte", "IntervalTreeTable.svelte", "JournalFilters.svelte", "JournalHeaders.svelte", "AutocompleteInput.svelte", "ModalBase.svelte", "Accounts.svelte", "DocumentPreviewEditor.svelte", "DocumentPreview.svelte", "Table.svelte", "Documents.svelte", "AppMenu.svelte", "AppMenuItem.svelte", "AppMenuSubItem.svelte", "Sources.svelte", "EditorMenu.svelte", "Editor.svelte", "QueryLinks.svelte", "EntryMetadata.svelte", "Note.svelte", "Posting.svelte", "Transaction.svelte", "Extract.svelte", "FileList.svelte", "Import.svelte", "OptionsTable.svelte", "ReadonlyQueryEditor.svelte", "QueryBox.svelte", "QueryEditor.svelte", "TreeTable.svelte", "AddEntry.svelte", "SliceEditor.svelte", "EntryContextLocation.svelte", "DocumentUpload.svelte", "AccountSelector.svelte", "SidebarLink.svelte", "AsideContents.svelte", "AsideWithButton.svelte", "FilterForm.svelte", "HeaderIcon.svelte", "AccountPageTitle.svelte", "PageTitle.svelte", "Header.svelte"],
|
|
4
|
+
"sourcesContent": [":root {\n /* Fonts */\n --font-family: \"Fira Sans\", sans-serif;\n --font-family-monospaced: \"Fira Mono\", monospace;\n --font-family-editor: \"Source Code Pro\", monospace;\n\n color-scheme: light dark;\n\n /* Scale of z-index values */\n --z-index-floating-ui: 1;\n --z-index-autocomplete: 2;\n --z-index-overlay: 3;\n --z-index-keyboard-overlays: 4;\n\n /* Named colors */\n --error: hsl(0deg 100% 30%);\n --warning: hsl(52deg 84% 56%);\n --red: var(--error);\n --yellow: var(--warning);\n --green: hsl(151deg 100% 25%);\n --gray: hsl(0deg 0% 67%);\n --dark-gray: hsl(0deg 0% 25%);\n\n /* Base colors (backgrounds) */\n --background: light-dark(hsl(0deg 0% 100%), hsl(0deg 0% 15%));\n --background-darker: light-dark(hsl(0deg 0% 95%), hsl(0deg 0% 20%));\n --background-darkest: light-dark(hsl(0deg 0% 90%), hsl(0deg 0% 25%));\n --background-button: light-dark(hsl(0deg 0% 80%), hsl(0deg 0% 35%));\n\n /* Base colors (borders) */\n --border-lighter: light-dark(hsl(0deg 0% 90%), hsl(0deg 0% 25%));\n --border: light-dark(hsl(0deg 0% 85%), hsl(0deg 0% 30%));\n --border-darker: light-dark(hsl(0deg 0% 80%), hsl(0deg 0% 35%));\n\n /* Base colors (foreground) */\n --text-color: light-dark(hsl(0deg 0% 25%), hsl(0deg 0% 80%));\n --text-color-lighter: light-dark(hsl(0deg 0% 30%), hsl(0deg 0% 75%));\n --text-color-lightest: light-dark(hsl(0deg 0% 40%), hsl(0deg 0% 65%));\n --link-color: light-dark(hsl(203deg 100% 32%), hsl(203deg 100% 68%));\n --link-hover-color: var(--text-color-lighter);\n\n /* Base elements */\n --heading-color: var(--text-color);\n --code-background: var(--background-darker);\n\n /* Box shadows */\n --box-shadow-button: 0 0 5px hsl(0deg 0% 50% / 50%);\n --box-shadow-dropdown: 3px 3px 3px\n light-dark(hsl(0deg 0% 50% / 50%), hsl(0deg 0% 25% / 50%));\n --box-shadow-kbd: inset 0 -1px 0 var(--border-darker);\n --box-shadow-overlay: 0 0 20px var(--overlay-wrapper-background);\n\n /* Buttons */\n --button-color: hsl(0deg 0% 100%);\n --button-background: hsl(203deg 100% 32%);\n --button-muted-color: var(--text-color);\n --button-muted-background: var(--background-button);\n\n /* Sidebar */\n --sidebar-color: var(--text-color-lighter);\n --sidebar-hover-color: var(--link-color);\n --sidebar-background: var(--background-darker);\n --sidebar-border: var(--border-lighter);\n\n /* Details */\n --summary-background: var(--background-darker);\n --summary-background-darker: var(--background-darkest);\n\n /* Header */\n --header-color: hsl(0deg 0% 100%);\n --header-background: light-dark(hsl(203deg 100% 32%), hsl(203deg 100% 25%));\n --header-placeholder-color: hsl(203deg 47% 66%);\n --header-placeholder-background: hsl(203deg 56% 45%);\n\n /* Tables */\n --table-header-text: var(--text-color-lightest);\n --table-header-background: var(--background-darkest);\n --table-border: var(--border-lighter);\n --table-background-even: var(--background-darker);\n --treetable-expander: light-dark(hsl(210deg 30% 45%), hsl(210deg 30% 55%));\n\n /* Amount differences. */\n --diff-red: light-dark(hsl(0deg 48% 40%), hsl(0deg 48% 60%));\n --diff-green: light-dark(hsl(125deg 48% 40%), hsl(125deg 48% 60%));\n --diff-negative: var(--diff-red);\n --diff-positive: var(--diff-green);\n\n /* Editor elements */\n --editor-activeline: light-dark(\n hsl(200deg 100% 90% / 30%),\n hsl(200deg 100% 30% / 30%)\n );\n --editor-selectionmatch: light-dark(\n hsl(105deg 100% 70% / 50%),\n hsl(105deg 100% 30% / 50%)\n );\n\n /* Beancount editor contents */\n --editor-account: var(--link-color);\n --editor-class: light-dark(hsl(34deg 50% 30%), hsl(34deg 50% 70%));\n --editor-comment: hsl(60deg 8% 50%);\n --editor-currencies: light-dark(hsl(293deg 100% 30%), hsl(293deg 100% 60%));\n --editor-date: light-dark(hsl(180deg 100% 20%), hsl(180deg 100% 50%));\n --editor-directive: var(--text-color);\n --editor-invalid-background: hsl(0deg 100% 80% / 50%);\n --editor-invalid: var(--text-color);\n --editor-label-name: light-dark(hsl(248deg 80% 33%), hsl(248deg 80% 67%));\n --editor-number: light-dark(hsl(156deg 71% 20%), hsl(156deg 71% 40%));\n --editor-string: light-dark(hsl(0deg 82% 33%), hsl(0deg 82% 67%));\n\n /* Query editor contents */\n --bql-keywords: var(--editor-currencies);\n --bql-values: light-dark(hsl(158deg 100% 30%), hsl(158deg 100% 60%));\n --bql-string: var(--editor-string);\n --bql-errors: var(--text-color);\n\n /* Misc */\n --notification-color: hsl(0deg 0% 100%);\n --chart-axis: hsl(0deg 0% 60%);\n --chart-line-at-zero: hsl(0deg 0% 40%);\n --autocomplete-match: hsl(39deg 100% 70% / 50%);\n --mobile-button-text: light-dark(hsl(0deg 0% 0%), hsl(0deg 0% 79%));\n --placeholder-color: light-dark(hsl(0deg 0% 47%), hsl(0deg 0% 85%));\n --placeholder-background: light-dark(hsl(0deg 0% 100%), hsl(0deg 0% 30%));\n --dragover-background: hsl(203deg 100% 32% / 50%);\n --overlay-wrapper-background: hsl(0deg 0% 50% / 50%);\n\n /* Help pages */\n --help-sidebar-background: var(--background-darker);\n --help-sidebar-border: var(--border-lighter);\n}\n\n:root.invert-gains-losses {\n --diff-negative: var(--diff-green);\n --diff-positive: var(--diff-red);\n}\n\n.journal {\n --journal-postings: light-dark(hsl(0deg 0% 92%), hsl(0deg 0% 10%));\n --journal-metadata: hsl(210deg 44% 67%);\n --journal-tag: hsl(210deg 61% 64%);\n --journal-link: hsl(203deg 39% 85%);\n --journal-posting-indicator: hsl(203deg 24% 80%);\n --journal-metadata-indicator: hsl(203deg 24% 40%);\n --journal-hover-highlight: light-dark(\n hsl(0deg 0% 90% / 60%),\n hsl(0deg 0% 20% / 60%)\n );\n\n .balance {\n --entry-background: light-dark(hsl(120deg 100% 90%), hsl(120deg 50% 15%));\n }\n\n .close {\n --entry-background: light-dark(hsl(0deg 0% 70%), hsl(0deg 0% 15%));\n }\n\n .custom {\n --entry-background: light-dark(hsl(51deg 100% 80%), hsl(52deg 100% 15%));\n }\n\n .document {\n --entry-background: light-dark(hsl(300deg 100% 80%), hsl(300deg 45% 25%));\n }\n\n .note {\n --entry-background: light-dark(hsl(213deg 100% 80%), hsl(212deg 43% 25%));\n }\n\n .open {\n --entry-background: light-dark(hsl(0deg 0% 92%), hsl(0deg 0% 20%));\n }\n\n .other {\n --entry-background: light-dark(hsl(180deg 100% 70%), hsl(180deg 100% 25%));\n }\n\n .pad {\n --entry-background: light-dark(hsl(180deg 100% 85%), hsl(180deg 100% 15%));\n }\n\n .pending {\n --entry-background: light-dark(hsl(343deg 100% 80%), hsl(343deg 60% 20%));\n }\n\n .query {\n --entry-background: light-dark(hsl(213deg 100% 80%), hsl(213deg 100% 25%));\n }\n\n .budget {\n --entry-background: light-dark(hsl(35deg 100% 80%), hsl(35deg 100% 20%));\n }\n}\n", "/* stylelint-disable no-descending-specificity */\n\n* {\n box-sizing: border-box;\n}\n\nhtml,\nbody {\n margin: 0;\n font-family: var(--font-family);\n font-size: 14px;\n font-weight: 400;\n line-height: 1.5;\n color: var(--text-color);\n background-color: var(--background);\n}\n\np,\nol,\nul,\ndl,\ntable,\npre {\n padding: 0;\n margin: 0 0 1rem;\n list-style-type: none;\n}\n\ndl {\n margin: 0;\n}\n\ncode,\npre {\n font-family: var(--font-family-monospaced);\n background-color: var(--code-background);\n border: 1px solid var(--border);\n border-radius: 3px;\n}\n\ncode {\n padding: 0 4px;\n line-height: 1;\n}\n\npre {\n padding: 6px 10px;\n overflow: auto;\n white-space: pre;\n}\n\npre code {\n padding: 0;\n margin: 0;\n line-height: inherit;\n border: 0;\n}\n\n.pre {\n white-space: pre-wrap;\n}\n\ntable {\n border-spacing: 0;\n border-collapse: collapse;\n}\n\ntd,\nth {\n padding: 2px 5px;\n white-space: nowrap;\n}\n\ntd.num,\nth.num {\n width: 7em;\n font-family: var(--font-family-monospaced);\n color: var(--text-color);\n text-align: right;\n}\n\nthead th,\ntfoot td {\n font-weight: 400;\n color: var(--table-header-text);\n background-color: var(--table-header-background);\n border: 1px solid var(--table-border);\n}\n\ntbody tr:nth-child(2n) {\n background-color: var(--table-background-even);\n}\n\ntbody td {\n border: 1px solid var(--table-border);\n}\n\ntable pre {\n padding: 0;\n margin: 0;\n overflow: inherit;\n background-color: inherit;\n border: 0;\n}\n\nh2,\nh3 {\n padding: 0;\n margin: 0 0.5rem 1rem 0;\n font-weight: 500;\n color: var(--heading-color);\n}\n\nh2 {\n font-size: 1.2857em;\n}\n\nh3 {\n font-size: 1.1429em;\n}\n\nh4,\nh5 {\n margin: 0;\n font-size: 1em;\n font-weight: 500;\n}\n\nhr {\n padding: 0;\n margin: 0;\n border: 1px solid var(--border);\n}\n\nb,\nstrong {\n font-weight: 500;\n}\n\na {\n text-decoration: none;\n}\n\na:link,\na:visited {\n color: var(--link-color);\n}\n\na:hover,\na:focus-visible {\n color: var(--link-hover-color);\n}\n\na:active,\na:focus,\na img {\n outline: none;\n border: 0;\n}\n\na:focus-visible {\n outline: var(--link-color) dotted 2px;\n}\n\nbutton,\ninput,\ntextarea {\n font: inherit;\n color: var(--text-color);\n}\n\ninput,\ntextarea {\n padding: var(--input-padding, 6px 10px);\n background: var(--placeholder-background);\n border: var(--input-border, 1px solid var(--border-darker));\n}\n\nlabel {\n cursor: pointer;\n}\n\nselect {\n font-size: inherit;\n}\n\ninput:invalid {\n outline: none;\n border: 1px solid var(--error);\n box-shadow: none;\n}\n\ninput[type=\"text\"]::-webkit-calendar-picker-indicator {\n display: none;\n}\n\ninput[type=\"date\"]::-webkit-inner-spin-button,\ninput[type=\"date\"]::-webkit-clear-button {\n display: none;\n appearance: none;\n}\n\ninput[type=\"text\"]::placeholder {\n color: var(--placeholder-color);\n opacity: 1;\n}\n\ninput[type=\"text\"]::placeholder:focus {\n color: var(--placeholder-color);\n}\n\ninput[type=\"text\"]:placeholder-shown {\n background-color: var(--placeholder-background);\n}\n\nbutton,\n.button {\n padding: 0.5em 0.75em;\n color: var(--button-color);\n cursor: pointer;\n outline: 0;\n background-color: var(--button-background);\n border: 0;\n border-radius: 0;\n}\n\nbutton:disabled {\n cursor: not-allowed;\n}\n\n.button {\n display: inline-block;\n}\n\nh3 .button,\nh3 button {\n font-size: 1rem;\n font-weight: normal;\n}\n\na.button {\n display: inline-block;\n padding: 2px 6px;\n}\n\nbutton:focus,\nbutton:active,\nbutton:hover,\n.button:focus,\n.button:active,\n.button:hover {\n box-shadow: var(--box-shadow-button);\n filter: brightness(90%);\n}\n\nbutton.unset {\n padding: 0;\n color: inherit;\n text-align: left;\n background: unset;\n}\n\nbutton.unset:active,\nbutton.unset:focus,\nbutton.unset:hover {\n box-shadow: unset;\n}\n\nbutton.unset:focus-visible {\n outline: var(--link-color) dotted 2px;\n}\n\nbutton:disabled,\nbutton.inactive,\nbutton.muted,\n.button:disabled,\n.button.inactive,\n.button.muted {\n color: var(--button-muted-color);\n background-color: var(--button-muted-background);\n}\n\nbutton.link,\n.button.link {\n padding: 0;\n color: var(--link-color);\n background: unset;\n}\n\nbutton.link:focus,\nbutton.link:active,\nbutton.link:hover,\n.button.link:focus,\n.button.link:active,\n.button.link:hover {\n box-shadow: unset;\n filter: brightness(90%);\n}\n\nbutton.round,\n.button.round {\n height: 1.5em;\n padding: 0 0.5em;\n border-radius: 15px;\n}\n\n.button:visited {\n height: 100%;\n color: var(--background);\n}\n\n/* Structural and generic elements */\n:root {\n --transitions: all 0.2s ease-out;\n}\n\n.dragover {\n background-color: var(--dragover-background);\n\n * {\n /* Avoid drag events firing on child elements */\n pointer-events: none;\n }\n}\n\n.headerline {\n display: flex;\n flex-wrap: wrap;\n margin: 0 0 1em;\n}\n\n.headerline h3 {\n margin: 0 1.5em 0 0;\n}\n\nkbd {\n display: inline-block;\n padding: 3px 6px;\n margin: 0 1px;\n font: 0.8em var(--font-family-monospaced);\n color: var(--text-color-lighter);\n background-color: var(--background);\n border: solid 1px var(--border);\n border-bottom-color: var(--border-darker);\n border-radius: 3px;\n box-shadow: var(--box-shadow-kbd);\n}\n\n.keyboard-tooltip {\n position: absolute;\n z-index: var(--z-index-keyboard-overlays);\n display: inline-block;\n padding: 0.3em 0.5em;\n font-size: 0.9em;\n color: var(--background);\n text-align: center;\n background-color: var(--text-color);\n opacity: 0.9;\n}\n\n.dimmed {\n opacity: 0.8;\n}\n\n/*\n * Components\n */\n\n.spacer {\n flex-grow: 1;\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n padding: 5px;\n margin: -10px -20px;\n}\n\n.column {\n flex: 1;\n margin: 5px;\n}\n\n.column h3 {\n text-align: center;\n}\n\n.left {\n float: left;\n margin-right: 20px;\n}\n\n.right {\n float: right;\n}\n\n.deprecation-notice {\n border: 1px solid var(--error);\n}\n\ncopyable-text {\n cursor: pointer;\n}\n\n.status-indicator {\n display: inline-block;\n width: 6px;\n height: 6px;\n margin: 5px;\n border-radius: 6px;\n}\n\ntd .status-indicator {\n float: right;\n margin: 7px 0 0;\n}\n\n.status-indicator.status-red {\n background-color: var(--red);\n}\n\n.status-indicator.status-yellow {\n background-color: var(--yellow);\n}\n\n.status-indicator.status-green {\n background-color: var(--green);\n}\n\n.status-indicator.status-gray {\n background-color: var(--gray);\n}\n\n.indicator-header {\n padding-left: 0;\n}\n\n[data-sort] {\n position: relative;\n padding-right: 18px;\n cursor: pointer;\n}\n\n[data-order=\"desc\"]::after {\n position: absolute;\n top: 12px;\n right: 4px;\n display: block;\n content: \"\";\n border-top: 5px solid var(--text-color-lightest);\n border-right: 5px solid transparent;\n border-left: 5px solid transparent;\n}\n\n[data-order=\"asc\"]::after {\n position: absolute;\n top: 10px;\n right: 4px;\n display: block;\n content: \"\";\n border-right: 5px solid transparent;\n border-bottom: 5px solid var(--text-color-lightest);\n border-left: 5px solid transparent;\n}\n", "/*\nThere are three main layout components.\n\nThe header (<header>), the left sidebar (<aside>) and the main content (<article>).\nIn the HTML markup, they are all direct children of the <body>.\n\nThese elements are arranged as follows:\n\n header\n ------------\n aside | main\n\nOn mobile at resolutions smaller than 768px, we hide the aside menu,\nhaving it slide in from the left side. This means that iPads and larger will show the side menu.\n\nFor most reports, we want the header to scroll on mobile but for some\nlike the editor we need to have a fixed size filling the whole screen.\nFor those reports, the .fixed-fullsize-container be used.\n*/\n\n:root {\n --aside-width: 160px;\n}\n\nbody {\n display: grid;\n grid:\n \"header header\" auto\n \"aside main\" 1fr\n /\n var(--aside-width) 1fr;\n width: 100vw;\n height: 100vh;\n padding: 0;\n}\n\nheader {\n display: flex;\n flex-wrap: wrap;\n grid-area: header;\n gap: 0.5em;\n align-items: center;\n padding: 0.5em;\n color: var(--header-color);\n background-color: var(--header-background);\n}\n\narticle {\n position: relative;\n grid-area: main;\n padding: 1.5em;\n overflow-x: auto;\n}\n\narticle:has(> .fixed-fullsize-container) {\n padding: 0;\n}\n\n.fixed-fullsize-container {\n width: 100%;\n max-width: 100vw;\n height: 100%;\n max-height: 100vh;\n}\n\n@media (width <= 767px) {\n article {\n padding: 1em;\n }\n\n body {\n display: block;\n font-size: 16px;\n transition: var(--transitions);\n }\n\n body:has(> article > .fixed-fullsize-container) {\n display: grid;\n grid-template: \"header\" max-content \"main\" 1fr;\n }\n\n header {\n padding-left: 50px;\n }\n}\n\n@media print {\n body {\n grid-template: \"header\" max-content \"main\" 1fr;\n }\n}\n", "svg text {\n font-family: var(--font-family);\n fill: var(--text-color-lightest);\n}\n\n.tooltip {\n position: absolute;\n z-index: var(--z-index-floating-ui);\n min-width: 5em;\n padding: 0.5em;\n font-family: var(--font-family-monospaced);\n text-align: center;\n pointer-events: none;\n background: var(--background);\n border: 1px solid var(--border);\n box-shadow: var(--box-shadow-button);\n opacity: 0;\n transform: translate(-50%, -100%);\n}\n\n.tooltip::before {\n position: absolute;\n top: 100%;\n left: 50%;\n width: 0;\n height: 0;\n margin-left: -15px;\n content: \"\";\n border: 15px solid transparent;\n border-top-color: var(--border);\n}\n\n.tooltip em {\n display: block;\n margin-top: 5px;\n font-family: var(--font-family);\n color: var(--text-color-lightest);\n}\n", "svelte-component.error {\n display: block;\n padding: 0.5em;\n margin: 0.5em;\n color: var(--error);\n border: 1px solid var(--error);\n}\n\ndetails {\n display: block;\n min-width: 400px;\n margin-bottom: 0.5em;\n border: 1px solid var(--table-border);\n}\n\ndetails.inactive {\n opacity: 0.5;\n}\n\ndetails summary {\n position: relative;\n display: flex;\n gap: 0.5em;\n align-items: center;\n padding: 0.25em 0.5em 0.25em 30px;\n cursor: pointer;\n background-color: var(--summary-background);\n}\n\ndetails summary::before {\n position: absolute;\n top: 50%;\n left: 10px;\n margin-right: 0.5em;\n content: \"\";\n border-top: 9px solid var(--treetable-expander);\n border-right: 6px solid transparent;\n border-left: 6px solid transparent;\n transform: translateY(-50%) rotate(270deg);\n}\n\ndetails summary::-webkit-details-marker {\n display: none;\n}\n\ndetails.error summary {\n background-color: var(--error);\n}\n\ndetails[open] summary::before {\n transform: translateY(-50%) rotate(0deg);\n}\n\ndetails summary pre {\n display: inline-block;\n padding: 3px 6px;\n margin: 0;\n}\n\ndetails > div {\n padding: 0.5em;\n}\n", "/* Editor */\n\n.cm-editor .cm-gutters {\n background: var(--sidebar-background);\n border-right: 1px solid var(--sidebar-border);\n}\n\n.cm-editor .cm-scroller {\n font-family: var(--font-family-editor);\n}\n\n.cm-editor .cm-placeholder {\n color: var(--placeholder-color);\n}\n\n.cm-editor .cm-tooltip {\n background-color: var(--sidebar-border);\n}\n\n/* stylelint-disable selector-class-pattern */\n.cm-editor .cm-activeLine {\n background-color: var(--editor-activeline);\n}\n\n.cm-editor .cm-selectionBackground {\n background-color: var(--editor-activeline);\n}\n\n.cm-editor.cm-focused\n > .cm-scroller\n > .cm-selectionLayer\n .cm-selectionBackground {\n background-color: var(--editor-activeline);\n}\n\n.cm-editor .cm-selectionMatch {\n background-color: var(--editor-selectionmatch);\n}\n\n.cm-editor .cm-cursor {\n border-left-color: var(--text-color-lighter);\n}\n/* stylelint-enable selector-class-pattern */\n", ":root {\n --flex-gap: 0.5rem;\n}\n\n.flex-column {\n display: flex;\n flex-direction: column;\n gap: var(--flex-gap);\n\n > h3 {\n margin: 0;\n }\n}\n\n.flex-row {\n display: flex;\n flex-wrap: wrap;\n gap: var(--flex-gap);\n align-items: center;\n\n > h3 {\n margin: 0;\n }\n\n > label {\n display: contents;\n }\n\n @media (hover: hover) and (width > 767px) {\n .remove-row {\n opacity: 0;\n }\n }\n\n &:hover .remove-row {\n opacity: 1;\n }\n}\n", "/* source-code-pro-cyrillic-ext-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-cyrillic-ext-400-normal.woff2) format('woff2'), url(./files/source-code-pro-cyrillic-ext-400-normal.woff) format('woff');\n unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;\n}\n\n/* source-code-pro-cyrillic-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-cyrillic-400-normal.woff2) format('woff2'), url(./files/source-code-pro-cyrillic-400-normal.woff) format('woff');\n unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;\n}\n\n/* source-code-pro-greek-ext-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-greek-ext-400-normal.woff2) format('woff2'), url(./files/source-code-pro-greek-ext-400-normal.woff) format('woff');\n unicode-range: U+1F00-1FFF;\n}\n\n/* source-code-pro-greek-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-greek-400-normal.woff2) format('woff2'), url(./files/source-code-pro-greek-400-normal.woff) format('woff');\n unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;\n}\n\n/* source-code-pro-vietnamese-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-vietnamese-400-normal.woff2) format('woff2'), url(./files/source-code-pro-vietnamese-400-normal.woff) format('woff');\n unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;\n}\n\n/* source-code-pro-latin-ext-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-latin-ext-400-normal.woff2) format('woff2'), url(./files/source-code-pro-latin-ext-400-normal.woff) format('woff');\n unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;\n}\n\n/* source-code-pro-latin-400-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/source-code-pro-latin-400-normal.woff2) format('woff2'), url(./files/source-code-pro-latin-400-normal.woff) format('woff');\n unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;\n}", "/* source-code-pro-cyrillic-ext-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-cyrillic-ext-500-normal.woff2) format('woff2'), url(./files/source-code-pro-cyrillic-ext-500-normal.woff) format('woff');\n unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;\n}\n\n/* source-code-pro-cyrillic-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-cyrillic-500-normal.woff2) format('woff2'), url(./files/source-code-pro-cyrillic-500-normal.woff) format('woff');\n unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;\n}\n\n/* source-code-pro-greek-ext-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-greek-ext-500-normal.woff2) format('woff2'), url(./files/source-code-pro-greek-ext-500-normal.woff) format('woff');\n unicode-range: U+1F00-1FFF;\n}\n\n/* source-code-pro-greek-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-greek-500-normal.woff2) format('woff2'), url(./files/source-code-pro-greek-500-normal.woff) format('woff');\n unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;\n}\n\n/* source-code-pro-vietnamese-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-vietnamese-500-normal.woff2) format('woff2'), url(./files/source-code-pro-vietnamese-500-normal.woff) format('woff');\n unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;\n}\n\n/* source-code-pro-latin-ext-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-latin-ext-500-normal.woff2) format('woff2'), url(./files/source-code-pro-latin-ext-500-normal.woff) format('woff');\n unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;\n}\n\n/* source-code-pro-latin-500-normal */\n@font-face {\n font-family: 'Source Code Pro';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/source-code-pro-latin-500-normal.woff2) format('woff2'), url(./files/source-code-pro-latin-500-normal.woff) format('woff');\n unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;\n}", "/* fira-mono-cyrillic-ext-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-cyrillic-ext-400-normal.woff2) format('woff2'), url(./files/fira-mono-cyrillic-ext-400-normal.woff) format('woff');\n unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;\n}\n\n/* fira-mono-cyrillic-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-cyrillic-400-normal.woff2) format('woff2'), url(./files/fira-mono-cyrillic-400-normal.woff) format('woff');\n unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;\n}\n\n/* fira-mono-greek-ext-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-greek-ext-400-normal.woff2) format('woff2'), url(./files/fira-mono-greek-ext-400-normal.woff) format('woff');\n unicode-range: U+1F00-1FFF;\n}\n\n/* fira-mono-greek-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-greek-400-normal.woff2) format('woff2'), url(./files/fira-mono-greek-400-normal.woff) format('woff');\n unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;\n}\n\n/* fira-mono-symbols2-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-symbols2-400-normal.woff2) format('woff2'), url(./files/fira-mono-symbols2-400-normal.woff) format('woff');\n unicode-range: U+2000-2001,U+2004-2008,U+200A,U+23B8-23BD,U+2500-259F;\n}\n\n/* fira-mono-latin-ext-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-latin-ext-400-normal.woff2) format('woff2'), url(./files/fira-mono-latin-ext-400-normal.woff) format('woff');\n unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;\n}\n\n/* fira-mono-latin-400-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-mono-latin-400-normal.woff2) format('woff2'), url(./files/fira-mono-latin-400-normal.woff) format('woff');\n unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;\n}", "/* fira-mono-cyrillic-ext-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-cyrillic-ext-500-normal.woff2) format('woff2'), url(./files/fira-mono-cyrillic-ext-500-normal.woff) format('woff');\n unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;\n}\n\n/* fira-mono-cyrillic-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-cyrillic-500-normal.woff2) format('woff2'), url(./files/fira-mono-cyrillic-500-normal.woff) format('woff');\n unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;\n}\n\n/* fira-mono-greek-ext-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-greek-ext-500-normal.woff2) format('woff2'), url(./files/fira-mono-greek-ext-500-normal.woff) format('woff');\n unicode-range: U+1F00-1FFF;\n}\n\n/* fira-mono-greek-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-greek-500-normal.woff2) format('woff2'), url(./files/fira-mono-greek-500-normal.woff) format('woff');\n unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;\n}\n\n/* fira-mono-symbols2-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-symbols2-500-normal.woff2) format('woff2'), url(./files/fira-mono-symbols2-500-normal.woff) format('woff');\n unicode-range: U+2000-2001,U+2004-2008,U+200A,U+23B8-23BD,U+2500-259F;\n}\n\n/* fira-mono-latin-ext-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-latin-ext-500-normal.woff2) format('woff2'), url(./files/fira-mono-latin-ext-500-normal.woff) format('woff');\n unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;\n}\n\n/* fira-mono-latin-500-normal */\n@font-face {\n font-family: 'Fira Mono';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-mono-latin-500-normal.woff2) format('woff2'), url(./files/fira-mono-latin-500-normal.woff) format('woff');\n unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;\n}", "/* fira-sans-cyrillic-ext-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-cyrillic-ext-400-normal.woff2) format('woff2'), url(./files/fira-sans-cyrillic-ext-400-normal.woff) format('woff');\n unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;\n}\n\n/* fira-sans-cyrillic-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-cyrillic-400-normal.woff2) format('woff2'), url(./files/fira-sans-cyrillic-400-normal.woff) format('woff');\n unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;\n}\n\n/* fira-sans-greek-ext-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-greek-ext-400-normal.woff2) format('woff2'), url(./files/fira-sans-greek-ext-400-normal.woff) format('woff');\n unicode-range: U+1F00-1FFF;\n}\n\n/* fira-sans-greek-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-greek-400-normal.woff2) format('woff2'), url(./files/fira-sans-greek-400-normal.woff) format('woff');\n unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;\n}\n\n/* fira-sans-vietnamese-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-vietnamese-400-normal.woff2) format('woff2'), url(./files/fira-sans-vietnamese-400-normal.woff) format('woff');\n unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;\n}\n\n/* fira-sans-latin-ext-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-latin-ext-400-normal.woff2) format('woff2'), url(./files/fira-sans-latin-ext-400-normal.woff) format('woff');\n unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;\n}\n\n/* fira-sans-latin-400-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 400;\n src: url(./files/fira-sans-latin-400-normal.woff2) format('woff2'), url(./files/fira-sans-latin-400-normal.woff) format('woff');\n unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;\n}", "/* fira-sans-cyrillic-ext-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-cyrillic-ext-500-normal.woff2) format('woff2'), url(./files/fira-sans-cyrillic-ext-500-normal.woff) format('woff');\n unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;\n}\n\n/* fira-sans-cyrillic-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-cyrillic-500-normal.woff2) format('woff2'), url(./files/fira-sans-cyrillic-500-normal.woff) format('woff');\n unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;\n}\n\n/* fira-sans-greek-ext-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-greek-ext-500-normal.woff2) format('woff2'), url(./files/fira-sans-greek-ext-500-normal.woff) format('woff');\n unicode-range: U+1F00-1FFF;\n}\n\n/* fira-sans-greek-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-greek-500-normal.woff2) format('woff2'), url(./files/fira-sans-greek-500-normal.woff) format('woff');\n unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;\n}\n\n/* fira-sans-vietnamese-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-vietnamese-500-normal.woff2) format('woff2'), url(./files/fira-sans-vietnamese-500-normal.woff) format('woff');\n unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;\n}\n\n/* fira-sans-latin-ext-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-latin-ext-500-normal.woff2) format('woff2'), url(./files/fira-sans-latin-ext-500-normal.woff) format('woff');\n unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;\n}\n\n/* fira-sans-latin-500-normal */\n@font-face {\n font-family: 'Fira Sans';\n font-style: normal;\n font-display: swap;\n font-weight: 500;\n src: url(./files/fira-sans-latin-500-normal.woff2) format('woff2'), url(./files/fira-sans-latin-500-normal.woff) format('woff');\n unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;\n}", "/* Help Pages */\n\n.help {\n --help-max-width: 600px;\n\n max-width: calc(var(--help-max-width) + 160px);\n}\n\n.help-text {\n max-width: var(--help-max-width);\n font-size: 16px;\n}\n\n.help-text .cm-editor {\n font-size: 14px;\n}\n\n.help-text h1 {\n margin: 0 0 1rem;\n font-weight: 500;\n}\n\n.help-text > div {\n margin-bottom: 1em;\n}\n\n.help-text code {\n font-size: 0.9em;\n}\n\n.help-text ul {\n padding-left: 2em;\n}\n\n.help-text li {\n list-style-type: disc;\n}\n\n.help-sidebar {\n float: right;\n padding: 10px 10px 0;\n margin: 0 0 10px 10px;\n font-size: 1.1em;\n background-color: var(--help-sidebar-background);\n border: 1px solid var(--help-sidebar-border);\n}\n\n.help-sidebar a:hover,\n.help-sidebar a.selected {\n font-weight: 500;\n}\n", "/* stylelint-disable no-descending-specificity */\n\n.flex-table {\n p,\n li,\n ul,\n ol {\n padding: 0;\n margin: 0;\n }\n\n p {\n display: flex;\n\n > * {\n flex-shrink: 0;\n padding: 2px 4px;\n }\n }\n\n .num {\n font-family: var(--font-family-monospaced);\n text-align: right;\n }\n\n .head p > * {\n padding: 3px 4px;\n font-family: inherit;\n color: var(--table-header-text);\n background-color: var(--table-header-background);\n }\n}\n\n.journal {\n /* display flex seems to improve performance in Firefox. */\n display: flex;\n flex-direction: column;\n\n p,\n dl {\n border-bottom: thin solid var(--table-border);\n }\n\n > li,\n &.show-custom .custom.budget,\n &.show-document .document.discovered,\n &.show-document .document.linked,\n .metadata,\n .postings {\n display: none;\n }\n\n & .head,\n &.show-balance .balance,\n &.show-close .close,\n &.show-custom .custom,\n &.show-document .document,\n &.show-note .note,\n &.show-open .open,\n &.show-pad .pad,\n &.show-query .query {\n display: block;\n }\n\n /* Show metadata and postings if it was toggled for the whole journal. */\n &.show-postings .postings,\n &.show-metadata .metadata {\n display: block;\n }\n\n /* Show metadata and postings where it was explicitly toggled with the indicators. */\n li.show-full-entry .postings,\n li.show-full-entry .metadata {\n display: block;\n }\n\n &.show-transaction.show-cleared .transaction.cleared,\n &.show-transaction.show-pending .transaction.pending,\n &.show-transaction.show-other .transaction.other,\n &.show-document.show-discovered .document.discovered,\n &.show-document.show-linked .document.linked,\n &.show-custom.show-budget .custom.budget {\n display: block;\n }\n\n .payee {\n cursor: pointer;\n }\n\n .postings {\n font-size: 0.9em;\n background-color: var(--journal-postings);\n opacity: 0.8;\n\n .num {\n overflow: auto;\n line-height: 1rem;\n }\n }\n\n .transaction:hover {\n background: var(--journal-hover-highlight);\n }\n\n /* Metadata */\n .metadata {\n font-size: 0.9em;\n\n dt {\n float: left;\n width: auto;\n min-width: 4rem;\n padding: 2px 3px;\n margin-left: 9rem;\n color: var(--journal-metadata);\n cursor: pointer;\n }\n\n dd {\n padding: 2px 3px;\n margin-left: 15rem;\n cursor: pointer;\n }\n }\n\n /* There's three number columns (units, cost, price).\n * They should add about to about half of the width */\n p > .num {\n width: min(calc(15%), 20rem);\n border-left: 1px solid var(--table-border);\n }\n\n .datecell,\n .flag {\n text-align: center;\n background-color: var(--entry-background);\n }\n\n .datecell {\n width: 6rem;\n white-space: nowrap;\n }\n\n .flag {\n width: 3rem;\n }\n\n .change {\n font-weight: 500;\n }\n\n .description {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n .separator::before {\n padding: 2px;\n margin: 0 6px;\n font-weight: bold;\n color: var(--text-color-lighter);\n content: \"\u2022\";\n }\n\n .num {\n margin: 0 5px;\n }\n }\n\n .show-postings .description {\n white-space: normal;\n }\n\n .tag,\n .link {\n margin-left: 8px;\n font-size: 0.9em;\n cursor: pointer;\n }\n\n .tag {\n color: var(--journal-tag);\n }\n\n .link {\n color: var(--journal-link);\n }\n\n .bal {\n background-color: var(--entry-background);\n }\n\n a:hover {\n filter: brightness(80%);\n }\n\n .filename,\n .url {\n font-family: var(--font-family-monospaced);\n font-size: 0.9em;\n }\n\n .document .filename {\n margin-left: 1em;\n }\n\n .indicators {\n display: flex;\n flex-shrink: 3;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n cursor: pointer;\n\n span {\n min-width: 6px;\n height: 6px;\n padding: 0;\n margin-right: 4px;\n background-color: var(--journal-posting-indicator);\n border-radius: 3px;\n }\n\n .pending,\n .other {\n background-color: var(--entry-background);\n }\n\n .metadata-indicator {\n height: 16px;\n padding: 0 6px;\n font-size: 10px;\n line-height: 16px;\n color: var(--journal-metadata-indicator);\n text-transform: lowercase;\n border-radius: 20px;\n }\n }\n}\n\n@media (width <= 767px) {\n .journal {\n p {\n flex-wrap: wrap;\n }\n\n /* show a colored top border for all entries */\n > li {\n border-top: thin solid var(--entry-background);\n }\n\n .head .flag {\n flex-grow: 1;\n text-align: left;\n }\n\n .description {\n flex: inherit;\n order: 1; /* push to second row */\n width: 100%;\n }\n\n .indicators {\n flex-grow: 1;\n }\n\n .balance .num {\n width: 35%;\n }\n\n .balance .change.num {\n display: none;\n }\n\n .postings .datecell,\n .postings .flag {\n display: none;\n }\n\n .postings .description {\n flex-grow: 1;\n order: inherit;\n width: inherit;\n }\n\n .metadata dt,\n .metadata dd {\n margin-left: initial;\n }\n }\n}\n", "/* Notifications */\n.notifications {\n position: fixed;\n top: 60px;\n right: 10px;\n width: 400px;\n}\n\n.notifications li {\n display: block;\n width: 100%;\n padding: 5px 10px;\n margin-bottom: 0.5em;\n color: var(--notification-color);\n white-space: pre-wrap;\n cursor: pointer;\n background-color: var(--green);\n}\n\n.notifications .error {\n background-color: var(--error);\n}\n\n.notifications .warning {\n color: var(--dark-gray);\n background-color: var(--yellow);\n}\n", "/* Collapsible trees\n *\n * some of the shared styles are in `journal-table.css`.\n *\n * The styles for .tree-table are not used in Fava anymore but are again provided\n * for extensions for the near future.\n */\n\n.tree-table-new p {\n margin-top: -1px;\n}\n\n.tree-table-new p > span {\n margin-right: -1px;\n border: 1px solid var(--table-border);\n}\n\n.tree-table-new .num {\n /** Space for about 14 characters, so a number like 1234512345.123 fits. */\n width: 9em;\n}\n\n.tree-table-new .other {\n /** Space for about 18 (four more) characters, so an amount like 1234512345.123 USD fits. */\n width: 12em;\n}\n\n.tree-table.fullwidth {\n display: block;\n max-width: 100%;\n overflow-x: auto;\n}\n\n.tree-table p {\n margin-top: -1px;\n}\n\n.tree-table p > span {\n margin-right: -1px;\n border: 1px solid var(--table-border);\n}\n\n.tree-table .account-cell {\n display: flex;\n flex: 1;\n align-items: center;\n min-width: 14em;\n max-width: 30em;\n}\n\n.tree-table .account-cell.depth-1 {\n min-width: 13em;\n max-width: 29em;\n margin-left: 1em;\n}\n\n.tree-table .account-cell.depth-2 {\n min-width: 12em;\n max-width: 28em;\n margin-left: 2em;\n}\n\n.tree-table .account-cell.depth-3 {\n min-width: 11em;\n max-width: 27em;\n margin-left: 3em;\n}\n\n.tree-table .account-cell.depth-4 {\n min-width: 10em;\n max-width: 26em;\n margin-left: 4em;\n}\n\n.tree-table .account-cell.depth-5 {\n min-width: 9em;\n max-width: 25em;\n margin-left: 5em;\n}\n\n.tree-table .account-cell.depth-6 {\n min-width: 8em;\n max-width: 24em;\n margin-left: 6em;\n}\n\n.tree-table .account-cell.depth-7 {\n min-width: 7em;\n max-width: 23em;\n margin-left: 7em;\n}\n\n.tree-table .account-cell.depth-8 {\n min-width: 6em;\n max-width: 22em;\n margin-left: 8em;\n}\n\n.tree-table .account-cell.depth-9 {\n min-width: 5em;\n max-width: 21em;\n margin-left: 9em;\n}\n\n.tree-table .account-cell a {\n margin-left: 1em;\n}\n\n.tree-table .has-children {\n cursor: pointer;\n}\n\n.tree-table .has-children::before {\n margin: 0 -10px 0 0;\n content: \"\";\n border-top: 5px solid var(--treetable-expander);\n border-right: 5px solid transparent;\n border-left: 5px solid transparent;\n}\n\n.tree-table .num {\n width: 10em;\n}\n\n.tree-table .num a {\n display: block;\n color: inherit;\n}\n\n.tree-table .other {\n width: 13em;\n}\n\n.tree-table .other a {\n display: block;\n color: inherit;\n}\n\n.tree-table .balance-children {\n display: block;\n opacity: 0.7;\n}\n\n.tree-table .has-balance .balance {\n display: block;\n}\n\n.tree-table .has-balance .balance-children {\n display: none;\n}\n\n.tree-table .toggled ol {\n display: none;\n}\n\n.tree-table .toggled .balance {\n display: none;\n}\n\n.tree-table .toggled .balance-children {\n display: block;\n color: var(--text-color);\n}\n\n.tree-table .toggled .has-children::before {\n transform: rotate(270deg);\n}\n\n.tree-table .expand-all {\n margin-left: 15px;\n font-weight: normal;\n color: inherit;\n opacity: 0.5;\n}\n\n.tree-table .diff {\n margin-right: 3px;\n font-size: 0.9em;\n white-space: nowrap;\n}\n\n.tree-table .diff.negative {\n color: var(--diff-negative);\n}\n\n.tree-table .diff.positive {\n color: var(--diff-positive);\n}\n\n/* For two or more operating currencies, set a slightly smaller size. */\n.two-currencies {\n font-size: 0.9em;\n}\n\n.two-currencies .num {\n width: 8em;\n}\n\n.two-currencies .other {\n width: 11em;\n}\n", "<script lang=\"ts\">\n import { errorWithCauses } from \"../lib/errors.ts\";\n\n interface Props {\n title: string;\n error: Error;\n }\n\n let { title, error }: Props = $props();\n</script>\n\n<h2>Loading {title} failed with error:</h2>\n\n<pre>{errorWithCauses(error)}</pre>\n\n<style>\n pre {\n color: var(--error);\n }\n</style>\n", "<script lang=\"ts\">\n import type { Axis } from \"d3-axis\";\n import type { NumberValue } from \"d3-scale\";\n import { select } from \"d3-selection\";\n\n type Ax = Axis<string> | Axis<NumberValue>;\n\n interface Props {\n /** The d3 axis to use. */\n axis: Ax;\n /** True if this is an x axis. */\n x?: boolean;\n /** True if this is a y axis. */\n y?: boolean;\n /** Show a pronounced line at zero (for y axis). */\n lineAtZero?: number;\n /** Height of the chart (needed for the correct offset of an x axis) */\n innerHeight?: number;\n }\n\n let {\n axis,\n x = false,\n y = false,\n lineAtZero,\n innerHeight = 0,\n }: Props = $props();\n\n let transform = $derived(\n x ? `translate(0,${innerHeight.toString()})` : undefined,\n );\n</script>\n\n<g\n class:y\n {transform}\n {@attach (node: SVGGElement) => {\n const selection = select(node);\n\n $effect(() => {\n axis(selection);\n });\n }}\n>\n {#if y && lineAtZero != null}\n <g class=\"zero\" transform={`translate(0,${lineAtZero.toString()})`}>\n <line x2={-axis.tickSizeInner()} />\n </g>\n {/if}\n</g>\n\n<style>\n g :global(path),\n g :global(line) {\n fill: none;\n stroke: var(--chart-axis);\n shape-rendering: crispedges;\n }\n\n g.y :global(line),\n g.y :global(path.domain) {\n opacity: 0.2;\n }\n\n g.y .zero line {\n opacity: 1;\n stroke: var(--chart-line-at-zero);\n }\n</style>\n", "<script lang=\"ts\">\n import { extent } from \"d3-array\";\n import { axisBottom, axisLeft } from \"d3-axis\";\n import { scaleBand, scaleLinear, scaleOrdinal } from \"d3-scale\";\n\n import { urlForAccount } from \"../helpers.ts\";\n import { barChartMode, chartToggledCurrencies } from \"../stores/chart.ts\";\n import { ctx, currentTimeFilterDateFormat, short } from \"../stores/format.ts\";\n import Axis from \"./Axis.svelte\";\n import type { BarChart } from \"./bar.ts\";\n import {\n currenciesScale,\n filterTicks,\n hclColorRange,\n includeZero,\n padExtent,\n urlForTimeFilter,\n } from \"./helpers.ts\";\n import { followingTooltip } from \"./tooltip.ts\";\n\n interface Props {\n chart: BarChart;\n width: number;\n }\n\n let { chart, width }: Props = $props();\n\n const today = new Date();\n const maxColumnWidth = 100;\n const margin = { top: 10, right: 10, bottom: 30, left: 40 };\n const height = 250;\n\n let accounts = $derived(chart.accounts);\n\n let filtered = $derived(chart.filter($chartToggledCurrencies));\n let currencies = $derived(filtered.currencies);\n let bar_groups = $derived(filtered.bar_groups);\n let stacks = $derived(filtered.stacks);\n\n let innerHeight = $derived(height - margin.top - margin.bottom);\n let maxWidth = $derived(bar_groups.length * maxColumnWidth);\n let offset = $derived(margin.left + Math.max(0, width - maxWidth) / 2);\n let innerWidth = $derived(\n Math.min(width - margin.left - margin.right, maxWidth),\n );\n\n /** Whether to display stacked bars. */\n let showStackedBars = $derived(\n $barChartMode === \"stacked\" && chart.hasStackedData,\n );\n /** The currently hovered account. */\n let highlighted: string | null = $state(null);\n\n // Scales\n let x0 = $derived(\n scaleBand([0, innerWidth])\n .domain(bar_groups.map((d) => d.label))\n .padding(0.1),\n );\n let x1 = $derived(scaleBand([0, x0.bandwidth()]).domain(currencies));\n\n let yExtent = $derived(\n showStackedBars\n ? extent(stacks.flatMap(([, s]) => s.flat(2)))\n : extent(\n bar_groups.flatMap((d) => d.values),\n (d) => d.value,\n ),\n );\n let y = $derived(\n scaleLinear([innerHeight, 0]).domain(padExtent(includeZero(yExtent))),\n );\n\n let colorScale = $derived(\n scaleOrdinal(hclColorRange(accounts.length)).domain(accounts),\n );\n\n // Axes\n let xAxis = $derived(\n axisBottom(x0)\n .tickSizeOuter(0)\n .tickValues(filterTicks(x0.domain(), innerWidth / 70)),\n );\n let yAxis = $derived(\n axisLeft(y).tickPadding(6).tickSize(-innerWidth).tickFormat($short),\n );\n</script>\n\n<svg viewBox={`0 0 ${width.toString()} ${height.toString()}`}>\n <g transform={`translate(${offset.toString()},${margin.top.toString()})`}>\n <Axis x axis={xAxis} {innerHeight} />\n <Axis y axis={yAxis} lineAtZero={y(0)} />\n {#each bar_groups as group (group.date)}\n <g\n class=\"group\"\n class:desaturate={group.date > today}\n {@attach followingTooltip(() => chart.tooltipText($ctx, group))}\n transform={`translate(${(x0(group.label) ?? 0).toString()},0)`}\n >\n <rect\n class=\"group-box\"\n x={(x0.bandwidth() - x0.step()) / 2}\n width={x0.step()}\n height={innerHeight}\n />\n <a\n href={urlForTimeFilter(group.date)}\n aria-label={$currentTimeFilterDateFormat(group.date)}\n >\n <rect\n class=\"axis-group-box\"\n transform={`translate(0,${innerHeight.toString()})`}\n width={x0.bandwidth()}\n height={margin.bottom}\n />\n </a>\n {#if !showStackedBars}\n {#each group.values as { currency, value, budget } (currency)}\n <rect\n fill={$currenciesScale(currency)}\n width={x1.bandwidth()}\n x={x1(currency)}\n y={y(Math.max(0, value))}\n height={Math.abs(y(value) - y(0))}\n />\n <rect\n class=\"budget\"\n width={x1.bandwidth()}\n x={x1(currency)}\n y={y(Math.max(0, budget))}\n height={Math.abs(y(budget) - y(0))}\n />\n {/each}\n {/if}\n </g>\n {/each}\n {#if showStackedBars}\n {#each stacks as [currency, account_stacks] (currency)}\n {#each account_stacks as stack (stack.key)}\n {@const account = stack.key}\n <a href={$urlForAccount(account)}>\n <g\n class=\"category\"\n class:faded={highlighted != null && account !== highlighted}\n onmouseover={() => {\n highlighted = account;\n }}\n onfocus={() => {\n highlighted = account;\n }}\n onmouseout={() => {\n highlighted = null;\n }}\n onblur={() => {\n highlighted = null;\n }}\n role=\"img\"\n >\n {#each stack as bar (bar.data.date)}\n <rect\n class:desaturate={bar.data.date > today}\n width={x1.bandwidth()}\n x={(x0(bar.data.label) ?? 0) + (x1(currency) ?? 0)}\n y={y(Math.max(bar[0], bar[1]))}\n height={Math.abs(y(bar[1]) - y(bar[0]))}\n fill={colorScale(account)}\n {@attach followingTooltip(() =>\n chart.tooltipTextAccount(\n $ctx,\n bar.data,\n account,\n $chartToggledCurrencies,\n ),\n )}\n />\n {/each}\n </g>\n </a>\n {/each}\n {/each}\n {/if}\n </g>\n</svg>\n\n<style>\n .category.faded {\n opacity: 0.5;\n }\n\n .axis-group-box {\n cursor: pointer;\n opacity: 0;\n }\n\n .group-box {\n opacity: 0;\n }\n\n .group:hover .group-box {\n opacity: 0.1;\n }\n\n .budget {\n opacity: 0.3;\n }\n\n .desaturate {\n filter: saturate(50%);\n }\n</style>\n", "<script lang=\"ts\">\n import type { Writable } from \"svelte/store\";\n\n import { currenciesScale } from \"./helpers.ts\";\n\n interface Props {\n /** The chart legend to show. */\n legend: readonly string[];\n /** Whether to use currency colors. */\n color: boolean;\n /** A list of elements that are toggled. */\n toggled?: Writable<string[]>;\n /** Alternatively, a single active element, all others are toggled. */\n active?: Writable<string | null>;\n }\n\n let { legend, color, toggled, active }: Props = $props();\n</script>\n\n<div>\n {#each legend as item (item)}\n <button\n type=\"button\"\n onclick={() => {\n if (active) {\n active.set(item);\n } else if (toggled) {\n toggled.update((v) =>\n v.includes(item) ? v.filter((i) => i !== item) : [...v, item],\n );\n }\n }}\n class:inactive={active ? item !== $active : $toggled?.includes(item)}\n >\n <i style=\"background-color: {color ? $currenciesScale(item) : '#bbb'}\"\n ></i>\n <span>{item}</span>\n </button>\n {/each}\n</div>\n\n<style>\n button {\n display: contents;\n color: inherit;\n }\n\n .inactive span {\n text-decoration: line-through;\n }\n\n i {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin-left: 5px;\n border-radius: 10px;\n }\n\n .inactive i {\n filter: grayscale();\n }\n\n @media print {\n .inactive {\n display: none;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import { partition } from \"d3-hierarchy\";\n\n import { formatPercentage } from \"../format.ts\";\n import { urlForAccount } from \"../helpers.ts\";\n import { leaf } from \"../lib/account.ts\";\n import { ctx } from \"../stores/format.ts\";\n import { sunburstScale } from \"./helpers.ts\";\n import type {\n AccountHierarchyDatum,\n AccountHierarchyNode,\n } from \"./hierarchy.ts\";\n import { domHelpers, followingTooltip } from \"./tooltip.ts\";\n\n interface Props {\n data: AccountHierarchyNode;\n currency: string;\n width: number;\n height: number;\n }\n\n let { data, currency, width, height }: Props = $props();\n\n let root = $derived(partition<AccountHierarchyDatum>()(data));\n let nodes = $derived(root.descendants().filter((d) => !d.data.dummy));\n\n let current: string | null = $state(null);\n\n function tooltipText(d: AccountHierarchyNode) {\n const val = d.value ?? 0;\n const rootValue = root.value ?? 1;\n\n return [\n domHelpers.t(\n `${$ctx.amount(val, currency)} (${formatPercentage(val / rootValue)})`,\n ),\n domHelpers.em(d.data.account),\n ];\n }\n</script>\n\n<g\n {width}\n {height}\n onmouseleave={() => {\n current = null;\n }}\n role=\"img\"\n>\n {#each nodes as d (d.data.account)}\n {@const account = d.data.account}\n <g\n {@attach followingTooltip(() => tooltipText(d))}\n class:current={current != null ? current.startsWith(account) : false}\n >\n <a\n href={$urlForAccount(account)}\n aria-label={account}\n onmouseover={() => {\n current = account;\n }}\n onfocus={() => {\n current = account;\n }}\n >\n <rect\n fill-rule=\"evenodd\"\n fill={$sunburstScale(account)}\n width={width * (d.y1 - d.y0)}\n height={height * (d.x1 - d.x0)}\n role=\"img\"\n x={width * d.y0}\n y={height * d.x0}\n />\n <text\n dy=\".5em\"\n text-anchor=\"middle\"\n x={(width * (d.y1 + d.y0)) / 2}\n y={(height * (d.x1 + d.x0)) / 2}\n visibility={height * (d.x1 - d.x0) > 14 ? \"visible\" : \"hidden\"}\n >\n {leaf(account)}\n </text>\n </a>\n </g>\n {/each}\n</g>\n\n<style>\n g:focus-within > g,\n g:hover > g {\n opacity: 0.7;\n }\n\n g:focus-within > g.current,\n g:hover > g.current {\n opacity: 1;\n }\n</style>\n", "<script lang=\"ts\">\n import type { HierarchyRectangularNode } from \"d3-hierarchy\";\n import { partition } from \"d3-hierarchy\";\n import { scaleLinear, scaleSqrt } from \"d3-scale\";\n import { arc } from \"d3-shape\";\n import { untrack } from \"svelte\";\n\n import { formatPercentage } from \"../format.ts\";\n import { urlForAccount } from \"../helpers.ts\";\n import { ctx } from \"../stores/format.ts\";\n import { sunburstScale } from \"./helpers.ts\";\n import type {\n AccountHierarchyDatum,\n AccountHierarchyNode,\n } from \"./hierarchy.ts\";\n\n interface Props {\n data: AccountHierarchyNode;\n currency: string;\n width: number;\n height: number;\n }\n\n let { data, currency, width, height }: Props = $props();\n\n let radius = $derived(Math.min(width, height) / 2);\n\n let root = $derived(partition<AccountHierarchyDatum>()(data));\n let nodes = $derived(\n root.descendants().filter((d) => !d.data.dummy && d.depth > 0),\n );\n\n let current: AccountHierarchyNode | null = $state(null);\n\n $effect.pre(() => {\n // if-expression to run on each change of chart\n void data;\n untrack(() => {\n current = null;\n });\n });\n\n function balanceText(d: AccountHierarchyNode): string {\n const val = d.value ?? 0;\n const total = root.value ?? 0;\n return total\n ? `${$ctx.amount(val, currency)} (${formatPercentage(val / total)})`\n : $ctx.amount(val, currency);\n }\n\n const x = scaleLinear([0, 2 * Math.PI]);\n let y = $derived(scaleSqrt([0, radius]));\n let arcShape = $derived(\n arc<HierarchyRectangularNode<AccountHierarchyDatum>>()\n .startAngle((d) => x(d.x0))\n .endAngle((d) => x(d.x1))\n .innerRadius((d) => y(d.y0))\n .outerRadius((d) => y(d.y1)),\n );\n</script>\n\n<g\n {width}\n {height}\n transform={`translate(${(width / 2).toString()},${(height / 2).toString()})`}\n onmouseleave={() => {\n current = null;\n }}\n role=\"img\"\n>\n <circle r={radius} />\n <text class=\"account\" text-anchor=\"middle\">\n {(current ?? root).data.account}\n </text>\n <text class=\"balance\" dy=\"1.2em\" text-anchor=\"middle\">\n {balanceText(current ?? root)}\n </text>\n {#each nodes as d (d.data.account)}\n <a href={$urlForAccount(d.data.account)} aria-label={d.data.account}>\n <path\n onmouseover={() => {\n current = d;\n }}\n onfocus={() => {\n current = d;\n }}\n class:half={current && !current.data.account.startsWith(d.data.account)}\n fill-rule=\"evenodd\"\n fill={$sunburstScale(d.data.account)}\n d={arcShape(d)}\n role=\"img\"\n />\n </a>\n {/each}\n</g>\n\n<style>\n circle {\n opacity: 0;\n }\n\n .half {\n opacity: 0.5;\n }\n\n .account {\n fill: var(--text-color);\n }\n\n .balance {\n font-family: var(--font-family-monospaced);\n }\n\n path {\n cursor: pointer;\n }\n</style>\n", "<script lang=\"ts\">\n import { treemap } from \"d3-hierarchy\";\n\n import { formatPercentage } from \"../format.ts\";\n import { urlForAccount } from \"../helpers.ts\";\n import { leaf } from \"../lib/account.ts\";\n import { ctx } from \"../stores/format.ts\";\n import { treemapScale } from \"./helpers.ts\";\n import type {\n AccountHierarchyDatum,\n AccountHierarchyNode,\n } from \"./hierarchy.ts\";\n import { domHelpers, followingTooltip } from \"./tooltip.ts\";\n\n interface Props {\n data: AccountHierarchyNode;\n width: number;\n height: number;\n currency: string;\n }\n\n let { data, width, height, currency }: Props = $props();\n\n const tree = treemap<AccountHierarchyDatum>().paddingInner(2).round(true);\n let root = $derived(tree.size([width, height])(data.copy()));\n let leaves = $derived(\n root.leaves().filter((d) => d.value != null && d.value !== 0),\n );\n\n function fill(d: AccountHierarchyNode) {\n const node = d.data.dummy && d.parent ? d.parent : d;\n if (node.depth === 1 || !node.parent) {\n return $treemapScale(node.data.account);\n }\n return $treemapScale(node.parent.data.account);\n }\n\n function tooltipText(d: AccountHierarchyNode) {\n const val = d.value ?? 0;\n const rootValue = root.value ?? 1;\n\n return [\n domHelpers.t(\n `${$ctx.amount(val, currency)} (${formatPercentage(val / rootValue)})`,\n ),\n domHelpers.em(d.data.account),\n ];\n }\n</script>\n\n<svg viewBox={`0 0 ${width.toString()} ${height.toString()}`}>\n {#each leaves as d (d.data.account)}\n {@const account = d.data.account}\n <g\n transform={`translate(${d.x0.toString()},${d.y0.toString()})`}\n {@attach followingTooltip(() => tooltipText(d))}\n >\n <rect fill={fill(d)} width={d.x1 - d.x0} height={d.y1 - d.y0} />\n <a href={$urlForAccount(account)}>\n <text\n dy=\".5em\"\n x={(d.x1 - d.x0) / 2}\n y={(d.y1 - d.y0) / 2}\n text-anchor=\"middle\"\n {@attach (node: SVGTextElement) => {\n // Hide account names that are too long.\n const length = node.getComputedTextLength();\n node.style.visibility =\n d.x1 - d.x0 > length + 4 && d.y1 - d.y0 > 14\n ? \"visible\"\n : \"hidden\";\n }}\n >\n {leaf(account)}\n </text>\n </a>\n </g>\n {/each}\n</svg>\n\n<style>\n svg {\n shape-rendering: crispedges;\n }\n</style>\n", "<script lang=\"ts\">\n import { extent, max, min } from \"d3-array\";\n import { axisBottom, axisLeft } from \"d3-axis\";\n import { quadtree } from \"d3-quadtree\";\n import { scaleLinear, scaleUtc } from \"d3-scale\";\n import { area, curveStepAfter, line } from \"d3-shape\";\n\n import { chartToggledCurrencies, lineChartMode } from \"../stores/chart.ts\";\n import { ctx, short } from \"../stores/format.ts\";\n import Axis from \"./Axis.svelte\";\n import { currenciesScale, includeZero, padExtent } from \"./helpers.ts\";\n import type { LineChart, LineChartDatum } from \"./line.ts\";\n import type { TooltipFindNode } from \"./tooltip.ts\";\n import { positionedTooltip } from \"./tooltip.ts\";\n\n interface Props {\n chart: LineChart;\n width: number;\n }\n\n let { chart, width }: Props = $props();\n\n const today = new Date();\n const margin = { top: 10, right: 10, bottom: 30, left: 40 };\n const height = 250;\n let innerWidth = $derived(width - margin.left - margin.right);\n let innerHeight = $derived(height - margin.top - margin.bottom);\n\n let data = $derived(chart.filter($chartToggledCurrencies));\n\n // Scales and quadtree\n let allValues = $derived(data.flatMap((d) => d.values));\n\n let xExtent = $derived([\n min(data, (s) => s.values[0]?.date) ?? today,\n max(data, (s) => s.values[s.values.length - 1]?.date) ?? today,\n ] as const);\n let x = $derived(scaleUtc([0, innerWidth]).domain(xExtent));\n let valueExtent = $derived(extent(allValues, (v) => v.value));\n // Include zero in area charts so the entire area is shown, not a cropped part of it\n let yExtent = $derived(\n $lineChartMode === \"area\" ? includeZero(valueExtent) : valueExtent,\n );\n // Span y-axis as max minus min value plus 5 percent margin\n let y = $derived(scaleLinear([innerHeight, 0]).domain(padExtent(yExtent)));\n\n // Quadtree for hover.\n let quad = $derived(\n quadtree(\n allValues,\n (d) => x(d.date),\n (d) => y(d.value),\n ),\n );\n\n let lineShape = $derived(\n line<LineChartDatum>()\n .x((d) => x(d.date))\n .y((d) => y(d.value))\n .curve(curveStepAfter),\n );\n\n let areaShape = $derived(\n area<LineChartDatum>()\n .x((d) => x(d.date))\n .y1((d) => y(d.value))\n .y0(Math.min(innerHeight, y(0)))\n .curve(curveStepAfter),\n );\n\n // Axes\n let xAxis = $derived(axisBottom(x).tickSizeOuter(0));\n let yAxis = $derived(\n axisLeft(y).tickPadding(6).tickSize(-innerWidth).tickFormat($short),\n );\n\n const tooltipFindNode: TooltipFindNode = (xPos, yPos) => {\n const d = quad.find(xPos, yPos);\n return d && [x(d.date), y(d.value), chart.tooltipText($ctx, d)];\n };\n\n let futureFilter = $derived(\n xExtent[1] > today ? \"url(#desaturateFuture)\" : undefined,\n );\n</script>\n\n<svg viewBox={`0 0 ${width.toString()} ${height.toString()}`}>\n <filter id=\"desaturateFuture\">\n <feColorMatrix type=\"saturate\" values=\"0.5\" x={x(today)} />\n <feBlend in2=\"SourceGraphic\" />\n </filter>\n <g\n {@attach positionedTooltip(tooltipFindNode)}\n transform={`translate(${margin.left.toString()},${margin.top.toString()})`}\n >\n <Axis x axis={xAxis} {innerHeight} />\n <Axis y axis={yAxis} />\n {#if $lineChartMode === \"area\"}\n <g class=\"area\" filter={futureFilter}>\n {#each data as d (d.name)}\n <path d={areaShape(d.values)} fill={$currenciesScale(d.name)} />\n {/each}\n </g>\n {/if}\n <g class=\"lines\" filter={futureFilter}>\n {#each data as d (d.name)}\n <path d={lineShape(d.values)} stroke={$currenciesScale(d.name)} />\n {/each}\n </g>\n {#if $lineChartMode === \"line\"}\n <g>\n {#each data as d (d.name)}\n <g fill={$currenciesScale(d.name)}>\n {#each d.values as v (v.date)}\n <circle\n r=\"2\"\n cx={x(v.date)}\n cy={y(v.value)}\n class:desaturate={v.date > today}\n />\n {/each}\n </g>\n {/each}\n </g>\n {/if}\n </g>\n</svg>\n\n<style>\n svg > g {\n pointer-events: all;\n }\n\n .lines path {\n fill: none;\n stroke-width: 2px;\n }\n\n .area path {\n opacity: 0.3;\n }\n\n .desaturate {\n filter: saturate(50%);\n }\n</style>\n", "<script lang=\"ts\" generics=\"T extends string\">\n import type { LocalStoreSyncedStore } from \"../lib/store.ts\";\n\n interface Props {\n /** The store to show a switch for. */\n store: LocalStoreSyncedStore<T>;\n }\n\n let { store }: Props = $props();\n</script>\n\n<span>\n {#each store.values() as [option, name] (option)}\n <label class=\"button\" class:muted={$store !== option}>\n <input type=\"radio\" bind:group={$store} value={option} />\n {name}\n </label>\n {/each}\n</span>\n\n<style>\n input {\n display: none;\n }\n\n label + label {\n margin-left: 0.125rem;\n }\n\n @media print {\n label {\n display: none;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import { extent } from \"d3-array\";\n import { axisBottom, axisLeft } from \"d3-axis\";\n import { quadtree } from \"d3-quadtree\";\n import { scalePoint, scaleUtc } from \"d3-scale\";\n\n import { day } from \"../format.ts\";\n import Axis from \"./Axis.svelte\";\n import { scatterplotScale } from \"./helpers.ts\";\n import type { ScatterPlot, ScatterPlotDatum } from \"./scatterplot.ts\";\n import type { TooltipFindNode } from \"./tooltip.ts\";\n import { domHelpers, positionedTooltip } from \"./tooltip.ts\";\n\n interface Props {\n chart: ScatterPlot;\n width: number;\n }\n\n let { chart, width }: Props = $props();\n\n const today = new Date();\n const margin = { top: 10, right: 10, bottom: 30, left: 70 };\n const height = 250;\n let innerWidth = $derived(width - margin.left - margin.right);\n let innerHeight = $derived(height - margin.top - margin.bottom);\n\n // Scales\n let dateExtent = $derived(extent(chart.data, (d) => d.date));\n let x = $derived(\n scaleUtc([0, innerWidth]).domain(dateExtent[0] ? dateExtent : [0, 1]),\n );\n let y = $derived(\n scalePoint([innerHeight, 0])\n .domain(chart.data.map((d) => d.type))\n .padding(1),\n );\n\n // Axes\n let xAxis = $derived(axisBottom(x).tickSizeOuter(0));\n let yAxis = $derived(\n axisLeft(y)\n .tickPadding(6)\n .tickSize(-innerWidth)\n .tickFormat((d) => d),\n );\n\n /** Quadtree for hover. */\n let quad = $derived(\n quadtree(\n [...chart.data],\n (d) => x(d.date),\n (d) => y(d.type) ?? 0,\n ),\n );\n\n function tooltipText(d: ScatterPlotDatum) {\n return [domHelpers.t(d.description), domHelpers.em(day(d.date))];\n }\n\n const tooltipFindNode: TooltipFindNode = (xPos, yPos) => {\n const d = quad.find(xPos, yPos);\n return d && [x(d.date), y(d.type) ?? 0, tooltipText(d)];\n };\n</script>\n\n<svg viewBox={`0 0 ${width.toString()} ${height.toString()}`}>\n <g\n {@attach positionedTooltip(tooltipFindNode)}\n transform={`translate(${margin.left.toString()},${margin.top.toString()})`}\n >\n <Axis x axis={xAxis} {innerHeight} />\n <Axis y axis={yAxis} />\n <g>\n {#each chart.data as dot (`${dot.date.toString()}-${dot.type}`)}\n <circle\n r=\"5\"\n fill={scatterplotScale(dot.type)}\n cx={x(dot.date)}\n cy={y(dot.type)}\n class:desaturate={dot.date > today}\n />\n {/each}\n </g>\n </g>\n</svg>\n\n<style>\n svg > g {\n pointer-events: all;\n }\n\n .desaturate {\n filter: saturate(50%);\n }\n</style>\n", "<script lang=\"ts\">\n import type { Snippet } from \"svelte\";\n\n import { router } from \"../router.ts\";\n import {\n barChartMode,\n chartToggledCurrencies,\n hierarchyChartMode,\n lineChartMode,\n } from \"../stores/chart.ts\";\n import { show_charts } from \"../stores/url.ts\";\n import BarChart from \"./BarChart.svelte\";\n import ChartLegend from \"./ChartLegend.svelte\";\n import HierarchyContainer from \"./HierarchyContainer.svelte\";\n import type { FavaChart } from \"./index.ts\";\n import LineChart from \"./LineChart.svelte\";\n import ModeSwitch from \"./ModeSwitch.svelte\";\n import ScatterPlot from \"./ScatterPlot.svelte\";\n\n interface Props {\n /** The chart to render. */\n chart: FavaChart;\n /** Additional elements to render in the top right. */\n children?: Snippet;\n }\n\n let { chart, children }: Props = $props();\n\n /** Width of the chart. */\n let width: number | undefined = $state();\n</script>\n\n<div class=\"flex-row\">\n {#if $show_charts}\n {#if chart.type === \"barchart\"}\n <ChartLegend\n legend={chart.currencies}\n color={!($barChartMode === \"stacked\" && chart.hasStackedData)}\n toggled={chartToggledCurrencies}\n />\n {/if}\n {#if chart.type === \"linechart\"}\n <ChartLegend\n legend={chart.series_names}\n color={true}\n toggled={chartToggledCurrencies}\n />\n {/if}\n {#if chart.type === \"hierarchy\" && $hierarchyChartMode === \"treemap\" && chart.treemap_currency}\n <ChartLegend\n legend={chart.currencies}\n color={false}\n active={chart.treemap_currency}\n />\n {/if}\n <span class=\"spacer\"></span>\n {#if chart.type === \"hierarchy\"}\n <ModeSwitch store={hierarchyChartMode} />\n {:else if chart.type === \"linechart\"}\n <ModeSwitch store={lineChartMode} />\n {:else if chart.type === \"barchart\" && chart.hasStackedData}\n <ModeSwitch store={barChartMode} />\n {/if}\n {:else}<span class=\"spacer\"></span>{/if}\n {@render children?.()}\n <button\n type=\"button\"\n class=\"show-charts\"\n onclick={() => {\n router.set_search_param(\"charts\", $show_charts ? \"false\" : \"\");\n }}\n >\n {$show_charts ? \"▼\" : \"◀\"}\n </button>\n</div>\n<div hidden={!$show_charts} bind:clientWidth={width}>\n {#if width}\n {#if chart.type === \"barchart\"}\n <BarChart {chart} {width} />\n {:else if chart.type === \"hierarchy\"}\n <HierarchyContainer {chart} {width} />\n {:else if chart.type === \"linechart\"}\n <LineChart {chart} {width} />\n {:else if chart.type === \"scatterplot\"}\n <ScatterPlot {chart} {width} />\n {/if}\n {/if}\n</div>\n\n<style>\n .flex-row {\n margin-bottom: var(--flex-gap);\n }\n\n @media print {\n button.show-charts {\n display: none;\n }\n }\n</style>\n", "<!--\n @component\n An element to select element(s) from a dropdown.\n\n It receives its `value` and a list of possible `options`. The `description` prop should\n render a human-readable string for the value (which will be displayed in the button) and\n option (which will be shown in the list popup). Optionally a `multiple_select` function\n can be passed and a selection of multiple options is possible for sets of options for\n which this returns true.\n\n This is an implementation of the Combobox pattern as described by the\n ARIA Authoring Practices Guide (APG) at\n https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n In particular it should match the Select-Only Combobox example at\n https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/\n-->\n<script lang=\"ts\">\n interface Props {\n /** The currently entered value. */\n value: string;\n /** The options for the value. */\n options: readonly string[];\n /** Function to get the human readable description of an option and the value. */\n description: (option: string) => string;\n /** Whether an option can be part of a multi-selection (separated by comma in value). */\n multiple_select?: (option: string) => boolean;\n }\n\n let {\n value = $bindable(),\n options,\n description,\n multiple_select,\n }: Props = $props();\n\n /** Whether the list of options in the Combobox popup is hidden. */\n let hidden = $state(true);\n /** The index of the option that is currently focused */\n // Use the initial index in options (options does not change).\n // svelte-ignore state_referenced_locally\n let index = $state(options.indexOf(value));\n /** The popup list element. */\n let ul: HTMLUListElement | undefined = $state();\n\n const uid = $props.id();\n const listbox_id = `combobox-listbox-${uid}`;\n\n const SEPARATOR = \",\";\n let values = $derived(value.split(SEPARATOR));\n\n // Scroll focused element into view.\n $effect(() => {\n if (!hidden && index) {\n ul?.children[index]?.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n });\n\n /** The various actions that can be triggered by user mouse or key events. */\n const actions = {\n /** Close the popup list. */\n close: () => {\n hidden = true;\n },\n /** Find the first element matching the typed letter and focus it. */\n find_letter: (key: string, event: KeyboardEvent) => {\n const match = options.findIndex((o) => o.toLowerCase().startsWith(key));\n if (match > -1) {\n event.stopPropagation();\n index = match;\n hidden = false;\n }\n },\n /** Focus the first element and open if not open yet. */\n first: () => {\n index = 0;\n hidden = false;\n },\n /** Focus the last element and open if not open yet. */\n last: () => {\n index = 0;\n hidden = false;\n },\n /** Focus the previous element in the popup. */\n next: () => {\n index = index === 0 ? options.length - 1 : index - 1;\n },\n /** Open the popup list. */\n open: () => {\n hidden = false;\n },\n /** Focus the previous element in the popup. */\n previous: () => {\n index = index === options.length - 1 ? 0 : index + 1;\n },\n /** Select the given or the focused element in the options list. */\n select: (o?: string) => {\n const option = o ?? options[index];\n if (option != null) {\n if (\n // biome-ignore lint/complexity/useOptionalChain: clashes with strict-boolean-expressions rule\n multiple_select != null &&\n multiple_select(option) &&\n values.every(multiple_select)\n ) {\n value = values.includes(option)\n ? values.filter((v) => v !== option).join(SEPARATOR)\n : [...values, option].join(SEPARATOR);\n } else {\n value = option;\n }\n index = options.indexOf(option);\n hidden = true;\n }\n },\n /** Toggle the popup list. */\n toggle: () => {\n hidden = !hidden;\n },\n };\n\n /** Get the action for a keyboard event. */\n function key_action(event: KeyboardEvent): (() => void) | null {\n const { key } = event;\n const modifier = event.altKey || event.ctrlKey || event.metaKey;\n\n if (/^[\\w]$/.exec(key) && !modifier) {\n return actions.find_letter.bind(null, key, event);\n }\n if (key === \"Home\") {\n return actions.first;\n }\n if (key === \"End\") {\n return actions.last;\n }\n if ((key === \"Enter\" || key === \" \") && !hidden) {\n return actions.select;\n }\n if (key === \"Escape\" && !hidden) {\n return actions.close;\n }\n if (key === \"ArrowUp\") {\n return hidden ? actions.open : actions.next;\n }\n if (key === \"ArrowDown\") {\n return hidden ? actions.open : actions.previous;\n }\n return null;\n }\n</script>\n\n<span>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-expanded={!hidden}\n aria-controls={listbox_id}\n class=\"muted\"\n onclick={actions.toggle}\n onblur={actions.close}\n onkeydown={(event) => {\n const action = key_action(event);\n if (action) {\n event.preventDefault();\n action();\n }\n }}\n >\n {description(value)}\n </button>\n <ul {hidden} role=\"listbox\" id={listbox_id} bind:this={ul}>\n {#each options as option, i (option)}\n <li\n role=\"option\"\n aria-selected={values.includes(option)}\n class:current={i === index}\n onmousedown={(ev) => {\n if (ev.button === 0) {\n actions.select(option);\n }\n }}\n >\n {description(option)}\n </li>\n {/each}\n </ul>\n</span>\n\n<style>\n span {\n position: relative;\n display: inline-block;\n }\n\n ul {\n position: absolute;\n z-index: var(--z-index-autocomplete);\n overflow: auto;\n background-color: var(--background);\n border: 1px solid var(--border-darker);\n box-shadow: var(--box-shadow-dropdown);\n }\n\n li {\n padding: 2px 5px;\n white-space: nowrap;\n cursor: pointer;\n }\n\n li.current {\n padding: 0 3px;\n border: var(--link-color) dotted 2px;\n }\n\n li[aria-selected=\"true\"],\n li:hover {\n color: var(--background);\n background-color: var(--link-color);\n }\n\n @media print {\n span {\n display: none;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import { _ } from \"../i18n.ts\";\n import type { KeySpec } from \"../keyboard-shortcuts.ts\";\n import { keyboardShortcut } from \"../keyboard-shortcuts.ts\";\n import { lastActiveChartName } from \"../stores/chart.ts\";\n import { show_charts } from \"../stores/url.ts\";\n import Chart from \"./Chart.svelte\";\n import { chartContext } from \"./context.ts\";\n import ConversionAndInterval from \"./ConversionAndInterval.svelte\";\n import type { ParsedFavaChart } from \"./index.ts\";\n\n interface Props {\n charts: readonly ParsedFavaChart[];\n }\n\n let { charts }: Props = $props();\n\n let active_chart = $derived(\n charts.find((c) => c.label === $lastActiveChartName) ?? charts[0],\n );\n\n // Get the shortcut key for jumping to the previous chart.\n let shortcutPrevious = $derived((index: number): KeySpec | undefined => {\n const current = active_chart ? charts.indexOf(active_chart) : -1;\n return index === (current - 1 + charts.length) % charts.length\n ? { key: \"C\", note: _(\"Previous\") }\n : undefined;\n });\n // Get the shortcut key for jumping to the next chart.\n let shortcutNext = $derived((index: number): KeySpec | undefined => {\n const current = active_chart ? charts.indexOf(active_chart) : -1;\n return index === (current + 1 + charts.length) % charts.length\n ? { key: \"c\", note: _(\"Next\") }\n : undefined;\n });\n</script>\n\n{#if active_chart}\n <Chart chart={active_chart.with_context($chartContext)}>\n <ConversionAndInterval />\n </Chart>\n <div hidden={!$show_charts}>\n {#each charts as chart, index (chart.label)}\n <button\n type=\"button\"\n class=\"unset\"\n class:selected={chart === active_chart}\n onclick={() => {\n $lastActiveChartName = chart.label;\n }}\n {@attach keyboardShortcut(shortcutPrevious(index))}\n {@attach keyboardShortcut(shortcutNext(index))}\n >\n {chart.label}\n </button>\n {/each}\n </div>\n{/if}\n\n<style>\n div {\n margin-bottom: 1em;\n color: var(--text-color-lightest);\n text-align: center;\n }\n\n button {\n padding: 0 0.5em;\n }\n\n button + button {\n border-left: 1px solid var(--text-color-lighter);\n }\n\n button.selected,\n button:hover {\n color: var(--text-color-lighter);\n }\n\n @media print {\n button {\n display: none;\n border-left: none;\n }\n\n button + button {\n border-left: none;\n }\n\n button.selected {\n display: inline;\n }\n }\n</style>\n", "<!--\n @component\n Header for the account column.\n-->\n<script lang=\"ts\">\n import { some } from \"d3-array\";\n\n import { _ } from \"../i18n.ts\";\n import { is_descendant_or_equal } from \"../lib/account.ts\";\n import { expand_all, toggled_accounts } from \"../stores/accounts.ts\";\n\n interface Props {\n /** The account this tree is rendered for. */\n account: string;\n }\n\n let { account }: Props = $props();\n\n const toggled_children = $derived(\n some($toggled_accounts, is_descendant_or_equal(account)),\n );\n\n const help_title = _(\n \"Hold Shift while clicking to expand all children.\\n\" +\n \"Hold Ctrl or Cmd while clicking to expand one level.\",\n );\n</script>\n\n<span title={help_title}>\n {#if toggled_children}\n <button\n type=\"button\"\n class=\"link\"\n title={_(\"Expand all accounts\")}\n onclick={() => {\n expand_all(account);\n }}\n >\n {_(\"Expand all\")}\n </button>\n {/if}\n</span>\n\n<style>\n span {\n flex: 1;\n min-width: 14em;\n max-width: 30em;\n }\n\n button {\n margin-left: 1em;\n font-weight: normal;\n color: inherit;\n opacity: 0.5;\n }\n</style>\n", "<script lang=\"ts\">\n import { timeDay } from \"d3-time\";\n\n import { uptodate_indicator_grey_lookback_days } from \"../stores/fava_options.ts\";\n import { account_details } from \"../stores/index.ts\";\n\n interface Props {\n /** The account name. */\n account: string;\n /** Whether the indicator should be slightly smaller for the tree tables. */\n small?: boolean;\n }\n\n let { account, small = false }: Props = $props();\n\n let details = $derived($account_details[account]);\n let status = $derived(details?.uptodate_status);\n let balance = $derived(details?.balance_string ?? \"\");\n let last_entry = $derived(details?.last_entry);\n\n let last_account_activity = $derived(\n last_entry ? timeDay.count(last_entry.date, new Date()) : 0,\n );\n</script>\n\n{#if status}\n {#if status === \"green\"}\n <span\n class=\"status-indicator status-green\"\n class:small\n title=\"The last entry is a passing balance check.\"\n ></span>\n {:else}\n <copyable-text\n class=\"status-indicator status-{status}\"\n class:small\n title={`${\n status === \"yellow\"\n ? \"The last entry is not a balance check.\"\n : \"The last entry is a failing balance check.\"\n }\n\nClick to copy the balance directives to the clipboard:\n\n${balance}`}\n data-clipboard-text={balance}\n ></copyable-text>\n {/if}\n {#if last_account_activity > $uptodate_indicator_grey_lookback_days}\n <span\n class=\"status-indicator status-gray\"\n class:small\n title=\"This account has not been updated in a while. ({last_account_activity} days ago)\"\n ></span>\n {/if}\n{/if}\n\n<style>\n .status-indicator {\n width: 10px;\n height: 10px;\n margin: 0 0 0 10px;\n border-radius: 10px;\n }\n\n .status-indicator.small {\n display: inline-block;\n width: 6px;\n height: 6px;\n margin: 5px;\n border-radius: 6px;\n }\n\n .status-indicator.status-gray {\n margin-left: 0;\n }\n</style>\n", "<!--\n @component\n Account name cell.\n-->\n<script lang=\"ts\">\n import type { AccountTreeNode } from \"../charts/hierarchy.ts\";\n import { urlForAccount } from \"../helpers.ts\";\n import { leaf } from \"../lib/account.ts\";\n import AccountIndicator from \"../sidebar/AccountIndicator.svelte\";\n import { toggle_account, toggled_accounts } from \"../stores/accounts.ts\";\n\n interface Props {\n /** The account node to render the name cell for. */\n node: AccountTreeNode;\n }\n\n let { node }: Props = $props();\n\n let { account, children } = $derived(node);\n let is_toggled = $derived($toggled_accounts.has(account));\n</script>\n\n<span class=\"droptarget\" data-account-name={account}>\n {#if children.length > 0}\n <button\n type=\"button\"\n class=\"unset\"\n onclick={(event) => {\n toggle_account(account, event);\n }}\n >\n {is_toggled ? \"▸\" : \"▾\"}\n </button>\n {/if}\n <a href={$urlForAccount(account)} class=\"account\">\n {leaf(account)}\n </a>\n <AccountIndicator {account} small />\n</span>\n\n<style>\n button {\n position: absolute;\n padding: 0 3px;\n color: var(--treetable-expander);\n }\n\n a {\n margin-left: 1em;\n }\n\n span {\n display: flex;\n flex: 1;\n align-items: center;\n min-width: calc(14em - var(--account-indent, 0em));\n max-width: calc(30em - var(--account-indent, 0em));\n margin-left: var(--account-indent, 0);\n }\n\n /* Indent each level of account by one more 1em. */\n :global(ol ol) span {\n --account-indent: 1em;\n }\n\n :global(ol ol ol) span {\n --account-indent: 2em;\n }\n\n :global(ol ol ol ol) span {\n --account-indent: 3em;\n }\n\n :global(ol ol ol ol ol) span {\n --account-indent: 4em;\n }\n\n :global(ol ol ol ol ol ol) span {\n --account-indent: 5em;\n }\n\n :global(ol ol ol ol ol ol ol) span {\n --account-indent: 6em;\n }\n\n :global(ol ol ol ol ol ol ol ol) span {\n --account-indent: 7em;\n }\n\n :global(ol ol ol ol ol ol ol ol ol) span {\n --account-indent: 8em;\n }\n</style>\n", "<script lang=\"ts\">\n import { ctx } from \"../stores/format.ts\";\n\n interface Props {\n /** Difference to show. */\n diff: number;\n /** Number to show on hover. */\n num: number;\n /** The currency that both numbers are in. */\n currency: string;\n }\n\n let { diff, num, currency }: Props = $props();\n let positive = $derived(diff > 0);\n</script>\n\n<br />\n<span class:positive title={$ctx.amount(num, currency)}>\n ({positive ? \"+\" : \"-\"}{$ctx.num(Math.abs(diff), currency)})\n</span>\n\n<style>\n span {\n margin-right: 3px;\n font-size: 0.9em;\n color: var(--diff-negative);\n white-space: nowrap;\n }\n\n .positive {\n color: var(--diff-positive);\n }\n</style>\n", "<script lang=\"ts\">\n import { intersection, min } from \"d3-array\";\n import { writable } from \"svelte/store\";\n\n import type { AccountBudget } from \"../api/validators.ts\";\n import type { AccountTreeNode } from \"../charts/hierarchy.ts\";\n import { urlForAccount } from \"../helpers.ts\";\n import type { NonEmptyArray } from \"../lib/array.ts\";\n import { currentTimeFilterDateFormat } from \"../stores/format.ts\";\n import AccountCellHeader from \"./AccountCellHeader.svelte\";\n import { get_not_shown, setTreeTableNotShownContext } from \"./helpers.ts\";\n import IntervalTreeTableNode from \"./IntervalTreeTableNode.svelte\";\n\n interface Props {\n /** The account trees to show. */\n trees: NonEmptyArray<AccountTreeNode>;\n /** The dates. */\n dates: { begin: Date; end: Date }[];\n /** The budgets (per account a list per date range). */\n budgets: Record<string, AccountBudget[]>;\n /** Whether this is cumulative. */\n accumulate: boolean;\n }\n\n let { trees, dates, budgets, accumulate }: Props = $props();\n\n const not_shown = writable(new Set<string>());\n setTreeTableNotShownContext(not_shown);\n\n $effect(() => {\n $not_shown = intersection(\n ...trees.map((n, index) => $get_not_shown(n, dates[index]?.end ?? null)),\n );\n });\n\n let account = $derived(trees[0].account);\n let start_date = $derived(\n accumulate ? min(dates, (d) => d.begin) : undefined,\n );\n let start_date_filter = $derived(\n start_date ? $currentTimeFilterDateFormat(start_date) : undefined,\n );\n let time_filters = $derived(\n dates.map((date_range): [string, string] => {\n const title = $currentTimeFilterDateFormat(date_range.begin);\n return start_date_filter != null\n ? [title, `${start_date_filter}-${title}`]\n : [title, title];\n }),\n );\n</script>\n\n<ol class=\"flex-table tree-table-new\">\n <li class=\"head\">\n <p>\n <AccountCellHeader {account} />\n {#each time_filters as [title, time] (time)}\n <span class=\"num other\">\n <a href={$urlForAccount(account, { time })}>\n {title}\n </a>\n </span>\n {/each}\n </p>\n </li>\n <IntervalTreeTableNode nodes={trees} {budgets} />\n</ol>\n\n<style>\n ol {\n overflow-x: auto;\n }\n</style>\n", "<script lang=\"ts\" module>\n import { _, format } from \"../../i18n.ts\";\n import type { KeySpec } from \"../../keyboard-shortcuts.ts\";\n import { keyboardShortcut } from \"../../keyboard-shortcuts.ts\";\n import { toggle } from \"../../lib/set.ts\";\n import { journal_show } from \"../../stores/journal.ts\";\n\n const toggleText = _(\"Toggle %(type)s entries\");\n\n /**\n * This is the list of all toggle buttons to show.\n * For some entry types we have subtypes (like 'cleared' for 'transaction'),\n * which get special-cased in the toggle logic below.\n */\n const buttons: [\n type: string,\n button_text: string,\n title: string | null,\n shortcut: KeySpec,\n supertype?: string,\n ][] = [\n [\"open\", \"Open\", null, \"s o\"],\n [\"close\", \"Close\", null, \"s c\"],\n [\"transaction\", \"Transaction\", null, \"s t\"],\n [\"cleared\", \"*\", _(\"Cleared transactions\"), \"t c\", \"transaction\"],\n [\"pending\", \"!\", _(\"Pending transactions\"), \"t p\", \"transaction\"],\n [\"other\", \"x\", _(\"Other transactions\"), \"t o\", \"transaction\"],\n [\"balance\", \"Balance\", null, \"s b\"],\n [\"note\", \"Note\", null, \"s n\"],\n [\"document\", \"Document\", null, \"s d\"],\n [\n \"discovered\",\n \"D\",\n _(\"Documents with a #discovered tag\"),\n \"d d\",\n \"document\",\n ],\n [\"linked\", \"L\", _(\"Documents with a #linked tag\"), \"d l\", \"document\"],\n [\"pad\", \"Pad\", null, \"s p\"],\n [\"query\", \"Query\", null, \"s q\"],\n [\"custom\", \"Custom\", null, \"s C\"],\n [\"budget\", \"B\", _(\"Budget entries\"), \"s B\", \"custom\"],\n [\"metadata\", _(\"Metadata\"), _(\"Toggle metadata\"), \"m\"],\n [\"postings\", _(\"Postings\"), _(\"Toggle postings\"), \"p\"],\n ];\n</script>\n\n<script lang=\"ts\">\n let shownSet = $derived(new Set($journal_show));\n\n function toggle_type(type: string) {\n journal_show.update((show) => {\n const set = new Set(show);\n toggle(set, type);\n // Also toggle all entries that have `type` as their supertype.\n buttons.filter((b) => b[4] === type).forEach((b) => toggle(set, b[0]));\n return [...set].sort();\n });\n }\n\n let active = $derived((type: string, supertype?: string): boolean =>\n supertype != null\n ? shownSet.has(type) && shownSet.has(supertype)\n : shownSet.has(type),\n );\n</script>\n\n<form class=\"flex-row\">\n {#each buttons as [type, button_text, title, shortcut, supertype] (type)}\n <button\n type=\"button\"\n title={title ?? format(toggleText, { type: button_text })}\n {@attach keyboardShortcut(shortcut)}\n class:inactive={!active(type, supertype)}\n onclick={() => {\n toggle_type(type);\n }}\n >\n {button_text}\n </button>\n {/each}\n</form>\n\n<style>\n form {\n justify-content: flex-end;\n }\n</style>\n", "<script lang=\"ts\">\n import { _ } from \"../../i18n.ts\";\n import { journal_sort } from \"../../stores/journal.ts\";\n import type { JournalSortColumn } from \"./sort.ts\";\n\n interface Props {\n disabled: boolean;\n show_change_and_balance: boolean;\n set_sort_column: (name: JournalSortColumn) => void;\n }\n\n let { disabled, show_change_and_balance, set_sort_column }: Props = $props();\n\n let [name, order] = $derived($journal_sort);\n</script>\n\n<ol class=\"flex-table journal\">\n <li class=\"head\">\n <p>\n <button\n type=\"button\"\n class=\"datecell unset\"\n data-order={name === \"date\" ? order : undefined}\n {disabled}\n onclick={() => {\n set_sort_column(\"date\");\n }}\n >\n {_(\"Date\")}\n </button>\n <button\n type=\"button\"\n class=\"flag unset\"\n data-order={name === \"flag\" ? order : undefined}\n {disabled}\n onclick={() => {\n set_sort_column(\"flag\");\n }}\n >\n {_(\"F\")}\n </button>\n <button\n type=\"button\"\n class=\"description unset\"\n data-order={name === \"narration\" ? order : undefined}\n {disabled}\n onclick={() => {\n set_sort_column(\"narration\");\n }}\n >\n {_(\"Payee\")}/{_(\"Narration\")}\n </button>\n <span class=\"num\">{_(\"Units\")}</span>\n {#if show_change_and_balance}\n <span class=\"num\">{_(\"Cost\")} / {_(\"Change\")}</span>\n <span class=\"num\">{_(\"Price\")} / {_(\"Balance\")}</span>\n {:else}\n <span class=\"num\">{_(\"Cost\")}</span>\n <span class=\"num\">{_(\"Price\")}</span>\n {/if}\n </p>\n </li>\n</ol>\n\n<style>\n ol {\n margin: var(--flex-gap) 0 0;\n }\n\n button {\n position: relative;\n }\n</style>\n", "<!--\n @component\n An autocomplete input for fuzzy selection of suggestions.\n\n It receives its `value` and a list of possible `suggestions`. Matching suggestions will be\n shown in a dropdown below the input field and can be selected by clicking or by keyboard.\n\n This is an implementation of the Combobox pattern as described by the\n ARIA Authoring Practices Guide (APG) at\n https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n In particular it should match the Editable Combobox With List Autocomplete example at\n https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/\n-->\n<script lang=\"ts\">\n import type { KeySpec } from \"./keyboard-shortcuts.ts\";\n import { keyboardShortcut } from \"./keyboard-shortcuts.ts\";\n import {\n fuzzyfilter,\n fuzzywrap,\n type FuzzyWrappedText,\n } from \"./lib/fuzzy.ts\";\n\n interface Props {\n /** The currently entered value (bindable). */\n value: string;\n /** A placeholder for the input field. */\n placeholder: string;\n /** The suggestions for the value. */\n suggestions: readonly string[];\n /** A function to extract the string that should be used for suggestion filtering. */\n valueExtractor?: (val: string, input: HTMLInputElement) => string;\n /** A function to update the value after selecting a suggestion. */\n valueSelector?: (val: string, input: HTMLInputElement) => string;\n /** Automatically adjust the size of the input element. */\n setSize?: boolean;\n /** A key binding to add for this input. */\n key?: KeySpec;\n /** A function that checks the entered value for validity. */\n checkValidity?: (val: string) => string;\n /** Whether to mark the input as required. */\n required?: boolean | undefined;\n /** Whether to show a button to clear the input. */\n clearButton?: boolean;\n /** An event handler to run on blur. */\n onBlur?: (el: HTMLInputElement) => void;\n /** An event handler to run on enter. */\n onEnter?: (el: HTMLInputElement) => void;\n /** An event handler to run on an element being selected. */\n onSelect?: (el: HTMLInputElement) => void;\n }\n\n let {\n value = $bindable(),\n placeholder,\n suggestions,\n valueExtractor,\n valueSelector,\n setSize = false,\n key,\n checkValidity,\n clearButton = false,\n required,\n onBlur,\n onEnter,\n onSelect,\n }: Props = $props();\n\n const uid = $props.id();\n const autocomple_id = `combobox-autocomplete-${uid}`;\n\n let hidden = $state.raw(true);\n let index = $state.raw(-1);\n let input: HTMLInputElement | undefined = $state.raw();\n\n let size = $derived(\n setSize ? Math.max(value.length, placeholder.length) + 1 : undefined,\n );\n let extractedValue = $derived(\n input && valueExtractor ? valueExtractor(value, input) : value,\n );\n let filteredSuggestions: {\n suggestion: string;\n fuzzywrapped: FuzzyWrappedText;\n }[] = $derived.by(() => {\n const filtered = fuzzyfilter(extractedValue, suggestions)\n .slice(0, 30)\n .map((suggestion) => ({\n suggestion,\n fuzzywrapped: fuzzywrap(extractedValue, suggestion),\n }));\n return filtered.length === 1 && filtered[0]?.suggestion === extractedValue\n ? []\n : filtered;\n });\n\n $effect(() => {\n const msg = checkValidity ? checkValidity(value) : \"\";\n input?.setCustomValidity(msg);\n });\n\n $effect.pre(() => {\n // ensure the index is pointing to a valid element.\n index = Math.min(index, filteredSuggestions.length - 1);\n });\n\n function select(suggestion: string) {\n value =\n input && valueSelector ? valueSelector(suggestion, input) : suggestion;\n if (input) {\n onSelect?.(input);\n }\n hidden = true;\n }\n\n function mousedown(event: MouseEvent, suggestion: string) {\n if (event.button === 0) {\n select(suggestion);\n }\n }\n\n let expanded = $derived(!hidden && filteredSuggestions.length > 0);\n\n function keydown(event: KeyboardEvent) {\n if (event.key === \"Enter\") {\n const suggestion = filteredSuggestions[index]?.suggestion;\n if (index > -1 && !hidden && suggestion != null) {\n event.preventDefault();\n select(suggestion);\n } else if (input) {\n onEnter?.(input);\n }\n } else if (event.key === \" \" && event.ctrlKey) {\n hidden = false;\n } else if (event.key === \"Escape\") {\n event.stopPropagation();\n if (expanded) {\n index = -1;\n hidden = true;\n } else {\n value = \"\";\n }\n } else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n index = index === 0 ? filteredSuggestions.length - 1 : index - 1;\n } else if (event.key === \"ArrowDown\") {\n event.preventDefault();\n index = index === filteredSuggestions.length - 1 ? 0 : index + 1;\n }\n }\n</script>\n\n<span>\n <input\n type=\"text\"\n autocomplete=\"off\"\n role=\"combobox\"\n aria-expanded={expanded}\n aria-controls={autocomple_id}\n bind:value\n bind:this={input}\n {@attach keyboardShortcut(key)}\n onblur={(event) => {\n hidden = true;\n onBlur?.(event.currentTarget);\n }}\n onfocus={() => {\n hidden = false;\n }}\n oninput={() => {\n hidden = false;\n }}\n onkeydown={keydown}\n {placeholder}\n {required}\n {size}\n />\n {#if clearButton && value}\n <button\n type=\"button\"\n tabindex={-1}\n class=\"muted round\"\n onclick={() => {\n value = \"\";\n if (input) {\n onSelect?.(input);\n }\n }}\n >\n ×\n </button>\n {/if}\n {#if filteredSuggestions.length}\n <ul {hidden} role=\"listbox\" id={autocomple_id}>\n {#each filteredSuggestions as { fuzzywrapped, suggestion }, i (suggestion)}\n <li\n role=\"option\"\n aria-selected={i === index}\n class:selected={i === index}\n onmousedown={(ev) => {\n mousedown(ev, suggestion);\n }}\n >\n {#each fuzzywrapped as [type, text], i (i)}\n {#if type === \"text\"}\n {text}\n {:else}\n <span>{text}</span>\n {/if}\n {/each}\n </li>\n {/each}\n </ul>\n {/if}\n</span>\n\n<style>\n span {\n position: relative;\n display: inline-block;\n flex: var(--autocomplete-wrapper-flex, initial);\n }\n\n input {\n width: 100%;\n }\n\n ul {\n position: var(--autocomplete-list-position, absolute);\n z-index: var(--z-index-autocomplete);\n overflow: hidden auto;\n background-color: var(--background);\n border: 1px solid var(--border-darker);\n box-shadow: var(--box-shadow-dropdown);\n }\n\n li {\n min-width: 8rem;\n padding: 0 0.5em;\n white-space: nowrap;\n cursor: pointer;\n }\n\n li.selected,\n li:hover {\n color: var(--background);\n background-color: var(--link-color);\n }\n\n button {\n position: absolute;\n top: 8px;\n right: 4px;\n background: transparent;\n }\n\n li span {\n height: 1.2em;\n padding: 0 0.05em;\n margin: 0 -0.05em;\n background-color: var(--autocomplete-match);\n border-radius: 2px;\n }\n\n @media print {\n button {\n display: none;\n }\n }\n</style>\n", "<!--\n @component\n A modal dialog.\n\n This tries to follow https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/.\n-->\n<script lang=\"ts\">\n import type { Snippet } from \"svelte\";\n import type { Attachment } from \"svelte/attachments\";\n\n import { attemptFocus, getFocusableElements } from \"../lib/focus.ts\";\n import { router } from \"../router.ts\";\n\n interface Props {\n shown: boolean;\n focus?: string;\n closeHandler?: () => void;\n children: Snippet;\n }\n\n let {\n shown,\n focus,\n closeHandler = router.close_overlay,\n children,\n }: Props = $props();\n\n /**\n * A Svelte action to handle focus within a modal.\n */\n const handleFocus: Attachment<HTMLDivElement> = (el) => {\n const keydown = (ev: KeyboardEvent) => {\n if (ev.key === \"Tab\") {\n const focusable = getFocusableElements(el);\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (ev.shiftKey && document.activeElement === first && last) {\n ev.preventDefault();\n attemptFocus(last);\n } else if (!ev.shiftKey && document.activeElement === last && first) {\n ev.preventDefault();\n attemptFocus(first);\n }\n } else if (ev.key === \"Escape\") {\n ev.preventDefault();\n closeHandler();\n }\n };\n\n document.addEventListener(\"keydown\", keydown);\n\n const selectorFocusEl = focus != null ? el.querySelector(focus) : undefined;\n const focusEl = selectorFocusEl ?? getFocusableElements(el)[0];\n if (focusEl) {\n attemptFocus(focusEl);\n }\n\n return () => {\n document.removeEventListener(\"keydown\", keydown);\n };\n };\n</script>\n\n{#if shown}\n <div class=\"overlay\">\n <div class=\"background\" onclick={closeHandler} aria-hidden=\"true\"></div>\n <div class=\"content\" role=\"dialog\" aria-modal=\"true\" {@attach handleFocus}>\n {@render children()}\n <button type=\"button\" class=\"muted close\" onclick={closeHandler}>\n x\n </button>\n </div>\n </div>\n{/if}\n\n<style>\n :global(body:has(.overlay)) {\n overflow: hidden;\n }\n\n .background {\n position: fixed;\n inset: 0;\n width: 100%;\n height: 100%;\n cursor: pointer;\n background: var(--overlay-wrapper-background);\n }\n\n .overlay {\n position: fixed;\n inset: 0;\n z-index: var(--z-index-overlay);\n display: flex;\n align-items: start;\n justify-content: center;\n width: 100vw;\n height: 100vh;\n overflow: auto;\n }\n\n .content {\n position: relative;\n display: flex;\n width: 100%;\n max-width: 767px;\n padding: 1em;\n margin: 0.5em;\n margin-top: 10vh;\n background: var(--background);\n box-shadow: var(--box-shadow-overlay);\n }\n\n .close {\n position: absolute;\n top: 1em;\n right: 1em;\n width: 2em;\n height: 2em;\n margin: 0;\n line-height: 1em;\n color: var(--text-color-lighter);\n }\n\n .content :global(form),\n .content > :global(div) {\n width: 100%;\n }\n\n @media (width <= 767px) {\n /* Show the modal full-screen on mobile. */\n .overlay {\n height: 100%;\n }\n\n .background {\n /* Ensure that modal overflow gets a white background. */\n background: var(--background);\n }\n\n .content {\n height: 100%;\n margin: 0;\n box-shadow: unset;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import { leaf } from \"../../lib/account.ts\";\n import type { TreeNode } from \"../../lib/tree.ts\";\n import { toggle_account, toggled_accounts } from \"../../stores/accounts.ts\";\n import Accounts from \"./Accounts.svelte\";\n import { selectedAccount } from \"./stores.ts\";\n\n interface Props {\n node: TreeNode<{ name: string; count: number }>;\n move: (m: { account: string; filename: string }) => void;\n }\n\n let { node, move }: Props = $props();\n let account = $derived(node.name);\n\n let drag = $state(false);\n let is_toggled = $derived($toggled_accounts.has(account));\n\n let hasChildren = $derived(node.children.length > 0);\n let selected = $derived($selectedAccount === node.name);\n\n /**\n * Start drag if a document filename is dragged onto an account.\n * @param event - The drag event that is passed to the event handler.\n */\n function dragenter(event: DragEvent) {\n const types = event.dataTransfer?.types ?? [];\n if (types.includes(\"fava/filename\")) {\n event.preventDefault();\n drag = true;\n }\n }\n\n /**\n * Handle a drop and bubble the event.\n * @param event - The drag event that is passed to the event handler.\n */\n function drop(event: DragEvent) {\n event.preventDefault();\n const filename = event.dataTransfer?.getData(\"fava/filename\");\n if (filename != null) {\n move({ account: node.name, filename });\n drag = false;\n }\n }\n</script>\n\n{#if account}\n <p\n ondragenter={dragenter}\n ondragover={dragenter}\n ondragleave={() => {\n drag = false;\n }}\n ondrop={drop}\n title={account}\n class=\"droptarget\"\n data-account-name={account}\n class:selected\n class:drag\n >\n {#if hasChildren}\n <button\n type=\"button\"\n class=\"unset toggle\"\n onclick={(event) => {\n toggle_account(account, event);\n event.stopPropagation();\n }}>{is_toggled ? \"▸\" : \"▾\"}</button\n >\n {/if}\n <button\n type=\"button\"\n class=\"unset leaf\"\n onclick={() => {\n $selectedAccount = selected ? \"\" : account;\n }}>{leaf(account)}</button\n >\n {#if node.count > 0}\n <span class=\"count\"> {node.count}</span>\n {/if}\n </p>\n{/if}\n{#if hasChildren && !is_toggled}\n <ul>\n {#each node.children as child (child.name)}\n <li>\n <Accounts node={child} {move} />\n </li>\n {/each}\n </ul>\n{/if}\n\n<style>\n ul {\n padding: 0 0 0 0.5em;\n margin: 0;\n }\n\n p {\n position: relative;\n display: flex;\n padding-right: 0.5em;\n margin: 0;\n overflow: hidden;\n border-bottom: 1px solid var(--table-border);\n border-left: 1px solid var(--table-border);\n }\n\n p > * {\n padding: 1px;\n }\n\n .count {\n opacity: 0.6;\n }\n\n .selected,\n .drag {\n background-color: var(--table-header-background);\n }\n\n .leaf {\n flex-grow: 1;\n margin-left: 1em;\n }\n\n .toggle {\n position: absolute;\n margin: 0 0.25rem;\n color: var(--treetable-expander);\n }\n</style>\n", "<!--\n @component\n A basic fullsize readonly editor that loads and displays the text document\n at the given URL.\n-->\n<script lang=\"ts\">\n import { attach_editor } from \"../codemirror/dom.ts\";\n import type { CodemirrorBql } from \"../codemirror/types.ts\";\n import { fetch_text } from \"../lib/fetch.ts\";\n\n interface Props {\n /** Codemirror setup module */\n codemirror_bql: CodemirrorBql;\n /** The URL to load the editor contents from. */\n url: string;\n }\n\n let { url, codemirror_bql }: Props = $props();\n\n // svelte-ignore state_referenced_locally\n const editor = codemirror_bql.init_document_preview_editor();\n\n const set_editor_content = (value: string) => {\n if (value !== editor.state.sliceDoc()) {\n editor.dispatch(codemirror_bql.replace_contents(editor.state, value));\n }\n };\n\n $effect(() => {\n fetch_text(url).then(set_editor_content, () => {\n set_editor_content(`Loading ${url} failed...`);\n });\n });\n</script>\n\n<div {@attach attach_editor(editor)}></div>\n\n<style>\n div {\n width: 100%;\n height: 100%;\n }\n\n div :global(.cm-editor) {\n width: 100%;\n height: 100%;\n }\n</style>\n", "<!--\n @component\n A component to show PDFs, text, images, and HTML files.\n-->\n<script lang=\"ts\" module>\n /** For these file extensions we show a plain-text read-only editor. */\n const plainTextExtensions = [\"csv\", \"json\", \"qfx\", \"txt\", \"xml\"];\n /** For these file extensions we try to show the file as an `<img>` */\n const imageExtensions = [\n \"gif\",\n \"jpg\",\n \"jpeg\",\n \"png\",\n \"svg\",\n \"webp\",\n \"bmp\",\n \"ico\",\n ];\n</script>\n\n<script lang=\"ts\">\n import DocumentPreviewEditor from \"../../editor/DocumentPreviewEditor.svelte\";\n import { urlForRaw } from \"../../helpers.ts\";\n import { ext } from \"../../lib/paths.ts\";\n\n interface Props {\n filename: string;\n }\n\n let { filename }: Props = $props();\n\n let extension = $derived(ext(filename).toLowerCase());\n let url = $derived($urlForRaw(\"document/\", { filename }));\n</script>\n\n{#if extension === \"pdf\"}\n <object title={filename} data={url}></object>\n{:else if plainTextExtensions.includes(extension)}\n {#await import(\"../../codemirror/bql.ts\") then codemirror_bql}\n <DocumentPreviewEditor {url} {codemirror_bql} />\n {/await}\n{:else if imageExtensions.includes(extension)}\n <img src={url} alt={filename} />\n{:else if [\"html\", \"htm\"].includes(extension)}\n <iframe src={url} title={filename} sandbox=\"\"></iframe>\n{:else}\n Preview for file `{filename}` with file type `{extension}` is not implemented\n{/if}\n\n<style>\n object,\n img,\n iframe {\n width: 100%;\n height: 100%;\n }\n\n img {\n object-fit: contain;\n }\n</style>\n", "<script lang=\"ts\">\n import type { Document } from \"../../entries/index.ts\";\n import { _ } from \"../../i18n.ts\";\n import { is_descendant_or_equal } from \"../../lib/account.ts\";\n import { basename } from \"../../lib/paths.ts\";\n import { DateColumn, Sorter, StringColumn } from \"../../sort/index.ts\";\n import SortHeader from \"../../sort/SortHeader.svelte\";\n import { selectedAccount } from \"./stores.ts\";\n\n interface Props {\n data: Document[];\n selected?: Document | null;\n }\n\n let { data, selected = $bindable(null) }: Props = $props();\n\n /**\n * Extract just the latter part of the filename if it starts with a date.\n */\n function name(doc: Document) {\n const base = basename(doc.filename);\n return base.startsWith(doc.date) ? base.substring(11) : base;\n }\n\n const columns = [\n new DateColumn<Document>(_(\"Date\")),\n new StringColumn<Document>(_(\"Name\"), (d) => name(d)),\n ] as const;\n let sorter = $state(new Sorter(columns[0], \"desc\"));\n\n let is_descendant_of_selected = $derived(\n is_descendant_or_equal($selectedAccount),\n );\n let filtered_documents = $derived(\n data.filter((doc) => is_descendant_of_selected(doc.account)),\n );\n let sorted_documents = $derived(sorter.sort(filtered_documents));\n</script>\n\n<table>\n <thead>\n <tr>\n {#each columns as column (column)}\n <SortHeader bind:sorter {column} />\n {/each}\n </tr>\n </thead>\n <tbody>\n {#each sorted_documents as doc (doc.filename)}\n <tr\n class:selected={selected === doc}\n draggable={true}\n title={doc.filename}\n ondragstart={(ev) => {\n ev.dataTransfer?.setData(\"fava/filename\", doc.filename);\n }}\n onclick={() => {\n selected = doc;\n }}\n >\n <td>{doc.date}</td>\n <td>{name(doc)}</td>\n </tr>\n {/each}\n </tbody>\n</table>\n\n<style>\n table {\n width: 100%;\n }\n\n tr {\n cursor: pointer;\n }\n\n .selected,\n tr:hover {\n background-color: var(--table-header-background);\n }\n</style>\n", "<script lang=\"ts\">\n import { group } from \"d3-array\";\n\n import { move_document } from \"../../api/index.ts\";\n import type { Document } from \"../../entries/index.ts\";\n import AccountInput from \"../../entry-forms/AccountInput.svelte\";\n import { _ } from \"../../i18n.ts\";\n import { basename } from \"../../lib/paths.ts\";\n import { stratifyAccounts } from \"../../lib/tree.ts\";\n import ModalBase from \"../../modals/ModalBase.svelte\";\n import { router } from \"../../router.ts\";\n import Accounts from \"./Accounts.svelte\";\n import DocumentPreview from \"./DocumentPreview.svelte\";\n import type { DocumentsReportProps } from \"./index.ts\";\n import Table from \"./Table.svelte\";\n\n let { documents }: DocumentsReportProps = $props();\n\n interface MoveDetails {\n account: string;\n filename: string;\n newName: string;\n }\n\n let grouped = $derived(group(documents, (d) => d.account));\n let node = $derived(\n stratifyAccounts(\n grouped.entries(),\n ([s]) => s,\n (name, d) => ({ name, count: d?.[1].length ?? 0 }),\n ),\n );\n\n let selected: Document | null = $state(null);\n let moving: MoveDetails | null = $state(null);\n\n /**\n * Rename the selected document with <F2>.\n */\n function keyup(ev: KeyboardEvent) {\n if (ev.key === \"F2\" && selected && !moving) {\n moving = {\n account: selected.account,\n filename: selected.filename,\n newName: basename(selected.filename),\n };\n }\n }\n\n async function move(event: SubmitEvent) {\n event.preventDefault();\n if (moving) {\n const moved = await move_document(\n moving.filename,\n moving.account,\n moving.newName,\n );\n if (moved) {\n moving = null;\n router.reload();\n }\n }\n }\n</script>\n\n<svelte:window onkeyup={keyup} />\n{#if moving}\n <ModalBase\n shown={true}\n closeHandler={() => {\n moving = null;\n }}\n >\n <form onsubmit={move}>\n <h3>{_(\"Move or rename document\")}</h3>\n <p><code>{moving.filename}</code></p>\n <p>\n <AccountInput bind:value={moving.account} />\n <input size={40} bind:value={moving.newName} />\n <button type=\"submit\">{_(\"Move\")}</button>\n </p>\n </form>\n </ModalBase>\n{/if}\n<div class=\"fixed-fullsize-container\">\n <Accounts\n {node}\n move={(arg: { account: string; filename: string }) => {\n moving = { ...arg, newName: basename(arg.filename) };\n }}\n />\n <div>\n <Table bind:selected data={documents} />\n </div>\n {#if selected}\n <DocumentPreview filename={selected.filename} />\n {/if}\n</div>\n\n<style>\n .fixed-fullsize-container {\n display: grid;\n grid-template-columns: 1fr 2fr 3fr;\n }\n\n .fixed-fullsize-container > :global(*) {\n height: 100%;\n overflow: auto;\n resize: horizontal;\n }\n\n .fixed-fullsize-container > :global(* + *) {\n border-left: thin solid var(--sidebar-border);\n }\n</style>\n", "<!--\n @component\n An application menu.\n-->\n<script lang=\"ts\">\n import type { Snippet } from \"svelte\";\n\n interface Props {\n children: Snippet;\n }\n\n let { children }: Props = $props();\n</script>\n\n<div role=\"menubar\">\n {@render children()}\n</div>\n\n<style>\n div {\n display: flex;\n gap: 0.5em;\n align-items: stretch;\n margin-right: 0.5em;\n }\n</style>\n", "<!--\n @component\n A single top level menu item in an app menu.\n\n The default slot should filled with its vertically arranged sub-items.\n-->\n<script lang=\"ts\">\n import type { Snippet } from \"svelte\";\n\n interface Props {\n /** The name of the menu item. */\n name: string;\n children: Snippet;\n }\n\n let { name, children }: Props = $props();\n\n let open = $state(false);\n</script>\n\n<span\n class:open\n tabindex=\"0\"\n role=\"menuitem\"\n onblur={() => {\n open = false;\n }}\n onkeydown={(event) => {\n if (event.key === \"Escape\") {\n open = false;\n } else if (event.key === \"ArrowDown\") {\n open = true;\n }\n }}\n>\n {name}\n <ul role=\"menu\">\n {@render children()}\n </ul>\n</span>\n\n<style>\n span {\n padding: 0.7em 0.5em;\n cursor: pointer;\n }\n\n span.open,\n span:hover {\n background-color: var(--background-darkest);\n }\n\n span::after {\n content: \"▾\";\n }\n\n ul {\n position: absolute;\n z-index: var(--z-index-floating-ui);\n display: none;\n width: 500px;\n max-height: 400px;\n margin: 0.7em 0 0 -0.5em; /* The top margin should match the (bottom) padding of the span above. */\n overflow-y: auto;\n background-color: var(--background);\n border: 1px solid var(--border);\n box-shadow: var(--box-shadow-dropdown);\n }\n\n span.open > ul,\n span:hover > ul {\n display: block;\n }\n</style>\n", "<!--\n @component\n A sub-item in an app menu.\n-->\n<script lang=\"ts\">\n import type { Snippet } from \"svelte\";\n\n interface Props {\n /** A title (optional) for the element. */\n title?: string;\n /** Whether this menu item should be marked as selected. */\n selected?: boolean;\n /** The action to execute on click. */\n action: () => void;\n children: Snippet;\n right?: Snippet;\n }\n\n let { title, selected = false, action, children, right }: Props = $props();\n</script>\n\n<li\n class:selected\n {title}\n role=\"menuitem\"\n onclick={action}\n onkeydown={(event) => {\n if (event.key === \"Enter\") {\n action();\n }\n }}\n>\n {@render children()}\n {#if right}\n <span>\n {@render right()}\n </span>\n {/if}\n</li>\n\n<style>\n .selected::before {\n content: \"›\";\n }\n\n li {\n padding: 0.25em 0.5em;\n }\n\n span {\n float: right;\n }\n\n li:hover,\n li:focus-visible {\n background-color: var(--background-darkest);\n }\n</style>\n", "<script lang=\"ts\">\n import type { SourceNode } from \"../../lib/sources.ts\";\n import Sources from \"./Sources.svelte\";\n import { expanded_directories, toggle_directory } from \"./stores.ts\";\n\n interface Props {\n is_root?: boolean;\n node: SourceNode;\n on_select: (source: string) => void;\n selected: string;\n }\n\n let { is_root = false, node, on_select, selected }: Props = $props();\n\n let is_expanded = $derived.by(() => {\n const result = $expanded_directories.get(node.path);\n // Even though root is always expanded, treat is as being collapsed by default.\n // This allows for expanding everything with one Ctrl/Meta-Click. The subsequent click would then collapse everything.\n return result ?? (!is_root && selected.startsWith(node.path));\n });\n\n let is_directory = $derived(node.children.length > 0);\n // Show where the selected file would be, if directories are collapsed\n let is_selected = $derived(\n is_directory && !is_expanded && !is_root\n ? selected.startsWith(node.path)\n : selected === node.path,\n );\n\n let action = (event: MouseEvent) => {\n if (is_directory) {\n toggle_directory(node.path, !is_expanded, event);\n } else {\n on_select(node.path);\n }\n event.stopPropagation();\n };\n</script>\n\n<li class:selected={is_selected} role=\"menuitem\">\n {#if is_root}\n <button\n type=\"button\"\n title=\"Beancount data root directory\nShift-Click to expand/collapse immediate directories\nCtrl-/Cmd-/Meta-Click to expand/collapse all directories.\"\n class=\"unset root\"\n onclick={action}\n >\n {node.name}\n </button>\n {:else}\n <p>\n {#if is_directory}\n <button type=\"button\" class=\"unset toggle\" onclick={action}>\n {is_expanded ? \"▾\" : \"▸\"}\n </button>\n {/if}\n <button type=\"button\" class=\"unset leaf\" onclick={action}>\n {node.name}\n </button>\n </p>\n {/if}\n {#if is_directory && (is_expanded || is_root)}\n <ul>\n {#each node.children as child (child.path)}\n <Sources node={child} {on_select} {selected} />\n {/each}\n </ul>\n {/if}\n</li>\n\n<style>\n ul {\n padding: 0 0 0 0.5em;\n margin: 0;\n }\n\n p {\n position: relative;\n display: flex;\n padding-right: 0.5em;\n margin: 0;\n overflow: hidden;\n border-bottom: 1px solid var(--table-border);\n border-left: 1px solid var(--table-border);\n }\n\n p > * {\n padding: 1px;\n }\n\n .selected {\n background-color: var(--table-header-background);\n }\n\n .leaf {\n flex-grow: 1;\n margin-left: 1em;\n }\n\n .toggle {\n position: absolute;\n margin: 0 0.25rem;\n color: var(--treetable-expander);\n }\n\n .root {\n margin: 0 0.25rem;\n }\n</style>\n", "<script lang=\"ts\">\n import type { EditorView } from \"@codemirror/view\";\n import type { Snippet } from \"svelte\";\n\n import type { CodemirrorBeancount } from \"../../codemirror/types.ts\";\n import { urlFor } from \"../../helpers.ts\";\n import { _ } from \"../../i18n.ts\";\n import { modKey } from \"../../keyboard-shortcuts.ts\";\n import { router } from \"../../router.ts\";\n import { insert_entry } from \"../../stores/fava_options.ts\";\n import AppMenu from \"./AppMenu.svelte\";\n import AppMenuItem from \"./AppMenuItem.svelte\";\n import AppMenuSubItem from \"./AppMenuSubItem.svelte\";\n import Key from \"./Key.svelte\";\n import Sources from \"./Sources.svelte\";\n import { sources_tree } from \"./stores.ts\";\n\n interface Props {\n file_path: string;\n editor: EditorView;\n codemirror_beancount: CodemirrorBeancount;\n children: Snippet;\n }\n\n let { file_path, editor, codemirror_beancount, children }: Props = $props();\n\n function goToFileAndLine(filename: string, line?: number) {\n const url = $urlFor(\"editor/\", { file_path: filename, line });\n // only load if the file changed.\n const load = filename !== file_path;\n router.navigate(url, load);\n if (!load && line != null) {\n // Scroll to line if we didn't change to a different file.\n editor.dispatch(codemirror_beancount.scroll_to_line(editor.state, line));\n editor.focus();\n }\n }\n</script>\n\n<div>\n <AppMenu>\n <AppMenuItem name={_(\"File\")}>\n <Sources\n is_root\n node={$sources_tree}\n on_select={(source: string) => {\n goToFileAndLine(source);\n }}\n selected={file_path}\n ></Sources>\n </AppMenuItem>\n <AppMenuItem name={_(\"Edit\")}>\n <AppMenuSubItem\n action={() => codemirror_beancount.beancount_format(editor)}\n >\n {_(\"Align Amounts\")}\n {#snippet right()}\n <Key key={[modKey, \"d\"]} />\n {/snippet}\n </AppMenuSubItem>\n <AppMenuSubItem action={() => codemirror_beancount.toggleComment(editor)}>\n {_(\"Toggle Comment (selection)\")}\n {#snippet right()}\n <Key key={[modKey, \"/\"]} />\n {/snippet}\n </AppMenuSubItem>\n <AppMenuSubItem action={() => codemirror_beancount.unfoldAll(editor)}>\n {_(\"Open all folds\")}\n {#snippet right()}\n <Key key={[\"Ctrl\", \"Alt\", \"]\"]} />\n {/snippet}\n </AppMenuSubItem>\n <AppMenuSubItem action={() => codemirror_beancount.foldAll(editor)}>\n {_(\"Close all folds\")}\n {#snippet right()}\n <Key key={[\"Ctrl\", \"Alt\", \"[\"]} />\n {/snippet}\n </AppMenuSubItem>\n </AppMenuItem>\n {#if $insert_entry.length}\n <AppMenuItem name={`'insert-entry' ${_(\"Options\")}`}>\n {#each $insert_entry as opt (`${opt.filename}:${opt.lineno.toString()}`)}\n <AppMenuSubItem\n title={`${opt.filename}:${opt.lineno.toString()}`}\n action={() => {\n goToFileAndLine(opt.filename, opt.lineno - 1);\n }}\n >\n {opt.re}\n {#snippet right()}\n <span>{opt.date}</span>\n {/snippet}\n </AppMenuSubItem>\n {/each}\n </AppMenuItem>\n {/if}\n </AppMenu>\n {@render children()}\n</div>\n\n<style>\n div {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n background: var(--sidebar-background);\n border-bottom: 1px solid var(--sidebar-border);\n }\n</style>\n", "<script lang=\"ts\">\n import type { EditorView } from \"@codemirror/view\";\n import { onMount, untrack } from \"svelte\";\n\n import { get_errors, put_source } from \"../../api/index.ts\";\n import { attach_editor } from \"../../codemirror/dom.ts\";\n import SaveButton from \"../../editor/SaveButton.svelte\";\n import { log_error } from \"../../log.ts\";\n import { notify_err } from \"../../notifications.ts\";\n import { router } from \"../../router.ts\";\n import {\n currency_column,\n indent,\n insert_entry,\n } from \"../../stores/fava_options.ts\";\n import { errors } from \"../../stores/index.ts\";\n import EditorMenu from \"./EditorMenu.svelte\";\n import type { EditorReportProps } from \"./index.ts\";\n\n let { source, line_search_param, codemirror_beancount }: EditorReportProps =\n $props();\n\n let file_path = $derived(source.file_path);\n\n let changed = $state(false);\n const onDocChanges = () => {\n changed = true;\n };\n\n let sha256sum = $state(\"\");\n let saving = $state(false);\n\n /**\n * Save the contents of the editor.\n */\n async function save(cm: EditorView) {\n saving = true;\n try {\n sha256sum = await put_source({\n file_path,\n source: cm.state.sliceDoc(),\n sha256sum,\n });\n changed = false;\n cm.focus();\n get_errors().then((v) => {\n errors.set(v);\n }, log_error);\n } catch (error) {\n notify_err(error, (e) => e.message);\n } finally {\n saving = false;\n }\n }\n\n // svelte-ignore state_referenced_locally\n const editor = codemirror_beancount.init_beancount_editor(\n \"\",\n onDocChanges,\n [\n {\n key: \"Control-s\",\n mac: \"Meta-s\",\n run: () => {\n save(editor).catch(() => {\n // save should catch all errors itself, see above\n });\n return true;\n },\n },\n ],\n $indent,\n $currency_column,\n );\n\n $effect(() => {\n // update editor contents if source changes\n void source;\n untrack(() => {\n editor.dispatch(\n codemirror_beancount.replace_contents(editor.state, source.source),\n );\n sha256sum = source.sha256sum;\n editor.focus();\n changed = false;\n });\n });\n\n $effect(() => {\n // Go to line if the edited file changes. The line number is obtained from the\n // URL, last file insert option, or last file line (in that order).\n const last_insert_opt = untrack(() =>\n $insert_entry.filter((f) => f.filename === file_path).at(-1),\n );\n let line = editor.state.doc.lines;\n if (line_search_param != null) {\n line = line_search_param;\n } else if (last_insert_opt) {\n line = last_insert_opt.lineno - 1;\n }\n editor.dispatch(codemirror_beancount.scroll_to_line(editor.state, line));\n });\n\n $effect(() => {\n // Update diagnostics, showing errors in the editor\n // Only show errors for this file, or general errors (AKA no source)\n const errorsForFile = $errors.filter(\n (err) => err.source == null || err.source.filename === file_path,\n );\n editor.dispatch(\n codemirror_beancount.set_errors(editor.state, errorsForFile),\n );\n });\n\n const checkEditorChanges = () =>\n changed\n ? \"There are unsaved changes. Are you sure you want to leave?\"\n : null;\n\n onMount(() => router.add_interrupt_handler(checkEditorChanges));\n</script>\n\n<form\n class=\"fixed-fullsize-container\"\n onsubmit={async (event) => {\n event.preventDefault();\n return save(editor);\n }}\n>\n <EditorMenu {file_path} {editor} {codemirror_beancount}>\n <SaveButton {changed} {saving} />\n </EditorMenu>\n <div {@attach attach_editor(editor)}></div>\n</form>\n\n<style>\n form {\n display: flex;\n flex-direction: column;\n }\n\n form div {\n flex: 1;\n width: 100%;\n height: 100px; /* As a flex-base so that it uses exactly the available space. */\n }\n\n form :global(.cm-editor) {\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n</style>\n", "<!--\n @component\n Renders the links to download the query result in CSV and possibly\n other formats.\n-->\n<script lang=\"ts\">\n import { urlFor } from \"../../helpers.ts\";\n import { _ } from \"../../i18n.ts\";\n import { HAVE_EXCEL } from \"../../stores/index.ts\";\n\n interface Props {\n /** The query string. */\n query: string;\n }\n\n let { query }: Props = $props();\n let params = $derived({ query_string: query });\n</script>\n\n<span>\n ({_(\"Download as\")}\n <a href={$urlFor(\"download-query/query_result.csv\", params)} data-remote>\n CSV\n </a>\n {#if $HAVE_EXCEL}\n ,\n <a href={$urlFor(\"download-query/query_result.xlsx\", params)} data-remote>\n XLSX\n </a>\n , or\n <a href={$urlFor(\"download-query/query_result.ods\", params)} data-remote>\n ODS\n </a>\n {/if}\n )\n</span>\n\n<style>\n span {\n color: var(--text-color-lighter);\n }\n</style>\n", "<script lang=\"ts\">\n import type { EntryMetadata } from \"../entries/index.ts\";\n import { _ } from \"../i18n.ts\";\n\n interface Props {\n meta: EntryMetadata;\n }\n\n let { meta = $bindable() }: Props = $props();\n\n let meta_entries = $derived(meta.entries());\n</script>\n\n{#each meta_entries as [key, value], index (index)}\n <div class=\"flex-row\">\n <button\n type=\"button\"\n class=\"muted round remove-row\"\n onclick={() => {\n meta = meta.delete(key);\n }}\n tabindex={-1}\n >\n ×\n </button>\n <input\n type=\"text\"\n class=\"key\"\n placeholder={_(\"Key\")}\n value={key}\n onchange={(event) => {\n meta = meta.update_key(key, event.currentTarget.value);\n }}\n required\n />\n :\n <input\n type=\"text\"\n class=\"value\"\n placeholder={_(\"Value\")}\n {value}\n onchange={(event) => {\n meta = meta.set_string(key, event.currentTarget.value);\n }}\n />\n {#if index === meta_entries.length - 1 && key}\n <button\n type=\"button\"\n class=\"muted round\"\n onclick={() => {\n meta = meta.add();\n }}\n aria-label={_(\"Add metadata\")}\n title={_(\"Add metadata\")}\n >\n +\n </button>\n {/if}\n </div>\n{/each}\n\n<style>\n div {\n padding-left: 3rem;\n }\n\n input.key {\n width: 12rem;\n }\n\n input.value {\n flex-grow: 1;\n }\n\n @media (width <= 767px) {\n div {\n padding-left: 0;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import type { EntryMetadata, Note } from \"../entries/index.ts\";\n import { _ } from \"../i18n.ts\";\n import AccountInput from \"./AccountInput.svelte\";\n import AddMetadataButton from \"./AddMetadataButton.svelte\";\n import EntryMetadataSvelte from \"./EntryMetadata.svelte\";\n\n interface Props {\n entry: Note;\n }\n\n let { entry = $bindable() }: Props = $props();\n</script>\n\n<div class=\"flex-column\">\n <div class=\"flex-row\">\n <input\n type=\"date\"\n name=\"date\"\n bind:value={\n () => entry.date,\n (date: string) => {\n entry = entry.set(\"date\", date);\n }\n }\n required\n />\n <h4>{_(\"Note\")}</h4>\n <AccountInput\n bind:value={\n () => entry.account,\n (account: string) => {\n entry = entry.set(\"account\", account);\n }\n }\n date={entry.date}\n required\n --autocomplete-wrapper-flex=\"1\"\n />\n <AddMetadataButton\n bind:meta={\n () => entry.meta,\n (meta: EntryMetadata) => {\n entry = entry.set(\"meta\", meta);\n }\n }\n />\n </div>\n <textarea\n rows={2}\n placeholder=\"Comment\"\n bind:value={\n () => entry.comment,\n (comment: string) => {\n entry = entry.set(\"comment\", comment);\n }\n }\n ></textarea>\n <EntryMetadataSvelte\n bind:meta={\n () => entry.meta,\n (meta: EntryMetadata) => {\n entry = entry.set(\"meta\", meta);\n }\n }\n />\n</div>\n\n<style>\n textarea {\n resize: vertical;\n }\n</style>\n", "<script lang=\"ts\">\n import AutocompleteInput from \"../AutocompleteInput.svelte\";\n import type { EntryMetadata, Posting } from \"../entries/index.ts\";\n import { _ } from \"../i18n.ts\";\n import { currencies } from \"../stores/index.ts\";\n import AccountInput from \"./AccountInput.svelte\";\n import AddMetadataButton from \"./AddMetadataButton.svelte\";\n import EntryMetadataSvelte from \"./EntryMetadata.svelte\";\n\n interface Props {\n /** The posting to show and edit. */\n posting: Posting;\n /** Index in the list of postings, used to move it. */\n index: number;\n /** Account suggestions. */\n suggestions?: string[] | undefined;\n /** Entry date to limit account suggestions. */\n date?: string;\n /** Handler to move a posting to another position on drag. */\n move: (arg: { from: number; to: number }) => void;\n /** Handler to remove this posting. */\n remove: () => void;\n }\n\n let {\n posting = $bindable(),\n index,\n suggestions,\n date,\n move,\n remove,\n }: Props = $props();\n\n let amount_number = $derived(posting.amount.replace(/[^\\-?0-9.]/g, \"\"));\n let amountSuggestions = $derived(\n $currencies.map((c) => `${amount_number} ${c}`),\n );\n\n let drag = $state.raw(false);\n let draggable = $state.raw(true);\n\n function mousemove(event: MouseEvent) {\n draggable = !(event.target instanceof HTMLInputElement);\n }\n function dragstart(event: DragEvent) {\n event.dataTransfer?.setData(\"fava/posting\", index.toString());\n }\n function dragenter(event: DragEvent) {\n const types = event.dataTransfer?.types ?? [];\n if (types.includes(\"fava/posting\")) {\n event.preventDefault();\n drag = true;\n }\n }\n function dragleave() {\n drag = false;\n }\n function drop(event: DragEvent) {\n event.preventDefault();\n const from = event.dataTransfer?.getData(\"fava/posting\");\n if (from != null) {\n move({ from: +from, to: index });\n drag = false;\n }\n }\n</script>\n\n<div\n class=\"flex-row\"\n class:drag\n {draggable}\n onmousemove={mousemove}\n ondragstart={dragstart}\n ondragenter={dragenter}\n ondragover={dragenter}\n ondragleave={dragleave}\n ondrop={drop}\n role=\"group\"\n>\n <button\n type=\"button\"\n class=\"muted round remove-row\"\n onclick={remove}\n tabindex={-1}\n >\n ×\n </button>\n <AccountInput\n bind:value={\n () => posting.account,\n (account: string) => {\n posting = posting.set(\"account\", account);\n }\n }\n {suggestions}\n {date}\n --autocomplete-wrapper-flex=\"2\"\n />\n <AutocompleteInput\n placeholder={_(\"Amount\")}\n suggestions={amountSuggestions}\n bind:value={\n () => posting.amount,\n (amount: string) => {\n posting = posting.set(\"amount\", amount);\n }\n }\n --autocomplete-wrapper-flex=\"1\"\n />\n <AddMetadataButton\n bind:meta={\n () => posting.meta,\n (meta: EntryMetadata) => {\n posting = posting.set(\"meta\", meta);\n }\n }\n />\n</div>\n<EntryMetadataSvelte\n bind:meta={\n () => posting.meta,\n (meta: EntryMetadata) => {\n posting = posting.set(\"meta\", meta);\n }\n }\n/>\n\n<style>\n .drag {\n box-shadow: var(--box-shadow-button);\n }\n\n div {\n padding-left: 3rem;\n cursor: grab;\n }\n\n div > * {\n cursor: initial;\n }\n\n div:last-child .remove-row {\n visibility: hidden;\n }\n\n @media (width <= 767px) {\n div {\n padding-left: 0;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import {\n get_narration_transaction,\n get_narrations,\n get_payee_accounts,\n get_payee_transaction,\n } from \"../api/index.ts\";\n import AutocompleteInput from \"../AutocompleteInput.svelte\";\n import type { EntryMetadata, Transaction } from \"../entries/index.ts\";\n import { Posting } from \"../entries/index.ts\";\n import { _ } from \"../i18n.ts\";\n import { move } from \"../lib/array.ts\";\n import { notify_err } from \"../notifications.ts\";\n import { payees } from \"../stores/index.ts\";\n import AddMetadataButton from \"./AddMetadataButton.svelte\";\n import EntryMetadataSvelte from \"./EntryMetadata.svelte\";\n import PostingSvelte from \"./Posting.svelte\";\n\n interface Props {\n entry: Transaction;\n }\n\n let { entry = $bindable() }: Props = $props();\n let suggestions: string[] | undefined = $state.raw();\n\n let payee = $derived(entry.payee);\n $effect(() => {\n if (payee) {\n suggestions = undefined;\n if ($payees.includes(payee)) {\n get_payee_accounts({ payee })\n .then((s) => {\n suggestions = s;\n })\n .catch((error: unknown) => {\n notify_err(\n error,\n (err) =>\n `Fetching account suggestions for payee ${payee} failed: ${err.message}`,\n );\n });\n }\n }\n });\n\n let narration = $derived(entry.get_narration_tags_links());\n let narration_suggestions: string[] = $state.raw([]);\n $effect(() => {\n get_narrations()\n .then((s) => {\n narration_suggestions = s;\n })\n .catch((error: unknown) => {\n notify_err(\n error,\n (err) => `Fetching narration suggestions failed: ${err.message}`,\n );\n });\n });\n\n // Autofill complete transactions.\n async function autocompleteSelectPayee() {\n if (entry.narration || entry.postings.some((p) => !p.is_empty())) {\n return;\n }\n const payee_transaction = await get_payee_transaction({\n payee: entry.payee,\n });\n entry = payee_transaction.set(\"date\", entry.date);\n }\n async function autocompleteSelectNarration() {\n if (entry.payee || entry.postings.some((p) => !p.is_empty())) {\n return;\n }\n const data = await get_narration_transaction({ narration });\n data.set(\"date\", entry.date);\n entry = data;\n narration = entry.get_narration_tags_links();\n }\n\n // Always have one empty posting at the end.\n $effect(() => {\n if (!entry.postings.some((p) => p.is_empty())) {\n entry = entry.set(\"postings\", entry.postings.concat(Posting.empty()));\n }\n });\n</script>\n\n<div class=\"flex-column\">\n <div class=\"flex-row\">\n <input\n type=\"date\"\n bind:value={\n () => entry.date,\n (date: string) => {\n entry = entry.set(\"date\", date);\n }\n }\n required\n />\n <input\n type=\"text\"\n name=\"flag\"\n bind:value={\n () => entry.flag,\n (flag: string) => {\n entry = entry.set(\"flag\", flag);\n }\n }\n required\n />\n <label>\n <span class=\"hide-on-desktop\">{_(\"Payee\")}:</span>\n <AutocompleteInput\n placeholder={_(\"Payee\")}\n bind:value={\n () => entry.payee,\n (payee: string) => {\n entry = entry.set(\"payee\", payee);\n }\n }\n suggestions={$payees}\n onSelect={autocompleteSelectPayee}\n --autocomplete-wrapper-flex=\"1\"\n />\n </label>\n <label class=\"narration\">\n <span class=\"hide-on-desktop\">{_(\"Narration\")}:</span>\n <AutocompleteInput\n placeholder={_(\"Narration\")}\n bind:value={narration}\n suggestions={narration_suggestions}\n onSelect={autocompleteSelectNarration}\n onEnter={() => {\n entry = entry.set_narration_tags_links(narration);\n }}\n onBlur={() => {\n entry = entry.set_narration_tags_links(narration);\n }}\n --autocomplete-wrapper-flex=\"2\"\n />\n <AddMetadataButton\n bind:meta={\n () => entry.meta,\n (meta: EntryMetadata) => {\n entry = entry.set(\"meta\", meta);\n }\n }\n />\n </label>\n </div>\n <EntryMetadataSvelte\n bind:meta={\n () => entry.meta,\n (meta: EntryMetadata) => {\n entry = entry.set(\"meta\", meta);\n }\n }\n />\n <div class=\"flex-row hide-on-desktop\">\n <span class=\"label\">{_(\"Postings\")}:</span>\n </div>\n {#each entry.postings, index (index)}\n <!-- Using the indexed access (instead of `as posting` in the each) seems to track\n the reactivity differently and avoids cursor jumping on the posting inputs. -->\n {@const posting = entry.postings[index]}\n {#if posting}\n <PostingSvelte\n bind:posting={\n () => posting,\n (posting: Posting) => {\n entry = entry.set(\"postings\", entry.postings.with(index, posting));\n }\n }\n {index}\n {suggestions}\n date={entry.date}\n move={({ from, to }: { from: number; to: number }) => {\n entry = entry.set(\"postings\", move(entry.postings, from, to));\n }}\n remove={() => {\n entry = entry.set(\"postings\", entry.postings.toSpliced(index, 1));\n }}\n />\n {/if}\n {/each}\n</div>\n\n<style>\n input[name=\"flag\"] {\n width: 1.5em;\n padding-right: 2px;\n padding-left: 2px;\n text-align: center;\n }\n\n .hide-on-desktop {\n display: none;\n }\n\n @media (width <= 767px) {\n .hide-on-desktop {\n display: initial;\n width: 100%;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import type { Entry as EntryType } from \"../../entries/index.ts\";\n import Entry from \"../../entry-forms/Entry.svelte\";\n import { _ } from \"../../i18n.ts\";\n import ModalBase from \"../../modals/ModalBase.svelte\";\n\n interface Props {\n entries: EntryType[];\n save: () => void;\n close: () => void;\n }\n\n let { entries = $bindable(), save, close }: Props = $props();\n\n let currentIndex = $state.raw(0);\n let count = $derived(entries.length);\n let shown = $derived(count > 0);\n\n let entry = $derived(entries[currentIndex]);\n let duplicate = $derived(entry?.is_duplicate());\n let count_duplicates = $derived(\n entries.filter((e) => e.is_duplicate()).length,\n );\n $effect(() => {\n if (count > 0 && currentIndex >= count) {\n currentIndex = 0;\n }\n });\n\n function submitOrNext(event: SubmitEvent) {\n event.preventDefault();\n if (currentIndex < count - 1) {\n currentIndex += 1;\n } else {\n save();\n }\n }\n\n function previousEntry() {\n currentIndex = Math.max(currentIndex - 1, 0);\n }\n\n function toggleDuplicate() {\n if (entry) {\n entries[currentIndex] = entry.set_meta(\n \"__duplicate__\",\n !entry.is_duplicate(),\n );\n }\n }\n\n let current_index_from_one = $derived(currentIndex + 1);\n let count_without_duplicates = $derived(count - count_duplicates);\n</script>\n\n<ModalBase {shown} closeHandler={close}>\n <form class=\"flex-column\" novalidate={duplicate} onsubmit={submitOrNext}>\n <h3>{_(\"Import\")}</h3>\n {#if entry}\n <div class=\"flex-row\">\n <h3>\n Entry\n {current_index_from_one}\n of\n {count}\n ({count_without_duplicates}\n to import):\n </h3>\n <span class=\"spacer\"></span>\n <label class=\"button muted\">\n <input\n type=\"checkbox\"\n checked={duplicate}\n onclick={toggleDuplicate}\n />\n {_(\"ignore duplicate\")}\n </label>\n </div>\n <div class:duplicate>\n <Entry\n bind:entry={\n () => entry,\n (entry: EntryType) => {\n entries[currentIndex] = entry;\n }\n }\n />\n </div>\n <div class=\"flex-row\">\n {#if currentIndex > 0}\n <button\n type=\"button\"\n class=\"muted\"\n onclick={() => {\n currentIndex = 0;\n }}\n >\n ⏮\n </button>\n <button type=\"button\" class=\"muted\" onclick={previousEntry}>\n {_(\"Previous\")}\n </button>\n {/if}\n <span class=\"spacer\"></span>\n {#if currentIndex < entries.length - 1}\n <button type=\"submit\">{_(\"Next\")}</button>\n <button\n type=\"button\"\n class=\"muted\"\n onclick={() => {\n currentIndex = entries.length - 1;\n }}\n >\n ⏭\n </button>\n {:else}<button type=\"submit\">{_(\"Save\")}</button>{/if}\n </div>\n {#if entry.meta.get(\"__source__\")}\n <hr />\n <h3>\n {_(\"Source\")}\n {#if entry.meta.lineno}({_(\"Line\")}: {entry.meta.lineno}){/if}\n </h3>\n <pre>{entry.meta.get(\"__source__\")}</pre>\n {/if}\n {/if}\n </form>\n</ModalBase>\n\n<style>\n pre {\n margin: 0;\n font-size: 0.9em;\n white-space: pre-wrap;\n }\n\n .duplicate {\n display: contents;\n opacity: 0.5;\n }\n</style>\n", "<script lang=\"ts\">\n import type { Entry } from \"../../entries/index.ts\";\n import AccountInput from \"../../entry-forms/AccountInput.svelte\";\n import { _ } from \"../../i18n.ts\";\n import type { ProcessedImportableFile } from \"./index.ts\";\n\n interface Props {\n files: ProcessedImportableFile[];\n extract_cache: Map<string, Entry[]>;\n file_accounts: Map<string, string>;\n file_names: Map<string, string>;\n selected: string | null;\n remove: (name: string) => void;\n move: (name: string, a: string, newName: string) => void;\n extract: (name: string, importer: string) => void;\n }\n\n let {\n files,\n extract_cache = $bindable(),\n file_accounts = $bindable(),\n file_names = $bindable(),\n selected = $bindable(),\n remove,\n move,\n extract,\n }: Props = $props();\n</script>\n\n{#each files as file (file.name)}\n <div class=\"header\" title={file.name} class:selected={selected === file.name}>\n <button\n type=\"button\"\n class=\"unset\"\n onclick={() => {\n selected = selected === file.name ? null : file.name;\n }}\n >\n {file.basename}\n </button>\n <button\n type=\"button\"\n class=\"round\"\n onclick={() => {\n remove(file.name);\n }}\n title={_(\"Delete\")}\n tabindex={-1}\n >\n ×\n </button>\n </div>\n <div class=\"flex-column\">\n {#each file.importers as info (info.importer_name)}\n {@const file_importer_key = `${file.name}:${info.importer_name}`}\n {@const account = file_accounts.get(file_importer_key) ?? info.account}\n {@const new_name = file_names.get(file_importer_key) ?? info.newName}\n <form\n class=\"flex-row\"\n onsubmit={(event) => {\n event.preventDefault();\n move(file.name, account, new_name);\n }}\n >\n <AccountInput\n bind:value={\n () => account,\n (value: string) => {\n file_accounts.set(file_importer_key, value);\n }\n }\n required\n />\n <input\n size={40}\n bind:value={\n () => new_name,\n (value: string) => {\n file_names.set(file_importer_key, value);\n }\n }\n />\n <button type=\"submit\">\n {_(\"Move\")}\n </button>\n {#if info.importer_name}\n {@const is_cached = extract_cache.has(file_importer_key)}\n <button\n type=\"button\"\n title=\"{_('Extract')} with importer {info.importer_name}\"\n onclick={() => {\n extract(file.name, info.importer_name);\n }}\n >\n {is_cached ? _(\"Continue\") : _(\"Extract\")}\n </button>\n {#if is_cached}\n <button\n type=\"button\"\n onclick={() => {\n extract_cache.delete(file_importer_key);\n }}\n >\n {_(\"Clear\")}\n </button>\n {/if}\n {info.importer_name}\n {/if}\n </form>\n {/each}\n </div>\n{/each}\n\n<style>\n .header {\n padding: 0.5rem;\n background-color: var(--summary-background);\n }\n\n .header button:first-child {\n width: 90%;\n }\n\n .header button:nth-child(2) {\n float: right;\n }\n\n .header.selected {\n background-color: var(--summary-background-darker);\n }\n</style>\n", "<script lang=\"ts\">\n import { onMount } from \"svelte\";\n import { SvelteMap } from \"svelte/reactivity\";\n\n import {\n delete_document,\n get_extract,\n move_document,\n save_entries,\n } from \"../../api/index.ts\";\n import type { Entry } from \"../../entries/index.ts\";\n import { urlFor } from \"../../helpers.ts\";\n import { _ } from \"../../i18n.ts\";\n import { is_non_empty } from \"../../lib/array.ts\";\n import { notify, notify_err } from \"../../notifications.ts\";\n import { router } from \"../../router.ts\";\n import { import_config } from \"../../stores/fava_options.ts\";\n import DocumentPreview from \"../documents/DocumentPreview.svelte\";\n import Extract from \"./Extract.svelte\";\n import FileList from \"./FileList.svelte\";\n import ImportFileUpload from \"./ImportFileUpload.svelte\";\n import type { ImportReportProps } from \"./index.ts\";\n\n let { files }: ImportReportProps = $props();\n\n // initially show the other files if no importable files are present\n // svelte-ignore state_referenced_locally\n const show_other_files_initially = files.every(\n (file) => !file.identified_by_importers,\n );\n\n /** Whether the `<details>` for the \"other files\" is open. */\n let show_other_files = $state.raw(show_other_files_initially);\n\n /** The array of entries to show the modal for. */\n let entries: Entry[] = $state([]);\n\n /** Name of the currently selected file. */\n let selected: string | null = $state.raw(null);\n\n /** The lists of entries for file and importer combos where extract was started and not completed. */\n let extract_cache = new SvelteMap<string, Entry[]>();\n /** The account names chosen for a file and importer. */\n let file_accounts = new SvelteMap<string, string>();\n /** The names chosen for a file and importer. */\n let file_names = new SvelteMap<string, string>();\n\n /** Importable files. */\n let importable_files = $derived(\n files.filter((file) => file.identified_by_importers),\n );\n /** Files not identified by any importer. */\n let other_files = $derived(\n files.filter((file) => !file.identified_by_importers),\n );\n\n const preventNavigation = () =>\n extract_cache.size > 0\n ? \"There are unfinished imports, are you sure you want to continue?\"\n : null;\n\n onMount(() => router.add_interrupt_handler(preventNavigation));\n\n /**\n * Move the given file to the new file name (and remove from the list).\n */\n async function move(filename: string, account: string, newName: string) {\n const moved = await move_document(filename, account, newName);\n if (moved) {\n router.reload();\n }\n }\n\n /**\n * Delete the given file and remove it from the displayed list.\n */\n async function remove(filename: string) {\n if (!window.confirm(_(\"Delete this file?\"))) {\n return;\n }\n const removed = await delete_document(filename);\n if (removed) {\n if (selected === filename) {\n selected = null;\n }\n router.reload();\n }\n }\n\n /**\n * Open the extract dialog for the given file/importer combination.\n */\n async function extract(filename: string, importer: string) {\n const file_importer_key = `${filename}:${importer}`;\n const cached = extract_cache.get(file_importer_key);\n if (cached) {\n entries = cached;\n return;\n }\n try {\n entries = await get_extract({ filename, importer });\n if (entries.length) {\n extract_cache.set(file_importer_key, entries);\n } else {\n notify(\"No entries to import from this file.\", \"warning\");\n }\n } catch (error) {\n notify_err(error);\n }\n }\n\n /**\n * Save the current entries.\n */\n async function save() {\n const without_duplicates = entries.filter((e) => !e.is_duplicate());\n const key = [...extract_cache].find(([, e]) => e === entries)?.[0];\n if (key != null) {\n extract_cache.delete(key);\n }\n entries = [];\n if (is_non_empty(without_duplicates)) {\n await save_entries(without_duplicates);\n }\n }\n</script>\n\n{#if $import_config == null}\n <p>\n No importers configured. See <a href={$urlFor(\"help/import\")}\n >Help (Import)</a\n > for more information.\n </p>\n{:else}\n <Extract\n bind:entries\n close={() => {\n entries = [];\n }}\n {save}\n />\n <div class=\"fixed-fullsize-container\">\n <div class=\"filelist flex-column\">\n {#if files.length === 0}\n <p>{_(\"No files were found for import.\")}</p>\n {/if}\n {#if importable_files.length > 0}\n <h2>{_(\"Importable Files\")}</h2>\n <FileList\n files={importable_files}\n {extract_cache}\n {file_accounts}\n {file_names}\n bind:selected\n {move}\n {remove}\n {extract}\n />\n {/if}\n {#if other_files.length > 0}\n <details bind:open={show_other_files}>\n <summary>{_(\"Non-importable Files\")}</summary>\n <FileList\n files={other_files}\n {extract_cache}\n {file_accounts}\n {file_names}\n bind:selected\n {move}\n {remove}\n {extract}\n />\n </details>\n {/if}\n <ImportFileUpload />\n </div>\n {#if selected}\n <div>\n <DocumentPreview filename={selected} />\n </div>\n {/if}\n </div>\n{/if}\n\n<style>\n .fixed-fullsize-container {\n display: flex;\n align-items: stretch;\n }\n\n .fixed-fullsize-container > * {\n flex: 1 1 40%;\n overflow: auto;\n }\n\n .filelist {\n padding: 1rem;\n }\n</style>\n", "<script lang=\"ts\">\n import { _ } from \"../../i18n.ts\";\n import { Sorter, StringColumn } from \"../../sort/index.ts\";\n import SortHeader from \"../../sort/SortHeader.svelte\";\n\n type T = [string, string];\n interface Props {\n options: Record<string, string>;\n }\n\n let { options }: Props = $props();\n\n const columns = [\n new StringColumn<T>(_(\"Key\"), (d) => d[0]),\n new StringColumn<T>(_(\"Value\"), (d) => d[1]),\n ] as const;\n let sorter = $state(new Sorter(columns[0], \"asc\"));\n\n let options_array = $derived(Object.entries(options));\n let sorted_options = $derived(sorter.sort(options_array));\n</script>\n\n<table>\n <thead>\n <tr>\n {#each columns as column (column)}\n <SortHeader bind:sorter {column} />\n {/each}\n </tr>\n </thead>\n <tbody>\n {#each sorted_options as [key, value] (key)}\n <tr>\n <td>{key}</td>\n <td><pre>{value}</pre></td>\n </tr>\n {/each}\n </tbody>\n</table>\n\n<style>\n td:nth-child(1) {\n font-weight: 500;\n }\n</style>\n", "<script lang=\"ts\">\n import { attach_editor } from \"../../codemirror/dom.ts\";\n import type { CodemirrorBql } from \"../../codemirror/types.ts\";\n\n interface Props {\n value: string;\n error?: boolean | undefined;\n codemirror_bql: CodemirrorBql;\n }\n\n let { value, error = false, codemirror_bql }: Props = $props();\n\n let editor = $derived(codemirror_bql.init_readonly_query_editor(value));\n</script>\n\n<pre class:error {@attach attach_editor(editor)}></pre>\n\n<style>\n .error {\n border: 1px solid var(--error);\n }\n</style>\n", "<!--\n @component\n Renders a query result in a collapsible box.\n-->\n<script lang=\"ts\">\n import Chart from \"../../charts/Chart.svelte\";\n import { chartContext } from \"../../charts/context.ts\";\n import { getQueryChart } from \"../../charts/query-charts.ts\";\n import type { CodemirrorBql } from \"../../codemirror/types.ts\";\n import type { Result } from \"../../lib/result.ts\";\n import type { QueryResult } from \"./query_table.ts\";\n import QueryLinks from \"./QueryLinks.svelte\";\n import QueryTable from \"./QueryTable.svelte\";\n import ReadonlyQueryEditor from \"./ReadonlyQueryEditor.svelte\";\n\n interface Props {\n /** The query string. */\n query: string;\n /** The query result, possibly missing or an error. */\n result?: Result<QueryResult, string> | undefined;\n /** Whether this box is open. */\n open?: boolean | undefined;\n /** Handler to run on 'select' (clicking the summary bar). */\n onselect: () => void;\n /** Handler to run on 'delete' (clicking the x button). */\n ondelete: () => void;\n codemirror_bql: CodemirrorBql;\n }\n\n let {\n query,\n result,\n open = $bindable(),\n onselect,\n ondelete,\n codemirror_bql,\n }: Props = $props();\n\n let inactive = $derived(!result);\n</script>\n\n<details bind:open>\n <summary class:inactive onclick={inactive ? onselect : null}>\n <ReadonlyQueryEditor\n value={query}\n error={result?.is_err}\n {codemirror_bql}\n />\n <span class=\"spacer\"></span>\n {#if result && result.is_ok && result.value.t === \"table\"}\n <QueryLinks {query} />\n {/if}\n <button\n type=\"button\"\n onclick={(ev) => {\n ev.stopPropagation();\n ondelete();\n }}\n >\n x\n </button>\n </summary>\n <div>\n {#if result}\n {#if result.is_ok}\n {#if result.value.t === \"string\"}\n <pre><code>{result.value.contents}</code></pre>\n {:else}\n {@const chart = getQueryChart(result.value, $chartContext)}\n {#if chart}\n <Chart {chart} />\n {/if}\n <QueryTable table={result.value} />\n {/if}\n {:else}\n <pre><code>{result.error}</code></pre>\n {/if}\n {/if}\n </div>\n</details>\n\n<style>\n details > div {\n max-height: 70vh;\n overflow: auto;\n }\n\n .inactive {\n filter: opacity(0.5);\n }\n\n pre {\n margin: 0;\n }\n</style>\n", "<script lang=\"ts\">\n import { attach_editor } from \"../../codemirror/dom.ts\";\n import type { CodemirrorBql } from \"../../codemirror/types.ts\";\n import { _ } from \"../../i18n.ts\";\n import { keyboardShortcut } from \"../../keyboard-shortcuts.ts\";\n\n interface Props {\n value: string;\n submit: () => void;\n codemirror_bql: CodemirrorBql;\n }\n\n let { value = $bindable(), submit, codemirror_bql }: Props = $props();\n\n // svelte-ignore state_referenced_locally\n const editor = codemirror_bql.init_query_editor(\n value,\n (state) => {\n value = state.sliceDoc();\n },\n _(\"...enter a BQL query. 'help' to list available commands.\"),\n () => submit,\n );\n\n $effect(() => {\n if (value !== editor.state.sliceDoc()) {\n editor.dispatch(codemirror_bql.replace_contents(editor.state, value));\n }\n });\n</script>\n\n<form\n onsubmit={(event) => {\n event.preventDefault();\n submit();\n }}\n>\n <div {@attach attach_editor(editor)}></div>\n <button type=\"submit\" {@attach keyboardShortcut(\"Control+Enter\")}>\n {_(\"Submit\")}\n </button>\n</form>\n\n<style>\n form {\n display: flex;\n align-items: center;\n padding-bottom: 1em;\n }\n\n button {\n margin: 0;\n }\n\n div {\n flex-grow: 1;\n width: 100%;\n height: auto;\n margin-right: 0.5em;\n font-size: 16px;\n border: 1px solid var(--border);\n }\n\n form :global(.cm-editor) {\n width: 100%;\n }\n</style>\n", "<script lang=\"ts\">\n import { writable } from \"svelte/store\";\n\n import type { AccountTreeNode } from \"../charts/hierarchy.ts\";\n import { _ } from \"../i18n.ts\";\n import { invert_account } from \"../stores/accounts.ts\";\n import { currency_name } from \"../stores/index.ts\";\n import { operating_currency } from \"../stores/options.ts\";\n import AccountCellHeader from \"./AccountCellHeader.svelte\";\n import { get_not_shown, setTreeTableNotShownContext } from \"./helpers.ts\";\n import TreeTableNode from \"./TreeTableNode.svelte\";\n\n interface Props {\n /** The account tree to show. */\n tree: AccountTreeNode;\n /** The end date (for closed accounts). */\n end: Date | null;\n }\n\n let { tree, end }: Props = $props();\n let account = $derived(tree.account);\n\n const not_shown = writable(new Set<string>());\n setTreeTableNotShownContext(not_shown);\n\n $effect(() => {\n $not_shown = $get_not_shown(tree, end);\n });\n</script>\n\n<ol\n class=\"flex-table tree-table-new\"\n class:wider={$operating_currency.length > 1}\n>\n <li class=\"head\">\n <p>\n <AccountCellHeader {account} />\n {#each $operating_currency as currency (currency)}\n <span class=\"num\" title={$currency_name(currency)}>{currency}</span>\n {/each}\n <span class=\"num other\">{_(\"Other\")}</span>\n </p>\n </li>\n {#each account === \"\" ? tree.children : [tree] as node (node.account)}\n <TreeTableNode {node} invert={$invert_account(node.account) ? -1 : 1} />\n {/each}\n</ol>\n\n<style>\n /* For two or more operating currencies, set a slightly smaller size. */\n .wider {\n font-size: 0.9em;\n }\n</style>\n", "<script lang=\"ts\">\n import { save_entries } from \"../api/index.ts\";\n import { Balance, Note, Transaction } from \"../entries/index.ts\";\n import Entry from \"../entry-forms/Entry.svelte\";\n import { todayAsString } from \"../format.ts\";\n import { _ } from \"../i18n.ts\";\n import { router } from \"../router.ts\";\n import { addEntryContinue } from \"../stores/editor.ts\";\n import { hash } from \"../stores/url.ts\";\n import ModalBase from \"./ModalBase.svelte\";\n\n /** The entry types which have support adding in the modal. */\n const entryTypes = [\n [Transaction, _(\"Transaction\")],\n [Balance, _(\"Balance\")],\n [Note, _(\"Note\")],\n ] as const;\n\n // For the first entry to be added, use today as the default date.\n let entry: Transaction | Balance | Note = $state.raw(\n Transaction.empty(todayAsString()),\n );\n\n async function submit(event: SubmitEvent) {\n event.preventDefault();\n await save_entries([entry]);\n const added_entry_date = entry.date;\n // Reuse the date of the entry that was just added.\n // @ts-expect-error all these entries have that static method, but TS is not able to determine that\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n entry = entry.constructor.empty(added_entry_date);\n if (!$addEntryContinue) {\n router.close_overlay();\n }\n }\n\n let shown = $derived($hash === \"add-transaction\");\n</script>\n\n<ModalBase {shown} focus=\".payee input\">\n <form onsubmit={submit} class=\"flex-column\">\n <h3>\n {_(\"Add\")}\n {#each entryTypes as [Cls, displayName] (displayName)}\n <button\n type=\"button\"\n class:muted={!(entry instanceof Cls)}\n onclick={() => {\n // when switching between entry types, keep the date.\n entry = Cls.empty(entry.date);\n }}\n >\n {displayName}\n </button>\n <!-- eslint-disable-next-line svelte/no-useless-mustaches -->\n {\" \"}\n {/each}\n </h3>\n <Entry bind:entry />\n <div class=\"flex-row\">\n <span class=\"spacer\"></span>\n <label>\n <input type=\"checkbox\" bind:checked={$addEntryContinue} />\n <span>{_(\"continue\")}</span>\n </label>\n <button type=\"submit\">{_(\"Save\")}</button>\n </div>\n </form>\n</ModalBase>\n\n<style>\n h3 {\n margin: 0;\n }\n\n label span {\n margin-right: 1rem;\n }\n</style>\n", "<script lang=\"ts\">\n import { delete_source_slice, put_source_slice } from \"../api/index.ts\";\n import { attach_editor } from \"../codemirror/dom.ts\";\n import type { CodemirrorBeancount } from \"../codemirror/types.ts\";\n import { _ } from \"../i18n.ts\";\n import { notify_err } from \"../notifications.ts\";\n import { router } from \"../router.ts\";\n import { reloadAfterSavingEntrySlice } from \"../stores/editor.ts\";\n import { currency_column, indent } from \"../stores/fava_options.ts\";\n import DeleteButton from \"./DeleteButton.svelte\";\n import SaveButton from \"./SaveButton.svelte\";\n\n interface Props {\n slice: string;\n entry_hash: string;\n sha256sum: string;\n codemirror_beancount: CodemirrorBeancount;\n }\n\n let {\n slice,\n entry_hash = $bindable(),\n sha256sum = $bindable(),\n codemirror_beancount,\n }: Props = $props();\n\n // Keep the initital slice value to check for changes.\n // svelte-ignore state_referenced_locally\n const initial_slice = slice;\n\n let currentSlice = $state(initial_slice);\n let changed = $derived(currentSlice !== initial_slice);\n\n let saving = $state(false);\n let deleting = $state(false);\n\n async function save(event?: SubmitEvent) {\n event?.preventDefault();\n saving = true;\n try {\n sha256sum = await put_source_slice({\n entry_hash,\n source: currentSlice,\n sha256sum,\n });\n if ($reloadAfterSavingEntrySlice) {\n router.reload();\n }\n router.close_overlay();\n } catch (error) {\n notify_err(error, (err) => `Saving failed: ${err.message}`);\n } finally {\n saving = false;\n }\n }\n\n async function deleteSlice() {\n deleting = true;\n try {\n await delete_source_slice({ entry_hash, sha256sum });\n entry_hash = \"\";\n if ($reloadAfterSavingEntrySlice) {\n router.reload();\n }\n router.close_overlay();\n } catch (error) {\n notify_err(error, (err) => `Deleting failed: ${err.message}`);\n } finally {\n deleting = false;\n }\n }\n\n // svelte-ignore state_referenced_locally\n const editor = codemirror_beancount.init_beancount_editor(\n initial_slice,\n (state) => {\n currentSlice = state.sliceDoc();\n },\n [\n {\n key: \"Control-s\",\n mac: \"Meta-s\",\n run: () => {\n save().catch(() => {\n // save should catch all errors itself, see above\n });\n return true;\n },\n },\n ],\n $indent,\n $currency_column,\n );\n</script>\n\n<form onsubmit={save} class=\"flex-column\">\n <div class=\"editor\" {@attach attach_editor(editor)}></div>\n <div class=\"flex-row\">\n <span class=\"spacer\"></span>\n <label>\n <input type=\"checkbox\" bind:checked={$reloadAfterSavingEntrySlice} />\n <span>{_(\"reload\")}</span>\n </label>\n <DeleteButton {deleting} onDelete={deleteSlice} />\n <SaveButton {changed} {saving} />\n </div>\n</form>\n\n<style>\n .editor {\n border: 1px solid var(--sidebar-border);\n }\n</style>\n", "<script lang=\"ts\">\n import type { EntryBaseAttributes } from \"../entries/index.ts\";\n import { urlForSource } from \"../helpers.ts\";\n import { _ } from \"../i18n.ts\";\n\n interface Props {\n entry: EntryBaseAttributes;\n }\n\n let { entry }: Props = $props();\n</script>\n\n<p>\n {_(\"Location\")}:\n <code>\n <a href={$urlForSource(entry.meta.filename, entry.meta.lineno)}>\n {entry.meta.filename}:{entry.meta.lineno}\n </a>\n </code>\n</p>\n\n<style>\n code {\n display: inline-block;\n max-width: 80%;\n padding: 2px 4px;\n vertical-align: top;\n }\n</style>\n", "<!--\n @component\n On drag-and-dropping of links (to documents) or files onto an entry or an\n account, this modal overlay allows one to fill in account name and or change\n the file name.\n\n File uploads via Drag and Drop on elements with class \"droptarget\"\n and attribute \"data-account-name\".\n-->\n<script lang=\"ts\">\n import { SvelteMap } from \"svelte/reactivity\";\n\n import { put_add_document, put_attach_document } from \"../api/index.ts\";\n import AccountInput from \"../entry-forms/AccountInput.svelte\";\n import { todayAsString } from \"../format.ts\";\n import { _ } from \"../i18n.ts\";\n import { get_el } from \"../lib/dom.ts\";\n import { basename, documentHasAccount } from \"../lib/paths.ts\";\n import { notify, notify_err } from \"../notifications.ts\";\n import { router } from \"../router.ts\";\n import { documents } from \"../stores/options.ts\";\n import { is_supported_datatransfer } from \"./document-upload.ts\";\n import ModalBase from \"./ModalBase.svelte\";\n\n let account = $state(\"\");\n let files = $state<FileList | null>(null);\n let entry_date = $state<string | null>(null);\n let entry_hash = $state<string | null>(null);\n let documents_folder = $state($documents[0] ?? \"\");\n const new_file_names = new SvelteMap<File, string>();\n let shown = $derived(files != null);\n\n /**\n * Handle a dragenter event on '.droptarget'.\n *\n * We want to allow a drop if the dragged thing is either a file that could be\n * dragged from a file manager or a URL (as dragged from a document link in Fava).\n *\n * Setting the .dragover class disables pointer-events on children via CSS, so\n * that the relevant next events are received on this droptarget element.\n *\n * Alternatively, this event can be handled in other components, setting the\n * .dragover class to indicate to the other events handlers below that it is\n * a valid drop zone.\n */\n function ondragenter(event: DragEvent): void {\n if (is_supported_datatransfer(event.dataTransfer)) {\n const droptarget = get_el(event.target)?.closest(\".droptarget\");\n if (droptarget) {\n droptarget.classList.add(\"dragover\");\n event.preventDefault();\n }\n }\n }\n\n /**\n * Handle a dragover event\n *\n * If the .dragover class is present, enable it to receive drop events.\n */\n function ondragover(event: DragEvent): void {\n const dragover = get_el(event.target)?.closest(\".dragover\");\n if (dragover) {\n event.preventDefault();\n }\n }\n /**\n * On dragleave, remove the nearest `.dragover` class.\n */\n function ondragleave(event: DragEvent): void {\n const dragover = get_el(event.target)?.closest(\".dragover\");\n dragover?.classList.remove(\"dragover\");\n }\n\n /**\n * On drop, handle both files and links.\n */\n function ondrop(event: DragEvent): void {\n const dragover = get_el(event.target)?.closest(\".dragover\");\n const { dataTransfer } = event;\n // Account name that the document should be attached to.\n const target_account = dragover?.getAttribute(\"data-account-name\");\n if (dragover == null || target_account == null || dataTransfer == null) {\n return;\n }\n dragover.classList.remove(\"dragover\");\n event.preventDefault();\n\n if (dataTransfer.types.includes(\"Files\")) {\n // Files are being dropped.\n account = target_account;\n entry_date = dragover.getAttribute(\"data-entry-date\");\n entry_hash = dragover.getAttribute(\"data-entry-hash\");\n files = dataTransfer.files;\n } else if (dataTransfer.types.includes(\"text/uri-list\")) {\n // Links are being dropped\n const url = dataTransfer.getData(\"URL\");\n // Try to extract the filename from the URL.\n let filename = new URL(url).searchParams.get(\"filename\");\n const entry_hash = dragover.getAttribute(\"data-entry-hash\");\n if (filename != null && entry_hash != null) {\n if (documentHasAccount(filename, target_account)) {\n filename = basename(filename);\n }\n put_attach_document({ filename, entry_hash }).then(\n notify,\n (error: unknown) => {\n notify_err(\n error,\n (e) => `Adding document metadata failed: ${e.message}`,\n );\n },\n );\n }\n }\n }\n\n function closeHandler() {\n account = \"\";\n entry_date = null;\n entry_hash = null;\n files = null;\n new_file_names.clear();\n }\n\n function get_name(file: File): string {\n const new_file_name = new_file_names.get(file);\n if (new_file_name != null) {\n return new_file_name;\n }\n return /^\\d{4}-\\d{2}-\\d{2}/.test(file.name)\n ? file.name\n : `${entry_date ?? todayAsString()} ${file.name}`;\n }\n\n async function onsubmit(event: SubmitEvent) {\n if (files == null) {\n return;\n }\n event.preventDefault();\n await Promise.all(\n Array.from(files).map(async (file) => {\n const formData = new FormData();\n formData.set(\"account\", account);\n if (entry_hash != null) {\n formData.set(\"hash\", entry_hash);\n }\n formData.set(\"folder\", documents_folder);\n const name = get_name(file);\n formData.set(\"file\", file, name);\n return put_add_document(formData).then(notify, (error: unknown) => {\n notify_err(\n error,\n (err) => `Uploading ${name} failed: ${err.message}`,\n );\n });\n }),\n );\n closeHandler();\n router.reload();\n }\n</script>\n\n<svelte:document {ondragenter} {ondragover} {ondragleave} {ondrop} />\n<ModalBase {shown} {closeHandler}>\n <form {onsubmit}>\n <h3>{_(\"Upload file(s)\")}:</h3>\n <label>\n <span>{_(\"Files\")}:</span>\n <input type=\"file\" multiple bind:files />\n </label>\n {#each files as file (file)}\n <input\n class=\"file\"\n bind:value={\n () => get_name(file),\n (new_file_name: string) => {\n new_file_names.set(file, new_file_name);\n }\n }\n />\n {/each}\n <label>\n <span>{_(\"Documents folder\")}:</span>\n <select bind:value={documents_folder}>\n {#each $documents as folder (folder)}\n <option>{folder}</option>\n {/each}\n </select>\n </label>\n <label>\n <span>{_(\"Account\")}:</span>\n <AccountInput bind:value={account} required />\n </label>\n <button type=\"submit\">{_(\"Upload\")}</button>\n </form>\n</ModalBase>\n\n<style>\n input.file {\n width: 100%;\n margin-bottom: 0.5rem;\n }\n\n label {\n display: flex;\n align-items: center;\n margin-bottom: 0.5rem;\n\n > span:first-child {\n flex-basis: 10rem;\n }\n\n > :global(span):last-child {\n flex: 1;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import AutocompleteInput from \"../AutocompleteInput.svelte\";\n import { urlForAccount } from \"../helpers.ts\";\n import { _ } from \"../i18n.ts\";\n import { router } from \"../router.ts\";\n import { accounts } from \"../stores/index.ts\";\n\n let value = $state(\"\");\n\n function select(el: HTMLInputElement) {\n if (value) {\n router.navigate($urlForAccount(value));\n el.blur();\n value = \"\";\n }\n }\n</script>\n\n<li>\n <AutocompleteInput\n bind:value\n placeholder={_(\"Go to account\")}\n suggestions={$accounts}\n key=\"g a\"\n onSelect={select}\n onEnter={select}\n />\n</li>\n\n<style>\n li {\n --input-border: none;\n --input-padding: 0.25em 0.5em 0.25em 1em;\n --autocomplete-list-position: fixed;\n }\n</style>\n", "<script lang=\"ts\">\n import type { Snippet } from \"svelte\";\n\n import { urlFor } from \"../helpers.ts\";\n import type { KeySpec } from \"../keyboard-shortcuts.ts\";\n import { keyboardShortcut } from \"../keyboard-shortcuts.ts\";\n import { pathname } from \"../stores/url.ts\";\n\n interface Props {\n /** Report to generate the URL for. */\n report: string;\n /** Name to display for this link. */\n name: string;\n /** Key combination for the link. */\n key?: KeySpec;\n /** Whether this is a remote link (for which we do not intercept clicks). */\n remote?: true;\n /** Show a bubble with a number */\n bubble?: [number, \"error\" | \"info\"];\n children?: Snippet;\n }\n\n let { report, name, key, remote, bubble, children }: Props = $props();\n\n let href = $derived(remote ? report : $urlFor(`${report}/`));\n let selected = $derived(remote ? false : href.includes($pathname));\n</script>\n\n<li>\n <a class:selected {href} {@attach keyboardShortcut(key)} data-remote={remote}>\n {name}\n {#if bubble && bubble[0] > 0}\n <span class=\"bubble\" class:error={bubble[1] === \"error\"}>\n {bubble[0]}\n </span>\n {/if}\n </a>\n {@render children?.()}\n</li>\n\n<style>\n a {\n display: block;\n padding: 0.25em 0.5em 0.25em 1em;\n color: inherit;\n }\n\n a.selected,\n a:hover {\n color: var(--sidebar-hover-color);\n background-color: var(--sidebar-border);\n }\n\n li {\n display: flex;\n flex-wrap: wrap;\n }\n\n li:last-child {\n margin-bottom: 0;\n border: none;\n }\n\n li a:first-child {\n flex: 1;\n }\n\n .bubble {\n float: right;\n padding: 0 8px;\n font-size: 0.9em;\n color: var(--sidebar-color);\n background-color: var(--sidebar-border);\n border-radius: 12px;\n }\n\n .error.bubble {\n color: white;\n background-color: var(--error);\n }\n</style>\n", "<script lang=\"ts\">\n import { urlFor } from \"../helpers.ts\";\n import { _ } from \"../i18n.ts\";\n import { keyboardShortcut } from \"../keyboard-shortcuts.ts\";\n import { errors, extensions, ledgerData } from \"../stores/index.ts\";\n import AccountSelector from \"./AccountSelector.svelte\";\n import Link from \"./SidebarLink.svelte\";\n\n const truncate = (s: string) => (s.length < 25 ? s : `${s.slice(25)}…`);\n\n let user_queries = $derived($ledgerData.user_queries);\n let upcoming_events_count = $derived($ledgerData.upcoming_events_count);\n let sidebar_links = $derived($ledgerData.sidebar_links);\n let extension_reports = $derived(\n $extensions.filter((e) => e.report_title != null),\n );\n</script>\n\n{#if sidebar_links.length}\n <ul class=\"navigation\">\n {#each sidebar_links as [label, link] (link)}\n <Link report={link} name={label} remote />\n {/each}\n </ul>\n{/if}\n<ul class=\"navigation\">\n <Link report=\"income_statement\" name={_(\"Income Statement\")} key=\"g i\" />\n <Link report=\"balance_sheet\" name={_(\"Balance Sheet\")} key=\"g b\" />\n <Link report=\"trial_balance\" name={_(\"Trial Balance\")} key=\"g t\" />\n <Link report=\"journal\" name={_(\"Journal\")} key=\"g j\" />\n <Link report=\"query\" name={_(\"Query\")} key=\"g q\">\n {#if user_queries.length}\n <ul class=\"submenu\">\n {#each user_queries as { query_string, name } (query_string)}\n <li>\n <a href={$urlFor(\"query/\", { query_string })}>{truncate(name)}</a>\n </li>\n {/each}\n </ul>\n {/if}\n </Link>\n <AccountSelector />\n</ul>\n<ul class=\"navigation\">\n <Link report=\"holdings\" name={_(\"Holdings\")} key=\"g h\" />\n <Link report=\"commodities\" name={_(\"Commodities\")} key=\"g c\" />\n <Link report=\"documents\" name={_(\"Documents\")} key=\"g d\" />\n <Link\n report=\"events\"\n name={_(\"Events\")}\n key=\"g E\"\n bubble={[upcoming_events_count, \"info\"]}\n />\n <Link report=\"statistics\" name={_(\"Statistics\")} key=\"g s\" />\n</ul>\n<ul class=\"navigation\">\n <Link report=\"editor\" name={_(\"Editor\")} key=\"g e\">\n <a\n href=\"#add-transaction\"\n class=\"secondary add-transaction\"\n title={_(\"Add Journal Entry\")}\n {@attach keyboardShortcut(\"n\")}>+</a\n >\n </Link>\n {#if $errors.length > 0}\n <Link\n report=\"errors\"\n name={_(\"Errors\")}\n bubble={[$errors.length, \"error\"]}\n />\n {/if}\n <Link report=\"import\" name={_(\"Import\")} key=\"g n\">\n <a href=\"#export\" class=\"secondary\" title={_(\"Export\")}>⬇</a>\n </Link>\n <Link report=\"options\" name={_(\"Options\")} key=\"g o\" />\n <Link report=\"help\" name={_(\"Help\")} key=\"g H\" />\n</ul>\n{#if extension_reports.length}\n <ul class=\"navigation\">\n {#each extension_reports as ext (ext.name)}\n <Link report={`extension/${ext.name}`} name={ext.report_title ?? \"\"} />\n {/each}\n </ul>\n{/if}\n\n<style>\n .navigation {\n padding-bottom: 0.5rem;\n margin: 0;\n }\n\n .navigation + .navigation {\n padding-top: 0.5rem;\n border-top: 1px solid var(--sidebar-border);\n }\n\n a {\n display: block;\n padding: 0.25em 0.5em 0.25em 1em;\n color: inherit;\n }\n\n a:hover {\n color: var(--sidebar-hover-color);\n background-color: var(--sidebar-border);\n }\n\n .secondary {\n width: 30px;\n padding: 3px 9px;\n line-height: 22px;\n color: inherit;\n background-color: var(--sidebar-background);\n }\n\n .add-transaction {\n font-size: 23px;\n }\n\n .submenu {\n width: 100%;\n margin: 0 0 0.5em;\n }\n\n .submenu a {\n width: 100%;\n padding-left: 35px;\n }\n\n .submenu li {\n font-size: 0.9em;\n }\n</style>\n", "<script lang=\"ts\">\n import AsideContents from \"./AsideContents.svelte\";\n\n /** Whether the sidebar is currently shown. */\n let active = $state(false);\n const toggle = () => {\n active = !active;\n };\n</script>\n\n{#if active}\n <div class=\"overlay\" onclick={toggle} aria-hidden=\"true\"></div>\n{/if}\n<div class:active class=\"aside-buttons\">\n <button type=\"button\" onclick={toggle}>☰</button>\n <a class=\"button\" href=\"#add-transaction\">+</a>\n</div>\n<aside class:active>\n <AsideContents />\n</aside>\n\n<style>\n aside {\n grid-area: aside;\n padding-top: 0.5rem;\n margin: 0;\n overflow-y: auto;\n color: var(--sidebar-color);\n background-color: var(--sidebar-background);\n border-right: 1px solid var(--sidebar-border);\n }\n\n .aside-buttons {\n display: none;\n }\n\n @media (width <= 767px) {\n :root {\n --aside-width: 200px;\n }\n\n aside {\n position: fixed;\n top: 0;\n bottom: 0;\n z-index: var(--z-index-floating-ui);\n width: var(--aside-width);\n margin-left: calc(-1 * var(--aside-width));\n transition: var(--transitions);\n }\n\n .overlay {\n position: fixed;\n inset: 0;\n z-index: var(--z-index-floating-ui);\n cursor: pointer;\n background: var(--overlay-wrapper-background);\n transition: var(--transitions);\n }\n\n aside.active {\n margin-left: 0;\n }\n\n .aside-buttons {\n position: fixed;\n top: 0;\n left: 0;\n z-index: var(--z-index-floating-ui);\n display: flex;\n flex-direction: column;\n transition: var(--transitions);\n }\n\n .active.aside-buttons {\n left: var(--aside-width);\n }\n\n .aside-buttons > * {\n width: 42px;\n height: 42px;\n color: var(--mobile-button-text);\n text-align: center;\n background-color: var(--sidebar-background);\n border: 1px solid var(--sidebar-border);\n }\n\n .aside-buttons a {\n font-size: 28px;\n }\n }\n\n @media print {\n aside,\n .aside-buttons {\n display: none;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import AutocompleteInput from \"../AutocompleteInput.svelte\";\n import { _ } from \"../i18n.ts\";\n import { escape_for_regex } from \"../lib/regex.ts\";\n import { router, set_query_param } from \"../router.ts\";\n import {\n account_filter,\n fql_filter,\n time_filter,\n } from \"../stores/filters.ts\";\n import { accounts, links, payees, tags, years } from \"../stores/index.ts\";\n\n let fql_filter_suggestions = $derived([\n ...$tags.map((tag) => `#${tag}`),\n ...$links.map((link) => `^${link}`),\n ...$payees.map((payee) => `payee:\"${escape_for_regex(payee)}\"`),\n ]);\n\n function valueExtractor(value: string, input: HTMLInputElement) {\n const match = /\\S*$/.exec(\n value.slice(0, input.selectionStart ?? undefined),\n );\n return match?.[0] ?? value;\n }\n function valueSelector(value: string, input: HTMLInputElement) {\n const selectionStart = input.selectionStart ?? 0;\n const match = /\\S*$/.exec(input.value.slice(0, selectionStart));\n const matchLength = match?.[0]?.length;\n return matchLength !== undefined\n ? `${input.value.slice(\n 0,\n selectionStart - matchLength,\n )}${value}${input.value.slice(selectionStart)}`\n : value;\n }\n\n let account_filter_value = $state(\"\");\n let fql_filter_value = $state(\"\");\n let time_filter_value = $state(\"\");\n account_filter.subscribe((v) => {\n account_filter_value = v;\n });\n fql_filter.subscribe((v) => {\n fql_filter_value = v;\n });\n time_filter.subscribe((v) => {\n time_filter_value = v;\n });\n\n /** Set the target we want to navigate to to avoid duplicate navigation. */\n let target: URL | null = null;\n\n /**\n * Submit the filter form.\n *\n * This is called on all the three possible events (blur, select, enter)\n * and also on the form submit. Having the listener on:enter would\n * theoretically be unnecessary (as the form would also be submitted) but\n * it seems to work around a Safari bug, see #809 and #1528.\n */\n function submit() {\n const url = new URL(router.current);\n set_query_param(url, \"account\", account_filter_value);\n set_query_param(url, \"filter\", fql_filter_value);\n set_query_param(url, \"time\", time_filter_value);\n if (url.href !== router.current.href) {\n target = url;\n setTimeout(() => {\n if (target) {\n router.navigate(target);\n target = null;\n }\n });\n }\n }\n</script>\n\n<form\n class=\"flex-row\"\n onsubmit={(ev) => {\n ev.preventDefault();\n submit();\n }}\n>\n <AutocompleteInput\n bind:value={time_filter_value}\n placeholder={_(\"Time\")}\n suggestions={$years}\n key=\"f t\"\n clearButton={true}\n setSize={true}\n onBlur={submit}\n onSelect={submit}\n onEnter={submit}\n />\n <AutocompleteInput\n bind:value={account_filter_value}\n placeholder={_(\"Account\")}\n suggestions={$accounts}\n key=\"f a\"\n clearButton={true}\n setSize={true}\n onBlur={submit}\n onSelect={submit}\n onEnter={submit}\n />\n <AutocompleteInput\n bind:value={fql_filter_value}\n placeholder={_(\"Filter by tag, payee, ...\")}\n suggestions={fql_filter_suggestions}\n key=\"f f\"\n clearButton={true}\n setSize={true}\n {valueExtractor}\n {valueSelector}\n onBlur={submit}\n onSelect={submit}\n onEnter={submit}\n />\n <!-- svelte-ignore a11y_consider_explicit_label -->\n <button type=\"submit\"></button>\n</form>\n\n<style>\n form {\n color: var(--text-color);\n\n --placeholder-color: var(--header-placeholder-color);\n --placeholder-background: var(--header-placeholder-background);\n --input-padding: 8px 25px 8px 10px;\n }\n\n form > :global(span) {\n max-width: 18rem;\n }\n\n form :global(input) {\n outline: none;\n background-color: var(--background);\n border: 0;\n }\n\n form :global([type=\"text\"]:focus) {\n background-color: var(--background);\n }\n\n [type=\"submit\"] {\n display: none;\n }\n\n @media print {\n form {\n --input-padding: 8px 10px;\n }\n\n form :global(input):placeholder-shown {\n display: none;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import { is_loading } from \"../router.ts\";\n</script>\n\n<svg\n class:loading={$is_loading}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 100 100\"\n>\n <rect width=\"100\" height=\"100\" rx=\"20\" fill=\"#0a0a0a\" />\n <text\n x=\"50\"\n y=\"68\"\n font-size=\"50\"\n font-family=\"system-ui\"\n font-weight=\"bold\"\n text-anchor=\"middle\"\n >\n <tspan fill=\"#f97316\">r</tspan><tspan fill=\"white\">f</tspan>\n </text>\n</svg>\n\n<style>\n @keyframes spinner {\n to {\n transform: rotate(360deg);\n }\n }\n\n .loading {\n padding: 0;\n border-top: 2px solid var(--header-color);\n border-radius: 50%;\n animation: spinner 1s linear infinite;\n }\n\n .loading rect,\n .loading text {\n opacity: 0;\n }\n\n @media print {\n svg {\n display: none;\n }\n }\n</style>\n", "<script lang=\"ts\">\n import { day } from \"../format.ts\";\n import { urlForAccount } from \"../helpers.ts\";\n import { ancestors, leaf } from \"../lib/account.ts\";\n import { account_details } from \"../stores/index.ts\";\n import AccountIndicator from \"./AccountIndicator.svelte\";\n\n interface Props {\n account: string;\n }\n\n let { account }: Props = $props();\n\n let parts = $derived(ancestors(account));\n let details = $derived($account_details[account]);\n let last = $derived(details?.last_entry);\n</script>\n\n<span class=\"droptarget\" data-account-name={account}>\n {#each parts as name, index (index)}\n <a href={$urlForAccount(name)} title={name}>{leaf(name)}</a\n >{#if index < parts.length - 1}:{/if}\n {/each}\n <AccountIndicator {account} />\n {#if last}\n <span class=\"last-activity\">\n (Last entry: <a href=\"#context-{last.entry_hash}\">{day(last.date)}</a>)\n </span>\n {/if}\n</span>\n\n<style>\n a {\n color: unset;\n }\n\n .droptarget {\n padding: 0.6em;\n margin-left: -0.6em;\n }\n\n .last-activity {\n display: inline-block;\n margin-left: 10px;\n font-size: 12px;\n font-weight: normal;\n opacity: 0.8;\n }\n</style>\n", "<script lang=\"ts\">\n import AccountPageTitle from \"./AccountPageTitle.svelte\";\n import { page_title } from \"./page-title.ts\";\n\n let { title, type } = $derived($page_title);\n\n let is_account = $derived(type === \"account\");\n</script>\n\n<strong>\n {#if !is_account}\n {title}\n {:else}\n <AccountPageTitle account={title} />\n {/if}\n</strong>\n\n<style>\n strong::before {\n margin: 0 10px;\n font-weight: normal;\n content: \"›\";\n opacity: 0.5;\n }\n</style>\n", "<script lang=\"ts\">\n import { keyboardShortcut } from \"../keyboard-shortcuts.ts\";\n import { router } from \"../router.ts\";\n import { ledgerData } from \"../stores/index.ts\";\n import { ledger_title } from \"../stores/options.ts\";\n import FilterForm from \"./FilterForm.svelte\";\n import HeaderIcon from \"./HeaderIcon.svelte\";\n import { has_changes } from \"./page-title.ts\";\n import PageTitle from \"./PageTitle.svelte\";\n\n let other_ledgers = $derived($ledgerData.other_ledgers);\n let has_dropdown = $derived(other_ledgers.length);\n</script>\n\n<header>\n <HeaderIcon />\n <h1>\n {$ledger_title}{#if has_dropdown} ▾{/if}<PageTitle />\n {#if has_dropdown}\n <div class=\"beancount-files\">\n <ul>\n {#each other_ledgers as [name, url] (url)}\n <li>\n <a href={url} data-remote>{name}</a>\n </li>\n {/each}\n </ul>\n </div>\n {/if}\n </h1>\n <button\n type=\"button\"\n hidden={!$has_changes}\n class=\"reload-page\"\n {@attach keyboardShortcut(\"r\")}\n onclick={router.reload}\n >\n ↻\n </button>\n <span class=\"spacer\"></span>\n <FilterForm />\n</header>\n\n<style>\n .reload-page {\n color: var(--dark-gray);\n background-color: var(--warning);\n }\n\n h1 {\n display: inline-block;\n padding: 0.5rem;\n margin: 0;\n overflow: hidden;\n font-size: 16px;\n font-weight: normal;\n }\n\n a:hover,\n a:link,\n a:visited {\n color: inherit;\n }\n\n .beancount-files {\n position: absolute;\n z-index: var(--z-index-floating-ui);\n display: none;\n width: 20em;\n margin-top: 0.25em;\n color: var(--link-color);\n background-color: var(--background);\n border: 1px solid var(--border);\n box-shadow: var(--box-shadow-dropdown);\n }\n\n .beancount-files a {\n display: block;\n padding: 8px 12px 8px 28px;\n cursor: pointer;\n }\n\n h1:hover .beancount-files {\n display: block;\n }\n\n .beancount-files ul {\n max-height: 400px;\n margin-bottom: 0;\n overflow-y: auto;\n }\n\n .beancount-files a:hover {\n color: var(--background);\n background-color: var(--link-color);\n }\n</style>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|