From 1ba1d936e9a110c2fcc297783762e8a15846bfaf Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Thu, 12 May 2022 18:38:12 +0800 Subject: [PATCH 01/17] [Version] Clean and start new version 1.17.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7b90e67..a0247754 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dbm", - "version": "1.16.0", + "version": "1.17.0-SNAPSHOT", "author": "qianmoQ ", "description": "ClickHouse DataBase GUI", "github": "https://github.com/EdurtIO/dbm.git", From d0b50675fa4497614cabe00373d0dae59f9c0ad8 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Sun, 15 May 2022 23:02:07 +0800 Subject: [PATCH 02/17] [Enhancement] Support metadata management to filter the table --- .../assets/images/versions/1.17.0/img.png | Bin 0 -> 38587 bytes .../assets/images/versions/1.17.0/img_1.png | Bin 0 -> 28552 bytes .../assets/images/versions/1.17.0/img_2.png | Bin 0 -> 9187 bytes .../development/version/1.17.0-development.md | 5 +++ electron-builder.yml | 15 +------ .../management/metadata/metadata.module.ts | 4 +- .../table/common/common.table.component.html | 4 ++ .../table/filter/table.filter.component.html | 33 ++++++++++++++++ .../table/filter/table.filter.component.ts | 37 ++++++++++++++++++ src/renderer/config/base.config.ts | 2 + src/renderer/config/clickhouse.config.ts | 12 ++++++ src/renderer/config/operation.config.ts | 1 + .../services/management/metadata.service.ts | 10 ++++- 13 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 docs/docs/assets/images/versions/1.17.0/img.png create mode 100644 docs/docs/assets/images/versions/1.17.0/img_1.png create mode 100644 docs/docs/assets/images/versions/1.17.0/img_2.png create mode 100644 src/renderer/components/table/filter/table.filter.component.html create mode 100644 src/renderer/components/table/filter/table.filter.component.ts diff --git a/docs/docs/assets/images/versions/1.17.0/img.png b/docs/docs/assets/images/versions/1.17.0/img.png new file mode 100644 index 0000000000000000000000000000000000000000..4b68d5f7373768b3ad3149ff435eb59869597cc4 GIT binary patch literal 38587 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�*Q4al-PNXm`?x`lq-z+&ykj;@ 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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/versions/1.17.0/img_1.png b/docs/docs/assets/images/versions/1.17.0/img_1.png new file mode 100644 index 0000000000000000000000000000000000000000..953c4a94f040a4d2759ccaf4423df252644d28c1 GIT binary patch literal 28552 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 CpYhB9 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/versions/1.17.0/img_2.png b/docs/docs/assets/images/versions/1.17.0/img_2.png new file mode 100644 index 0000000000000000000000000000000000000000..7293c8b937898938c7fae96887bd2e000e262067 GIT binary patch literal 9187 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 literal 0 HcmV?d00001 diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index e8dca3d4..df283c8a 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -13,6 +13,11 @@ DBM Version for `1.17.0` is development! --- +- Support metadata management to filter the table
+![img.png](../../assets/images/versions/1.17.0/img.png)
+![img_1.png](../../assets/images/versions/1.17.0/img_1.png)
+![img_2.png](../../assets/images/versions/1.17.0/img_2.png)
+ #### UI --- diff --git a/electron-builder.yml b/electron-builder.yml index fc5ee175..1d11d06f 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -10,37 +10,24 @@ releaseInfo: --- - - SSH login is supported #40 - - Support query ClickHouse to dynamically add configuration - - Support metadata management to filter the database - - Support automatic prompt function of code editor + - Support metadata management to filter the table #### Docs --- - - Fix Monitor --> Processor document image pointing error - #### Optimize ---- - - Optimize error reporting pop-up window #148 - #### Bug --- - - Fix the release error that the new version of the CI tool was not merged with the code release error - #### UI --- - - Optimize query history display list - - Migrate the software update function to the system menu - - Support editor bracket matching - directories: output: ./release files: diff --git a/src/renderer/app/pages/management/metadata/metadata.module.ts b/src/renderer/app/pages/management/metadata/metadata.module.ts index 9e0586da..37bcd8bc 100644 --- a/src/renderer/app/pages/management/metadata/metadata.module.ts +++ b/src/renderer/app/pages/management/metadata/metadata.module.ts @@ -41,6 +41,7 @@ import { DatabaseRenameComponent } from '@renderer/components/database/rename/da import { ColumnCreateComponent } from '@renderer/components/column/create/column.create.component'; import { CommentColumnComponent } from '@renderer/components/column/comment/column.comment.component'; import { DatabaseFilterComponent } from '@renderer/components/database/filter/database.filter.component'; +import { TableFilterComponent } from '@renderer/components/table/filter/table.filter.component'; const MANAGEMENT_METADATA_ROUTES: Routes = [ {path: '', component: MetadataComponent} @@ -85,7 +86,8 @@ const MANAGEMENT_METADATA_ROUTES: Routes = [ DatabaseRenameComponent, ColumnCreateComponent, CommentColumnComponent, - DatabaseFilterComponent + DatabaseFilterComponent, + TableFilterComponent ], providers: [ DatasourceService, diff --git a/src/renderer/components/table/common/common.table.component.html b/src/renderer/components/table/common/common.table.component.html index bbc0d155..bb83e1d9 100644 --- a/src/renderer/components/table/common/common.table.component.html +++ b/src/renderer/components/table/common/common.table.component.html @@ -34,5 +34,9 @@ [value]="value?.origin?.key" [database]="database" (emitter)="handlerEmitter($event)"> + + diff --git a/src/renderer/components/table/filter/table.filter.component.html b/src/renderer/components/table/filter/table.filter.component.html new file mode 100644 index 00000000..94aae9ba --- /dev/null +++ b/src/renderer/components/table/filter/table.filter.component.html @@ -0,0 +1,33 @@ +
+
+ + {{'common.database'|translate}} + + {{database}} + + + + {{'common.name'|translate}} + + + + + + {{'common.precise'|translate}} + + + + + +
+
+ diff --git a/src/renderer/components/table/filter/table.filter.component.ts b/src/renderer/components/table/filter/table.filter.component.ts new file mode 100644 index 00000000..fb801387 --- /dev/null +++ b/src/renderer/components/table/filter/table.filter.component.ts @@ -0,0 +1,37 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { BaseComponent } from '@renderer/app/base.component'; +import { ConfigModel } from '@renderer/model/config.model'; +import { StringUtils } from '@renderer/utils/string.utils'; +import { FilterModel } from '@renderer/model/filter.model'; + +@Component({ + selector: 'app-component-filter-table', + templateUrl: './table.filter.component.html' +}) +export class TableFilterComponent extends BaseComponent { + @Input() + config: ConfigModel; + @Input() + database: string; + @Output() + emitter = new EventEmitter(); + filter: FilterModel = new FilterModel(); + + constructor() { + super(); + } + + handlerValidate() { + if (StringUtils.isNotEmpty(this.filter.value)) { + this.disabled.button = false; + } else { + this.disabled.button = true; + } + } + + async handlerFilter() { + this.config.status = true; + this.config.filter = this.filter; + this.emitter.emit(this.config); + } +} diff --git a/src/renderer/config/base.config.ts b/src/renderer/config/base.config.ts index fecf0960..00aab9af 100644 --- a/src/renderer/config/base.config.ts +++ b/src/renderer/config/base.config.ts @@ -7,5 +7,7 @@ export interface BaseConfig { databaseItemsFilterPrecise: string; databaseItemsFilterFuzzy: string; tableItems: string; + tableItemsFilterPrecise: string; + tableItemsFilterFuzzy: string; columnItems: string; } diff --git a/src/renderer/config/clickhouse.config.ts b/src/renderer/config/clickhouse.config.ts index ca8dc6a2..99895a0e 100644 --- a/src/renderer/config/clickhouse.config.ts +++ b/src/renderer/config/clickhouse.config.ts @@ -88,6 +88,18 @@ WHERE name LIKE '%{0}%' SELECT uuid, name, engine AS value, partition_key, sorting_key, total_rows, total_bytes, database FROM system.tables WHERE database = '{0}' + `; + tableItemsFilterPrecise = ` +SELECT uuid, name, engine AS value, partition_key, sorting_key, total_rows, total_bytes, database +FROM system.tables +WHERE database = '{0}' +AND name = '{1}' + `; + tableItemsFilterFuzzy = ` +SELECT uuid, name, engine AS value, partition_key, sorting_key, total_rows, total_bytes, database +FROM system.tables +WHERE database = '{0}' +AND name LIKE '%{1}%' `; columnItems = ` DESC {0}.{1} diff --git a/src/renderer/config/operation.config.ts b/src/renderer/config/operation.config.ts index 0851842e..9f3ab452 100644 --- a/src/renderer/config/operation.config.ts +++ b/src/renderer/config/operation.config.ts @@ -19,6 +19,7 @@ export class OperationConfig { database.type = TypeEnum.database; database.operations = [ {type: TypeEnum.table, actions: [OperationEnum.create]}, + {type: TypeEnum.table, actions: [OperationEnum.filter]}, {type: TypeEnum.database, actions: [OperationEnum.delete]}, {type: TypeEnum.database, actions: [OperationEnum.structure]}, {type: TypeEnum.database, actions: [OperationEnum.rename]} diff --git a/src/renderer/services/management/metadata.service.ts b/src/renderer/services/management/metadata.service.ts index c10da5b4..2083f56f 100644 --- a/src/renderer/services/management/metadata.service.ts +++ b/src/renderer/services/management/metadata.service.ts @@ -68,7 +68,15 @@ export class MetadataService extends ForwardService implements BaseService { } break; case TypeEnum.database: - sql = StringUtils.format(this.baseConfig.tableItems, [config.key]); + if (filter) { + if (filter.precise) { + sql = StringUtils.format(this.baseConfig.tableItemsFilterPrecise, [config.key, filter.value]); + } else { + sql = StringUtils.format(this.baseConfig.tableItemsFilterFuzzy, [config.key, filter.value]); + } + } else { + sql = StringUtils.format(this.baseConfig.tableItems, [config.key]); + } break; case TypeEnum.table: sql = StringUtils.format(this.baseConfig.columnItems, [config.database, config.key]); From 2da61830e81d98ae5379572f26f84849e321daa0 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Mon, 16 May 2022 17:13:12 +0800 Subject: [PATCH 03/17] [Optimize] Optimize project description and introduction --- README.md | 104 ++++++++---------- .../development/version/1.17.0-development.md | 2 + electron-builder.yml | 2 + src/shared/assets/integrate/clickhouse.png | Bin 0 -> 6297 bytes 4 files changed, 48 insertions(+), 60 deletions(-) create mode 100644 src/shared/assets/integrate/clickhouse.png diff --git a/README.md b/README.md index 58125e6a..b29dff1d 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,20 @@ Logo -

DBM

-

- An awesome database management tool specified for ClickHouse. For more information: https://dbm.incubator.edurt.io. -
-

---- - -Contributors: +[![Typing SVG](https://readme-typing-svg.herokuapp.com?size=25&width=750&lines=DBM+is+a+open+source+database+management+system.)](https://git.io/typing-svg) ![GitHub Contributors Image](https://contrib.rocks/image?repo=EdurtIO/dbm) -Basic: +**Documentation** + +[中文](http://dbm-zh.edurt.io/)
+[English](https://dbm.edurt.io/) + +## Overview + +--- ![](https://visitor-badge.glitch.me/badge?page_id=dbm) ![version](https://img.shields.io/github/v/release/EdurtIO/dbm.svg) @@ -31,39 +31,53 @@ Basic: ![GitHub contributors](https://img.shields.io/github/contributors-anon/EdurtIO/dbm?style=flat-square) ![GitHub last commit](https://img.shields.io/github/last-commit/EdurtIO/dbm?style=flat-square) -Workflow: +## Workflow -[![Test by push](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml) +--- -[![Publish New Release](https://github.com/EdurtIO/dbm/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/upload-to-release.yml) +**GitHub Actions workflow** +[![Test by push](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml) +[![Publish New Release](https://github.com/EdurtIO/dbm/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/upload-to-release.yml) [![Publish docs via GitHub Pages](https://github.com/EdurtIO/dbm/actions/workflows/publish-docs.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/publish-docs.yml) -Development: +**Development workflow** [![codebeat badge](https://codebeat.co/badges/a291d700-2d4b-435f-aa70-468bd1800d19)](https://codebeat.co/projects/github-com-edurtio-incubator-dbm-master) [![With Electron](https://img.shields.io/badge/with-electron-blue.svg)](https://electronjs.org/) [![With Angular](https://img.shields.io/badge/with-angular-blue.svg)](https://angular.io/) [![With Jetbrains](https://img.shields.io/badge/with-Jetbrains-blue.svg)](https://www.jetbrains.com/) -GitHub: +## Mirror + +--- + +**GitHub** [![GitHub stars](https://img.shields.io/github/stars/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/stargazers) [![GitHub license](https://img.shields.io/github/license/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/issues) [![GitHub forks](https://img.shields.io/github/forks/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/network) -## Join Us +**Gitee** -Open the DingTalk software and scan the following QR code to join +[![star](https://gitee.com/EdurtIO/dbm/badge/star.svg?theme=dark)](https://gitee.com/EdurtIO/dbm/stargazers) +[![fork](https://gitee.com/EdurtIO/dbm/badge/fork.svg?theme=white)](https://gitee.com/EdurtIO/dbm/members) +[![Fork me on Gitee](https://gitee.com/EdurtIO/dbm/widgets/widget_3.svg)](https://gitee.com/EdurtIO/dbm) - +## Supported Databases -## Thank you +--- -- [Jetbrains](https://www.jetbrains.com/) +DBM can query data from any SQL-speaking datastore or data engine (ClickHouse and more). + +Here are some of the major database solutions that are supported: -## :rocket: Features +[![ClickHouse](./src/shared/assets/integrate/clickhouse.png)](https://clickhouse.com/) + +## Features + +--- - Support query history (pagination, clear all, etc.) - Support selected sql clauses query @@ -86,52 +100,22 @@ Open the DingTalk software and scan the following QR code to join - Support monitor (processor, connection, query) - Support migrate data -## :laughing: Download - -- [Windows](https://github.com/EdurtIO/incubator-dbm/releases/download/1.4.0/dbm-win.zip) -- [Mac](https://github.com/EdurtIO/incubator-dbm/releases/download/1.4.0/dbm-mac.tar.gz) - -## :gear: Installation - -macOS and Windows - -- Download zip from [here](https://github.com/EdurtIO/incubator-dbm/releases). -- Unzip the archive, and install to macOS Applications. - -Other platforms - -- Unsupported temporarily. You can install the DBM by [building from source](#hammer_and_wrench-build-from-source). - -Install other versions? - -- Go ahead to [Github Release](https://github.com/EdurtIO/incubator-dbm/releases) for all releases. - -## :hammer_and_wrench: Build from source - -1. Install dependencies +## Join Us -```bash -npm install -g node-sass +--- -yarn install -``` +Open the DingTalk software and scan the following QR code to join -2. Build electron app for production + -```bash -yarn run build -``` +## Thank you -3. Install from built zip: `./build/dbm-.*` +--- -4. Run dev mode +- [Jetbrains](https://www.jetbrains.com/) -```bash -yarn run dev -``` +## Installation and Configuration -or +--- -```bash -npm start -``` +[Extended documentation for DBM](http://dbm-zh.edurt.io/reference/get_started/install.html) diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index df283c8a..fa9e3fff 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -26,6 +26,8 @@ DBM Version for `1.17.0` is development! ---- +- Optimize project description and introduction
+ #### Docs --- diff --git a/electron-builder.yml b/electron-builder.yml index 1d11d06f..5bc6fde5 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -20,6 +20,8 @@ releaseInfo: ---- + - Optimize project description and introduction + #### Bug --- diff --git a/src/shared/assets/integrate/clickhouse.png b/src/shared/assets/integrate/clickhouse.png new file mode 100644 index 0000000000000000000000000000000000000000..c3986051796e70e10572c5a02f5258b9e0c3e5bc GIT binary patch literal 6297 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 literal 0 HcmV?d00001 From 4c8d36a173e9de3fcb81e380e0d9b2bc3a5245df Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Wed, 18 May 2022 18:40:43 +0800 Subject: [PATCH 04/17] [Enhancement] Support trino and presto (only custom query and data source management) #158 --- README.md | 6 +- angular.json | 7 +- .../assets/images/versions/1.17.0/img_3.png | Bin 0 -> 56057 bytes .../development/version/1.17.0-development.md | 2 + electron-builder.yml | 1 + package.json | 4 + .../app/layout/header/header.component.ts | 3 - src/renderer/app/layout/layout.module.ts | 36 ++++---- src/renderer/app/ng-zorro-antd.module.ts | 4 +- .../app/pages/home/home.component.html | 17 +++- src/renderer/app/pages/home/home.component.ts | 34 ++++---- src/renderer/app/pages/home/home.module.ts | 7 +- .../datasource/datasource.component.html | 17 +++- .../datasource/datasource.component.ts | 2 + .../datasource/datasource.module.ts | 4 +- .../management/metadata/metadata.component.ts | 10 ++- .../monitor.connection.component.ts | 8 +- .../mutations/monitor.mutations.component.ts | 8 +- .../processor/monitor.processor.component.ts | 8 +- .../monitor/query/monitor.query.component.ts | 8 +- .../pages/tools/migrte/migrte.component.ts | 8 +- .../app/pages/tools/track/track.component.ts | 8 +- src/renderer/app/service.module.ts | 14 +-- src/renderer/assets/i18n/en.json | 12 ++- src/renderer/assets/i18n/zh.json | 12 ++- src/renderer/assets/icon/source/presto.svg | 1 + src/renderer/assets/icon/source/trino.svg | 1 + src/renderer/config/base.config.ts | 1 + src/renderer/config/clickhouse.config.ts | 5 +- src/renderer/config/presto.config.ts | 20 +++++ src/renderer/config/source.type.config.ts | 45 +++++++--- src/renderer/db/dexiedb.ts | 2 +- src/renderer/enum/database.enum.ts | 4 +- src/renderer/services/dbm.promise.ts | 42 +++++++++ src/renderer/services/factory.service.ts | 19 ++++ src/renderer/services/forward.service.ts | 39 ++++++--- .../services/management/column.service.ts | 30 ++++--- .../services/management/database.service.ts | 22 ++--- .../services/management/datasource.service.ts | 47 +++++----- .../services/management/metadata.service.ts | 38 ++++---- .../services/management/table.service.ts | 72 ++++++++-------- .../services/monitor/monitor.service.ts | 24 +++--- .../plugin/clickhouse.plugin.service.ts | 22 ++--- src/renderer/services/presto.service.ts | 81 ++++++++++++++++++ src/renderer/services/query/query.service.ts | 8 +- .../services/snippet/snippet.service.ts | 34 ++++---- .../services/tools/migrate.service.ts | 30 ++++--- src/renderer/services/tools/track.service.ts | 28 +++--- src/renderer/styles.scss | 7 ++ src/shared/assets/integrate/presto.png | Bin 0 -> 18862 bytes src/shared/assets/integrate/trino.png | Bin 0 -> 20758 bytes 51 files changed, 604 insertions(+), 258 deletions(-) create mode 100644 docs/docs/assets/images/versions/1.17.0/img_3.png create mode 100644 src/renderer/assets/icon/source/presto.svg create mode 100644 src/renderer/assets/icon/source/trino.svg create mode 100644 src/renderer/config/presto.config.ts create mode 100644 src/renderer/services/dbm.promise.ts create mode 100644 src/renderer/services/factory.service.ts create mode 100644 src/renderer/services/presto.service.ts create mode 100644 src/shared/assets/integrate/presto.png create mode 100644 src/shared/assets/integrate/trino.png diff --git a/README.md b/README.md index b29dff1d..6d782221 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,11 @@ DBM can query data from any SQL-speaking datastore or data engine (ClickHouse an Here are some of the major database solutions that are supported: -[![ClickHouse](./src/shared/assets/integrate/clickhouse.png)](https://clickhouse.com/) +

+ clickhouse + trino + presto +

## Features diff --git a/angular.json b/angular.json index 0277f27e..588f0c0d 100644 --- a/angular.json +++ b/angular.json @@ -31,7 +31,12 @@ "inlineStyleLanguage": "scss", "assets": [ "src/shared/assets", - "src/renderer/assets" + "src/renderer/assets", + { + "glob": "**/*", + "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", + "output": "/assets/" + } ], "styles": [ "src/renderer/styles.scss", diff --git a/docs/docs/assets/images/versions/1.17.0/img_3.png b/docs/docs/assets/images/versions/1.17.0/img_3.png new file mode 100644 index 0000000000000000000000000000000000000000..190db3df35c126b2080770738cda67bcbb08fe1a GIT binary patch literal 56057 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 literal 0 HcmV?d00001 diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index fa9e3fff..fc77e9ee 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -17,6 +17,8 @@ DBM Version for `1.17.0` is development! ![img.png](../../assets/images/versions/1.17.0/img.png)
![img_1.png](../../assets/images/versions/1.17.0/img_1.png)
![img_2.png](../../assets/images/versions/1.17.0/img_2.png)
+- Support trino and presto (only custom query and data source management)
+![img_3.png](../../assets/images/versions/1.17.0/img_3.png)
#### UI diff --git a/electron-builder.yml b/electron-builder.yml index 5bc6fde5..f547a881 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -11,6 +11,7 @@ releaseInfo: --- - Support metadata management to filter the table + - Support trino and presto (only custom query and data source management) #### Docs diff --git a/package.json b/package.json index a0247754..329d92d8 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,9 @@ "@angular/platform-browser": "12.1.2", "@angular/platform-browser-dynamic": "12.1.2", "@angular/router": "12.1.2", + "@ant-design/icons-angular": "^13.1.0", "@ctrl/ngx-codemirror": "^5.1.1", + "@dalongrong/presto-client": "^0.6.5", "@ngx-translate/core": "^14.0.0", "@ngx-translate/http-loader": "^7.0.0", "angular-highcharts": "^13.0.1", @@ -68,6 +70,8 @@ "ngx-markdown": "^13.1.0", "ngx-moment": "^6.0.2", "node-sql-parser": "^4.1.1", + "presto-stream-client": "^1.0.15", + "promise-timeout": "^1.3.0", "rxjs": "~6.6.0", "sass-loader": "^12.3.0", "sql-formatter": "^4.0.2", diff --git a/src/renderer/app/layout/header/header.component.ts b/src/renderer/app/layout/header/header.component.ts index df365a0c..bb246d67 100644 --- a/src/renderer/app/layout/header/header.component.ts +++ b/src/renderer/app/layout/header/header.component.ts @@ -74,7 +74,6 @@ export class HeaderComponent extends BaseComponent implements OnInit { handlerUpdateState() { ipcRenderer.on('updater', (event, arg) => { - console.log('update status ', arg); this.loading.button = false; this.ref.markForCheck(); this.ref.detectChanges(); @@ -86,7 +85,6 @@ export class HeaderComponent extends BaseComponent implements OnInit { this.releaseNotes = arg?.message?.releaseNotes; break; case UpdateEnum.downloading: - console.log(arg) this.disabled.button = false; this.percentage = arg.message.percent.toFixed(2); break; @@ -105,7 +103,6 @@ export class HeaderComponent extends BaseComponent implements OnInit { this.disabled.button = true; break; default: - console.log('default', arg) this.updateResponse = arg; this.disabled.button = true; break; diff --git a/src/renderer/app/layout/layout.module.ts b/src/renderer/app/layout/layout.module.ts index fbf94618..466c0194 100644 --- a/src/renderer/app/layout/layout.module.ts +++ b/src/renderer/app/layout/layout.module.ts @@ -1,18 +1,20 @@ -import { FormsModule } from '@angular/forms'; -import { NgModule } from '@angular/core'; -import { LayoutRouting } from './layout.routing'; -import { LayoutComponent } from './layout.component'; -import { HeaderComponent } from './header/header.component'; -import { CommonModule } from '@angular/common'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { HttpClient } from '@angular/common/http'; -import { TranslateHttpLoader } from '@ngx-translate/http-loader'; -import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { MarkdownModule } from 'ngx-markdown'; -import { DatasourceService } from '@renderer/services/management/datasource.service'; -import { HttpService } from '@renderer/services/http.service'; -import { SshService } from '@renderer/services/ssh.service'; +import {FormsModule} from '@angular/forms'; +import {NgModule} from '@angular/core'; +import {LayoutRouting} from './layout.routing'; +import {LayoutComponent} from './layout.component'; +import {HeaderComponent} from './header/header.component'; +import {CommonModule} from '@angular/common'; +import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; +import {HttpClient} from '@angular/common/http'; +import {TranslateHttpLoader} from '@ngx-translate/http-loader'; +import {NgZorroAntdModule} from '@renderer/app/ng-zorro-antd.module'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {MarkdownModule} from 'ngx-markdown'; +import {DatasourceService} from '@renderer/services/management/datasource.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {FactoryService} from "@renderer/services/factory.service"; const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './renderer/assets/i18n/', '.json'); @@ -40,7 +42,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => BasicService, DatasourceService, HttpService, - SshService + SshService, + PrestoService, + FactoryService ] }) export class LayoutModule { diff --git a/src/renderer/app/ng-zorro-antd.module.ts b/src/renderer/app/ng-zorro-antd.module.ts index cc962f07..cc63dac1 100644 --- a/src/renderer/app/ng-zorro-antd.module.ts +++ b/src/renderer/app/ng-zorro-antd.module.ts @@ -37,6 +37,7 @@ import { NzBadgeModule } from 'ng-zorro-antd/badge'; import { NzPaginationModule } from 'ng-zorro-antd/pagination'; import { NzDrawerModule } from 'ng-zorro-antd/drawer'; import { NzTypographyModule } from 'ng-zorro-antd/typography'; +import { NzIconModule } from "ng-zorro-antd/icon"; @NgModule({ declarations: [], @@ -78,7 +79,8 @@ import { NzTypographyModule } from 'ng-zorro-antd/typography'; NzBadgeModule, NzPaginationModule, NzDrawerModule, - NzTypographyModule + NzTypographyModule, + NzIconModule ] }) export class NgZorroAntdModule { diff --git a/src/renderer/app/pages/home/home.component.html b/src/renderer/app/pages/home/home.component.html index 4afb6bd3..05cdc495 100644 --- a/src/renderer/app/pages/home/home.component.html +++ b/src/renderer/app/pages/home/home.component.html @@ -5,10 +5,19 @@
- - - - + + + + + + + + + + + +
diff --git a/src/renderer/app/pages/home/home.component.ts b/src/renderer/app/pages/home/home.component.ts index 9dd11624..974ea4c5 100644 --- a/src/renderer/app/pages/home/home.component.ts +++ b/src/renderer/app/pages/home/home.component.ts @@ -6,6 +6,7 @@ import { QueryService } from '@renderer/services/query/query.service'; import { RequestModel } from '@renderer/model/request.model'; import { ClickhousePluginService } from '@renderer/services/plugin/clickhouse.plugin.service'; import { DatasourceModel } from '@renderer/model/datasource.model'; +import {DatabaseEnum} from "@renderer/enum/database.enum"; @Component({ selector: 'app-home', @@ -16,6 +17,7 @@ export class HomeComponent implements OnInit { dataSources: DatasourceModel[] = new Array(); chartsConfig: ChartsModel[] = new Array(); chartsSkeleton: boolean[] = new Array(); + dataSourceType = DatabaseEnum; constructor(private datasourceService: DatasourceService, private queryService: QueryService, @@ -34,21 +36,23 @@ export class HomeComponent implements OnInit { handlerInitChart() { this.dataSources.forEach((value, index) => { - const request = new RequestModel(); - request.config = value; - this.clickhousePluginService.getQueryCount(request).then(response => { - if (response.status) { - const config = new ChartsModel(); - config.type = 'area'; - const series = new ChartsSeriesModel(); - config.xAxis.categories = response.data.columns.map(v => v.categories); - series.data = response.data.columns.map(v => v.value); - series.name = 'Count'; - config.series.push(series); - this.chartsConfig[index] = config; - } - this.chartsSkeleton[index] = false; - }); + if (value.type === DatabaseEnum.clickhosue) { + const request = new RequestModel(); + request.config = value; + this.clickhousePluginService.getQueryCount(request).then(response => { + if (response.status) { + const config = new ChartsModel(); + config.type = 'area'; + const series = new ChartsSeriesModel(); + config.xAxis.categories = response.data.columns.map(v => v.categories); + series.data = response.data.columns.map(v => v.value); + series.name = 'Count'; + config.series.push(series); + this.chartsConfig[index] = config; + } + this.chartsSkeleton[index] = false; + }); + } }); } } diff --git a/src/renderer/app/pages/home/home.module.ts b/src/renderer/app/pages/home/home.module.ts index 5f214c5a..a8cd7422 100644 --- a/src/renderer/app/pages/home/home.module.ts +++ b/src/renderer/app/pages/home/home.module.ts @@ -10,6 +10,7 @@ import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module'; import { QueryService } from '@renderer/services/query/query.service'; import { ClickhousePluginService } from '@renderer/services/plugin/clickhouse.plugin.service'; import { CommonShareModule } from '@renderer/app/common-share.module'; +import { TranslateModule } from "@ngx-translate/core"; const HOME_ROUTES: Routes = [ {path: '', component: HomeComponent} @@ -23,10 +24,10 @@ const HOME_ROUTES: Routes = [ ServiceModule, NgZorroAntdModule, CommonShareModule, - RouterModule.forChild(HOME_ROUTES) - ], - exports: [ + RouterModule.forChild(HOME_ROUTES), + TranslateModule ], + exports: [], declarations: [ HomeComponent ], diff --git a/src/renderer/app/pages/management/datasource/datasource.component.html b/src/renderer/app/pages/management/datasource/datasource.component.html index df27e505..7ea6ca1a 100644 --- a/src/renderer/app/pages/management/datasource/datasource.component.html +++ b/src/renderer/app/pages/management/datasource/datasource.component.html @@ -18,6 +18,7 @@ {{'common.name' | translate}} {{'common.host' | translate}} {{'common.protocol' | translate}} + {{'common.type' | translate}} {{'common.username' | translate}} {{'common.version' | translate}} {{'common.action' | translate}} @@ -29,6 +30,7 @@ {{data.name ? data.name : '-'}} {{data.host}} {{data.protocol}} + {{data.type}} {{data.username ? data.username : '-'}} {{data.version ? data.version : '-'}} @@ -99,10 +101,17 @@
@@ -140,7 +149,7 @@ - + diff --git a/src/renderer/app/pages/management/datasource/datasource.component.ts b/src/renderer/app/pages/management/datasource/datasource.component.ts index c0e70a7f..53979af0 100644 --- a/src/renderer/app/pages/management/datasource/datasource.component.ts +++ b/src/renderer/app/pages/management/datasource/datasource.component.ts @@ -12,6 +12,7 @@ import { NzModalService } from 'ng-zorro-antd/modal'; import { TranslateService } from '@ngx-translate/core'; import { StringUtils } from '@renderer/utils/string.utils'; import { RequestModel } from '@renderer/model/request.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-management-datasource', @@ -41,6 +42,7 @@ export class DatasourceComponent extends BaseComponent implements OnInit { next: false }; sourceTypes: DatabaseModel[]; + dataSourceType = DatabaseEnum; constructor(private service: DatasourceService, private messageService: NzMessageService, diff --git a/src/renderer/app/pages/management/datasource/datasource.module.ts b/src/renderer/app/pages/management/datasource/datasource.module.ts index 4758c003..7ebde5c6 100644 --- a/src/renderer/app/pages/management/datasource/datasource.module.ts +++ b/src/renderer/app/pages/management/datasource/datasource.module.ts @@ -11,6 +11,7 @@ import { ServiceModule } from '@renderer/app/service.module'; import { CommonShareModule } from '@renderer/app/common-share.module'; import { NzModalService } from 'ng-zorro-antd/modal'; import { SshService } from '@renderer/services/ssh.service'; +import {PrestoService} from "@renderer/services/presto.service"; const DATASOURCE_ROUTES: Routes = [ {path: '', component: DatasourceComponent} @@ -35,7 +36,8 @@ const DATASOURCE_ROUTES: Routes = [ DatasourceService, DatasourceJob, NzModalService, - SshService + SshService, + PrestoService ] }) export class DatasourceModule { diff --git a/src/renderer/app/pages/management/metadata/metadata.component.ts b/src/renderer/app/pages/management/metadata/metadata.component.ts index 793641f7..f74fb1dd 100644 --- a/src/renderer/app/pages/management/metadata/metadata.component.ts +++ b/src/renderer/app/pages/management/metadata/metadata.component.ts @@ -12,6 +12,7 @@ import { TreeUtils } from '@renderer/utils/tree.utils'; import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown'; import { NzMessageService } from 'ng-zorro-antd/message'; import { NzFormatEmitEvent } from 'ng-zorro-antd/tree'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-management-metadata', @@ -54,6 +55,9 @@ export class MetadataComponent extends BaseComponent implements OnInit { configModel.title = k.alias; configModel.type = TypeEnum.disk; configModel.disabled = k.status ? false : true; + if (k.type === DatabaseEnum.presto || k.type === DatabaseEnum.trino) { + configModel.disabled = true; + } if (configModel.disabled) { configModel.isLeaf = true; } @@ -61,9 +65,9 @@ export class MetadataComponent extends BaseComponent implements OnInit { }); this.nodes = datasourceConfigs; }) - .catch(error => { - this.messageService.error(error.message); - }); + .catch(error => { + this.messageService.error(error.message); + }); this.outerHeight = window.outerHeight; } diff --git a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts index 2120eb7d..beaa2cc0 100644 --- a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts +++ b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts @@ -7,6 +7,7 @@ import { RequestModel } from '@renderer/model/request.model'; import { NzMessageService } from 'ng-zorro-antd/message'; import { ResponseDataModel } from '@renderer/model/response.model'; import { ChartsModel, ChartsSeriesModel } from '@renderer/model/charts.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-connection', @@ -28,7 +29,12 @@ export class MonitorConnectionComponent extends BaseComponent implements OnDestr private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts b/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts index 8c04e347..24e8f04b 100644 --- a/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts +++ b/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts @@ -8,6 +8,7 @@ import { NzMessageService } from 'ng-zorro-antd/message'; import { ResponseDataModel } from '@renderer/model/response.model'; import { BaseModel } from '@renderer/model/base.model'; import { ChartsModel, ChartsSeriesModel } from '@renderer/model/charts.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-mutations', @@ -30,7 +31,12 @@ export class MonitorMutationsComponent extends BaseComponent implements OnDestro private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts index f11c1ef3..707d19fb 100644 --- a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts +++ b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts @@ -8,6 +8,7 @@ import { NzMessageService } from 'ng-zorro-antd/message'; import { ResponseDataModel } from '@renderer/model/response.model'; import { BaseModel } from '@renderer/model/base.model'; import { ChartsModel, ChartsSeriesModel } from '@renderer/model/charts.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-processor', @@ -30,7 +31,12 @@ export class MonitorProcessorComponent extends BaseComponent implements OnDestro private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/pages/monitor/query/monitor.query.component.ts b/src/renderer/app/pages/monitor/query/monitor.query.component.ts index 2d7a74ff..fe92c685 100644 --- a/src/renderer/app/pages/monitor/query/monitor.query.component.ts +++ b/src/renderer/app/pages/monitor/query/monitor.query.component.ts @@ -7,6 +7,7 @@ import { ResponseDataModel } from '@renderer/model/response.model'; import { DatasourceService } from '@renderer/services/management/datasource.service'; import { MonitorService } from '@renderer/services/monitor/monitor.service'; import { NzMessageService } from 'ng-zorro-antd/message'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-query', @@ -27,7 +28,12 @@ export class MonitorQueryComponent extends BaseComponent { private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/pages/tools/migrte/migrte.component.ts b/src/renderer/app/pages/tools/migrte/migrte.component.ts index a4c7981d..8348fa31 100644 --- a/src/renderer/app/pages/tools/migrte/migrte.component.ts +++ b/src/renderer/app/pages/tools/migrte/migrte.component.ts @@ -8,6 +8,7 @@ import { TableService } from '@renderer/services/management/table.service'; import { MigrateService } from '@renderer/services/tools/migrate.service'; import { StringUtils } from '@renderer/utils/string.utils'; import { NzMessageService } from 'ng-zorro-antd/message'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-tools-migrte', @@ -26,7 +27,12 @@ export class MigrteComponent extends BaseComponent { private migrateService: MigrateService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/pages/tools/track/track.component.ts b/src/renderer/app/pages/tools/track/track.component.ts index f3d651a1..5b497d6e 100644 --- a/src/renderer/app/pages/tools/track/track.component.ts +++ b/src/renderer/app/pages/tools/track/track.component.ts @@ -7,6 +7,7 @@ import { NzMessageService } from 'ng-zorro-antd/message'; import { TrackEnum } from '@renderer/enum/track.enum'; import { ColorEnum } from '@renderer/enum/color.enum'; import { NzModalService } from 'ng-zorro-antd/modal'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-tools-track', @@ -26,7 +27,12 @@ export class TrackComponent extends BaseComponent { private modal: NzModalService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/service.module.ts b/src/renderer/app/service.module.ts index a17400b0..b56db163 100644 --- a/src/renderer/app/service.module.ts +++ b/src/renderer/app/service.module.ts @@ -1,14 +1,18 @@ -import { NgModule } from '@angular/core'; -import { HttpService } from '@renderer/services/http.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { SshService } from '@renderer/services/ssh.service'; +import {NgModule} from '@angular/core'; +import {HttpService} from '@renderer/services/http.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {FactoryService} from "@renderer/services/factory.service"; @NgModule({ exports: [], providers: [ BasicService, HttpService, - SshService + SshService, + PrestoService, + FactoryService ] }) export class ServiceModule { diff --git a/src/renderer/assets/i18n/en.json b/src/renderer/assets/i18n/en.json index 306fcf6e..ba8e75d1 100644 --- a/src/renderer/assets/i18n/en.json +++ b/src/renderer/assets/i18n/en.json @@ -156,7 +156,9 @@ "more": "More", "matchBrackets": "Match Brackets", "filter": "Filter", - "precise": "Precise" + "precise": "Precise", + "trino": "Trino", + "presto": "Presto" }, "language": { "english": "English", @@ -260,7 +262,9 @@ }, "source": { "basic": "Basic DataSource Type", - "clickhouse": "Integrate ClickHouse data sources" + "clickhouse": "Integrate ClickHouse data sources", + "trino": "Integrate Trino data sources", + "presto": "Integrate Presto data sources" } }, "alert": { @@ -275,7 +279,9 @@ "only_one_column": "You cannot delete all columns in a data table, the table must contain at least one column", "delete_it": "We don't recommend that you delete it? This operation produces the following?", "migrate_datasource": "The storage method of the data source has been modified. Please continue to use the original storage content after migrating the data.", - "migrate_data_success": "After the migration is successful, the source data will be cleaned up!" + "migrate_data_success": "After the migration is successful, the source data will be cleaned up!", + "not_support_data_source_type": "The data source type is not supported", + "get_analysis_failed": "Failed to get the analysis data" }, "formatter": { "migrate_data": "Need to migrate {0} data, please confirm whether to migrate?" diff --git a/src/renderer/assets/i18n/zh.json b/src/renderer/assets/i18n/zh.json index dcf150b9..1bf43318 100644 --- a/src/renderer/assets/i18n/zh.json +++ b/src/renderer/assets/i18n/zh.json @@ -155,7 +155,9 @@ "more": "更多", "matchBrackets": "匹配括号", "filter": "过滤", - "precise": "精确" + "precise": "精确", + "trino": "Trino", + "presto": "Presto" }, "language": { "english": "英语", @@ -261,7 +263,9 @@ }, "source": { "basic": "基本数据源", - "clickhouse": "整合ClickHouse数据源" + "clickhouse": "整合ClickHouse数据源", + "trino": "整合Trino数据源", + "presto": "整合Presto数据源" } }, "alert": { @@ -276,7 +280,9 @@ "only_one_column": "不能删除数据表中的所有列, 该数据表必须至少包含一列", "delete_it": "我们不建议你删除它?这个操作会产生以下结果?", "migrate_datasource": "数据源存储方式已经修改请迁移数据后继续使用原有存储内容", - "migrate_data_success": "迁移成功后源数据将被清理!" + "migrate_data_success": "迁移成功后源数据将被清理!", + "not_support_data_source_type": "不支持的数据源类型", + "get_analysis_failed": "获取远程数据失败" }, "formatter": { "migrate_data": "需要迁移{0}条数据, 请确认是否迁移?" diff --git a/src/renderer/assets/icon/source/presto.svg b/src/renderer/assets/icon/source/presto.svg new file mode 100644 index 00000000..bf0e662a --- /dev/null +++ b/src/renderer/assets/icon/source/presto.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/icon/source/trino.svg b/src/renderer/assets/icon/source/trino.svg new file mode 100644 index 00000000..1c83e1ef --- /dev/null +++ b/src/renderer/assets/icon/source/trino.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/config/base.config.ts b/src/renderer/config/base.config.ts index 00aab9af..1430fc5c 100644 --- a/src/renderer/config/base.config.ts +++ b/src/renderer/config/base.config.ts @@ -1,4 +1,5 @@ export interface BaseConfig { + version: string; diskUsedRatio: string; databaseDiskUsedRatio: string; tableDiskUsedRatio: string; diff --git a/src/renderer/config/clickhouse.config.ts b/src/renderer/config/clickhouse.config.ts index 99895a0e..e16ef48d 100644 --- a/src/renderer/config/clickhouse.config.ts +++ b/src/renderer/config/clickhouse.config.ts @@ -1,6 +1,9 @@ -import { BaseConfig } from '@renderer/config/base.config'; +import {BaseConfig} from '@renderer/config/base.config'; export class ClickhouseConfig implements BaseConfig { + version = ` +SELECT version() AS version +`; diskUsedRatio = ` SELECT name, path, formatReadableSize(free_space) AS freeSize, formatReadableSize(total_space) AS totalSize, diff --git a/src/renderer/config/presto.config.ts b/src/renderer/config/presto.config.ts new file mode 100644 index 00000000..ca964c8a --- /dev/null +++ b/src/renderer/config/presto.config.ts @@ -0,0 +1,20 @@ +import {BaseConfig} from "@renderer/config/base.config"; + +export class PrestoConfig implements BaseConfig { + version = ` +SELECT node_version AS version +FROM system.runtime.nodes +LIMIT 1 + `; + columnDiskUsedRatio: string; + columnItems: string; + databaseDiskUsedRatio: string; + databaseItems: string; + databaseItemsFilterFuzzy: string; + databaseItemsFilterPrecise: string; + diskUsedRatio: string; + tableDiskUsedRatio: string; + tableItems: string; + tableItemsFilterFuzzy: string; + tableItemsFilterPrecise: string; +} diff --git a/src/renderer/config/source.type.config.ts b/src/renderer/config/source.type.config.ts index caa715f8..76876f30 100644 --- a/src/renderer/config/source.type.config.ts +++ b/src/renderer/config/source.type.config.ts @@ -1,17 +1,17 @@ -import { Injectable } from '@angular/core'; -import { DatabaseEnum } from '@renderer/enum/database.enum'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { TranslateUtils } from '@renderer/utils/translate.utils'; +import {Injectable} from '@angular/core'; +import {DatabaseEnum} from '@renderer/enum/database.enum'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {TranslateUtils} from '@renderer/utils/translate.utils'; @Injectable() export class SourceTypeConfig { getConfig(): DatabaseModel[] { + const basicType = new DatabaseModel(); const typeEngines = new Array(); - const basicEngine = new DatabaseModel(); - basicEngine.name = StringUtils.format('{0}', + basicType.name = StringUtils.format('{0}', [TranslateUtils.getValue('common.basic')]); - basicEngine.description = TranslateUtils.getValue('tooltip.source.basic'); + basicType.description = TranslateUtils.getValue('tooltip.source.basic'); const basicEngines = new Array(); // ClickHouse basicEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.clickhouse'), @@ -21,8 +21,33 @@ export class SourceTypeConfig { false, null, './renderer/assets/icon/source/clickhouse.svg')); - basicEngine.engines = basicEngines; - typeEngines.push(basicEngine); + basicType.engines = basicEngines; + + // -------------- Experimental ---------------- + const experimentalType = new DatabaseModel(); + const experimentalEngines = new Array(); + experimentalType.name = StringUtils.format('{0}', + [TranslateUtils.getValue('common.experimental')]); + experimentalType.description = TranslateUtils.getValue('tooltip.experimental'); + // Presto + experimentalEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.presto'), + TranslateUtils.getValue('tooltip.source.presto'), + DatabaseEnum.presto, + null, + true, + null, + './renderer/assets/icon/source/presto.svg')); + // Trino + experimentalEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.trino'), + TranslateUtils.getValue('tooltip.source.trino'), + DatabaseEnum.trino, + null, + true, + null, + './renderer/assets/icon/source/trino.svg')); + experimentalType.engines = experimentalEngines; + + typeEngines.push(basicType, experimentalType); return typeEngines; } } diff --git a/src/renderer/db/dexiedb.ts b/src/renderer/db/dexiedb.ts index 61a6ed90..29485dc2 100644 --- a/src/renderer/db/dexiedb.ts +++ b/src/renderer/db/dexiedb.ts @@ -10,7 +10,7 @@ export class DexieDb extends Dexie { constructor() { super('dbm_db'); - this.version(4) + this.version(5) .stores({ QueryHistoryTable: '++id,createdTime,startTime,endTime', SnippetTable: '++id,name,created,updated', diff --git a/src/renderer/enum/database.enum.ts b/src/renderer/enum/database.enum.ts index f08ea018..31ea25a5 100644 --- a/src/renderer/enum/database.enum.ts +++ b/src/renderer/enum/database.enum.ts @@ -16,5 +16,7 @@ export enum DatabaseEnum { odbc = 'ODBC', // DataSource Type - clickhosue = 'ClickHouse' + clickhosue = 'ClickHouse', + trino = 'Trino', + presto = 'Presto' } diff --git a/src/renderer/services/dbm.promise.ts b/src/renderer/services/dbm.promise.ts new file mode 100644 index 00000000..184ea9da --- /dev/null +++ b/src/renderer/services/dbm.promise.ts @@ -0,0 +1,42 @@ +export class DbmPromise extends Promise { + constructor(timeout, callback) { + // We need to support being called with no milliseconds + // value, because the various Promise methods (`then` and + // such) correctly call the subclass constructor when + // building the new promises they return. + const haveTimeout = typeof timeout === "number"; + const init = haveTimeout ? callback : timeout; + super((resolve, reject) => { + if (haveTimeout) { + const timer = setTimeout(() => { + reject(new Error(`Promise timed out after ${timeout}ms`)); + }, timeout); + init( + (value) => { + clearTimeout(timer); + resolve(value); + }, + (error) => { + clearTimeout(timer); + reject(error); + } + ); + } else { + init(resolve, reject); + } + }); + } + + // Pick your own name of course. (You could even override `resolve` itself + // if you liked; just be sure to do the same arguments detection we do + // above in the constructor, since you need to support the standard use of + // `resolve`.) + static resolveWithTimeout(timeout, x) { + if (!x || typeof x.then !== "function") { + // `x` isn't a thenable, no need for the timeout, + // fulfill immediately + return this.resolve(x); + } + return new this(timeout, x.then.bind(x)); + } +} diff --git a/src/renderer/services/factory.service.ts b/src/renderer/services/factory.service.ts new file mode 100644 index 00000000..e00762fb --- /dev/null +++ b/src/renderer/services/factory.service.ts @@ -0,0 +1,19 @@ +import {DatabaseEnum} from "@renderer/enum/database.enum"; +import {Factory} from "@renderer/factory"; +import {ClickhouseConfig} from "@renderer/config/clickhouse.config"; +import {PrestoConfig} from "@renderer/config/presto.config"; + +export class FactoryService { + public forward(type: string) { + switch (type) { + case DatabaseEnum.clickhosue: + return Factory.create(ClickhouseConfig); + case DatabaseEnum.trino: + case DatabaseEnum.presto: + return Factory.create(PrestoConfig); + default: + new Error("Unsupported database type"); + return null; + } + } +} diff --git a/src/renderer/services/forward.service.ts b/src/renderer/services/forward.service.ts index ca1ff89e..bd94783d 100644 --- a/src/renderer/services/forward.service.ts +++ b/src/renderer/services/forward.service.ts @@ -1,17 +1,22 @@ -import { HttpService } from '@renderer/services/http.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { ResponseModel } from '@renderer/model/response.model'; -import { UrlUtils } from '@renderer/utils/url.utils'; -import { SshModel } from '@renderer/model/ssh.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { SystemBasicModel } from '@renderer/model/system.model'; -import { BasicService } from '@renderer/services/system/basic.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {ResponseModel} from '@renderer/model/response.model'; +import {UrlUtils} from '@renderer/utils/url.utils'; +import {SshModel} from '@renderer/model/ssh.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {SystemBasicModel} from '@renderer/model/system.model'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {DatabaseEnum} from "@renderer/enum/database.enum"; +import {FactoryService} from "@renderer/services/factory.service"; export class ForwardService { constructor( - private httpService: HttpService, - private sshService: SshService, - private basicService: BasicService + protected basicService: BasicService, + protected factoryService: FactoryService, + protected httpService: HttpService, + protected sshService: SshService, + protected prestoService?: PrestoService, ) { } @@ -23,7 +28,17 @@ export class ForwardService { const configure = request.config; switch (configure.protocol) { case 'HTTP': - return this.httpService.post(UrlUtils.formatUrl(request), sql); + let response; + switch (configure.type) { + case DatabaseEnum.clickhosue: + response = this.httpService.post(UrlUtils.formatUrl(request), sql); + break + case DatabaseEnum.trino: + case DatabaseEnum.presto: + response = this.prestoService.execute(configure, sql); + break + } + return response; case 'SSH': const basicConfig = this.getConfig(); const network = basicConfig.network * 1000; diff --git a/src/renderer/services/management/column.service.ts b/src/renderer/services/management/column.service.ts index 1faaab0f..1b61fd56 100644 --- a/src/renderer/services/management/column.service.ts +++ b/src/renderer/services/management/column.service.ts @@ -1,23 +1,25 @@ -import { Injectable } from '@angular/core'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { SqlUtils } from '@renderer/utils/sql.utils'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { ColumnModel } from '@renderer/model/column.model'; -import { ColumnUtils } from '@renderer/utils/column.utils'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SqlUtils} from '@renderer/utils/sql.utils'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {ColumnModel} from '@renderer/model/column.model'; +import {ColumnUtils} from '@renderer/utils/column.utils'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class ColumnService extends ForwardService implements BaseService { constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/management/database.service.ts b/src/renderer/services/management/database.service.ts index d83dd92c..c3f46532 100644 --- a/src/renderer/services/management/database.service.ts +++ b/src/renderer/services/management/database.service.ts @@ -1,19 +1,21 @@ -import { Injectable } from '@angular/core'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class DatabaseService extends ForwardService implements BaseService { constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/management/datasource.service.ts b/src/renderer/services/management/datasource.service.ts index 80a995df..56ff978c 100644 --- a/src/renderer/services/management/datasource.service.ts +++ b/src/renderer/services/management/datasource.service.ts @@ -1,28 +1,33 @@ -import { BaseService } from '@renderer/services/base.service'; -import { ResponseModel } from '@renderer/model/response.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { DatasourceModel } from '@renderer/model/datasource.model'; -import { HttpService } from '@renderer/services/http.service'; -import { Injectable } from '@angular/core'; -import { PromiseExtended } from 'dexie'; -import { PersistenceService } from '@renderer/services/persistence.service'; -import { DexieDb } from '@renderer/db/dexiedb'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; +import {BaseService} from '@renderer/services/base.service'; +import {ResponseModel} from '@renderer/model/response.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {DatasourceModel} from '@renderer/model/datasource.model'; +import {HttpService} from '@renderer/services/http.service'; +import {Injectable} from '@angular/core'; +import {PromiseExtended} from 'dexie'; +import {PersistenceService} from '@renderer/services/persistence.service'; +import {DexieDb} from '@renderer/db/dexiedb'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class DatasourceService extends PersistenceService implements BaseService { private db: DexieDb; - constructor(httpService: HttpService, - sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + constructor( + basicService: BasicService, + factoryService: FactoryService, + httpService: HttpService, + sshService: SshService, + prestoService: PrestoService) { + super(basicService, factoryService, httpService, sshService, prestoService); this.db = new DexieDb(); } getResponse(request: RequestModel, sql?: string): Promise { - sql = 'SELECT version() AS version'; + sql = this.factoryService.forward(request.config.type).version; return this.forward(request, sql); } @@ -33,9 +38,9 @@ export class DatasourceService extends PersistenceService implements BaseService */ getAll(): PromiseExtended { return this.db.DataSourceTable - .orderBy('created') - .reverse() - .toArray(); + .orderBy('created') + .reverse() + .toArray(); } delete(id: number): PromiseExtended { @@ -69,8 +74,8 @@ export class DatasourceService extends PersistenceService implements BaseService async getByAliasAsync(alias: string): Promise { let dataSource; dataSource = await this.db.DataSourceTable.where('alias') - .equals(alias) - .toArray(); + .equals(alias) + .toArray(); return dataSource.length > 0 ? dataSource[0] : new DatasourceModel(); } } diff --git a/src/renderer/services/management/metadata.service.ts b/src/renderer/services/management/metadata.service.ts index 2083f56f..7418b5a5 100644 --- a/src/renderer/services/management/metadata.service.ts +++ b/src/renderer/services/management/metadata.service.ts @@ -1,20 +1,21 @@ -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { Injectable } from '@angular/core'; -import { ResponseModel } from '@renderer/model/response.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { ConfigModel } from '@renderer/model/config.model'; -import { TypeEnum } from '@renderer/enum/type.enum'; -import { ClickhouseConfig } from '@renderer/config/clickhouse.config'; -import { Factory } from '@renderer/factory'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { DatabaseEnum } from '@renderer/enum/database.enum'; -import { PropertyModel } from '@renderer/model/property.model'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; -import { FilterModel } from '@renderer/model/filter.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {Injectable} from '@angular/core'; +import {ResponseModel} from '@renderer/model/response.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {ConfigModel} from '@renderer/model/config.model'; +import {TypeEnum} from '@renderer/enum/type.enum'; +import {ClickhouseConfig} from '@renderer/config/clickhouse.config'; +import {Factory} from '@renderer/factory'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {DatabaseEnum} from '@renderer/enum/database.enum'; +import {PropertyModel} from '@renderer/model/property.model'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FilterModel} from '@renderer/model/filter.model'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class MetadataService extends ForwardService implements BaseService { @@ -22,9 +23,10 @@ export class MetadataService extends ForwardService implements BaseService { WORD = 'ENGINE'; constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); this.baseConfig = Factory.create(ClickhouseConfig); } diff --git a/src/renderer/services/management/table.service.ts b/src/renderer/services/management/table.service.ts index 97d77f77..77d0d64f 100644 --- a/src/renderer/services/management/table.service.ts +++ b/src/renderer/services/management/table.service.ts @@ -1,26 +1,28 @@ -import { Injectable } from '@angular/core'; -import { LogicEnum } from '@renderer/enum/logic.enum'; -import { PropertyEnum } from '@renderer/enum/property.enum'; -import { ColumnModel } from '@renderer/model/column.model'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { PropertyModel } from '@renderer/model/property.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { SqlUtils } from '@renderer/utils/sql.utils'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { TableTtlModel } from '@renderer/model/table/table.ttl.model'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {LogicEnum} from '@renderer/enum/logic.enum'; +import {PropertyEnum} from '@renderer/enum/property.enum'; +import {ColumnModel} from '@renderer/model/column.model'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {PropertyModel} from '@renderer/model/property.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SqlUtils} from '@renderer/utils/sql.utils'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {TableTtlModel} from '@renderer/model/table/table.ttl.model'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class TableService extends ForwardService implements BaseService { constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { @@ -220,11 +222,11 @@ export class TableService extends ForwardService implements BaseService { // } // }); properties - .filter(p => p.origin !== undefined && StringUtils.isNotEmpty(p.origin)) - .filter(p => p.value !== undefined) - .forEach(p => { - substr += StringUtils.format('\n {0} = \'{1}\',', [p.origin, p.value]); - }); + .filter(p => p.origin !== undefined && StringUtils.isNotEmpty(p.origin)) + .filter(p => p.value !== undefined) + .forEach(p => { + substr += StringUtils.format('\n {0} = \'{1}\',', [p.origin, p.value]); + }); if (StringUtils.isNotEmpty(substr)) { substr = StringUtils.format('SETTINGS {0}', [substr.substring(0, substr.length - 1)]); } @@ -241,9 +243,9 @@ export class TableService extends ForwardService implements BaseService { break; case PropertyEnum.name: const substr = configure.properties - .filter(element => StringUtils.isNotEmpty(element.value)) - .flatMap(element => StringUtils.format('\'{0}\'', [element.value])) - .join(', '); + .filter(element => StringUtils.isNotEmpty(element.value)) + .flatMap(element => StringUtils.format('\'{0}\'', [element.value])) + .join(', '); sql = StringUtils.format('{0} {1}({2})', [prefix, configure.type, substr]); break; } @@ -253,16 +255,16 @@ export class TableService extends ForwardService implements BaseService { private flatProperties(properties: PropertyModel[]): Map { const map = new Map(); properties - .filter(p => p.isSetting === undefined || p.isSetting) - .forEach(p => { - if (StringUtils.isNotEmpty(p.origin)) { - map.set('type', PropertyEnum.key); - map.set(p.origin, p.value); - } else { - map.set('type', PropertyEnum.name); - map.set(p.name, p.value); - } - }); + .filter(p => p.isSetting === undefined || p.isSetting) + .forEach(p => { + if (StringUtils.isNotEmpty(p.origin)) { + map.set('type', PropertyEnum.key); + map.set(p.origin, p.value); + } else { + map.set('type', PropertyEnum.name); + map.set(p.name, p.value); + } + }); return map; } diff --git a/src/renderer/services/monitor/monitor.service.ts b/src/renderer/services/monitor/monitor.service.ts index 0e591297..5e71c473 100644 --- a/src/renderer/services/monitor/monitor.service.ts +++ b/src/renderer/services/monitor/monitor.service.ts @@ -1,19 +1,21 @@ -import { BaseService } from '@renderer/services/base.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { Injectable } from '@angular/core'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {BaseService} from '@renderer/services/base.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {Injectable} from '@angular/core'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class MonitorService extends ForwardService implements BaseService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/plugin/clickhouse.plugin.service.ts b/src/renderer/services/plugin/clickhouse.plugin.service.ts index 6ea6bcf3..7b2727bc 100644 --- a/src/renderer/services/plugin/clickhouse.plugin.service.ts +++ b/src/renderer/services/plugin/clickhouse.plugin.service.ts @@ -1,18 +1,20 @@ -import { BasePluginService } from '@renderer/services/plugin/base.plugin.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { HttpService } from '@renderer/services/http.service'; -import { Injectable } from '@angular/core'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {BasePluginService} from '@renderer/services/plugin/base.plugin.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {HttpService} from '@renderer/services/http.service'; +import {Injectable} from '@angular/core'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class ClickhousePluginService extends ForwardService implements BasePluginService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/presto.service.ts b/src/renderer/services/presto.service.ts new file mode 100644 index 00000000..4459ed19 --- /dev/null +++ b/src/renderer/services/presto.service.ts @@ -0,0 +1,81 @@ +import {Injectable} from "@angular/core"; +import {SystemBasicModel} from "@renderer/model/system.model"; +import {BasicService} from "@renderer/services/system/basic.service"; +import {DatasourceModel} from "@renderer/model/datasource.model"; +import {ResponseDataModel, ResponseModel} from "@renderer/model/response.model"; +import {StringUtils} from "@renderer/utils/string.utils"; +import {timeout, TimeoutError} from 'promise-timeout'; + +@Injectable() +export class PrestoService { + + constructor(private basicService: BasicService) { + } + + private getConfig(): SystemBasicModel { + return this.basicService.get() === null ? new SystemBasicModel() : this.basicService.get(); + } + + execute(configure: DatasourceModel, sql: string): Promise { + const {Client} = require('presto-stream-client'); + const network = this.getConfig().network * 1000; + let client; + const hasAuthentication = (StringUtils.isNotEmpty(configure.username) && StringUtils.isNotEmpty(configure.password)); + if (hasAuthentication) { + client = new Client({ + host: configure.host, + port: configure.port, + user: configure.username, + password: configure.password, + pollInterval: network, + source: 'dbm-client' + }); + } else { + client = new Client({host: configure.host, port: configure.port, pollInterval: network, source: 'dbm-client'}); + } + const response = new ResponseModel(); + const responseData = new ResponseDataModel(); + const somePromise = new Promise((resolve) => { + client.execute({ + query: sql, + catalog: 'hive', + schema: 'default', + objectMode: true + }).then((statement) => { + statement.on('columns', (columns) => { + responseData.headers = columns; + }); + statement.on('data', (rows) => { + responseData.columns.push(rows); + }); + statement.on('end', () => { + response.status = true; + response.data = responseData; + resolve(response); + }); + statement.on('error', (err) => { + response.status = false; + response.message = err?.message; + resolve(response); + }); + }, (err) => { + response.status = false; + response.message = err; + resolve(response); + }); + }); + return timeout(somePromise, network) + .then((thing) => { + return thing; + }) + .catch((err) => { + response.status = false; + if (err instanceof TimeoutError) { + response.message = `Promise timed out after ${this.getConfig().network} ms`; + } else { + response.message = err; + } + return response; + }); + } +} diff --git a/src/renderer/services/query/query.service.ts b/src/renderer/services/query/query.service.ts index 652a4d0e..d1d61319 100644 --- a/src/renderer/services/query/query.service.ts +++ b/src/renderer/services/query/query.service.ts @@ -7,6 +7,8 @@ import { StringUtils } from '@renderer/utils/string.utils'; import { ForwardService } from '@renderer/services/forward.service'; import { SshService } from '@renderer/services/ssh.service'; import { BasicService } from '@renderer/services/system/basic.service'; +import { FactoryService } from "@renderer/services/factory.service"; +import { PrestoService } from "@renderer/services/presto.service"; const {Parser} = require('node-sql-parser'); @@ -14,8 +16,10 @@ const {Parser} = require('node-sql-parser'); export class QueryService extends ForwardService implements BaseService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService, + prestoService: PrestoService) { + super(basicService, factoryService, httpService, sshService, prestoService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/snippet/snippet.service.ts b/src/renderer/services/snippet/snippet.service.ts index a07de6fb..debe85e1 100644 --- a/src/renderer/services/snippet/snippet.service.ts +++ b/src/renderer/services/snippet/snippet.service.ts @@ -1,14 +1,15 @@ -import { BaseService } from '@renderer/services/base.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { PersistenceService } from '@renderer/services/persistence.service'; -import { DexieDb } from '@renderer/db/dexiedb'; -import { SnippetModel } from '@renderer/model/snippet.model'; -import { PromiseExtended } from 'dexie'; -import { Injectable } from '@angular/core'; -import { HttpService } from '@renderer/services/http.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; +import {BaseService} from '@renderer/services/base.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {PersistenceService} from '@renderer/services/persistence.service'; +import {DexieDb} from '@renderer/db/dexiedb'; +import {SnippetModel} from '@renderer/model/snippet.model'; +import {PromiseExtended} from 'dexie'; +import {Injectable} from '@angular/core'; +import {HttpService} from '@renderer/services/http.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class SnippetService extends PersistenceService implements BaseService { @@ -16,8 +17,9 @@ export class SnippetService extends PersistenceService implements BaseService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService) { + super(basicService, factoryService, httpService, sshService); this.db = new DexieDb(); } @@ -37,9 +39,9 @@ export class SnippetService extends PersistenceService implements BaseService { getAll(): PromiseExtended { return this.db.SnippetTable - .orderBy('id') - .reverse() - .toArray(); + .orderBy('id') + .reverse() + .toArray(); } clear(): boolean { diff --git a/src/renderer/services/tools/migrate.service.ts b/src/renderer/services/tools/migrate.service.ts index a24e0bb0..bb80d46c 100644 --- a/src/renderer/services/tools/migrate.service.ts +++ b/src/renderer/services/tools/migrate.service.ts @@ -1,23 +1,25 @@ -import { Injectable } from '@angular/core'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { DatasourceService } from '../management/datasource.service'; -import { TableService } from '../management/table.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {DatasourceService} from '../management/datasource.service'; +import {TableService} from '../management/table.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class MigrateService extends ForwardService implements BaseService { constructor(private tableService: TableService, private datasourceService: DatasourceService, + basicService: BasicService, + factoryService: FactoryService, httpService: HttpService, - sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + sshService: SshService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/tools/track.service.ts b/src/renderer/services/tools/track.service.ts index 9a7acd0f..d77d1cae 100644 --- a/src/renderer/services/tools/track.service.ts +++ b/src/renderer/services/tools/track.service.ts @@ -1,21 +1,23 @@ -import { BaseService } from '@renderer/services/base.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { Injectable } from '@angular/core'; -import { DatasourceService } from '@renderer/services/management/datasource.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {BaseService} from '@renderer/services/base.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {Injectable} from '@angular/core'; +import {DatasourceService} from '@renderer/services/management/datasource.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class TrackService extends ForwardService implements BaseService { constructor(private datasourceService: DatasourceService, + basicService: BasicService, + factoryService: FactoryService, httpService: HttpService, - sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + sshService: SshService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/styles.scss b/src/renderer/styles.scss index d6196641..9c509fc7 100644 --- a/src/renderer/styles.scss +++ b/src/renderer/styles.scss @@ -11,3 +11,10 @@ .table-body-flex { overflow: hidden; } + +.ant-avatar>img { + width: 85%; + height: 85%; + display: unset; + object-fit: cover; +} diff --git a/src/shared/assets/integrate/presto.png b/src/shared/assets/integrate/presto.png new file mode 100644 index 0000000000000000000000000000000000000000..d9a895412953d958f2bd9c7f8b7794f8d985626c GIT binary patch literal 18862 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 R0MB7!@O1TaS?83{1OQPkq-g*E literal 0 HcmV?d00001 diff --git a/src/shared/assets/integrate/trino.png b/src/shared/assets/integrate/trino.png new file mode 100644 index 0000000000000000000000000000000000000000..ea2873251db508e3b9e634e95320bf9ab7aa1209 GIT binary patch literal 20758 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 RX8QmD002ovPDHLkV1h7fpE>{l literal 0 HcmV?d00001 From ed2b61cbc2383c1cf7a49914aa03e13fece1bd3f Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Wed, 18 May 2022 21:21:43 +0800 Subject: [PATCH 05/17] [Optimize] Optimize the homepage is not available & does not support data source charts --- .../assets/images/versions/1.17.0/img_4.png | Bin 0 -> 24580 bytes .../assets/images/versions/1.17.0/img_5.png | Bin 0 -> 22376 bytes .../development/version/1.17.0-development.md | 3 +++ electron-builder.yml | 1 + package.json | 4 +++- 5 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/docs/assets/images/versions/1.17.0/img_4.png create mode 100644 docs/docs/assets/images/versions/1.17.0/img_5.png diff --git a/docs/docs/assets/images/versions/1.17.0/img_4.png b/docs/docs/assets/images/versions/1.17.0/img_4.png new file mode 100644 index 0000000000000000000000000000000000000000..fc9cbc32a6951004eeb658c607f1d97969efb2a4 GIT binary patch literal 24580 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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/versions/1.17.0/img_5.png b/docs/docs/assets/images/versions/1.17.0/img_5.png new file mode 100644 index 0000000000000000000000000000000000000000..c5cdda638c09cee26b9dcf762e7d262f93d45c3a GIT binary patch literal 22376 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 literal 0 HcmV?d00001 diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index fc77e9ee..eaec63a1 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -29,6 +29,9 @@ DBM Version for `1.17.0` is development! ---- - Optimize project description and introduction <br /> +- Optimize the homepage is not available & does not support data source charts <br /> +![img_4.png](../../assets/images/versions/1.17.0/img_4.png) <br /> +![img_5.png](../../assets/images/versions/1.17.0/img_5.png) <br /> #### Docs diff --git a/electron-builder.yml b/electron-builder.yml index f547a881..4a9afd19 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -22,6 +22,7 @@ releaseInfo: ---- - Optimize project description and introduction + - Optimize the homepage is not available & does not support data source charts #### Bug diff --git a/package.json b/package.json index 329d92d8..716cb631 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "mac", "linux", "dbm", - "clickhouse" + "clickhouse", + "trino", + "presto" ], "publish": [ { From cdcfbe43ff38186dcbff1dfc9ffb8b230e112019 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Wed, 18 May 2022 21:51:34 +0800 Subject: [PATCH 06/17] [CI] Update some github template --- CODE_OF_CONDUCT.md | 2 +- CONTRIBUTING.md | 39 +++++++++++++++++++++++++++++++++++++++ LICENSE | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f95d6907..18c91471 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -125,4 +125,4 @@ enforcement ladder](https://github.com/mozilla/diversity). For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. \ No newline at end of file +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e69de29b..f6ebb812 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +## Contributing + +[fork]: /fork +[pr]: /compare +[code-of-conduct]: CODE_OF_CONDUCT.md + +Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. + +Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. + +## Issues and PRs + +If you have suggestions for how this project could be improved, or want to report a bug, open an issue! We'd love all and any contributions. If you have questions, too, we'd love to hear them. + +We'd also love PRs. If you're thinking of a large PR, we advise opening up an issue first to talk about it, though! Look at the links below if you're not sure how to open a PR. + +## Submitting a pull request + +1. [Fork][fork] and clone the repository. +1. Configure and install the dependencies: `npm install`. +1. Make sure the tests pass on your machine: `npm test`, note: these tests also apply the linter, so there's no need to lint separately. +1. Create a new branch: `git checkout -b my-branch-name`. +1. Make your change, add tests, and make sure the tests still pass. +1. Push to your fork and [submit a pull request][pr]. +1. Pat your self on the back and wait for your pull request to be reviewed and merged. + +Here are a few things you can do that will increase the likelihood of your pull request being accepted: + +- Write and update tests. +- Keep your changes as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. +- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). + +Work in Progress pull requests are also welcome to get feedback early on, or if there is something blocked you. + +## Resources + +- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) +- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) +- [GitHub Help](https://help.github.com) diff --git a/LICENSE b/LICENSE index a4121939..67390133 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [2021] [incubator-dbm of copyright EdurtIO] + Copyright [2021] [dbm of copyright EdurtIO] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From b4533a25d3eb5f1983f1cfe0e3a77dc47051e690 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Wed, 18 May 2022 22:55:23 +0800 Subject: [PATCH 07/17] [UI] Add multiple editor themes --- docs/docs/development/version/1.17.0-development.md | 2 ++ electron-builder.yml | 2 ++ src/renderer/editor.theme.scss | 9 +++++++++ src/renderer/enum/editor/theme.enum.ts | 11 ++++++++++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index eaec63a1..f3e88db4 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -24,6 +24,8 @@ DBM Version for `1.17.0` is development! --- +- Add multiple editor themes <br /> + #### Optimize ---- diff --git a/electron-builder.yml b/electron-builder.yml index 4a9afd19..df837e8d 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -32,6 +32,8 @@ releaseInfo: --- + - Add multiple editor themes + directories: output: ./release files: diff --git a/src/renderer/editor.theme.scss b/src/renderer/editor.theme.scss index 2696b30b..c138c48b 100644 --- a/src/renderer/editor.theme.scss +++ b/src/renderer/editor.theme.scss @@ -36,6 +36,15 @@ @import "~codemirror/theme/midnight.css"; @import "~codemirror/theme/monokai.css"; @import "~codemirror/theme/moxer.css"; +@import "~codemirror/theme/neat.css"; +@import "~codemirror/theme/neo.css"; +@import "~codemirror/theme/night.css"; +@import "~codemirror/theme/nord.css"; +@import "~codemirror/theme/oceanic-next.css"; +@import "~codemirror/theme/panda-syntax.css"; +@import "~codemirror/theme/paraiso-dark.css"; +@import "~codemirror/theme/paraiso-light.css"; +@import "~codemirror/theme/pastel-on-dark.css"; //@import "~codemirror/theme/"; // Wait for all themes to load after loading, load the hint style to prevent style confusion diff --git a/src/renderer/enum/editor/theme.enum.ts b/src/renderer/enum/editor/theme.enum.ts index 077293d4..76fc2ce8 100644 --- a/src/renderer/enum/editor/theme.enum.ts +++ b/src/renderer/enum/editor/theme.enum.ts @@ -35,5 +35,14 @@ export enum EditorThemeEnum { mbo = ('mbo'), 'mdn-like' = ('mdn-like'), midnight = ('midnight'), - moxer = ('moxer') + moxer = ('moxer'), + neat = ('neat'), + neo = ('neo'), + night = ('night'), + nord = ('nord'), + 'oceanic-next' = ('oceanic-next'), + 'panda-syntax' = ('panda-syntax'), + 'paraiso-dark' = ('paraiso-dark'), + 'paraiso-light' = ('paraiso-light'), + 'pastel-on-dark' = ('pastel-on-dark') } From d3a31ea62f044971398194e267a5e3d80f6e61a2 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Mon, 23 May 2022 18:04:07 +0800 Subject: [PATCH 08/17] [Enhancement] Support trino and presto for monitor --> processors #158 --- .../processor/monitor.processor.component.ts | 7 +----- src/renderer/config/base.config.ts | 1 + src/renderer/config/clickhouse.config.ts | 18 +++++++++++++ src/renderer/config/presto.config.ts | 18 +++++++++++++ .../services/monitor/monitor.service.ts | 25 ++++--------------- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts index 707d19fb..6563bc50 100644 --- a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts +++ b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts @@ -31,12 +31,7 @@ export class MonitorProcessorComponent extends BaseComponent implements OnDestro private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response.map(item => { - if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { - item.status = false; - } - return item; - }); + this.dataSources = response; }); } diff --git a/src/renderer/config/base.config.ts b/src/renderer/config/base.config.ts index 1430fc5c..aff7bcda 100644 --- a/src/renderer/config/base.config.ts +++ b/src/renderer/config/base.config.ts @@ -1,5 +1,6 @@ export interface BaseConfig { version: string; + processesFetchAll: string; diskUsedRatio: string; databaseDiskUsedRatio: string; tableDiskUsedRatio: string; diff --git a/src/renderer/config/clickhouse.config.ts b/src/renderer/config/clickhouse.config.ts index e16ef48d..b5271887 100644 --- a/src/renderer/config/clickhouse.config.ts +++ b/src/renderer/config/clickhouse.config.ts @@ -4,6 +4,24 @@ export class ClickhouseConfig implements BaseConfig { version = ` SELECT version() AS version `; + processesFetchAll = ` +SELECT + query_id AS id, + now() AS time, + query AS query, + toUInt64(toUInt64(read_rows) + toUInt64(written_rows)) AS rows, + round(elapsed, 1) AS elapsed, + formatReadableSize(toUInt64(read_bytes) + toUInt64(written_bytes)) AS bytes, + formatReadableSize(memory_usage) AS memoryUsage, + formatReadableSize(read_bytes) AS bytesRead, + formatReadableSize(written_bytes) AS bytesWritten, + cityHash64(query) AS hash, + hostName() AS host +FROM + system.processes +WHERE + round(elapsed, 1) > 0 + `; diskUsedRatio = ` SELECT name, path, formatReadableSize(free_space) AS freeSize, formatReadableSize(total_space) AS totalSize, diff --git a/src/renderer/config/presto.config.ts b/src/renderer/config/presto.config.ts index ca964c8a..02238548 100644 --- a/src/renderer/config/presto.config.ts +++ b/src/renderer/config/presto.config.ts @@ -6,6 +6,24 @@ SELECT node_version AS version FROM system.runtime.nodes LIMIT 1 `; + processesFetchAll = ` +SELECT + query_id AS id, + now() AS time, + query AS query, + '0' AS rows, + analysis_time_ms + planning_time_ms + queued_time_ms AS elapsed, + '0' AS bytes, + '0' AS memoryUsage, + '0' AS bytesRead, + '0' AS bytesWritten, + '' AS hash, + '' AS host +FROM + system.runtime.queries +WHERE + state = 'RUNNING' +`; columnDiskUsedRatio: string; columnItems: string; databaseDiskUsedRatio: string; diff --git a/src/renderer/services/monitor/monitor.service.ts b/src/renderer/services/monitor/monitor.service.ts index 5e71c473..2eca11d4 100644 --- a/src/renderer/services/monitor/monitor.service.ts +++ b/src/renderer/services/monitor/monitor.service.ts @@ -8,14 +8,16 @@ import {SshService} from '@renderer/services/ssh.service'; import {BasicService} from '@renderer/services/system/basic.service'; import {ForwardService} from '@renderer/services/forward.service'; import {FactoryService} from "@renderer/services/factory.service"; +import { PrestoService } from "@renderer/services/presto.service"; @Injectable() export class MonitorService extends ForwardService implements BaseService { constructor(httpService: HttpService, sshService: SshService, basicService: BasicService, - factoryService: FactoryService) { - super(basicService, factoryService, httpService, sshService); + factoryService: FactoryService, + prestoService: PrestoService) { + super(basicService, factoryService, httpService, sshService, prestoService); } getResponse(request: RequestModel, sql?: string): Promise<ResponseModel> { @@ -23,24 +25,7 @@ export class MonitorService extends ForwardService implements BaseService { } getProcesses(request: RequestModel): Promise<ResponseModel> { - const sql = ` -SELECT - query_id AS id, - now() AS time, - query AS query, - toUInt64(toUInt64(read_rows) + toUInt64(written_rows)) AS rows, - round(elapsed, 1) AS elapsed, - formatReadableSize(toUInt64(read_bytes) + toUInt64(written_bytes)) AS bytes, - formatReadableSize(memory_usage) AS memoryUsage, - formatReadableSize(read_bytes) AS bytesRead, - formatReadableSize(written_bytes) AS bytesWritten, - cityHash64(query) AS hash, - hostName() AS host -FROM - system.processes -WHERE - round(elapsed, 1) > 0 - `; + const sql = this.factoryService.forward(request.config.type).processesFetchAll; return this.getResponse(request, sql); } From 5bc509372dfd20e629d7886cbb51cbb0a97eed6f Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Tue, 24 May 2022 17:06:47 +0800 Subject: [PATCH 09/17] [Enhancement] Support trino and presto for monitor --> connection #158 --- .../connection/monitor.connection.component.ts | 7 +------ src/renderer/config/base.config.ts | 1 + src/renderer/config/clickhouse.config.ts | 9 +++++++++ src/renderer/config/presto.config.ts | 9 +++++++++ src/renderer/services/monitor/monitor.service.ts | 14 +------------- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts index beaa2cc0..51cf156e 100644 --- a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts +++ b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts @@ -29,12 +29,7 @@ export class MonitorConnectionComponent extends BaseComponent implements OnDestr private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response.map(item => { - if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { - item.status = false; - } - return item; - }); + this.dataSources = response; }); } diff --git a/src/renderer/config/base.config.ts b/src/renderer/config/base.config.ts index aff7bcda..4505e617 100644 --- a/src/renderer/config/base.config.ts +++ b/src/renderer/config/base.config.ts @@ -1,6 +1,7 @@ export interface BaseConfig { version: string; processesFetchAll: string; + connectionFetchAll: string; diskUsedRatio: string; databaseDiskUsedRatio: string; tableDiskUsedRatio: string; diff --git a/src/renderer/config/clickhouse.config.ts b/src/renderer/config/clickhouse.config.ts index b5271887..dab46830 100644 --- a/src/renderer/config/clickhouse.config.ts +++ b/src/renderer/config/clickhouse.config.ts @@ -21,6 +21,15 @@ FROM system.processes WHERE round(elapsed, 1) > 0 + `; + connectionFetchAll = ` +SELECT + metric AS categories, + toUInt32(SUM(value)) AS value +FROM system.metrics +WHERE metric LIKE '%Connection' +GROUP BY metric +ORDER BY metric DESC `; diskUsedRatio = ` SELECT diff --git a/src/renderer/config/presto.config.ts b/src/renderer/config/presto.config.ts index 02238548..84926de6 100644 --- a/src/renderer/config/presto.config.ts +++ b/src/renderer/config/presto.config.ts @@ -23,6 +23,15 @@ FROM system.runtime.queries WHERE state = 'RUNNING' +`; + connectionFetchAll = ` +SELECT + source AS categories, + COUNT(1) AS value +FROM system.runtime.queries +WHERE state = 'RUNNING' +GROUP BY source +ORDER BY source DESC `; columnDiskUsedRatio: string; columnItems: string; diff --git a/src/renderer/services/monitor/monitor.service.ts b/src/renderer/services/monitor/monitor.service.ts index 2eca11d4..d64d4399 100644 --- a/src/renderer/services/monitor/monitor.service.ts +++ b/src/renderer/services/monitor/monitor.service.ts @@ -71,19 +71,7 @@ WHERE is_done = 0 } getConnections(request: RequestModel): Promise<ResponseModel> { - const sql = ` -SELECT - metric AS categories, - toUInt32(SUM(value)) AS value -FROM - system.metrics -WHERE - metric LIKE '%Connection' -GROUP BY - metric -ORDER BY - metric DESC - `; + const sql = this.factoryService.forward(request.config.type).connectionFetchAll; return this.getResponse(request, sql); } } From 4364d7ef5de8ffb61635cd81bc1124167b714e66 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Thu, 26 May 2022 11:03:30 +0800 Subject: [PATCH 10/17] [UI] Query the list of data sources on the page, support the display of logo --- .../assets/images/versions/1.17.0/img_6.png | Bin 0 -> 12827 bytes .../development/version/1.17.0-development.md | 6 +++++- electron-builder.yml | 5 ++++- .../app/pages/query/query/query.component.html | 10 ++++++++-- .../source/{clickhouse.svg => ClickHouse.svg} | 0 .../icon/source/{presto.svg => Presto.svg} | 0 .../assets/icon/source/{trino.svg => Trino.svg} | 0 src/renderer/config/source.type.config.ts | 8 ++++---- 8 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 docs/docs/assets/images/versions/1.17.0/img_6.png rename src/renderer/assets/icon/source/{clickhouse.svg => ClickHouse.svg} (100%) rename src/renderer/assets/icon/source/{presto.svg => Presto.svg} (100%) rename src/renderer/assets/icon/source/{trino.svg => Trino.svg} (100%) diff --git a/docs/docs/assets/images/versions/1.17.0/img_6.png b/docs/docs/assets/images/versions/1.17.0/img_6.png new file mode 100644 index 0000000000000000000000000000000000000000..e3ac2d0b754a86d76312b5dcec8b4fcf9bee765e GIT binary patch literal 12827 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 literal 0 HcmV?d00001 diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index f3e88db4..e9830f59 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -17,14 +17,18 @@ DBM Version for `1.17.0` is development! ![img.png](../../assets/images/versions/1.17.0/img.png) <br /> ![img_1.png](../../assets/images/versions/1.17.0/img_1.png) <br /> ![img_2.png](../../assets/images/versions/1.17.0/img_2.png) <br /> -- Support trino and presto (only custom query and data source management) <br /> +- Support trino and presto for query <br /> ![img_3.png](../../assets/images/versions/1.17.0/img_3.png) <br /> +- Support trino and presto for monitor --> processors <br /> +- Support trino and presto for monitor --> connection <br /> #### UI --- - Add multiple editor themes <br /> +- Query the list of data sources on the page, support the display of logo <br /> +![img_6.png](../../assets/images/versions/1.17.0/img_6.png) <br /> #### Optimize diff --git a/electron-builder.yml b/electron-builder.yml index df837e8d..7d437250 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -11,7 +11,9 @@ releaseInfo: --- - Support metadata management to filter the table - - Support trino and presto (only custom query and data source management) + - Support trino and presto for query + - Support trino and presto for monitor --> processors <br /> + - Support trino and presto for monitor --> connection <br /> #### Docs @@ -33,6 +35,7 @@ releaseInfo: --- - Add multiple editor themes + - Query the list of data sources on the page, support the display of logo directories: output: ./release diff --git a/src/renderer/app/pages/query/query/query.component.html b/src/renderer/app/pages/query/query/query.component.html index 29418f83..2f9d9d47 100644 --- a/src/renderer/app/pages/query/query/query.component.html +++ b/src/renderer/app/pages/query/query/query.component.html @@ -20,11 +20,17 @@ <ng-template #titleTemplate> <div> <nz-select [(ngModel)]="datasource" nzShowSearch nzAllowClear nzSize="small" - style="width: 150px; margin-right: 8px;" + style="width: 180px; margin-right: 8px;" [disabled]="loading.button" (ngModelChange)="handlerCheckStatus()"> <nz-option *ngFor="let detail of dataSources" [nzDisabled]="!detail.status" - nzValue="{{detail.alias}}" nzLabel="{{detail.alias}}"></nz-option> + nzCustomContent + nzValue="{{detail.alias}}" nzLabel="{{detail.alias}}"> + <nz-avatar nzSize="small" + nzSrc="./renderer/assets/icon/source/{{detail.type}}.svg"> + </nz-avatar> + {{detail.alias}} + </nz-option> </nz-select> <nz-button-group> <button id="executeButton" nz-button nzType="primary" nzSize="small" diff --git a/src/renderer/assets/icon/source/clickhouse.svg b/src/renderer/assets/icon/source/ClickHouse.svg similarity index 100% rename from src/renderer/assets/icon/source/clickhouse.svg rename to src/renderer/assets/icon/source/ClickHouse.svg diff --git a/src/renderer/assets/icon/source/presto.svg b/src/renderer/assets/icon/source/Presto.svg similarity index 100% rename from src/renderer/assets/icon/source/presto.svg rename to src/renderer/assets/icon/source/Presto.svg diff --git a/src/renderer/assets/icon/source/trino.svg b/src/renderer/assets/icon/source/Trino.svg similarity index 100% rename from src/renderer/assets/icon/source/trino.svg rename to src/renderer/assets/icon/source/Trino.svg diff --git a/src/renderer/config/source.type.config.ts b/src/renderer/config/source.type.config.ts index 76876f30..fdbd2fcc 100644 --- a/src/renderer/config/source.type.config.ts +++ b/src/renderer/config/source.type.config.ts @@ -20,7 +20,7 @@ export class SourceTypeConfig { null, false, null, - './renderer/assets/icon/source/clickhouse.svg')); + './renderer/assets/icon/source/ClickHouse.svg')); basicType.engines = basicEngines; // -------------- Experimental ---------------- @@ -31,12 +31,12 @@ export class SourceTypeConfig { experimentalType.description = TranslateUtils.getValue('tooltip.experimental'); // Presto experimentalEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.presto'), - TranslateUtils.getValue('tooltip.source.presto'), + TranslateUtils.getValue('tooltip.source.resto'), DatabaseEnum.presto, null, true, null, - './renderer/assets/icon/source/presto.svg')); + './renderer/assets/icon/source/Presto.svg')); // Trino experimentalEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.trino'), TranslateUtils.getValue('tooltip.source.trino'), @@ -44,7 +44,7 @@ export class SourceTypeConfig { null, true, null, - './renderer/assets/icon/source/trino.svg')); + './renderer/assets/icon/source/Trino.svg')); experimentalType.engines = experimentalEngines; typeEngines.push(basicType, experimentalType); From d7954e32e3f5458f4fb1b699b17350e8fb5d9b9c Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Thu, 26 May 2022 13:30:24 +0800 Subject: [PATCH 11/17] [Docs] Refactoring software homepage --- docs/docs/assets/integrate/ClickHouse.svg | 1 + docs/docs/assets/integrate/Presto.svg | 1 + docs/docs/assets/integrate/Trino.svg | 1 + .../development/version/1.17.0-development.md | 2 + docs/docs/reference/get_started/install.md | 2 +- docs/docs/stylesheets/extra.css | 20 + docs/material/overrides/home.html | 95 ++- docs/material/overrides/home.zh.html | 124 ++- docs/material/overrides/main.html | 3 +- docs/mkdocs.yml | 4 +- docs/src/.icons/logo.afdesign | Bin 31465 -> 0 bytes docs/src/.icons/logo.svg | 6 - docs/src/404.html | 31 - docs/src/__init__.py | 0 docs/src/assets/images/favicon.png | Bin 1870 -> 0 bytes docs/src/assets/javascripts/_/index.ts | 141 ---- .../src/assets/javascripts/actions/_/index.ts | 76 -- .../javascripts/actions/anchor/index.ts | 73 -- .../javascripts/actions/dialog/index.ts | 62 -- .../javascripts/actions/header/_/index.ts | 48 -- .../javascripts/actions/header/index.ts | 24 - .../javascripts/actions/header/title/index.ts | 48 -- docs/src/assets/javascripts/actions/index.ts | 31 - .../javascripts/actions/search/index.ts | 24 - .../javascripts/actions/search/query/index.ts | 50 -- .../actions/search/result/index.ts | 91 -- .../javascripts/actions/sidebar/index.ts | 88 -- .../javascripts/actions/source/index.ts | 49 -- .../assets/javascripts/actions/tabs/index.ts | 48 -- .../assets/javascripts/actions/top/index.ts | 73 -- .../javascripts/browser/document/index.ts | 48 -- .../javascripts/browser/element/_/.eslintrc | 5 - .../javascripts/browser/element/_/index.ts | 129 --- .../browser/element/focus/index.ts | 67 -- .../javascripts/browser/element/index.ts | 27 - .../browser/element/offset/index.ts | 112 --- .../browser/element/selection/index.ts | 39 - .../javascripts/browser/element/size/index.ts | 154 ---- docs/src/assets/javascripts/browser/index.ts | 31 - .../javascripts/browser/keyboard/index.ts | 108 --- .../javascripts/browser/location/_/index.ts | 61 -- .../browser/location/hash/index.ts | 91 -- .../javascripts/browser/location/index.ts | 24 - .../assets/javascripts/browser/media/index.ts | 92 -- .../javascripts/browser/request/index.ts | 90 -- .../javascripts/browser/toggle/index.ts | 98 --- .../javascripts/browser/viewport/_/index.ts | 121 --- .../javascripts/browser/viewport/index.ts | 25 - .../browser/viewport/offset/index.ts | 84 -- .../browser/viewport/size/index.ts | 67 -- .../javascripts/browser/worker/index.ts | 104 --- docs/src/assets/javascripts/bundle.ts | 254 ------ .../assets/javascripts/components/_/index.ts | 132 --- .../javascripts/components/content/_/index.ts | 89 -- .../components/content/code/index.ts | 183 ---- .../components/content/details/index.ts | 118 --- .../javascripts/components/content/index.ts | 26 - .../components/content/table/index.ts | 71 -- .../javascripts/components/dialog/index.ts | 139 --- .../javascripts/components/header/_/index.ts | 206 ----- .../javascripts/components/header/index.ts | 24 - .../components/header/title/index.ts | 147 ---- .../assets/javascripts/components/index.ts | 34 - .../javascripts/components/main/index.ts | 124 --- .../javascripts/components/palette/index.ts | 148 ---- .../javascripts/components/search/_/index.ts | 229 ----- .../components/search/highlight/.eslintrc | 5 - .../components/search/highlight/index.ts | 113 --- .../javascripts/components/search/index.ts | 28 - .../components/search/query/index.ts | 180 ---- .../components/search/result/index.ts | 160 ---- .../components/search/share/index.ts | 123 --- .../components/search/suggest/index.ts | 152 ---- .../javascripts/components/sidebar/index.ts | 165 ---- .../javascripts/components/source/_/index.ts | 125 --- .../components/source/facts/_/index.ts | 88 -- .../components/source/facts/github/index.ts | 95 --- .../components/source/facts/gitlab/index.ts | 55 -- .../components/source/facts/index.ts | 25 - .../javascripts/components/source/index.ts | 24 - .../javascripts/components/tabs/index.ts | 153 ---- .../javascripts/components/toc/index.ts | 275 ------ .../javascripts/components/top/index.ts | 183 ---- .../integrations/clipboard/index.ts | 58 -- .../assets/javascripts/integrations/index.ts | 26 - .../integrations/instant/.eslintrc | 6 - .../javascripts/integrations/instant/index.ts | 364 -------- .../integrations/search/_/.eslintrc | 6 - .../integrations/search/_/index.ts | 322 ------- .../integrations/search/document/index.ts | 105 --- .../integrations/search/highlighter/index.ts | 91 -- .../javascripts/integrations/search/index.ts | 28 - .../integrations/search/options/index.ts | 48 -- .../integrations/search/query/_/.eslintrc | 5 - .../integrations/search/query/_/index.ts | 92 -- .../integrations/search/query/index.ts | 24 - .../search/query/transform/.eslintrc | 5 - .../search/query/transform/index.ts | 71 -- .../integrations/search/worker/_/index.ts | 139 --- .../integrations/search/worker/index.ts | 24 - .../integrations/search/worker/main/.eslintrc | 5 - .../integrations/search/worker/main/index.ts | 172 ---- .../search/worker/message/index.ts | 137 --- .../javascripts/integrations/version/index.ts | 41 - .../patches/indeterminate/index.ts | 84 -- docs/src/assets/javascripts/patches/index.ts | 25 - .../javascripts/patches/scrollfix/index.ts | 99 --- .../javascripts/patches/scrolllock/index.ts | 86 -- .../javascripts/templates/clipboard/index.tsx | 45 - .../src/assets/javascripts/templates/index.ts | 27 - .../javascripts/templates/search/index.tsx | 156 ---- .../javascripts/templates/source/index.tsx | 47 -- .../javascripts/templates/table/index.tsx | 44 - .../javascripts/templates/version/index.tsx | 99 --- .../assets/javascripts/utilities/h/.eslintrc | 7 - .../assets/javascripts/utilities/h/index.ts | 126 --- .../src/assets/javascripts/utilities/index.ts | 24 - .../javascripts/utilities/string/index.ts | 90 -- docs/src/assets/javascripts/workers/search.ts | 23 - docs/src/assets/stylesheets/_config.scss | 42 - docs/src/assets/stylesheets/main.scss | 75 -- docs/src/assets/stylesheets/main/_colors.scss | 107 --- docs/src/assets/stylesheets/main/_icons.scss | 37 - .../assets/stylesheets/main/_modifiers.scss | 63 -- docs/src/assets/stylesheets/main/_reset.scss | 113 --- docs/src/assets/stylesheets/main/_shame.scss | 25 - .../src/assets/stylesheets/main/_typeset.scss | 640 -------------- .../main/extensions/markdown/_admonition.scss | 197 ----- .../main/extensions/markdown/_footnotes.scss | 153 ---- .../main/extensions/markdown/_toc.scss | 172 ---- .../main/extensions/pymdownx/_arithmatex.scss | 48 -- .../main/extensions/pymdownx/_critic.scss | 81 -- .../main/extensions/pymdownx/_details.scss | 128 --- .../main/extensions/pymdownx/_emoji.scss | 45 - .../main/extensions/pymdownx/_highlight.scss | 275 ------ .../main/extensions/pymdownx/_keys.scss | 120 --- .../main/extensions/pymdownx/_tabbed.scss | 123 --- .../main/extensions/pymdownx/_tasklist.scss | 91 -- .../stylesheets/main/layout/_announce.scss | 44 - .../assets/stylesheets/main/layout/_base.scss | 184 ---- .../stylesheets/main/layout/_clipboard.scss | 103 --- .../stylesheets/main/layout/_content.scss | 119 --- .../stylesheets/main/layout/_dialog.scss | 73 -- .../stylesheets/main/layout/_footer.scss | 211 ----- .../assets/stylesheets/main/layout/_form.scss | 84 -- .../stylesheets/main/layout/_header.scss | 272 ------ .../assets/stylesheets/main/layout/_nav.scss | 687 --------------- .../stylesheets/main/layout/_search.scss | 790 ------------------ .../stylesheets/main/layout/_select.scss | 126 --- .../stylesheets/main/layout/_sidebar.scss | 191 ----- .../stylesheets/main/layout/_source.scss | 203 ----- .../assets/stylesheets/main/layout/_tabs.scss | 113 --- .../assets/stylesheets/main/layout/_top.scss | 79 -- .../stylesheets/main/layout/_version.scss | 173 ---- docs/src/assets/stylesheets/palette.scss | 40 - .../assets/stylesheets/palette/_accent.scss | 60 -- .../assets/stylesheets/palette/_primary.scss | 170 ---- .../assets/stylesheets/palette/_scheme.scss | 99 --- .../assets/stylesheets/utilities/_break.scss | 215 ----- .../stylesheets/utilities/_convert.scss | 79 -- docs/src/base.html | 411 --------- docs/src/main.html | 23 - docs/src/mkdocs_theme.yml | 68 -- .../overrides/assets/javascripts/bundle.ts | 56 -- .../assets/javascripts/components/_/index.ts | 104 --- .../components/iconsearch/_/index.ts | 94 --- .../components/iconsearch/index.ts | 25 - .../components/iconsearch/query/index.ts | 96 --- .../components/iconsearch/result/index.ts | 199 ----- .../assets/javascripts/components/index.ts | 25 - .../components/sponsorship/index.ts | 150 ---- .../integrations/analytics/index.ts | 42 - .../assets/javascripts/integrations/index.ts | 23 - .../templates/iconsearch/index.tsx | 90 -- .../assets/javascripts/templates/index.ts | 24 - .../templates/sponsorship/index.tsx | 67 -- .../overrides/assets/stylesheets/main.scss | 46 - .../assets/stylesheets/main/_shame.scss | 25 - .../assets/stylesheets/main/_typeset.scss | 148 ---- .../stylesheets/main/layout/_announce.scss | 46 - .../assets/stylesheets/main/layout/_hero.scss | 124 --- .../stylesheets/main/layout/_iconsearch.scss | 130 --- .../stylesheets/main/layout/_sponsorship.scss | 110 --- docs/src/overrides/home.html | 106 --- docs/src/overrides/main.html | 53 -- docs/src/partials/footer.html | 110 --- docs/src/partials/header.html | 161 ---- docs/src/partials/integrations/analytics.html | 36 - .../integrations/analytics/google.html | 93 --- docs/src/partials/integrations/disqus.html | 46 - docs/src/partials/javascripts/base.html | 39 - docs/src/partials/javascripts/palette.html | 29 - docs/src/partials/language.html | 28 - docs/src/partials/languages/af.html | 45 - docs/src/partials/languages/ar.html | 46 - docs/src/partials/languages/bg.html | 52 -- docs/src/partials/languages/bn.html | 50 -- docs/src/partials/languages/ca.html | 44 - docs/src/partials/languages/cs.html | 44 - docs/src/partials/languages/da.html | 45 - docs/src/partials/languages/de.html | 55 -- docs/src/partials/languages/en.html | 62 -- docs/src/partials/languages/eo.html | 50 -- docs/src/partials/languages/es.html | 57 -- docs/src/partials/languages/et.html | 44 - docs/src/partials/languages/fa.html | 46 - docs/src/partials/languages/fi.html | 45 - docs/src/partials/languages/fr.html | 57 -- docs/src/partials/languages/gl.html | 57 -- docs/src/partials/languages/gr.html | 45 - docs/src/partials/languages/he.html | 46 - docs/src/partials/languages/hi.html | 45 - docs/src/partials/languages/hr.html | 44 - docs/src/partials/languages/hu.html | 54 -- docs/src/partials/languages/id.html | 45 - docs/src/partials/languages/is.html | 51 -- docs/src/partials/languages/it.html | 45 - docs/src/partials/languages/ja.html | 56 -- docs/src/partials/languages/ka.html | 50 -- docs/src/partials/languages/kr.html | 55 -- docs/src/partials/languages/mn.html | 51 -- docs/src/partials/languages/my.html | 50 -- docs/src/partials/languages/nl.html | 45 - docs/src/partials/languages/nn.html | 45 - docs/src/partials/languages/no.html | 45 - docs/src/partials/languages/pl.html | 54 -- docs/src/partials/languages/pt.html | 59 -- docs/src/partials/languages/ro.html | 45 - docs/src/partials/languages/ru.html | 45 - docs/src/partials/languages/sh.html | 58 -- docs/src/partials/languages/si.html | 52 -- docs/src/partials/languages/sk.html | 44 - docs/src/partials/languages/sl.html | 44 - docs/src/partials/languages/sr.html | 57 -- docs/src/partials/languages/sv.html | 54 -- docs/src/partials/languages/th.html | 45 - docs/src/partials/languages/tr.html | 45 - docs/src/partials/languages/uk.html | 45 - docs/src/partials/languages/vi.html | 45 - docs/src/partials/languages/zh-Hant.html | 48 -- docs/src/partials/languages/zh-TW.html | 48 -- docs/src/partials/languages/zh.html | 48 -- docs/src/partials/logo.html | 29 - docs/src/partials/nav-item.html | 169 ---- docs/src/partials/nav.html | 68 -- docs/src/partials/palette.html | 66 -- docs/src/partials/search.html | 105 --- docs/src/partials/social.html | 42 - docs/src/partials/source-date.html | 24 - docs/src/partials/source-file.html | 44 - docs/src/partials/source.html | 39 - docs/src/partials/tabs-item.html | 56 -- docs/src/partials/tabs.html | 39 - docs/src/partials/toc-item.html | 39 - docs/src/partials/toc.html | 52 -- electron-builder.yml | 2 + 256 files changed, 224 insertions(+), 21851 deletions(-) create mode 100644 docs/docs/assets/integrate/ClickHouse.svg create mode 100644 docs/docs/assets/integrate/Presto.svg create mode 100644 docs/docs/assets/integrate/Trino.svg delete mode 100644 docs/src/.icons/logo.afdesign delete mode 100644 docs/src/.icons/logo.svg delete mode 100644 docs/src/404.html delete mode 100644 docs/src/__init__.py delete mode 100644 docs/src/assets/images/favicon.png delete mode 100644 docs/src/assets/javascripts/_/index.ts delete mode 100644 docs/src/assets/javascripts/actions/_/index.ts delete mode 100644 docs/src/assets/javascripts/actions/anchor/index.ts delete mode 100644 docs/src/assets/javascripts/actions/dialog/index.ts delete mode 100644 docs/src/assets/javascripts/actions/header/_/index.ts delete mode 100644 docs/src/assets/javascripts/actions/header/index.ts delete mode 100644 docs/src/assets/javascripts/actions/header/title/index.ts delete mode 100644 docs/src/assets/javascripts/actions/index.ts delete mode 100644 docs/src/assets/javascripts/actions/search/index.ts delete mode 100644 docs/src/assets/javascripts/actions/search/query/index.ts delete mode 100644 docs/src/assets/javascripts/actions/search/result/index.ts delete mode 100644 docs/src/assets/javascripts/actions/sidebar/index.ts delete mode 100644 docs/src/assets/javascripts/actions/source/index.ts delete mode 100644 docs/src/assets/javascripts/actions/tabs/index.ts delete mode 100644 docs/src/assets/javascripts/actions/top/index.ts delete mode 100644 docs/src/assets/javascripts/browser/document/index.ts delete mode 100644 docs/src/assets/javascripts/browser/element/_/.eslintrc delete mode 100644 docs/src/assets/javascripts/browser/element/_/index.ts delete mode 100644 docs/src/assets/javascripts/browser/element/focus/index.ts delete mode 100644 docs/src/assets/javascripts/browser/element/index.ts delete mode 100644 docs/src/assets/javascripts/browser/element/offset/index.ts delete mode 100644 docs/src/assets/javascripts/browser/element/selection/index.ts delete mode 100644 docs/src/assets/javascripts/browser/element/size/index.ts delete mode 100644 docs/src/assets/javascripts/browser/index.ts delete mode 100644 docs/src/assets/javascripts/browser/keyboard/index.ts delete mode 100644 docs/src/assets/javascripts/browser/location/_/index.ts delete mode 100644 docs/src/assets/javascripts/browser/location/hash/index.ts delete mode 100644 docs/src/assets/javascripts/browser/location/index.ts delete mode 100644 docs/src/assets/javascripts/browser/media/index.ts delete mode 100644 docs/src/assets/javascripts/browser/request/index.ts delete mode 100644 docs/src/assets/javascripts/browser/toggle/index.ts delete mode 100644 docs/src/assets/javascripts/browser/viewport/_/index.ts delete mode 100644 docs/src/assets/javascripts/browser/viewport/index.ts delete mode 100644 docs/src/assets/javascripts/browser/viewport/offset/index.ts delete mode 100644 docs/src/assets/javascripts/browser/viewport/size/index.ts delete mode 100644 docs/src/assets/javascripts/browser/worker/index.ts delete mode 100644 docs/src/assets/javascripts/bundle.ts delete mode 100644 docs/src/assets/javascripts/components/_/index.ts delete mode 100644 docs/src/assets/javascripts/components/content/_/index.ts delete mode 100644 docs/src/assets/javascripts/components/content/code/index.ts delete mode 100644 docs/src/assets/javascripts/components/content/details/index.ts delete mode 100644 docs/src/assets/javascripts/components/content/index.ts delete mode 100644 docs/src/assets/javascripts/components/content/table/index.ts delete mode 100644 docs/src/assets/javascripts/components/dialog/index.ts delete mode 100644 docs/src/assets/javascripts/components/header/_/index.ts delete mode 100644 docs/src/assets/javascripts/components/header/index.ts delete mode 100644 docs/src/assets/javascripts/components/header/title/index.ts delete mode 100644 docs/src/assets/javascripts/components/index.ts delete mode 100644 docs/src/assets/javascripts/components/main/index.ts delete mode 100644 docs/src/assets/javascripts/components/palette/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/_/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/highlight/.eslintrc delete mode 100644 docs/src/assets/javascripts/components/search/highlight/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/query/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/result/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/share/index.ts delete mode 100644 docs/src/assets/javascripts/components/search/suggest/index.ts delete mode 100644 docs/src/assets/javascripts/components/sidebar/index.ts delete mode 100644 docs/src/assets/javascripts/components/source/_/index.ts delete mode 100644 docs/src/assets/javascripts/components/source/facts/_/index.ts delete mode 100644 docs/src/assets/javascripts/components/source/facts/github/index.ts delete mode 100644 docs/src/assets/javascripts/components/source/facts/gitlab/index.ts delete mode 100644 docs/src/assets/javascripts/components/source/facts/index.ts delete mode 100644 docs/src/assets/javascripts/components/source/index.ts delete mode 100644 docs/src/assets/javascripts/components/tabs/index.ts delete mode 100644 docs/src/assets/javascripts/components/toc/index.ts delete mode 100644 docs/src/assets/javascripts/components/top/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/clipboard/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/instant/.eslintrc delete mode 100644 docs/src/assets/javascripts/integrations/instant/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/_/.eslintrc delete mode 100644 docs/src/assets/javascripts/integrations/search/_/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/document/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/highlighter/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/options/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/query/_/.eslintrc delete mode 100644 docs/src/assets/javascripts/integrations/search/query/_/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/query/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc delete mode 100644 docs/src/assets/javascripts/integrations/search/query/transform/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/worker/_/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/worker/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc delete mode 100644 docs/src/assets/javascripts/integrations/search/worker/main/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/search/worker/message/index.ts delete mode 100644 docs/src/assets/javascripts/integrations/version/index.ts delete mode 100644 docs/src/assets/javascripts/patches/indeterminate/index.ts delete mode 100644 docs/src/assets/javascripts/patches/index.ts delete mode 100644 docs/src/assets/javascripts/patches/scrollfix/index.ts delete mode 100644 docs/src/assets/javascripts/patches/scrolllock/index.ts delete mode 100644 docs/src/assets/javascripts/templates/clipboard/index.tsx delete mode 100644 docs/src/assets/javascripts/templates/index.ts delete mode 100644 docs/src/assets/javascripts/templates/search/index.tsx delete mode 100644 docs/src/assets/javascripts/templates/source/index.tsx delete mode 100644 docs/src/assets/javascripts/templates/table/index.tsx delete mode 100644 docs/src/assets/javascripts/templates/version/index.tsx delete mode 100644 docs/src/assets/javascripts/utilities/h/.eslintrc delete mode 100644 docs/src/assets/javascripts/utilities/h/index.ts delete mode 100644 docs/src/assets/javascripts/utilities/index.ts delete mode 100644 docs/src/assets/javascripts/utilities/string/index.ts delete mode 100644 docs/src/assets/javascripts/workers/search.ts delete mode 100644 docs/src/assets/stylesheets/_config.scss delete mode 100644 docs/src/assets/stylesheets/main.scss delete mode 100644 docs/src/assets/stylesheets/main/_colors.scss delete mode 100644 docs/src/assets/stylesheets/main/_icons.scss delete mode 100644 docs/src/assets/stylesheets/main/_modifiers.scss delete mode 100644 docs/src/assets/stylesheets/main/_reset.scss delete mode 100644 docs/src/assets/stylesheets/main/_shame.scss delete mode 100644 docs/src/assets/stylesheets/main/_typeset.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss delete mode 100644 docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_announce.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_base.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_clipboard.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_content.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_dialog.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_footer.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_form.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_header.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_nav.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_search.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_select.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_sidebar.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_source.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_tabs.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_top.scss delete mode 100644 docs/src/assets/stylesheets/main/layout/_version.scss delete mode 100644 docs/src/assets/stylesheets/palette.scss delete mode 100644 docs/src/assets/stylesheets/palette/_accent.scss delete mode 100644 docs/src/assets/stylesheets/palette/_primary.scss delete mode 100644 docs/src/assets/stylesheets/palette/_scheme.scss delete mode 100644 docs/src/assets/stylesheets/utilities/_break.scss delete mode 100644 docs/src/assets/stylesheets/utilities/_convert.scss delete mode 100644 docs/src/base.html delete mode 100644 docs/src/main.html delete mode 100644 docs/src/mkdocs_theme.yml delete mode 100644 docs/src/overrides/assets/javascripts/bundle.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/_/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/iconsearch/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/components/sponsorship/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/integrations/analytics/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/integrations/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx delete mode 100644 docs/src/overrides/assets/javascripts/templates/index.ts delete mode 100644 docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx delete mode 100644 docs/src/overrides/assets/stylesheets/main.scss delete mode 100644 docs/src/overrides/assets/stylesheets/main/_shame.scss delete mode 100644 docs/src/overrides/assets/stylesheets/main/_typeset.scss delete mode 100644 docs/src/overrides/assets/stylesheets/main/layout/_announce.scss delete mode 100644 docs/src/overrides/assets/stylesheets/main/layout/_hero.scss delete mode 100644 docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss delete mode 100644 docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss delete mode 100644 docs/src/overrides/home.html delete mode 100644 docs/src/overrides/main.html delete mode 100644 docs/src/partials/footer.html delete mode 100644 docs/src/partials/header.html delete mode 100644 docs/src/partials/integrations/analytics.html delete mode 100644 docs/src/partials/integrations/analytics/google.html delete mode 100644 docs/src/partials/integrations/disqus.html delete mode 100644 docs/src/partials/javascripts/base.html delete mode 100644 docs/src/partials/javascripts/palette.html delete mode 100644 docs/src/partials/language.html delete mode 100644 docs/src/partials/languages/af.html delete mode 100644 docs/src/partials/languages/ar.html delete mode 100644 docs/src/partials/languages/bg.html delete mode 100644 docs/src/partials/languages/bn.html delete mode 100644 docs/src/partials/languages/ca.html delete mode 100644 docs/src/partials/languages/cs.html delete mode 100644 docs/src/partials/languages/da.html delete mode 100644 docs/src/partials/languages/de.html delete mode 100644 docs/src/partials/languages/en.html delete mode 100644 docs/src/partials/languages/eo.html delete mode 100644 docs/src/partials/languages/es.html delete mode 100644 docs/src/partials/languages/et.html delete mode 100644 docs/src/partials/languages/fa.html delete mode 100644 docs/src/partials/languages/fi.html delete mode 100644 docs/src/partials/languages/fr.html delete mode 100644 docs/src/partials/languages/gl.html delete mode 100644 docs/src/partials/languages/gr.html delete mode 100644 docs/src/partials/languages/he.html delete mode 100644 docs/src/partials/languages/hi.html delete mode 100644 docs/src/partials/languages/hr.html delete mode 100644 docs/src/partials/languages/hu.html delete mode 100644 docs/src/partials/languages/id.html delete mode 100644 docs/src/partials/languages/is.html delete mode 100644 docs/src/partials/languages/it.html delete mode 100644 docs/src/partials/languages/ja.html delete mode 100644 docs/src/partials/languages/ka.html delete mode 100644 docs/src/partials/languages/kr.html delete mode 100644 docs/src/partials/languages/mn.html delete mode 100644 docs/src/partials/languages/my.html delete mode 100644 docs/src/partials/languages/nl.html delete mode 100644 docs/src/partials/languages/nn.html delete mode 100644 docs/src/partials/languages/no.html delete mode 100755 docs/src/partials/languages/pl.html delete mode 100644 docs/src/partials/languages/pt.html delete mode 100644 docs/src/partials/languages/ro.html delete mode 100644 docs/src/partials/languages/ru.html delete mode 100644 docs/src/partials/languages/sh.html delete mode 100644 docs/src/partials/languages/si.html delete mode 100644 docs/src/partials/languages/sk.html delete mode 100644 docs/src/partials/languages/sl.html delete mode 100644 docs/src/partials/languages/sr.html delete mode 100644 docs/src/partials/languages/sv.html delete mode 100644 docs/src/partials/languages/th.html delete mode 100644 docs/src/partials/languages/tr.html delete mode 100644 docs/src/partials/languages/uk.html delete mode 100644 docs/src/partials/languages/vi.html delete mode 100644 docs/src/partials/languages/zh-Hant.html delete mode 100644 docs/src/partials/languages/zh-TW.html delete mode 100644 docs/src/partials/languages/zh.html delete mode 100644 docs/src/partials/logo.html delete mode 100644 docs/src/partials/nav-item.html delete mode 100644 docs/src/partials/nav.html delete mode 100644 docs/src/partials/palette.html delete mode 100644 docs/src/partials/search.html delete mode 100644 docs/src/partials/social.html delete mode 100644 docs/src/partials/source-date.html delete mode 100644 docs/src/partials/source-file.html delete mode 100644 docs/src/partials/source.html delete mode 100644 docs/src/partials/tabs-item.html delete mode 100644 docs/src/partials/tabs.html delete mode 100644 docs/src/partials/toc-item.html delete mode 100644 docs/src/partials/toc.html diff --git a/docs/docs/assets/integrate/ClickHouse.svg b/docs/docs/assets/integrate/ClickHouse.svg new file mode 100644 index 00000000..f2144b5d --- /dev/null +++ b/docs/docs/assets/integrate/ClickHouse.svg @@ -0,0 +1 @@ +<svg height="2222" viewBox="0 0 9 8" width="2500" xmlns="http://www.w3.org/2000/svg"><path d="m0 7h1v1h-1z" fill="#f00"/><path d="m0 0h1v7h-1zm2 0h1v8h-1zm2 0h1v8h-1zm2 0h1v8h-1zm2 3.25h1v1.5h-1z" fill="#fc0"/></svg> \ No newline at end of file diff --git a/docs/docs/assets/integrate/Presto.svg b/docs/docs/assets/integrate/Presto.svg new file mode 100644 index 00000000..bf0e662a --- /dev/null +++ b/docs/docs/assets/integrate/Presto.svg @@ -0,0 +1 @@ +<svg width="2500" height="2500" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><rect width="256" height="256" rx="18"/><path d="M230.118 128.531c0 7.047-5.713 12.76-12.761 12.76-7.047 0-12.76-5.713-12.76-12.76 0-7.048 5.713-12.761 12.76-12.761 7.048 0 12.761 5.713 12.761 12.761" fill="#669CFE"/><path d="M203.806 154.531c0 7.047-5.713 12.76-12.761 12.76-7.048 0-12.761-5.713-12.761-12.76 0-7.048 5.713-12.761 12.761-12.761 7.048 0 12.761 5.713 12.761 12.761" fill="#3FE7FE"/><path d="M177.451 181.072c0 7.048-5.713 12.761-12.76 12.761-7.048 0-12.761-5.713-12.761-12.761 0-7.047 5.713-12.76 12.761-12.76 7.047 0 12.76 5.713 12.76 12.76" fill="#FFF"/><path d="M202.993 102.336c0 6.597-5.348 11.944-11.944 11.944-6.597 0-11.945-5.347-11.945-11.944s5.348-11.945 11.945-11.945c6.596 0 11.944 5.348 11.944 11.945" fill="#669CFE"/><path d="M176.738 128.298c0 6.597-5.348 11.945-11.944 11.945-6.597 0-11.945-5.348-11.945-11.945s5.348-11.945 11.945-11.945c6.596 0 11.944 5.348 11.944 11.945" fill="#3FE7FE"/><path d="M150.569 154.642c0 6.597-5.347 11.945-11.944 11.945s-11.945-5.348-11.945-11.945 5.348-11.944 11.945-11.944 11.944 5.347 11.944 11.944" fill="#FFF"/><path d="M175.743 76.235c0 5.991-4.857 10.849-10.849 10.849s-10.849-4.858-10.849-10.849c0-5.992 4.857-10.849 10.849-10.849s10.849 4.857 10.849 10.849" fill="#669CFE"/><path d="M149.522 102.191c0 5.991-4.858 10.849-10.85 10.849-5.991 0-10.849-4.858-10.849-10.849 0-5.992 4.858-10.85 10.849-10.85 5.992 0 10.85 4.858 10.85 10.85" fill="#3FE7FE"/><path d="M123.253 128.618c0 5.992-4.857 10.849-10.849 10.849s-10.849-4.857-10.849-10.849c0-5.991 4.857-10.849 10.849-10.849s10.849 4.858 10.849 10.849" fill="#FFF"/><path d="M148.618 50.008c0 5.386-4.366 9.752-9.752 9.752-5.386 0-9.752-4.366-9.752-9.752 0-5.387 4.366-9.753 9.752-9.753 5.386 0 9.752 4.366 9.752 9.753" fill="#669CFE"/><path d="M122.297 76.089c0 5.386-4.366 9.753-9.752 9.753-5.386 0-9.752-4.367-9.752-9.753s4.366-9.752 9.752-9.752c5.386 0 9.752 4.366 9.752 9.752" fill="#3FE7FE"/><path d="M96.06 102.471c0 5.386-4.367 9.752-9.753 9.752s-9.752-4.366-9.752-9.752c0-5.386 4.366-9.753 9.752-9.753 5.386 0 9.753 4.367 9.753 9.753" fill="#FFF"/><path d="M95.06 154.721a8.67 8.67 0 1 1-17.338-.002 8.67 8.67 0 0 1 17.338.002M121.185 180.846a8.67 8.67 0 1 1-17.338-.002 8.67 8.67 0 0 1 17.338.002M147.268 206.929a8.669 8.669 0 0 1-8.669 8.669 8.669 8.669 0 0 1-8.669-8.669 8.669 8.669 0 0 1 8.669-8.669 8.669 8.669 0 0 1 8.669 8.669M95.185 206.929a8.67 8.67 0 1 1-17.339 0 8.67 8.67 0 0 1 17.339 0M42.601 206.929a8.67 8.67 0 1 1-17.337 0 8.67 8.67 0 0 1 17.337 0M68.726 180.804a8.67 8.67 0 1 1-17.337 0 8.67 8.67 0 0 1 17.337 0" fill="#6A9EFE"/><path d="M95.172 50.032a9.06 9.06 0 0 1-18.118 0 9.06 9.06 0 1 1 18.118 0" fill="#3FE7FE"/><path d="M68.799 76.538a9.06 9.06 0 1 1-18.12 0 9.06 9.06 0 0 1 18.12 0M41.174 49.663a7.31 7.31 0 1 1-14.62 0 7.31 7.31 0 0 1 14.62 0" fill="#FFF"/></svg> \ No newline at end of file diff --git a/docs/docs/assets/integrate/Trino.svg b/docs/docs/assets/integrate/Trino.svg new file mode 100644 index 00000000..1c83e1ef --- /dev/null +++ b/docs/docs/assets/integrate/Trino.svg @@ -0,0 +1 @@ +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 42.1 62.45"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#dd00a1;}.cls-3{fill:#f9d8d2;}.cls-4{fill:#10110e;}.cls-5{fill:#e5e5e5;}.cls-6{fill:#8accce;opacity:0.2;isolation:isolate;}.cls-7{fill:#515151;}</style></defs><path class="cls-1" d="M14.24,55.36c.92-.61-1.49-.38-1.69-.79a15,15,0,0,1-2.82-.51C8,53.62,3.9,50.85,3.47,48.25s0-7.65,1.83-10.61A17,17,0,0,1,9.73,33S6.16,24.51,5.85,18.1,6,.21,10.24,0s3.49,10.48,2.82,17.43a89.47,89.47,0,0,0-.21,13.89,19.45,19.45,0,0,1,5.51-.92,21.2,21.2,0,0,1,4.9.46S24.58,21,29,14.86,38,2.4,41,4.19s-.81,8.19-3.46,11.52-7.25,8.33-8.78,11a47.26,47.26,0,0,0-2.65,5.51,15,15,0,0,1,6.4,6.32c2.07,4.28,2.27,9.59,1.15,11.83a8.1,8.1,0,0,1-5.61,4c-1.32.1-6.91,1.48-6.91,1.48Z" transform="translate(0 0)"/><path class="cls-2" d="M24,30.94s3.33-8.7,6.32-13.6,7-8.59,8.26-7.84S36,14.85,32.66,19.32a112.3,112.3,0,0,0-7.44,12.37Z" transform="translate(0 0)"/><path class="cls-2" d="M10.64,32.44l.95-.75s-.13-8.7,0-14S12,5.78,10.23,5.85,7.23,11,7.92,18.23A86.92,86.92,0,0,0,10.64,32.44Z" transform="translate(0 0)"/><circle class="cls-3" cx="7.65" cy="49.17" r="1.94"/><circle class="cls-3" cx="30.57" cy="49.17" r="1.94"/><path class="cls-4" d="M22.33,49a.19.19,0,0,0-.25,0h0s-.57,1-1.41,1.06a2.11,2.11,0,0,1-1.5-.7V48c.54-.29,1.41-1.19,1.41-1.5a1.4,1.4,0,0,0-1.5-1.09c-1,0-1.7.65-1.7,1.19s1.1,1.23,1.41,1.44v1.45a1.77,1.77,0,0,1-1.3.7c-.8,0-1.4-1.08-1.4-1.09a.19.19,0,0,0-.25-.08h0a.18.18,0,0,0-.08.23h0c0,.06.71,1.29,1.73,1.29a2.07,2.07,0,0,0,1.5-.72,2.46,2.46,0,0,0,1.59.73h.14a2.47,2.47,0,0,0,1.71-1.25.18.18,0,0,0,0-.25A.24.24,0,0,0,22.33,49Z" transform="translate(0 0)"/><path class="cls-5" d="M9.73,33S7,26,6.42,22.29s-1-9.78-.3-13.85A46.3,46.3,0,0,1,7.31,2.85S6,12.34,6.49,16.49,9.73,33,9.73,33Z" transform="translate(0 0)"/><path class="cls-5" d="M23.26,30.85s2-10.59,4.91-14.76S34.73,6.9,36.52,5.62l1.82-1.28S31,12,28.17,18.34,23.26,30.85,23.26,30.85Z" transform="translate(0 0)"/><path class="cls-4" d="M11.6,42.85a1.52,1.52,0,1,0,1.52,1.52h0a1.52,1.52,0,0,0-1.5-1.52Zm.4,1.41a.42.42,0,1,1,.42-.42h0a.42.42,0,0,1-.41.43h0Z" transform="translate(0 0)"/><path class="cls-4" d="M26.55,42.85a1.52,1.52,0,1,0,1.51,1.53h0a1.52,1.52,0,0,0-1.51-1.53ZM27,44.26a.42.42,0,0,1-.43-.41h0a.43.43,0,0,1,.41-.43.42.42,0,0,1,.43.41h0a.41.41,0,0,1-.4.42h0Z" transform="translate(0 0)"/><ellipse class="cls-6" cx="19.36" cy="44.95" rx="14.1" ry="10.16"/><path class="cls-1" d="M36.43,39.3V32.58a2.46,2.46,0,0,0,1.91-2.29,2.65,2.65,0,0,0-5.27,0A2.48,2.48,0,0,0,35,32.58v6.55h-.2c-2-6.94-7.91-11.28-15.63-11.28S5.51,32.15,3.55,39.13H2.88A2.76,2.76,0,0,0,0,41.71v5.14a2.75,2.75,0,0,0,2.88,2.59h.91a13,13,0,0,0,3.59,5.11L6.09,55.72A.78.78,0,0,0,6,56.82l0,0H6c2.93,3.53,7.72,5.6,13.13,5.6s10.21-2,13.14-5.6a.79.79,0,0,0-.09-1.11h0l-1.3-1.19a13,13,0,0,0,3.59-5.08h1a2.74,2.74,0,0,0,2.87-2.6V41.71A2.58,2.58,0,0,0,36.43,39.3Zm-17.26-4c7.14,0,12.94,4.7,12.94,10.47,0,6.25-6.51,9-12.94,9S6.23,52,6.23,45.72C6.23,40,12,35.25,19.17,35.25Z" transform="translate(0 0)"/><path class="cls-7" d="M36.91,45.16H35v-1a18.61,18.61,0,0,0-.39-3.79h.82a1.35,1.35,0,0,1,1.44,1.25h0Z" transform="translate(0 0)"/><path class="cls-7" d="M35.47,48.18h-1A16.13,16.13,0,0,0,34.89,46h2v.85a1.34,1.34,0,0,1-1.36,1.32h-.06Z" transform="translate(0 0)"/><path class="cls-7" d="M19.17,61.1c-4.79,0-9.06-1.72-11.74-4.78l1.3-1.21a17.87,17.87,0,0,0,10.4,3,17.73,17.73,0,0,0,10.4-3l1.35,1.21C28.23,59.38,24,61.1,19.17,61.1Z" transform="translate(0 0)"/><path class="cls-7" d="M2.88,40.42h.85a19.33,19.33,0,0,0-.38,3.79,8.34,8.34,0,0,0,0,1H1.49v-3.5a1.27,1.27,0,0,1,1.24-1.29Z" transform="translate(0 0)"/><path d="M19.17,34.39a17.66,17.66,0,0,0-4.79.69V29.85a17.23,17.23,0,0,1,4.79-.64,17.3,17.3,0,0,1,4.8.64v5.26A15.91,15.91,0,0,0,19.17,34.39Z" transform="translate(0 0)"/><path class="cls-7" d="M1.44,46h2a17.56,17.56,0,0,0,.43,2.16h-1a1.35,1.35,0,0,1-1.44-1.25h0V46Z" transform="translate(0 0)"/><ellipse class="cls-7" cx="35.71" cy="30.29" rx="1.2" ry="1.08"/></svg> \ No newline at end of file diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index e9830f59..9c2d1168 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -43,6 +43,8 @@ DBM Version for `1.17.0` is development! --- +- Refactoring software homepage <br /> + #### Bug --- diff --git a/docs/docs/reference/get_started/install.md b/docs/docs/reference/get_started/install.md index c738b173..fb59b61f 100644 --- a/docs/docs/reference/get_started/install.md +++ b/docs/docs/reference/get_started/install.md @@ -2,7 +2,7 @@ template: overrides/main.html --- -DBM is a cross-platform ClickHouse GUI desktop tool. +DBM is a cross-platform Database GUI desktop tool. #### System requirements diff --git a/docs/docs/stylesheets/extra.css b/docs/docs/stylesheets/extra.css index 52d52b2a..5366ea78 100644 --- a/docs/docs/stylesheets/extra.css +++ b/docs/docs/stylesheets/extra.css @@ -5,3 +5,23 @@ .blue { color: #1890ff; } + +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:transparent;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root,[data-md-color-scheme=default]{--md-default-fg-color:rgba(0,0,0,.87);--md-default-fg-color--light:rgba(0,0,0,.54);--md-default-fg-color--lighter:rgba(0,0,0,.32);--md-default-fg-color--lightest:rgba(0,0,0,.07);--md-default-bg-color:#fff;--md-default-bg-color--light:hsla(0,0%,100%,.7);--md-default-bg-color--lighter:hsla(0,0%,100%,.3);--md-default-bg-color--lightest:hsla(0,0%,100%,.12);--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.05),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.35)}:root>*,[data-md-color-scheme=default]>*{--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:rgba(255,255,0,.5);--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:rgba(255,255,0,.5);--md-typeset-del-color:rgba(245,80,61,.15);--md-typeset-ins-color:rgba(11,213,112,.15);--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:rgba(0,0,0,.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:hsla(0,0%,100%,.7);--md-footer-fg-color--lighter:hsla(0,0%,100%,.3);--md-footer-bg-color:rgba(0,0,0,.87);--md-footer-bg-color--dark:rgba(0,0,0,.32)}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root,[data-md-color-scheme=default]{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m18 21-4-4h3V7h-3l4-4 4 4h-3v10h3M2 19v-2h10v2M2 13v-2h7v2M2 7V5h4v2H2Z"/></svg>');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 17h3l-4 4-4-4h3V3h2M2 17h10v2H2M6 5v2H2V5m0 6h7v2H2v-2Z"/></svg>');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7h3l-4-4-4 4h3v14h2M2 17h10v2H2M6 5v2H2V5m0 6h7v2H2v-2Z"/></svg>')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg{height:auto;max-width:100%}.md-typeset img[align=left],.md-typeset svg[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right],.md-typeset svg[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child,.md-typeset svg[align]:only-child{margin-top:0}.md-typeset img[src$="#gh-dark-mode-only"],.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) th a{color:inherit}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:rgba(0,0,0,.035);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}.md-banner__button{color:inherit;cursor:pointer;float:right;transition:opacity .25s}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.9375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root,[data-md-color-scheme=default]{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"/></svg>')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}@-webkit-keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes overlay{0%{opacity:0}to{opacity:1}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{-webkit-animation:overlay .25s both;animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:rgba(0,0,0,.54);height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{-webkit-animation:consent .5s cubic-bezier(.1,.7,.1,1) both;animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.9375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{float:right;margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}[dir=rtl] .md-content__button{float:left}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{align-content:baseline;display:flex;flex-wrap:wrap;justify-content:center;min-height:2.4rem;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__name{color:var(--md-default-fg-color--light);font-size:.68rem;opacity:0;position:absolute;top:1.2rem;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;width:100%}:disabled .md-feedback__name{display:none}.md-feedback__icon:hover+.md-feedback__name{opacity:1;transform:translateX(0)}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{display:flex;justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,:hover){color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem transparent,0 .2rem .4rem transparent;color:var(--md-primary-bg-color);left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header--shadow{box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header--hidden{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}:root,[data-md-color-scheme=default]{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z"/></svg>');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 9h14V7H3v2m0 4h14v-2H3v2m0 4h14v-2H3v2m16 0h2v-2h-2v2m0-10v2h2V7h-2m0 6h2v-2h-2v2Z"/></svg>')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{flex-grow:1;position:relative}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}[dir=ltr] .md-nav__link svg+*{margin-left:.4rem}[dir=rtl] .md-nav__link svg+*{margin-right:.4rem}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest);padding:0}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.9375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);font-weight:700;margin-top:0;padding:0 .6rem;position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}:root,[data-md-color-scheme=default]{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h7c-.41-.25-.8-.56-1.14-.9-.33-.33-.61-.7-.86-1.1H6V4h7v5h5v1.18c.71.16 1.39.43 2 .82V8l-6-6m6.31 16.9c1.33-2.11.69-4.9-1.4-6.22-2.11-1.33-4.91-.68-6.22 1.4-1.34 2.11-.69 4.89 1.4 6.22 1.46.93 3.32.93 4.79.02L22 23.39 23.39 22l-3.08-3.1m-3.81.1a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5Z"/></svg>')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:rgba(0,0,0,.54);cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){.md-search__inner{float:right;padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}[dir=rtl] .md-search__inner{float:left}}@media screen and (min-width:60em) and (max-width:76.1875em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem transparent;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:rgba(0,0,0,.26);border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:hsla(0,0%,100%,.12)}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem rgba(0,0,0,.07);color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:transparent;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::-moz-placeholder{-moz-transition:color .25s;transition:color .25s}.md-search__input::-ms-input-placeholder{-ms-transition:color .25s;transition:color .25s}.md-search__input::placeholder{transition:color .25s}.md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.9375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::-moz-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.9375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:-webkit-sticky;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:-webkit-any(:focus,:hover)>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more>summary:-moz-any(:focus,:hover)>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more>summary:is(:focus,:hover)>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.9375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid transparent;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid transparent;border-right:.2rem solid transparent;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;-ms-scroll-snap-type:none;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media screen and (max-width:76.1875em){.md-overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@-webkit-keyframes facts{0%{height:0}to{height:.65rem}}@keyframes facts{0%{height:0}to{height:.65rem}}@-webkit-keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root,[data-md-color-scheme=default]{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm0 2.122a2.25 2.25 0 1 0-1.5 0v.878A2.25 2.25 0 0 0 5.75 8.5h1.5v2.128a2.251 2.251 0 1 0 1.5 0V8.5h1.5a2.25 2.25 0 0 0 2.25-2.25v-.878a2.25 2.25 0 1 0-1.5 0v.878a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 5 6.25v-.878zm3.75 7.378a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm3-8.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z"/></svg>');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 1 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 0 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8zM5 12.25v3.25a.25.25 0 0 0 .4.2l1.45-1.087a.25.25 0 0 1 .3 0L8.6 15.7a.25.25 0 0 0 .4-.2v-3.25a.25.25 0 0 0-.25-.25h-3.5a.25.25 0 0 0-.25.25z"/></svg>');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694v.001z"/></svg>');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2.5 7.775V2.75a.25.25 0 0 1 .25-.25h5.025a.25.25 0 0 1 .177.073l6.25 6.25a.25.25 0 0 1 0 .354l-5.025 5.025a.25.25 0 0 1-.354 0l-6.25-6.25a.25.25 0 0 1-.073-.177zm-1.5 0V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.75 1.75 0 0 1 1 7.775zM6 5a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/></svg>')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{font-size:.55rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0}.md-source__repository--active .md-source__facts{-webkit-animation:facts .25s ease-in;animation:facts .25s ease-in}.md-source__fact{display:inline-block}.md-source__repository--active .md-source__fact{-webkit-animation:fact .4s ease-out;animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}[dir=ltr] .md-source__fact:nth-child(1n+2):before{margin-left:.4rem}[dir=rtl] .md-source__fact:nth-child(1n+2):before{margin-right:.4rem}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);line-height:1.3;overflow:auto;width:100%}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs--hidden{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs.md-tabs--hidden .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root,[data-md-color-scheme=default]{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m5.41 21 .71-4h-4l.35-2h4l1.06-6h-4l.35-2h4l.71-4h2l-.71 4h6l.71-4h2l-.71 4h4l-.35 2h-4l-1.06 6h4l-.35 2h-4l-.71 4h-2l.71-4h-6l-.71 4h-2M9.53 9l-1.06 6h6l1.06-6h-6Z"/></svg>')}.md-tags{margin-bottom:.75em}[dir=ltr] .md-tag{margin-right:.5em}[dir=rtl] .md-tag{margin-left:.5em}.md-tag{background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-block;font-size:.64rem;font-weight:700;letter-spacing:normal;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-tag[href]:focus,.md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-tag{vertical-align:text-top}.md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;margin-right:.4em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.2em}.md-tag-icon:-webkit-any(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}.md-tag-icon:-moz-any(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}.md-tag-icon:is(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}:root,[data-md-color-scheme=default]{--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}:-webkit-any(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}:-moz-any(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}:is(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation__index{cursor:pointer;font-family:var(--md-code-font-family);font-size:.85em;margin:0 1ch;outline:none;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0}.md-annotation .md-annotation__index{color:#fff;transition:z-index .25s}.md-annotation .md-annotation__index:-webkit-any(:focus,:hover){color:#fff}.md-annotation .md-annotation__index:-moz-any(:focus,:hover){color:#fff}.md-annotation .md-annotation__index:is(:focus,:hover){color:#fff}.md-annotation__index:after{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.125em;margin:0 -.4ch;padding:0 .4ch;position:absolute;top:0;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media (prefers-reduced-motion){.md-annotation__index:after{-webkit-animation:none;animation:none}}.md-tooltip--active+.md-annotation__index:after{-webkit-animation:none;animation:none;transition:color .25s,background-color .25s}code .md-annotation__index{font-family:var(--md-code-font-family);font-size:inherit}:-webkit-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:-moz-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:is(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:-webkit-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}:-moz-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}:is(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}.md-tooltip--active+.md-annotation__index{-webkit-animation:none;animation:none;transition:none;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top--hidden{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top--hidden{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@-webkit-keyframes hoverfix{0%{pointer-events:none}}@keyframes hoverfix{0%{pointer-events:none}}:root,[data-md-color-scheme=default]{--md-version-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="m310.6 246.6-127.1 128c-7.1 6.3-15.3 9.4-23.5 9.4s-16.38-3.125-22.63-9.375l-127.1-128C.224 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75s3.12 25.75-6.08 34.85z"/></svg>')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{-webkit-animation:hoverfix .25s forwards;animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{-webkit-animation:none;animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root,[data-md-color-scheme=default]{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25Z"/></svg>');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2Z"/></svg>');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2Z"/></svg>');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.66 11.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33 7.26 13 4.85 13.95 3c-.95.23-1.78.75-2.49 1.32-2.59 2.08-3.61 5.75-2.39 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.23.1-.47.04-.66-.12a.58.58 0 0 1-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78 10 4.87 12.3 5 14.47c.06.5.12 1 .29 1.5.14.6.41 1.2.71 1.73 1.08 1.73 2.95 2.97 4.96 3.22 2.14.27 4.43-.12 6.07-1.6 1.83-1.66 2.47-4.32 1.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16 6.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82 1.19-.28 1.9-1.16 2.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63 1.06.77 1 1.98 1.44 2.24 2.8.04.14.06.28.06.43.03.82-.33 1.72-.93 2.27Z"/></svg>');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m9 20.42-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42Z"/></svg>');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m15.07 11.25-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 0 0-2-2 2 2 0 0 0-2 2H8a4 4 0 0 1 4-4 4 4 0 0 1 4 4 3.2 3.2 0 0 1-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10c0-5.53-4.5-10-10-10Z"/></svg>');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2V9h2m0 9h-2v-2h2M1 21h22L12 2 1 21Z"/></svg>');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 6.91 17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91Z"/></svg>');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11 15H6l7-14v8h5l-7 14v-8Z"/></svg>');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 0 0-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8Z"/></svg>');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 0 1 .75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25Z"/></svg>');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4Z"/></svg>')}.md-typeset :-webkit-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}.md-typeset :-moz-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}[dir=ltr] .md-typeset :-webkit-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition,details){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition,details){border-right-width:.2rem}.md-typeset :is(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}@media print{.md-typeset :-webkit-any(.admonition,details){box-shadow:none}.md-typeset :-moz-any(.admonition,details){box-shadow:none}.md-typeset :is(.admonition,details){box-shadow:none}}.md-typeset :-webkit-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :-moz-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :is(.admonition,details)>*{box-sizing:border-box}.md-typeset :-webkit-any(.admonition,details) :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-moz-any(.admonition,details) :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :is(.admonition,details) :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-webkit-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :is(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-webkit-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :is(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-webkit-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :-moz-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :is(.admonition,details)>.tabbed-set:only-child{margin-top:0}html .md-typeset :-webkit-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :-moz-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :is(.admonition,details)>:last-child{margin-bottom:.6rem}.md-typeset :-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}.md-typeset :-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-right-width:.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}.md-typeset :is(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset :-webkit-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :-moz-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :is(.admonition-title,summary):last-child{margin-bottom:0}.md-typeset :-webkit-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-moz-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain;position:absolute;top:.625em;width:1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :is(.admonition-title,summary):before{left:.8rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary):before{right:.8rem}.md-typeset :is(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}:root,[data-md-color-scheme=default]{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2Z"/></svg>')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root,[data-md-color-scheme=default]{--md-details-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z"/></svg>')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji){--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset :-webkit-any(.lg,.xl,.xxl,.xxxl){vertical-align:text-bottom}.md-typeset :-moz-any(.lg,.xl,.xxl,.xxxl){vertical-align:text-bottom}.md-typeset :is(.lg,.xl,.xxl,.xxxl){vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color);display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,td){display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root,[data-md-color-scheme=default]{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.41 16.58 10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.42Z"/></svg>');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z"/></svg>')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;-ms-scroll-snap-type:x proximity;scroll-snap-type:x proximity;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid transparent;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;scroll-snap-align:start;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-accent-fg-color)}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,transparent);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,transparent);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.9375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-accent-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){background-color:var(--md-accent-fg-color--transparent)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root,[data-md-color-scheme=default]{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm16.28-2.72a.75.75 0 0 0-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l6.5-6.5z"/></svg>');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm16.28-2.72a.75.75 0 0 0-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l6.5-6.5z"/></svg>')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*,[data-md-color-scheme=default]>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));margin:1em 0}.md-typeset .grid.cards>:-webkit-any(ul,ol){display:contents}.md-typeset .grid.cards>:-moz-any(ul,ol){display:contents}.md-typeset .grid.cards>:is(ul,ol){display:contents}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;-webkit-transition:border .25s,box-shadow .25s;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>:-moz-any(ul,ol)>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;-moz-transition:border .25s,box-shadow .25s;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>:is(ul,ol)>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li:-webkit-any(:focus-within,:hover),.md-typeset .grid>.card:-webkit-any(:focus-within,:hover){border-color:transparent;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>:-moz-any(ul,ol)>li:-moz-any(:focus-within,:hover),.md-typeset .grid>.card:-moz-any(:focus-within,:hover){border-color:transparent;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>:is(ul,ol)>li:is(:focus-within,:hover),.md-typeset .grid>.card:is(:focus-within,:hover){border-color:transparent;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>:-moz-any(ul,ol)>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>:is(ul,ol)>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>:-moz-any(ul,ol)>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>:is(ul,ol)>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid.cards>:-moz-any(ul,ol)>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid.cards>:is(ul,ol)>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*{margin-bottom:0;margin-top:0}.md-typeset .grid>:-webkit-any(.admonition,details){margin-bottom:0;margin-top:0}.md-typeset .grid>:-moz-any(.admonition,details){margin-bottom:0;margin-top:0}.md-typeset .grid>:is(.admonition,details){margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{float:left;margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}.md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}} + +.mdx-container { + background: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1123 258'><path d='M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style='fill: hsla(0, 0%, 100%, 1)' /></svg>) no-repeat bottom,linear-gradient(to bottom,var(--md-primary-fg-color),#a63fd9 99%,var(--md-default-bg-color) 99%); + padding-top: 1rem; + max-height: 600px; +} + +.font-center { + text-align: center; +} + +.bottom-margin { + margin-bottom: 10px; +} + +.top-margin { + margin-top: 10px; +} diff --git a/docs/material/overrides/home.html b/docs/material/overrides/home.html index 7f188ebf..e850a2e2 100644 --- a/docs/material/overrides/home.html +++ b/docs/material/overrides/home.html @@ -13,19 +13,102 @@ </div> <div class="mdx-hero__content"> <h1>What is DBM?</h1> - <p class="lead">DBM is a 100% open source <a href="https://clickhouse.com" target="_blank">ClickHouse</a> database management system.</p> - <p>✓ Easy to install</p> - <p>✓ Simple development</p> - <p>✓ Git-based source control</p> - <p>✓ Cross Platform</p> + <h3 class="lead">DBM is a set of open source database management desktop software, it will support more data sources, masterpiece-friendly database desktop management tools.</h3> <a href="{{ page.next_page.url | url }}" title="{{ page.next_page.title | e }}" class="md-button md-button--primary"> Quick start </a> </div> </div> + + <div> + <h1 class="font-center">Overview?</h1> + <div class="grid cards"> + <ul> + <li> + <div class="font-center"> + <span class="twemoji"> + <i class="fa fa-cogs"></i> + </span> + <strong class="font-center">Easy to install</strong> + </div> + <div class="top-margin"> + Simple installation method, download the binary file directly from the official website to install + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <i class="fa fa-desktop"></i> + </span> + <strong>Cross Platform</strong> + </div> + <div class="top-margin"> + DBM binary can be quickly installed in macOS, Windows and other systems. + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <i class="fa fa-code"></i> + </span> + <strong>Git-based source control</strong> + </div> + <div class="top-margin"> + The source code uses the Git system for version control, and the source code can be downloaded in various regions at any time. + </div> + </li> + </ul> + </div> + </div> + + <br /> + + <div> + <h1 class="font-center">Supported Databases?</h1> + <div class="grid cards"> + <ul> + <li> + <div class="font-center"> + <span class="twemoji"> + <img src="/assets/integrate/ClickHouse.svg" width="30" height="100" /> + </span> + <strong class="font-center">ClickHouse</strong> + </div> + <div class="top-margin"> + ClickHouse as a Service, built by the creators of the fastest OLAP database on Earth. + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <img src="/assets/integrate/Presto.svg" width="30" height="100" /> + </span> + <strong class="font-center">Presto</strong> + </div> + <div class="top-margin"> + Presto is an open source distributed SQL query engine for running interactive analytic queries against data sources of all sizes ranging from gigabytes to petabytes. + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <img src="/assets/integrate/Trino.svg" width="30" height="100" /> + </span> + <strong class="font-center">Trino</strong> + </div> + <div class="top-margin"> + Trino, a query engine that runs at ludicrous speed Fast distributed SQL query engine for big data analytics that helps you explore your data universe. + </div> + </li> + </ul> + </div> + </div> </div> - </section> + <br /> + + </section> {% endblock %} {% block content %}{% endblock %} {% block footer %}{% endblock %} + diff --git a/docs/material/overrides/home.zh.html b/docs/material/overrides/home.zh.html index 28b34811..e1f21955 100644 --- a/docs/material/overrides/home.zh.html +++ b/docs/material/overrides/home.zh.html @@ -1,31 +1,113 @@ {#- - This file was automatically generated - do not edit +This file was automatically generated - do not edit -#} {% extends "overrides/main.html" %} {% block tabs %} - {{ super() }} - <style>.md-header{position:initial}.md-main__inner{margin:0}.md-content{display:none}@media screen and (min-width:60em){.md-sidebar--secondary{display:none}}@media screen and (min-width:76.25em){.md-sidebar--primary{display:none}}</style> - <section class="mdx-container"> - <div class="md-grid md-typeset"> - <div class="mdx-hero"> - <div class="mdx-hero__image"> - <img src="assets/images/illustration.png" alt="" width="1659" height="1200" draggable="false"> - </div> - <div class="mdx-hero__content"> - <h1>什么是DBM?</h1> - <p class="lead">DBM是一套完整开源的<a href="https://clickhouse.com" target="_blank">ClickHouse</a>数据库管理客户端.</p> - <p>✓ 便捷安装</p> - <p>✓ 开发简单</p> - <p>✓ Git-based源代码控制</p> - <p>✓ 跨平台</p> - <a href="{{ page.next_page.url | url }}" title="{{ page.next_page.title | e }}" class="md-button md-button--primary"> - 快速启动 - </a> - </div> +{{ super() }} +<style>.md-header{position:initial}.md-main__inner{margin:0}.md-content{display:none}@media screen and (min-width:60em){.md-sidebar--secondary{display:none}}@media screen and (min-width:76.25em){.md-sidebar--primary{display:none}}</style> +<section class="mdx-container"> + <div class="md-grid md-typeset"> + <div class="mdx-hero"> + <div class="mdx-hero__image"> + <img src="assets/images/illustration.png" alt="" width="1659" height="1200" draggable="false"> + </div> + <div class="mdx-hero__content"> + <h1>What is DBM?</h1> + <h3 class="lead">DBM is a set of open source database management desktop software, it will support more data sources, masterpiece-friendly database desktop management tools.</h3> + <a href="{{ page.next_page.url | url }}" title="{{ page.next_page.title | e }}" class="md-button md-button--primary"> + Quick start + </a> </div> </div> - </section> + <div> + <h1 class="font-center">Overview?</h1> + <div class="grid cards"> + <ul> + <li> + <div class="font-center"> + <span class="twemoji"> + <i class="fa fa-cogs"></i> + </span> + <strong class="font-center">Easy to install</strong> + </div> + <div class="top-margin"> + Simple installation method, download the binary file directly from the official website to install + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <i class="fa fa-desktop"></i> + </span> + <strong>Cross Platform</strong> + </div> + <div class="top-margin"> + DBM binary can be quickly installed in macOS, Windows and other systems. + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <i class="fa fa-code"></i> + </span> + <strong>Git-based source control</strong> + </div> + <div class="top-margin"> + The source code uses the Git system for version control, and the source code can be downloaded in various regions at any time. + </div> + </li> + </ul> + </div> + </div> + + <br /> + + <div> + <h1 class="font-center">Supported Databases?</h1> + <div class="grid cards"> + <ul> + <li> + <div class="font-center"> + <span class="twemoji"> + <img src="/assets/integrate/ClickHouse.svg" width="30" height="100" /> + </span> + <strong class="font-center">ClickHouse</strong> + </div> + <div class="top-margin"> + ClickHouse as a Service, built by the creators of the fastest OLAP database on Earth. + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <img src="/assets/integrate/Presto.svg" width="30" height="100" /> + </span> + <strong class="font-center">Presto</strong> + </div> + <div class="top-margin"> + Presto is an open source distributed SQL query engine for running interactive analytic queries against data sources of all sizes ranging from gigabytes to petabytes. + </div> + </li> + <li> + <div class="font-center"> + <span class="twemoji"> + <img src="/assets/integrate/Trino.svg" width="30" height="100" /> + </span> + <strong class="font-center">Trino</strong> + </div> + <div class="top-margin"> + Trino, a query engine that runs at ludicrous speed Fast distributed SQL query engine for big data analytics that helps you explore your data universe. + </div> + </li> + </ul> + </div> + </div> + </div> + + <br /> + +</section> {% endblock %} {% block content %}{% endblock %} {% block footer %}{% endblock %} diff --git a/docs/material/overrides/main.html b/docs/material/overrides/main.html index 6b94dbca..046f6e4f 100644 --- a/docs/material/overrides/main.html +++ b/docs/material/overrides/main.html @@ -3,7 +3,8 @@ -#} {% extends "base.html" %} {% block extrahead %} - <link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.82a6bf04.min.css' | url }}"> + <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> + <link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.82a6bf04.min.css' | url }}" /> {% endblock %} {% block announce %} <a href="https://twitter.com/qianmoQ"> diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 76d58c45..77f4003b 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -1,8 +1,8 @@ -site_name: ClickHouse Gui Tools DBM +site_name: DBM - Database GUI site_url: https://dbm.incubator.edurt.io/ site_author: qinamoQ site_description: >- - ClickHouse Database Gui Tools! + Database Gui! repo_name: EdurtIO/dbm repo_url: https://github.com/EdurtIO/dbm diff --git a/docs/src/.icons/logo.afdesign b/docs/src/.icons/logo.afdesign deleted file mode 100644 index 07f57d0abb41156d9c50e57403a60a3e9ed3b3d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31465 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 diff --git a/docs/src/.icons/logo.svg b/docs/src/.icons/logo.svg deleted file mode 100644 index 763eb2c2..00000000 --- a/docs/src/.icons/logo.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 89"> - <path d="M3.136,17.387l0,42.932l42.932,21.467l-42.932,-64.399Z" /> - <path d="M21.91,8l42.933,64.398l-18.775,9.388l-42.932,-64.399l18.774,-9.387Z" style="fill-opacity: 0.5" /> - <path d="M67.535,17.387l-27.262,18.156l21.878,32.818l5.384,2.691l0,-53.665Z" /> - <path d="M67.535,17.387l0,53.666l18.774,-9.388l0,-53.665l-18.774,9.387Z" style="fill-opacity: 0.25" /> -</svg> diff --git a/docs/src/404.html b/docs/src/404.html deleted file mode 100644 index 27941f8c..00000000 --- a/docs/src/404.html +++ /dev/null @@ -1,31 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% extends "main.html" %} - -<!-- Content --> -{% block content %} - <h1>404 - Not found</h1> -{% endblock %} - -<!-- Disqus integration --> -{% block disqus %}{% endblock %} diff --git a/docs/src/__init__.py b/docs/src/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/src/assets/images/favicon.png b/docs/src/assets/images/favicon.png deleted file mode 100644 index 1cf13b9f9d978896599290a74f77d5dbe7d1655c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1870 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 IM6N<$f(jP3KmY&$ diff --git a/docs/src/assets/javascripts/_/index.ts b/docs/src/assets/javascripts/_/index.ts deleted file mode 100644 index b00cda9c..00000000 --- a/docs/src/assets/javascripts/_/index.ts +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { getElementOrThrow, getLocation } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Feature flag - */ -export type Flag = - | "header.autohide" /* Hide header */ - | "navigation.expand" /* Automatic expansion */ - | "navigation.instant" /* Instant loading */ - | "navigation.indexes" /* Section pages */ - | "navigation.sections" /* Section navigation */ - | "navigation.tabs" /* Tabs navigation */ - | "navigation.tabs.sticky" /* Tabs navigation (sticky) */ - | "navigation.top" /* Back-to-top button */ - | "search.highlight" /* Search highlighting */ - | "search.share" /* Search sharing */ - | "search.suggest" /* Search suggestions */ - | "toc.integrate" /* Integrated table of contents */ - -/* ------------------------------------------------------------------------- */ - -/** - * Translation - */ -export type Translation = - | "clipboard.copy" /* Copy to clipboard */ - | "clipboard.copied" /* Copied to clipboard */ - | "search.config.lang" /* Search language */ - | "search.config.pipeline" /* Search pipeline */ - | "search.config.separator" /* Search separator */ - | "search.placeholder" /* Search */ - | "search.result.placeholder" /* Type to start searching */ - | "search.result.none" /* No matching documents */ - | "search.result.one" /* 1 matching document */ - | "search.result.other" /* # matching documents */ - | "search.result.more.one" /* 1 more on this page */ - | "search.result.more.other" /* # more on this page */ - | "search.result.term.missing" /* Missing */ - | "select.version.title" /* Version selector */ - -/** - * Translations - */ -export type Translations = Record<Translation, string> - -/* ------------------------------------------------------------------------- */ - -/** - * Versioning - */ -export interface Versioning { - provider: "mike" /* Version provider */ -} - -/** - * Configuration - */ -export interface Config { - base: string /* Base URL */ - features: Flag[] /* Feature flags */ - translations: Translations /* Translations */ - search: string /* Search worker URL */ - version?: Versioning /* Versioning */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Retrieve global configuration and make base URL absolute - */ -const script = getElementOrThrow("#__config") -const config: Config = JSON.parse(script.textContent!) -config.base = `${new URL(config.base, getLocation())}` - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve global configuration - * - * @returns Global configuration - */ -export function configuration(): Config { - return config -} - -/** - * Check whether a feature flag is enabled - * - * @param flag - Feature flag - * - * @returns Test result - */ -export function feature(flag: Flag): boolean { - return config.features.includes(flag) -} - -/** - * Retrieve the translation for the given key - * - * @param key - Key to be translated - * @param value - Positional value, if any - * - * @returns Translation - */ -export function translation( - key: Translation, value?: string | number -): string { - return typeof value !== "undefined" - ? config.translations[key].replace("#", value.toString()) - : config.translations[key] -} diff --git a/docs/src/assets/javascripts/actions/_/index.ts b/docs/src/assets/javascripts/actions/_/index.ts deleted file mode 100644 index babb9d33..00000000 --- a/docs/src/assets/javascripts/actions/_/index.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set focusable property - * - * @param el - Element - * @param value - Tabindex value - */ -export function setFocusable( - el: HTMLElement, value = 0 -): void { - el.setAttribute("tabindex", value.toString()) -} - -/** - * Reset focusable property - * - * @param el - Element - */ -export function resetFocusable( - el: HTMLElement -): void { - el.removeAttribute("tabindex") -} - -/** - * Set scroll lock - * - * @param el - Scrollable element - * @param value - Vertical offset - */ -export function setScrollLock( - el: HTMLElement, value: number -): void { - el.setAttribute("data-md-state", "lock") - el.style.top = `-${value}px` -} - -/** - * Reset scroll lock - * - * @param el - Scrollable element - */ -export function resetScrollLock( - el: HTMLElement -): void { - const value = -1 * parseInt(el.style.top, 10) - el.removeAttribute("data-md-state") - el.style.top = "" - if (value) - window.scrollTo(0, value) -} diff --git a/docs/src/assets/javascripts/actions/anchor/index.ts b/docs/src/assets/javascripts/actions/anchor/index.ts deleted file mode 100644 index b1d3c896..00000000 --- a/docs/src/assets/javascripts/actions/anchor/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set anchor state - * - * @param el - Anchor element - * @param state - Anchor state - */ -export function setAnchorState( - el: HTMLElement, state: "blur" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset anchor state - * - * @param el - Anchor element - */ -export function resetAnchorState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set anchor active - * - * @param el - Anchor element - * @param value - Whether the anchor is active - */ -export function setAnchorActive( - el: HTMLElement, value: boolean -): void { - el.classList.toggle("md-nav__link--active", value) -} - -/** - * Reset anchor active - * - * @param el - Anchor element - */ -export function resetAnchorActive( - el: HTMLElement -): void { - el.classList.remove("md-nav__link--active") -} diff --git a/docs/src/assets/javascripts/actions/dialog/index.ts b/docs/src/assets/javascripts/actions/dialog/index.ts deleted file mode 100644 index d951d34d..00000000 --- a/docs/src/assets/javascripts/actions/dialog/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set dialog message - * - * @param el - Dialog element - * @param value - Dialog message - */ -export function setDialogMessage( - el: HTMLElement, value: string -): void { - el.firstElementChild!.innerHTML = value -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set dialog state - * - * @param el - Dialog element - * @param state - Dialog state - */ -export function setDialogState( - el: HTMLElement, state: "open" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset dialog state - * - * @param el - Dialog element - */ -export function resetDialogState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/header/_/index.ts b/docs/src/assets/javascripts/actions/header/_/index.ts deleted file mode 100644 index 400f44bd..00000000 --- a/docs/src/assets/javascripts/actions/header/_/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set header state - * - * @param el - Header element - * @param state - Header state - */ -export function setHeaderState( - el: HTMLElement, state: "shadow" | "hidden" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset header state - * - * @param el - Header element - */ -export function resetHeaderState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/header/index.ts b/docs/src/assets/javascripts/actions/header/index.ts deleted file mode 100644 index e98ef06a..00000000 --- a/docs/src/assets/javascripts/actions/header/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./title" diff --git a/docs/src/assets/javascripts/actions/header/title/index.ts b/docs/src/assets/javascripts/actions/header/title/index.ts deleted file mode 100644 index 62e24798..00000000 --- a/docs/src/assets/javascripts/actions/header/title/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set header title state - * - * @param el - Header title element - * @param state - Header title state - */ -export function setHeaderTitleState( - el: HTMLElement, state: "active" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset header title state - * - * @param el - Header title element - */ -export function resetHeaderTitleState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/index.ts b/docs/src/assets/javascripts/actions/index.ts deleted file mode 100644 index 24f2676d..00000000 --- a/docs/src/assets/javascripts/actions/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./anchor" -export * from "./dialog" -export * from "./header" -export * from "./search" -export * from "./sidebar" -export * from "./source" -export * from "./tabs" -export * from "./top" diff --git a/docs/src/assets/javascripts/actions/search/index.ts b/docs/src/assets/javascripts/actions/search/index.ts deleted file mode 100644 index efacc39d..00000000 --- a/docs/src/assets/javascripts/actions/search/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./query" -export * from "./result" diff --git a/docs/src/assets/javascripts/actions/search/query/index.ts b/docs/src/assets/javascripts/actions/search/query/index.ts deleted file mode 100644 index 42696fa0..00000000 --- a/docs/src/assets/javascripts/actions/search/query/index.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { translation } from "~/_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set search query placeholder - * - * @param el - Search query element - * @param value - Placeholder - */ -export function setSearchQueryPlaceholder( - el: HTMLInputElement, value: string -): void { - el.placeholder = value -} - -/** - * Reset search query placeholder - * - * @param el - Search query element - */ -export function resetSearchQueryPlaceholder( - el: HTMLInputElement -): void { - el.placeholder = translation("search.placeholder") -} diff --git a/docs/src/assets/javascripts/actions/search/result/index.ts b/docs/src/assets/javascripts/actions/search/result/index.ts deleted file mode 100644 index b9d23952..00000000 --- a/docs/src/assets/javascripts/actions/search/result/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { translation } from "~/_" -import { round } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set number of search results - * - * @param el - Search result metadata element - * @param value - Number of results - */ -export function setSearchResultMeta( - el: HTMLElement, value: number -): void { - switch (value) { - - /* No results */ - case 0: - el.textContent = translation("search.result.none") - break - - /* One result */ - case 1: - el.textContent = translation("search.result.one") - break - - /* Multiple result */ - default: - el.textContent = translation("search.result.other", round(value)) - } -} - -/** - * Reset number of search results - * - * @param el - Search result metadata element - */ -export function resetSearchResultMeta( - el: HTMLElement -): void { - el.textContent = translation("search.result.placeholder") -} - -/* ------------------------------------------------------------------------- */ - -/** - * Add an element to the search result list - * - * @param el - Search result list element - * @param child - Search result element - */ -export function addToSearchResultList( - el: HTMLElement, child: Element -): void { - el.appendChild(child) -} - -/** - * Reset search result list - * - * @param el - Search result list element - */ -export function resetSearchResultList( - el: HTMLElement -): void { - el.innerHTML = "" -} diff --git a/docs/src/assets/javascripts/actions/sidebar/index.ts b/docs/src/assets/javascripts/actions/sidebar/index.ts deleted file mode 100644 index 403bcc60..00000000 --- a/docs/src/assets/javascripts/actions/sidebar/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set sidebar offset - * - * @param el - Sidebar element - * @param value - Sidebar offset - */ -export function setSidebarOffset( - el: HTMLElement, value: number -): void { - el.style.top = `${value}px` -} - -/** - * Reset sidebar offset - * - * @param el - Sidebar element - */ -export function resetSidebarOffset( - el: HTMLElement -): void { - el.style.top = "" -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set sidebar height - * - * This function doesn't set the height of the actual sidebar, but of its first - * child – the `.md-sidebar__scrollwrap` element in order to mitigiate jittery - * sidebars when the footer is scrolled into view. At some point we switched - * from `absolute` / `fixed` positioning to `sticky` positioning, significantly - * reducing jitter in some browsers (respectively Firefox and Safari) when - * scrolling from the top. However, top-aligned sticky positioning means that - * the sidebar snaps to the bottom when the end of the container is reached. - * This is what leads to the mentioned jitter, as the sidebar's height may be - * updated too slowly. - * - * This behaviour can be mitigiated by setting the height of the sidebar to `0` - * while preserving the padding, and the height on its first element. - * - * @param el - Sidebar element - * @param value - Sidebar height - */ -export function setSidebarHeight( - el: HTMLElement, value: number -): void { - const scrollwrap = el.firstElementChild as HTMLElement - scrollwrap.style.height = `${value - 2 * scrollwrap.offsetTop}px` -} - -/** - * Reset sidebar height - * - * @param el - Sidebar element - */ -export function resetSidebarHeight( - el: HTMLElement -): void { - const scrollwrap = el.firstElementChild as HTMLElement - scrollwrap.style.height = "" -} diff --git a/docs/src/assets/javascripts/actions/source/index.ts b/docs/src/assets/javascripts/actions/source/index.ts deleted file mode 100644 index d2074e0a..00000000 --- a/docs/src/assets/javascripts/actions/source/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set repository facts - * - * @param el - Repository element - * @param child - Repository facts element - */ -export function setSourceFacts( - el: HTMLElement, child: Element -): void { - el.lastElementChild!.appendChild(child) -} - -/** - * Set repository state - * - * @param el - Repository element - * @param state - Repository state - */ -export function setSourceState( - el: HTMLElement, state: "done" -): void { - el.lastElementChild!.setAttribute("data-md-state", state) -} diff --git a/docs/src/assets/javascripts/actions/tabs/index.ts b/docs/src/assets/javascripts/actions/tabs/index.ts deleted file mode 100644 index 5fd31afe..00000000 --- a/docs/src/assets/javascripts/actions/tabs/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set tabs state - * - * @param el - Tabs element - * @param state - Tabs state - */ -export function setTabsState( - el: HTMLElement, state: "hidden" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset tabs state - * - * @param el - Tabs element - */ -export function resetTabsState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/top/index.ts b/docs/src/assets/javascripts/actions/top/index.ts deleted file mode 100644 index 483e5ef7..00000000 --- a/docs/src/assets/javascripts/actions/top/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set back-to-top state - * - * @param el - Back-to-top element - * @param state - Back-to-top state - */ -export function setBackToTopState( - el: HTMLElement, state: "hidden" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset back-to-top state - * - * @param el - Back-to-top element - */ -export function resetBackToTopState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set back-to-top offset - * - * @param el - Back-to-top element - * @param value - Back-to-top offset - */ -export function setBackToTopOffset( - el: HTMLElement, value: number -): void { - el.style.top = `${value}px` -} - -/** - * Reset back-to-top offset - * - * @param el - Back-to-top element - */ -export function resetBackToTopOffset( - el: HTMLElement -): void { - el.style.top = "" -} diff --git a/docs/src/assets/javascripts/browser/document/index.ts b/docs/src/assets/javascripts/browser/document/index.ts deleted file mode 100644 index dbb290ad..00000000 --- a/docs/src/assets/javascripts/browser/document/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ReplaySubject, Subject, fromEvent } from "rxjs" -import { mapTo } from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch document - * - * Documents are implemented as subjects, so all downstream observables are - * automatically updated when a new document is emitted. - * - * @returns Document subject - */ -export function watchDocument(): Subject<Document> { - const document$ = new ReplaySubject<Document>() - fromEvent(document, "DOMContentLoaded") - .pipe( - mapTo(document) - ) - .subscribe(document$) - - /* Return document */ - return document$ -} diff --git a/docs/src/assets/javascripts/browser/element/_/.eslintrc b/docs/src/assets/javascripts/browser/element/_/.eslintrc deleted file mode 100644 index 82472629..00000000 --- a/docs/src/assets/javascripts/browser/element/_/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "jsdoc/require-jsdoc": "off" - } -} diff --git a/docs/src/assets/javascripts/browser/element/_/index.ts b/docs/src/assets/javascripts/browser/element/_/index.ts deleted file mode 100644 index 5fc98e69..00000000 --- a/docs/src/assets/javascripts/browser/element/_/index.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve an element matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element or nothing - */ -export function getElement<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] | undefined - -export function getElement<T extends HTMLElement>( - selector: string, node?: ParentNode -): T | undefined - -export function getElement<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T | undefined { - return node.querySelector<T>(selector) || undefined -} - -/** - * Retrieve an element matching a query selector or throw a reference error - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element - */ -export function getElementOrThrow<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] - -export function getElementOrThrow<T extends HTMLElement>( - selector: string, node?: ParentNode -): T - -export function getElementOrThrow<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T { - const el = getElement<T>(selector, node) - if (typeof el === "undefined") - throw new ReferenceError( - `Missing element: expected "${selector}" to be present` - ) - - /* Return element */ - return el -} - -/** - * Retrieve the currently active element - * - * @returns Element or nothing - */ -export function getActiveElement(): HTMLElement | undefined { - return document.activeElement instanceof HTMLElement - ? document.activeElement - : undefined -} - -/** - * Retrieve all elements matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Elements - */ -export function getElements<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T][] - -export function getElements<T extends HTMLElement>( - selector: string, node?: ParentNode -): T[] - -export function getElements<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T[] { - return Array.from(node.querySelectorAll<T>(selector)) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Replace an element with the given list of nodes - * - * @param el - Element - * @param nodes - Replacement nodes - */ -export function replaceElement( - el: HTMLElement, ...nodes: Node[] -): void { - el.replaceWith(...nodes) -} diff --git a/docs/src/assets/javascripts/browser/element/focus/index.ts b/docs/src/assets/javascripts/browser/element/focus/index.ts deleted file mode 100644 index 292a5f87..00000000 --- a/docs/src/assets/javascripts/browser/element/focus/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, merge } from "rxjs" -import { map, startWith } from "rxjs/operators" - -import { getActiveElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set element focus - * - * @param el - Element - * @param value - Whether the element should be focused - */ -export function setElementFocus( - el: HTMLElement, value = true -): void { - if (value) - el.focus() - else - el.blur() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element focus - * - * @param el - Element - * - * @returns Element focus observable - */ -export function watchElementFocus( - el: HTMLElement -): Observable<boolean> { - return merge( - fromEvent<FocusEvent>(el, "focus"), - fromEvent<FocusEvent>(el, "blur") - ) - .pipe( - map(({ type }) => type === "focus"), - startWith(el === getActiveElement()) - ) -} diff --git a/docs/src/assets/javascripts/browser/element/index.ts b/docs/src/assets/javascripts/browser/element/index.ts deleted file mode 100644 index 4cbe7f98..00000000 --- a/docs/src/assets/javascripts/browser/element/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./focus" -export * from "./offset" -export * from "./selection" -export * from "./size" diff --git a/docs/src/assets/javascripts/browser/element/offset/index.ts b/docs/src/assets/javascripts/browser/element/offset/index.ts deleted file mode 100644 index e51f784f..00000000 --- a/docs/src/assets/javascripts/browser/element/offset/index.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, merge } from "rxjs" -import { - distinctUntilChanged, - map, - startWith -} from "rxjs/operators" - -import { - getElementContentSize, - getElementSize -} from "../size" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element offset - * - * @param el - Element - * - * @returns Element offset - */ -export function getElementOffset(el: HTMLElement): ElementOffset { - return { - x: el.scrollLeft, - y: el.scrollTop - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element offset - * - * @param el - Element - * - * @returns Element offset observable - */ -export function watchElementOffset( - el: HTMLElement -): Observable<ElementOffset> { - return merge( - fromEvent(el, "scroll"), - fromEvent(window, "resize") - ) - .pipe( - map(() => getElementOffset(el)), - startWith(getElementOffset(el)) - ) -} - -/** - * Watch element threshold - * - * This function returns an observable which emits whether the bottom scroll - * offset of an elements is within a certain threshold. - * - * @param el - Element - * @param threshold - Threshold - * - * @returns Element threshold observable - */ -export function watchElementThreshold( - el: HTMLElement, threshold = 16 -): Observable<boolean> { - return watchElementOffset(el) - .pipe( - map(({ y }) => { - const visible = getElementSize(el) - const content = getElementContentSize(el) - return y >= ( - content.height - visible.height - threshold - ) - }), - distinctUntilChanged() - ) -} diff --git a/docs/src/assets/javascripts/browser/element/selection/index.ts b/docs/src/assets/javascripts/browser/element/selection/index.ts deleted file mode 100644 index ebbbaee0..00000000 --- a/docs/src/assets/javascripts/browser/element/selection/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set element text selection - * - * @param el - Element - */ -export function setElementSelection( - el: HTMLElement -): void { - if (el instanceof HTMLInputElement) - el.select() - else - throw new Error("Not implemented") -} diff --git a/docs/src/assets/javascripts/browser/element/size/index.ts b/docs/src/assets/javascripts/browser/element/size/index.ts deleted file mode 100644 index b45c29fb..00000000 --- a/docs/src/assets/javascripts/browser/element/size/index.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - Subject, - defer, - of -} from "rxjs" -import { - filter, - finalize, - map, - shareReplay, - startWith, - switchMap, - tap -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementSize { - width: number /* Element width */ - height: number /* Element height */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Resize observer entry subject - */ -const entry$ = new Subject<ResizeObserverEntry>() - -/** - * Resize observer observable - * - * This observable will create a `ResizeObserver` on the first subscription - * and will automatically terminate it when there are no more subscribers. - * It's quite important to centralize observation in a single `ResizeObserver`, - * as the performance difference can be quite dramatic, as the link shows. - * - * @see https://bit.ly/3iIYfEm - Google Groups on performance - */ -const observer$ = defer(() => of( - new ResizeObserver(entries => { - for (const entry of entries) - entry$.next(entry) - }) -)) - .pipe( - switchMap(resize => NEVER.pipe(startWith(resize)) - .pipe( - finalize(() => resize.disconnect()) - ) - ), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element size - * - * @param el - Element - * - * @returns Element size - */ -export function getElementSize(el: HTMLElement): ElementSize { - return { - width: el.offsetWidth, - height: el.offsetHeight - } -} - -/** - * Retrieve element content size, i.e. including overflowing content - * - * @param el - Element - * - * @returns Element size - */ -export function getElementContentSize(el: HTMLElement): ElementSize { - return { - width: el.scrollWidth, - height: el.scrollHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element size - * - * This function returns an observable that subscribes to a single internal - * instance of `ResizeObserver` upon subscription, and emit resize events until - * termination. Note that this function should not be called with the same - * element twice, as the first unsubscription will terminate observation. - * - * Sadly, we can't use the `DOMRect` objects returned by the observer, because - * we need the emitted values to be consistent with `getElementSize`, which will - * return the used values (rounded) and not actual values (unrounded). Thus, we - * use the `offset*` properties. See the linked GitHub issue. - * - * @see https://bit.ly/3m0k3he - GitHub issue - * - * @param el - Element - * - * @returns Element size observable - */ -export function watchElementSize( - el: HTMLElement -): Observable<ElementSize> { - return observer$ - .pipe( - tap(observer => observer.observe(el)), - switchMap(observer => entry$ - .pipe( - filter(({ target }) => target === el), - finalize(() => observer.unobserve(el)), - map(() => getElementSize(el)) - ) - ), - startWith(getElementSize(el)) - ) -} diff --git a/docs/src/assets/javascripts/browser/index.ts b/docs/src/assets/javascripts/browser/index.ts deleted file mode 100644 index 4c802761..00000000 --- a/docs/src/assets/javascripts/browser/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./document" -export * from "./element" -export * from "./keyboard" -export * from "./location" -export * from "./media" -export * from "./request" -export * from "./toggle" -export * from "./viewport" -export * from "./worker" diff --git a/docs/src/assets/javascripts/browser/keyboard/index.ts b/docs/src/assets/javascripts/browser/keyboard/index.ts deleted file mode 100644 index 8c7a46df..00000000 --- a/docs/src/assets/javascripts/browser/keyboard/index.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { filter, map, share } from "rxjs/operators" - -import { getActiveElement } from "../element" -import { getToggle } from "../toggle" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Keyboard mode - */ -export type KeyboardMode = - | "global" /* Global */ - | "search" /* Search is open */ - -/* ------------------------------------------------------------------------- */ - -/** - * Keyboard - */ -export interface Keyboard { - mode: KeyboardMode /* Keyboard mode */ - type: string /* Key type */ - claim(): void /* Key claim */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Check whether an element may receive keyboard input - * - * @param el - Element - * - * @returns Test result - */ -function isSusceptibleToKeyboard(el: HTMLElement): boolean { - switch (el.tagName) { - - /* Form elements */ - case "INPUT": - case "SELECT": - case "TEXTAREA": - return true - - /* Everything else */ - default: - return el.isContentEditable - } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch keyboard - * - * @returns Keyboard observable - */ -export function watchKeyboard(): Observable<Keyboard> { - return fromEvent<KeyboardEvent>(window, "keydown") - .pipe( - filter(ev => !(ev.metaKey || ev.ctrlKey)), - map(ev => ({ - mode: getToggle("search") ? "search" : "global", - type: ev.key, - claim() { - ev.preventDefault() - ev.stopPropagation() - } - } as Keyboard)), - filter(({ mode }) => { - if (mode === "global") { - const active = getActiveElement() - if (typeof active !== "undefined") - return !isSusceptibleToKeyboard(active) - } - return true - }), - share() - ) -} diff --git a/docs/src/assets/javascripts/browser/location/_/index.ts b/docs/src/assets/javascripts/browser/location/_/index.ts deleted file mode 100644 index a2ab32dc..00000000 --- a/docs/src/assets/javascripts/browser/location/_/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Subject } from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve location - * - * This function returns a `URL` object (and not `Location`) to normalize the - * typings across the application. Furthermore, locations need to be tracked - * without setting them and `Location` is a singleton which represents the - * current location. - * - * @returns URL - */ -export function getLocation(): URL { - return new URL(location.href) -} - -/** - * Set location - * - * @param url - URL to change to - */ -export function setLocation(url: URL): void { - location.href = url.href -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch location - * - * @returns Location subject - */ -export function watchLocation(): Subject<URL> { - return new Subject<URL>() -} diff --git a/docs/src/assets/javascripts/browser/location/hash/index.ts b/docs/src/assets/javascripts/browser/location/hash/index.ts deleted file mode 100644 index 0118f243..00000000 --- a/docs/src/assets/javascripts/browser/location/hash/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { - filter, - map, - shareReplay, - startWith -} from "rxjs/operators" - -import { getElement } from "~/browser" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve location hash - * - * @returns Location hash - */ -export function getLocationHash(): string { - return location.hash.substring(1) -} - -/** - * Set location hash - * - * Setting a new fragment identifier via `location.hash` will have no effect - * if the value doesn't change. When a new fragment identifier is set, we want - * the browser to target the respective element at all times, which is why we - * use this dirty little trick. - * - * @param hash - Location hash - */ -export function setLocationHash(hash: string): void { - const el = h("a", { href: hash }) - el.addEventListener("click", ev => ev.stopPropagation()) - el.click() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch location hash - * - * @returns Location hash observable - */ -export function watchLocationHash(): Observable<string> { - return fromEvent<HashChangeEvent>(window, "hashchange") - .pipe( - map(getLocationHash), - startWith(getLocationHash()), - filter(hash => hash.length > 0), - shareReplay(1) - ) -} - -/** - * Watch location target - * - * @returns Location target observable - */ -export function watchLocationTarget(): Observable<HTMLElement> { - return watchLocationHash() - .pipe( - map(id => getElement(`[id="${id}"]`)!), - filter(el => typeof el !== "undefined") - ) -} diff --git a/docs/src/assets/javascripts/browser/location/index.ts b/docs/src/assets/javascripts/browser/location/index.ts deleted file mode 100644 index 551a09ac..00000000 --- a/docs/src/assets/javascripts/browser/location/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./hash" diff --git a/docs/src/assets/javascripts/browser/media/index.ts b/docs/src/assets/javascripts/browser/media/index.ts deleted file mode 100644 index b6a9ae24..00000000 --- a/docs/src/assets/javascripts/browser/media/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - fromEvent, - fromEventPattern -} from "rxjs" -import { - mapTo, - startWith, - switchMap -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch media query - * - * Note that although `MediaQueryList.addListener` is deprecated we have to - * use it, because it's the only way to ensure proper downward compatibility. - * - * @see https://bit.ly/3dUBH2m - GitHub issue - * - * @param query - Media query - * - * @returns Media observable - */ -export function watchMedia(query: string): Observable<boolean> { - const media = matchMedia(query) - return fromEventPattern<boolean>(next => ( - media.addListener(() => next(media.matches)) - )) - .pipe( - startWith(media.matches) - ) -} - -/** - * Watch print mode, cross-browser - * - * @returns Print mode observable - */ -export function watchPrint(): Observable<void> { - return fromEvent(window, "beforeprint") - .pipe( - mapTo(undefined) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Toggle an observable with a media observable - * - * @template T - Data type - * - * @param query$ - Media observable - * @param factory - Observable factory - * - * @returns Toggled observable - */ -export function at<T>( - query$: Observable<boolean>, factory: () => Observable<T> -): Observable<T> { - return query$ - .pipe( - switchMap(active => active ? factory() : NEVER) - ) -} diff --git a/docs/src/assets/javascripts/browser/request/index.ts b/docs/src/assets/javascripts/browser/request/index.ts deleted file mode 100644 index c6f09a9f..00000000 --- a/docs/src/assets/javascripts/browser/request/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, from } from "rxjs" -import { - filter, - map, - shareReplay, - switchMap -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch the given URL - * - * @param url - Request URL - * @param options - Options - * - * @returns Response observable - */ -export function request( - url: URL | string, options: RequestInit = { credentials: "same-origin" } -): Observable<Response> { - return from(fetch(`${url}`, options)) - .pipe( - filter(res => res.status === 200), - ) -} - -/** - * Fetch JSON from the given URL - * - * @template T - Data type - * - * @param url - Request URL - * @param options - Options - * - * @returns Data observable - */ -export function requestJSON<T>( - url: URL | string, options?: RequestInit -): Observable<T> { - return request(url, options) - .pipe( - switchMap(res => res.json()), - shareReplay(1) - ) -} - -/** - * Fetch XML from the given URL - * - * @param url - Request URL - * @param options - Options - * - * @returns Data observable - */ -export function requestXML( - url: URL | string, options?: RequestInit -): Observable<Document> { - const dom = new DOMParser() - return request(url, options) - .pipe( - switchMap(res => res.text()), - map(res => dom.parseFromString(res, "text/xml")), - shareReplay(1) - ) -} diff --git a/docs/src/assets/javascripts/browser/toggle/index.ts b/docs/src/assets/javascripts/browser/toggle/index.ts deleted file mode 100644 index ae60577e..00000000 --- a/docs/src/assets/javascripts/browser/toggle/index.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { map, startWith } from "rxjs/operators" - -import { getElementOrThrow } from "../element" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Toggle - */ -export type Toggle = - | "drawer" /* Toggle for drawer */ - | "search" /* Toggle for search */ - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Toggle map - */ -const toggles: Record<Toggle, HTMLInputElement> = { - drawer: getElementOrThrow("[data-md-toggle=drawer]"), - search: getElementOrThrow("[data-md-toggle=search]") -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the value of a toggle - * - * @param name - Toggle - * - * @returns Toggle value - */ -export function getToggle(name: Toggle): boolean { - return toggles[name].checked -} - -/** - * Set toggle - * - * Simulating a click event seems to be the most cross-browser compatible way - * of changing the value while also emitting a `change` event. Before, Material - * used `CustomEvent` to programmatically change the value of a toggle, but this - * is a much simpler and cleaner solution which doesn't require a polyfill. - * - * @param name - Toggle - * @param value - Toggle value - */ -export function setToggle(name: Toggle, value: boolean): void { - if (toggles[name].checked !== value) - toggles[name].click() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch toggle - * - * @param name - Toggle - * - * @returns Toggle value observable - */ -export function watchToggle(name: Toggle): Observable<boolean> { - const el = toggles[name] - return fromEvent(el, "change") - .pipe( - map(() => el.checked), - startWith(el.checked) - ) -} diff --git a/docs/src/assets/javascripts/browser/viewport/_/index.ts b/docs/src/assets/javascripts/browser/viewport/_/index.ts deleted file mode 100644 index 827d9716..00000000 --- a/docs/src/assets/javascripts/browser/viewport/_/index.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, combineLatest } from "rxjs" -import { - distinctUntilKeyChanged, - map, - shareReplay -} from "rxjs/operators" - -import { Header } from "~/components" - -import { - ViewportOffset, - watchViewportOffset -} from "../offset" -import { - ViewportSize, - watchViewportSize -} from "../size" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport - */ -export interface Viewport { - offset: ViewportOffset /* Viewport offset */ - size: ViewportSize /* Viewport size */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch at options - */ -interface WatchAtOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch viewport - * - * @returns Viewport observable - */ -export function watchViewport(): Observable<Viewport> { - return combineLatest([ - watchViewportOffset(), - watchViewportSize() - ]) - .pipe( - map(([offset, size]) => ({ offset, size })), - shareReplay(1) - ) -} - -/** - * Watch viewport relative to element - * - * @param el - Element - * @param options - Options - * - * @returns Viewport observable - */ -export function watchViewportAt( - el: HTMLElement, { viewport$, header$ }: WatchAtOptions -): Observable<Viewport> { - const size$ = viewport$ - .pipe( - distinctUntilKeyChanged("size") - ) - - /* Compute element offset */ - const offset$ = combineLatest([size$, header$]) - .pipe( - map((): ViewportOffset => ({ - x: el.offsetLeft, - y: el.offsetTop - })) - ) - - /* Compute relative viewport, return hot observable */ - return combineLatest([header$, viewport$, offset$]) - .pipe( - map(([{ height }, { offset, size }, { x, y }]) => ({ - offset: { - x: offset.x - x, - y: offset.y - y + height - }, - size - })) - ) -} diff --git a/docs/src/assets/javascripts/browser/viewport/index.ts b/docs/src/assets/javascripts/browser/viewport/index.ts deleted file mode 100644 index d43797f7..00000000 --- a/docs/src/assets/javascripts/browser/viewport/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./offset" -export * from "./size" diff --git a/docs/src/assets/javascripts/browser/viewport/offset/index.ts b/docs/src/assets/javascripts/browser/viewport/offset/index.ts deleted file mode 100644 index d9d81e82..00000000 --- a/docs/src/assets/javascripts/browser/viewport/offset/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, merge } from "rxjs" -import { map, startWith } from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport offset - */ -export interface ViewportOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve viewport offset - * - * On iOS Safari, viewport offset can be negative due to overflow scrolling. - * As this may induce strange behaviors downstream, we'll just limit it to 0. - * - * @returns Viewport offset - */ -export function getViewportOffset(): ViewportOffset { - return { - x: Math.max(0, pageXOffset), - y: Math.max(0, pageYOffset) - } -} - -/** - * Set viewport offset - * - * @param offset - Viewport offset - */ -export function setViewportOffset( - { x, y }: Partial<ViewportOffset> -): void { - window.scrollTo(x || 0, y || 0) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch viewport offset - * - * @returns Viewport offset observable - */ -export function watchViewportOffset(): Observable<ViewportOffset> { - return merge( - fromEvent(window, "scroll", { passive: true }), - fromEvent(window, "resize", { passive: true }) - ) - .pipe( - map(getViewportOffset), - startWith(getViewportOffset()) - ) -} diff --git a/docs/src/assets/javascripts/browser/viewport/size/index.ts b/docs/src/assets/javascripts/browser/viewport/size/index.ts deleted file mode 100644 index 6bdfaaf8..00000000 --- a/docs/src/assets/javascripts/browser/viewport/size/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { map, startWith } from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport size - */ -export interface ViewportSize { - width: number /* Viewport width */ - height: number /* Viewport height */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve viewport size - * - * @returns Viewport size - */ -export function getViewportSize(): ViewportSize { - return { - width: innerWidth, - height: innerHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch viewport size - * - * @returns Viewport size observable - */ -export function watchViewportSize(): Observable<ViewportSize> { - return fromEvent(window, "resize", { passive: true }) - .pipe( - map(getViewportSize), - startWith(getViewportSize()) - ) -} diff --git a/docs/src/assets/javascripts/browser/worker/index.ts b/docs/src/assets/javascripts/browser/worker/index.ts deleted file mode 100644 index aa30d139..00000000 --- a/docs/src/assets/javascripts/browser/worker/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, Subject, fromEvent } from "rxjs" -import { - map, - share, - switchMapTo, - tap, - throttle -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Worker message - */ -export interface WorkerMessage { - type: unknown /* Message type */ - data?: unknown /* Message data */ -} - -/** - * Worker handler - * - * @template T - Message type - */ -export interface WorkerHandler< - T extends WorkerMessage -> { - tx$: Subject<T> /* Message transmission subject */ - rx$: Observable<T> /* Message receive observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - * - * @template T - Worker message type - */ -interface WatchOptions<T extends WorkerMessage> { - tx$: Observable<T> /* Message transmission observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch a web worker - * - * This function returns an observable that sends all values emitted by the - * message observable to the web worker. Web worker communication is expected - * to be bidirectional (request-response) and synchronous. Messages that are - * emitted during a pending request are throttled, the last one is emitted. - * - * @param worker - Web worker - * @param options - Options - * - * @returns Worker message observable - */ -export function watchWorker<T extends WorkerMessage>( - worker: Worker, { tx$ }: WatchOptions<T> -): Observable<T> { - - /* Intercept messages from worker-like objects */ - const rx$ = fromEvent<MessageEvent>(worker, "message") - .pipe( - map(({ data }) => data as T) - ) - - /* Send and receive messages, return hot observable */ - return tx$ - .pipe( - throttle(() => rx$, { leading: true, trailing: true }), - tap(message => worker.postMessage(message)), - switchMapTo(rx$), - share() - ) -} diff --git a/docs/src/assets/javascripts/bundle.ts b/docs/src/assets/javascripts/bundle.ts deleted file mode 100644 index bd223041..00000000 --- a/docs/src/assets/javascripts/bundle.ts +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import "focus-visible" -import { NEVER, Subject, defer, merge } from "rxjs" -import { - delay, - filter, - map, - mergeWith, - shareReplay, - switchMap -} from "rxjs/operators" - -import { configuration, feature } from "./_" -import { - at, - getElement, - requestJSON, - setToggle, - watchDocument, - watchKeyboard, - watchLocation, - watchLocationTarget, - watchMedia, - watchPrint, - watchViewport -} from "./browser" -import { - getComponentElement, - getComponentElements, - mountBackToTop, - mountContent, - mountDialog, - mountHeader, - mountHeaderTitle, - mountPalette, - mountSearch, - mountSearchHiglight, - mountSidebar, - mountSource, - mountTableOfContents, - mountTabs, - watchHeader, - watchMain -} from "./components" -import { - SearchIndex, - setupClipboardJS, - setupInstantLoading, - setupVersionSelector -} from "./integrations" -import { - patchIndeterminate, - patchScrollfix, - patchScrolllock -} from "./patches" - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/* Yay, JavaScript is available */ -document.documentElement.classList.remove("no-js") -document.documentElement.classList.add("js") - -/* Set up navigation observables and subjects */ -const document$ = watchDocument() -const location$ = watchLocation() -const target$ = watchLocationTarget() -const keyboard$ = watchKeyboard() - -/* Set up media observables */ -const viewport$ = watchViewport() -const tablet$ = watchMedia("(min-width: 960px)") -const screen$ = watchMedia("(min-width: 1220px)") -const print$ = watchPrint() - -/* Retrieve search index, if search is enabled */ -const config = configuration() -const index$ = document.forms.namedItem("search") - ? __search?.index || requestJSON<SearchIndex>( - new URL("search/search_index.json", config.base) - ) - : NEVER - -/* Set up Clipboard.js integration */ -const alert$ = new Subject<string>() -setupClipboardJS({ alert$ }) - -/* Set up instant loading, if enabled */ -if (feature("navigation.instant")) - setupInstantLoading({ document$, location$, viewport$ }) - -/* Set up version selector */ -if (config.version?.provider === "mike") - setupVersionSelector() - -/* Always close drawer and search on navigation */ -merge(location$, target$) - .pipe( - delay(125) - ) - .subscribe(() => { - setToggle("drawer", false) - setToggle("search", false) - }) - -/* Set up global keyboard handlers */ -keyboard$ - .pipe( - filter(({ mode }) => mode === "global") - ) - .subscribe(key => { - switch (key.type) { - - /* Go to previous page */ - case "p": - case ",": - const prev = getElement("[href][rel=prev]") - if (typeof prev !== "undefined") - prev.click() - break - - /* Go to next page */ - case "n": - case ".": - const next = getElement("[href][rel=next]") - if (typeof next !== "undefined") - next.click() - break - } - }) - -/* Set up patches */ -patchIndeterminate({ document$, tablet$ }) -patchScrollfix({ document$ }) -patchScrolllock({ viewport$, tablet$ }) - -/* Set up header and main area observable */ -const header$ = watchHeader(getComponentElement("header"), { viewport$ }) -const main$ = document$ - .pipe( - map(() => getComponentElement("main")), - switchMap(el => watchMain(el, { viewport$, header$ })), - shareReplay(1) - ) - -/* Set up control component observables */ -const control$ = merge( - - /* Dialog */ - ...getComponentElements("dialog") - .map(el => mountDialog(el, { alert$ })), - - /* Header */ - ...getComponentElements("header") - .map(el => mountHeader(el, { viewport$, header$, main$ })), - - /* Color palette */ - ...getComponentElements("palette") - .map(el => mountPalette(el)), - - /* Search */ - ...getComponentElements("search") - .map(el => mountSearch(el, { index$, keyboard$ })), - - /* Repository information */ - ...getComponentElements("source") - .map(el => mountSource(el)) -) - -/* Set up content component observables */ -const content$ = defer(() => merge( - - /* Content */ - ...getComponentElements("content") - .map(el => mountContent(el, { target$, viewport$, print$ })), - - /* Search highlighting */ - ...getComponentElements("content") - .map(el => feature("search.highlight") - ? mountSearchHiglight(el, { index$, location$ }) - : NEVER - ), - - /* Header title */ - ...getComponentElements("header-title") - .map(el => mountHeaderTitle(el, { viewport$, header$ })), - - /* Sidebar */ - ...getComponentElements("sidebar") - .map(el => el.getAttribute("data-md-type") === "navigation" - ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ })) - : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ })) - ), - - /* Navigation tabs */ - ...getComponentElements("tabs") - .map(el => mountTabs(el, { viewport$, header$ })), - - /* Table of contents */ - ...getComponentElements("toc") - .map(el => mountTableOfContents(el, { viewport$, header$ })), - - /* Back-to-top button */ - ...getComponentElements("top") - .map(el => mountBackToTop(el, { viewport$, header$, main$ })) -)) - -/* Set up component observables */ -const component$ = document$ - .pipe( - switchMap(() => content$), - mergeWith(control$), - shareReplay(1) - ) - -/* Subscribe to all components */ -component$.subscribe() - -/* ---------------------------------------------------------------------------- - * Exports - * ------------------------------------------------------------------------- */ - -window.document$ = document$ /* Document observable */ -window.location$ = location$ /* Location subject */ -window.target$ = target$ /* Location target observable */ -window.keyboard$ = keyboard$ /* Keyboard observable */ -window.viewport$ = viewport$ /* Viewport observable */ -window.tablet$ = tablet$ /* Tablet observable */ -window.screen$ = screen$ /* Screen observable */ -window.print$ = print$ /* Print mode observable */ -window.alert$ = alert$ /* Alert subject */ -window.component$ = component$ /* Component observable */ diff --git a/docs/src/assets/javascripts/components/_/index.ts b/docs/src/assets/javascripts/components/_/index.ts deleted file mode 100644 index 375372fc..00000000 --- a/docs/src/assets/javascripts/components/_/index.ts +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { getElementOrThrow, getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Component type - */ -export type ComponentType = - | "announce" /* Announcement bar */ - | "container" /* Container */ - | "content" /* Content */ - | "dialog" /* Dialog */ - | "header" /* Header */ - | "header-title" /* Header title */ - | "header-topic" /* Header topic */ - | "main" /* Main area */ - | "palette" /* Color palette */ - | "search" /* Search */ - | "search-query" /* Search input */ - | "search-result" /* Search results */ - | "search-share" /* Search sharing */ - | "search-suggest" /* Search suggestions */ - | "sidebar" /* Sidebar */ - | "skip" /* Skip link */ - | "source" /* Repository information */ - | "tabs" /* Navigation tabs */ - | "toc" /* Table of contents */ - | "top" /* Back-to-top button */ - -/** - * Component - * - * @template T - Component type - * @template U - Reference type - */ -export type Component< - T extends {} = {}, - U extends HTMLElement = HTMLElement -> = - T & { - ref: U /* Component reference */ - } - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Component type map - */ -interface ComponentTypeMap { - "announce": HTMLElement /* Announcement bar */ - "container": HTMLElement /* Container */ - "content": HTMLElement /* Content */ - "dialog": HTMLElement /* Dialog */ - "header": HTMLElement /* Header */ - "header-title": HTMLElement /* Header title */ - "header-topic": HTMLElement /* Header topic */ - "main": HTMLElement /* Main area */ - "palette": HTMLElement /* Color palette */ - "search": HTMLElement /* Search */ - "search-query": HTMLInputElement /* Search input */ - "search-result": HTMLElement /* Search results */ - "search-share": HTMLAnchorElement /* Search sharing */ - "search-suggest": HTMLElement /* Search suggestions */ - "sidebar": HTMLElement /* Sidebar */ - "skip": HTMLAnchorElement /* Skip link */ - "source": HTMLAnchorElement /* Repository information */ - "tabs": HTMLElement /* Navigation tabs */ - "toc": HTMLElement /* Table of contents */ - "top": HTMLAnchorElement /* Back-to-top button */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the element for a given component or throw a reference error - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Element - */ -export function getComponentElement<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T] { - return getElementOrThrow(`[data-md-component=${type}]`, node) -} - -/** - * Retrieve all elements for a given component - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Elements - */ -export function getComponentElements<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T][] { - return getElements(`[data-md-component=${type}]`, node) -} diff --git a/docs/src/assets/javascripts/components/content/_/index.ts b/docs/src/assets/javascripts/components/content/_/index.ts deleted file mode 100644 index ddd1504a..00000000 --- a/docs/src/assets/javascripts/components/content/_/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, merge } from "rxjs" - -import { Viewport, getElements } from "~/browser" - -import { Component } from "../../_" -import { CodeBlock, mountCodeBlock } from "../code" -import { Details, mountDetails } from "../details" -import { DataTable, mountDataTable } from "../table" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Content - */ -export type Content = - | CodeBlock - | DataTable - | Details - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - target$: Observable<HTMLElement> /* Location target observable */ - viewport$: Observable<Viewport> /* Viewport observable */ - print$: Observable<void> /* Print mode observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount content - * - * This function mounts all components that are found in the content of the - * actual article, including code blocks, data tables and details. - * - * @param el - Content element - * @param options - Options - * - * @returns Content component observable - */ -export function mountContent( - el: HTMLElement, { target$, viewport$, print$ }: MountOptions -): Observable<Component<Content>> { - return merge( - - /* Code blocks */ - ...getElements("pre > code", el) - .map(child => mountCodeBlock(child, { viewport$ })), - - /* Data tables */ - ...getElements("table:not([class])", el) - .map(child => mountDataTable(child)), - - /* Details */ - ...getElements("details", el) - .map(child => mountDetails(child, { target$, print$ })) - ) -} diff --git a/docs/src/assets/javascripts/components/content/code/index.ts b/docs/src/assets/javascripts/components/content/code/index.ts deleted file mode 100644 index 142eb520..00000000 --- a/docs/src/assets/javascripts/components/content/code/index.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import ClipboardJS from "clipboard" -import { - NEVER, - Observable, - Subject, - fromEvent, - merge, - of -} from "rxjs" -import { - distinctUntilKeyChanged, - finalize, - map, - switchMap, - tap, - withLatestFrom -} from "rxjs/operators" - -import { resetFocusable, setFocusable } from "~/actions" -import { - Viewport, - getElementContentSize, - getElementSize, - getElements, - watchMedia -} from "~/browser" -import { renderClipboardButton } from "~/templates" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Code block - */ -export interface CodeBlock { - scroll: boolean /* Code block overflows */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Global index for Clipboard.js integration - */ -let index = 0 - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch code block - * - * This function monitors size changes of the viewport, as well as switches of - * content tabs with embedded code blocks, as both may trigger overflow. - * - * @param el - Code block element - * @param options - Options - * - * @returns Code block observable - */ -export function watchCodeBlock( - el: HTMLElement, { viewport$ }: WatchOptions -): Observable<CodeBlock> { - const container$ = of(el) - .pipe( - switchMap(child => { - const container = child.closest("[data-tabs]") - if (container instanceof HTMLElement) { - return merge( - ...getElements("input", container) - .map(input => fromEvent(input, "change")) - ) - } - return NEVER - }) - ) - - /* Check overflow on resize and tab change */ - return merge( - viewport$.pipe(distinctUntilKeyChanged("size")), - container$ - ) - .pipe( - map(() => { - const visible = getElementSize(el) - const content = getElementContentSize(el) - return { - scroll: content.width > visible.width - } - }), - distinctUntilKeyChanged("scroll") - ) -} - -/** - * Mount code block - * - * This function ensures that an overflowing code block is focusable through - * keyboard, so it can be scrolled without a mouse to improve on accessibility. - * - * @param el - Code block element - * @param options - Options - * - * @returns Code block component observable - */ -export function mountCodeBlock( - el: HTMLElement, options: MountOptions -): Observable<Component<CodeBlock>> { - const internal$ = new Subject<CodeBlock>() - internal$ - .pipe( - withLatestFrom(watchMedia("(hover)")) - ) - .subscribe(([{ scroll }, hover]) => { - if (scroll && hover) - setFocusable(el) - else - resetFocusable(el) - }) - - /* Render button for Clipboard.js integration */ - if (ClipboardJS.isSupported()) { - const parent = el.closest("pre")! - parent.id = `__code_${index++}` - parent.insertBefore( - renderClipboardButton(parent.id), - el - ) - } - - /* Create and return component */ - return watchCodeBlock(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/content/details/index.ts b/docs/src/assets/javascripts/components/content/details/index.ts deleted file mode 100644 index 94fc6b02..00000000 --- a/docs/src/assets/javascripts/components/content/details/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, Subject } from "rxjs" -import { - filter, - finalize, - map, - mapTo, - mergeWith, - tap -} from "rxjs/operators" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Details - */ -export interface Details { - scroll?: boolean /* Scroll into view */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - target$: Observable<HTMLElement> /* Location target observable */ - print$: Observable<void> /* Print mode observable */ -} - -/** - * Mount options - */ -interface MountOptions { - target$: Observable<HTMLElement> /* Location target observable */ - print$: Observable<void> /* Print mode observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch details - * - * @param el - Details element - * @param options - Options - * - * @returns Details observable - */ -export function watchDetails( - el: HTMLDetailsElement, { target$, print$ }: WatchOptions -): Observable<Details> { - return target$ - .pipe( - map(target => target.closest("details:not([open])")!), - filter(details => el === details), - mapTo({ scroll: true }), - mergeWith(print$.pipe(mapTo({}))) - ) -} - -/** - * Mount details - * - * This function ensures that `details` tags are opened on anchor jumps and - * prior to printing, so the whole content of the page is visible. - * - * @param el - Details element - * @param options - Options - * - * @returns Details component observable - */ -export function mountDetails( - el: HTMLDetailsElement, options: MountOptions -): Observable<Component<Details>> { - const internal$ = new Subject<Details>() - internal$.subscribe(({ scroll }) => { - el.setAttribute("open", "") - if (scroll) - el.scrollIntoView() - }) - - /* Create and return component */ - return watchDetails(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - mapTo({ ref: el }) - ) -} diff --git a/docs/src/assets/javascripts/components/content/index.ts b/docs/src/assets/javascripts/components/content/index.ts deleted file mode 100644 index 5d1f2f32..00000000 --- a/docs/src/assets/javascripts/components/content/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./code" -export * from "./details" -export * from "./table" diff --git a/docs/src/assets/javascripts/components/content/table/index.ts b/docs/src/assets/javascripts/components/content/table/index.ts deleted file mode 100644 index 0066f338..00000000 --- a/docs/src/assets/javascripts/components/content/table/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, of } from "rxjs" - -import { replaceElement } from "~/browser" -import { renderTable } from "~/templates" -import { h } from "~/utilities" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Data table - */ -export interface DataTable {} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Sentinel for replacement - */ -const sentinel = h("table") - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount data table - * - * This function wraps a data table in another scrollable container, so it can - * be smoothly scrolled on smaller screen sizes and won't break the layout. - * - * @param el - Data table element - * - * @returns Data table component observable - */ -export function mountDataTable( - el: HTMLElement -): Observable<Component<DataTable>> { - replaceElement(el, sentinel) - replaceElement(sentinel, renderTable(el)) - - /* Create and return component */ - return of({ ref: el }) -} diff --git a/docs/src/assets/javascripts/components/dialog/index.ts b/docs/src/assets/javascripts/components/dialog/index.ts deleted file mode 100644 index bad32614..00000000 --- a/docs/src/assets/javascripts/components/dialog/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - merge, - of -} from "rxjs" -import { - delay, - finalize, - map, - observeOn, - switchMap, - tap -} from "rxjs/operators" - -import { - resetDialogState, - setDialogMessage, - setDialogState -} from "~/actions" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Dialog - */ -export interface Dialog { - message: string /* Dialog message */ - open: boolean /* Dialog is visible */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - alert$: Subject<string> /* Alert subject */ -} - -/** - * Mount options - */ -interface MountOptions { - alert$: Subject<string> /* Alert subject */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch dialog - * - * @param _el - Dialog element - * @param options - Options - * - * @returns Dialog observable - */ -export function watchDialog( - _el: HTMLElement, { alert$ }: WatchOptions -): Observable<Dialog> { - return alert$ - .pipe( - switchMap(message => merge( - of(true), - of(false).pipe(delay(2000)) - ) - .pipe( - map(open => ({ message, open })) - ) - ) - ) -} - -/** - * Mount dialog - * - * This function reveals the dialog in the right cornerwhen a new alert is - * emitted through the subject that is passed as part of the options. - * - * @param el - Dialog element - * @param options - Options - * - * @returns Dialog component observable - */ -export function mountDialog( - el: HTMLElement, options: MountOptions -): Observable<Component<Dialog>> { - const internal$ = new Subject<Dialog>() - internal$ - .pipe( - observeOn(animationFrameScheduler) - ) - .subscribe(({ message, open }) => { - setDialogMessage(el, message) - if (open) - setDialogState(el, "open") - else - resetDialogState(el) - }) - - /* Create and return component */ - return watchDialog(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/header/_/index.ts b/docs/src/assets/javascripts/components/header/_/index.ts deleted file mode 100644 index 4a5275ba..00000000 --- a/docs/src/assets/javascripts/components/header/_/index.ts +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest, - defer, - of -} from "rxjs" -import { - bufferCount, - combineLatestWith, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - map, - observeOn, - shareReplay, - startWith, - switchMap -} from "rxjs/operators" - -import { feature } from "~/_" -import { resetHeaderState, setHeaderState } from "~/actions" -import { - Viewport, - watchElementSize, - watchToggle -} from "~/browser" - -import { Component } from "../../_" -import { Main } from "../../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Header - */ -export interface Header { - height: number /* Header visible height */ - sticky: boolean /* Header stickyness */ - hidden: boolean /* User scrolled past threshold */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Compute whether the header is hidden - * - * If the user scrolls past a certain threshold, the header can be hidden when - * scrolling down, and shown when scrolling up. - * - * @param options - Options - * - * @returns Toggle observable - */ -function isHidden({ viewport$ }: WatchOptions): Observable<boolean> { - if (!feature("header.autohide")) - return of(false) - - /* Compute direction and turning point */ - const direction$ = viewport$ - .pipe( - map(({ offset: { y } }) => y), - bufferCount(2, 1), - map(([a, b]) => [a < b, b] as const), - distinctUntilKeyChanged(0) - ) - - /* Compute whether header should be hidden */ - const hidden$ = combineLatest([viewport$, direction$]) - .pipe( - filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100), - map(([, [direction]]) => direction), - distinctUntilChanged() - ) - - /* Compute threshold for hiding */ - const search$ = watchToggle("search") - return combineLatest([viewport$, search$]) - .pipe( - map(([{ offset }, search]) => offset.y > 400 && !search), - distinctUntilChanged(), - switchMap(active => active ? hidden$ : of(false)), - startWith(false) - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch header - * - * @param el - Header element - * @param options - Options - * - * @returns Header observable - */ -export function watchHeader( - el: HTMLElement, options: WatchOptions -): Observable<Header> { - return defer(() => { - const styles = getComputedStyle(el) - return of( - styles.position === "sticky" || - styles.position === "-webkit-sticky" - ) - }) - .pipe( - combineLatestWith(watchElementSize(el), isHidden(options)), - map(([sticky, { height }, hidden]) => ({ - height: sticky ? height : 0, - sticky, - hidden - })), - distinctUntilChanged((a, b) => ( - a.sticky === b.sticky && - a.height === b.height && - a.hidden === b.hidden - )), - shareReplay(1) - ) -} - -/** - * Mount header - * - * This function manages the different states of the header, i.e. whether it's - * hidden or rendered with a shadow. This depends heavily on the main area. - * - * @param el - Header element - * @param options - Options - * - * @returns Header component observable - */ -export function mountHeader( - el: HTMLElement, { header$, main$ }: MountOptions -): Observable<Component<Header>> { - const internal$ = new Subject<Main>() - internal$ - .pipe( - distinctUntilKeyChanged("active"), - combineLatestWith(header$), - observeOn(animationFrameScheduler) - ) - .subscribe(([{ active }, { hidden }]) => { - if (active) - setHeaderState(el, hidden ? "hidden" : "shadow") - else - resetHeaderState(el) - }) - - /* Connect to long-living subject and return component */ - main$.subscribe(main => internal$.next(main)) - return header$ - .pipe( - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/header/index.ts b/docs/src/assets/javascripts/components/header/index.ts deleted file mode 100644 index e98ef06a..00000000 --- a/docs/src/assets/javascripts/components/header/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./title" diff --git a/docs/src/assets/javascripts/components/header/title/index.ts b/docs/src/assets/javascripts/components/header/title/index.ts deleted file mode 100644 index 98283602..00000000 --- a/docs/src/assets/javascripts/components/header/title/index.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - Subject, - animationFrameScheduler -} from "rxjs" -import { - distinctUntilKeyChanged, - finalize, - map, - observeOn, - tap -} from "rxjs/operators" - -import { - resetHeaderTitleState, - setHeaderTitleState -} from "~/actions" -import { - Viewport, - getElement, - getElementSize, - watchViewportAt -} from "~/browser" - -import { Component } from "../../_" -import { Header } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Header - */ -export interface HeaderTitle { - active: boolean /* User scrolled past first headline */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch header title - * - * @param el - Heading element - * @param options - Options - * - * @returns Header title observable - */ -export function watchHeaderTitle( - el: HTMLHeadingElement, { viewport$, header$ }: WatchOptions -): Observable<HeaderTitle> { - return watchViewportAt(el, { header$, viewport$ }) - .pipe( - map(({ offset: { y } }) => { - const { height } = getElementSize(el) - return { - active: y >= height - } - }), - distinctUntilKeyChanged("active") - ) -} - -/** - * Mount header title - * - * This function swaps the header title from the site title to the title of the - * current page when the user scrolls past the first headline. - * - * @param el - Header title element - * @param options - Options - * - * @returns Header title component observable - */ -export function mountHeaderTitle( - el: HTMLElement, options: MountOptions -): Observable<Component<HeaderTitle>> { - const internal$ = new Subject<HeaderTitle>() - internal$ - .pipe( - observeOn(animationFrameScheduler) - ) - .subscribe(({ active }) => { - if (active) - setHeaderTitleState(el, "active") - else - resetHeaderTitleState(el) - }) - - /* Obtain headline, if any */ - const headline = getElement<HTMLHeadingElement>("article h1") - if (typeof headline === "undefined") - return NEVER - - /* Create and return component */ - return watchHeaderTitle(headline, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/index.ts b/docs/src/assets/javascripts/components/index.ts deleted file mode 100644 index 7f42bc38..00000000 --- a/docs/src/assets/javascripts/components/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./content" -export * from "./dialog" -export * from "./header" -export * from "./main" -export * from "./palette" -export * from "./search" -export * from "./sidebar" -export * from "./source" -export * from "./tabs" -export * from "./toc" -export * from "./top" diff --git a/docs/src/assets/javascripts/components/main/index.ts b/docs/src/assets/javascripts/components/main/index.ts deleted file mode 100644 index aac74e07..00000000 --- a/docs/src/assets/javascripts/components/main/index.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - combineLatest -} from "rxjs" -import { - distinctUntilChanged, - distinctUntilKeyChanged, - map, - switchMap -} from "rxjs/operators" - -import { Viewport, watchElementSize } from "~/browser" - -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Main area - */ -export interface Main { - offset: number /* Main area top offset */ - height: number /* Main area visible height */ - active: boolean /* User scrolled past header */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch main area - * - * This function returns an observable that computes the visual parameters of - * the main area which depends on the viewport vertical offset and height, as - * well as the height of the header element, if the header is fixed. - * - * @param el - Main area element - * @param options - Options - * - * @returns Main area observable - */ -export function watchMain( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<Main> { - - /* Compute necessary adjustment for header */ - const adjust$ = header$ - .pipe( - map(({ height }) => height), - distinctUntilChanged() - ) - - /* Compute the main area's top and bottom borders */ - const border$ = adjust$ - .pipe( - switchMap(() => watchElementSize(el) - .pipe( - map(({ height }) => ({ - top: el.offsetTop, - bottom: el.offsetTop + height - })), - distinctUntilKeyChanged("bottom") - ) - ) - ) - - /* Compute the main area's offset, visible height and if we scrolled past */ - return combineLatest([adjust$, border$, viewport$]) - .pipe( - map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => { - height = Math.max(0, height - - Math.max(0, top - y, header) - - Math.max(0, height + y - bottom) - ) - return { - offset: top - header, - height, - active: top - header <= y - } - }), - distinctUntilChanged((a, b) => ( - a.offset === b.offset && - a.height === b.height && - a.active === b.active - )) - ) -} diff --git a/docs/src/assets/javascripts/components/palette/index.ts b/docs/src/assets/javascripts/components/palette/index.ts deleted file mode 100644 index 100377f9..00000000 --- a/docs/src/assets/javascripts/components/palette/index.ts +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - fromEvent, - of -} from "rxjs" -import { - finalize, - map, - mapTo, - mergeMap, - shareReplay, - startWith, - tap -} from "rxjs/operators" - -import { getElements } from "~/browser" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Palette colors - */ -export interface PaletteColor { - scheme?: string /* Color scheme */ - primary?: string /* Primary color */ - accent?: string /* Accent color */ -} - -/** - * Palette - */ -export interface Palette { - index: number /* Palette index */ - color: PaletteColor /* Palette colors */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch color palette - * - * @param inputs - Color palette element - * - * @returns Color palette observable - */ -export function watchPalette( - inputs: HTMLInputElement[] -): Observable<Palette> { - const data = localStorage.getItem(__prefix("__palette"))! - const current = JSON.parse(data) || { - index: inputs.findIndex(input => ( - matchMedia(input.getAttribute("data-md-color-media")!).matches - )) - } - - /* Emit changes in color palette */ - const palette$ = of(...inputs) - .pipe( - mergeMap(input => fromEvent(input, "change") - .pipe( - mapTo(input) - ) - ), - startWith(inputs[Math.max(0, current.index)]), - map(input => ({ - index: inputs.indexOf(input), - color: { - scheme: input.getAttribute("data-md-color-scheme"), - primary: input.getAttribute("data-md-color-primary"), - accent: input.getAttribute("data-md-color-accent") - } - } as Palette)), - shareReplay(1) - ) - - /* Persist preference in local storage */ - palette$.subscribe(palette => { - localStorage.setItem(__prefix("__palette"), JSON.stringify(palette)) - }) - - /* Return palette */ - return palette$ -} - -/** - * Mount color palette - * - * @param el - Color palette element - * - * @returns Color palette component observable - */ -export function mountPalette( - el: HTMLElement -): Observable<Component<Palette>> { - const internal$ = new Subject<Palette>() - - /* Set color palette */ - internal$.subscribe(palette => { - for (const [key, value] of Object.entries(palette.color)) - if (typeof value === "string") - document.body.setAttribute(`data-md-color-${key}`, value) - - /* Toggle visibility */ - for (let index = 0; index < inputs.length; index++) { - const label = inputs[index].nextElementSibling - if (label instanceof HTMLElement) - label.hidden = palette.index !== index - } - }) - - /* Create and return component */ - const inputs = getElements<HTMLInputElement>("input", el) - return watchPalette(inputs) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/_/index.ts b/docs/src/assets/javascripts/components/search/_/index.ts deleted file mode 100644 index 43d93836..00000000 --- a/docs/src/assets/javascripts/components/search/_/index.ts +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { NEVER, Observable, ObservableInput, merge } from "rxjs" -import { filter, mergeWith, sample, take } from "rxjs/operators" - -import { configuration } from "~/_" -import { - Keyboard, - getActiveElement, - getElements, - setElementFocus, - setElementSelection, - setToggle -} from "~/browser" -import { - SearchIndex, - SearchResult, - isSearchQueryMessage, - isSearchReadyMessage, - setupSearchWorker -} from "~/integrations" - -import { - Component, - getComponentElement, - getComponentElements -} from "../../_" -import { SearchQuery, mountSearchQuery } from "../query" -import { mountSearchResult } from "../result" -import { SearchShare, mountSearchShare } from "../share" -import { SearchSuggest, mountSearchSuggest } from "../suggest" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search - */ -export type Search = - | SearchQuery - | SearchResult - | SearchShare - | SearchSuggest - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - index$: ObservableInput<SearchIndex> /* Search index observable */ - keyboard$: Observable<Keyboard> /* Keyboard observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search - * - * This function sets up the search functionality, including the underlying - * web worker and all keyboard bindings. - * - * @param el - Search element - * @param options - Options - * - * @returns Search component observable - */ -export function mountSearch( - el: HTMLElement, { index$, keyboard$ }: MountOptions -): Observable<Component<Search>> { - const config = configuration() - try { - const url = __search?.worker || config.search - const worker = setupSearchWorker(url, index$) - - /* Retrieve query and result components */ - const query = getComponentElement("search-query", el) - const result = getComponentElement("search-result", el) - - /* Re-emit query when search is ready */ - const { tx$, rx$ } = worker - tx$ - .pipe( - filter(isSearchQueryMessage), - sample(rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - ) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Set up search keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "search") - ) - .subscribe(key => { - const active = getActiveElement() - switch (key.type) { - - /* Enter: go to first (best) result */ - case "Enter": - if (active === query) { - const anchors = new Map<HTMLAnchorElement, number>() - for (const anchor of getElements<HTMLAnchorElement>( - ":first-child [href]", result - )) { - const article = anchor.firstElementChild! - anchors.set(anchor, parseFloat( - article.getAttribute("data-md-score")! - )) - } - - /* Go to result with highest score, if any */ - if (anchors.size) { - const [[best]] = [...anchors].sort(([, a], [, b]) => b - a) - best.click() - } - - /* Otherwise omit form submission */ - key.claim() - } - break - - /* Escape or Tab: close search */ - case "Escape": - case "Tab": - setToggle("search", false) - setElementFocus(query, false) - break - - /* Vertical arrows: select previous or next search result */ - case "ArrowUp": - case "ArrowDown": - if (typeof active === "undefined") { - setElementFocus(query) - } else { - const els = [query, ...getElements( - ":not(details) > [href], summary, details[open] [href]", - result - )] - const i = Math.max(0, ( - Math.max(0, els.indexOf(active)) + els.length + ( - key.type === "ArrowUp" ? -1 : +1 - ) - ) % els.length) - setElementFocus(els[i]) - } - - /* Prevent scrolling of page */ - key.claim() - break - - /* All other keys: hand to search query */ - default: - if (query !== getActiveElement()) - setElementFocus(query) - } - }) - - /* Set up global keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "global"), - ) - .subscribe(key => { - switch (key.type) { - - /* Open search and select query */ - case "f": - case "s": - case "/": - setElementFocus(query) - setElementSelection(query) - key.claim() - break - } - }) - - /* Create and return component */ - const query$ = mountSearchQuery(query, worker) - const result$ = mountSearchResult(result, worker, { query$ }) - return merge(query$, result$) - .pipe( - mergeWith( - - /* Search sharing */ - ...getComponentElements("search-share", el) - .map(child => mountSearchShare(child, { query$ })), - - /* Search suggestions */ - ...getComponentElements("search-suggest", el) - .map(child => mountSearchSuggest(child, worker, { keyboard$ })) - ) - ) - - /* Gracefully handle broken search */ - } catch (err) { - el.hidden = true - return NEVER - } -} diff --git a/docs/src/assets/javascripts/components/search/highlight/.eslintrc b/docs/src/assets/javascripts/components/search/highlight/.eslintrc deleted file mode 100644 index 38a5714d..00000000 --- a/docs/src/assets/javascripts/components/search/highlight/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-null/no-null": "off" - } -} diff --git a/docs/src/assets/javascripts/components/search/highlight/index.ts b/docs/src/assets/javascripts/components/search/highlight/index.ts deleted file mode 100644 index b54deea8..00000000 --- a/docs/src/assets/javascripts/components/search/highlight/index.ts +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - ObservableInput, - combineLatest -} from "rxjs" -import { filter, map, startWith } from "rxjs/operators" - -import { getLocation } from "~/browser" -import { - SearchIndex, - setupSearchHighlighter -} from "~/integrations" -import { h } from "~/utilities" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search highlighting - */ -export interface SearchHighlight { - nodes: Map<ChildNode, string> /* Map of replacements */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - index$: ObservableInput<SearchIndex> /* Search index observable */ - location$: Observable<URL> /* Location observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search highlighting - * - * @param el - Content element - * @param options - Options - * - * @returns Search highlighting component observable - */ -export function mountSearchHiglight( - el: HTMLElement, { index$, location$ }: MountOptions -): Observable<Component<SearchHighlight>> { - return combineLatest([ - index$, - location$ - .pipe( - startWith(getLocation()), - filter(url => url.searchParams.has("h")) - ) - ]) - .pipe( - map(([index, url]) => setupSearchHighlighter(index.config, true)( - url.searchParams.get("h")! - )), - map(fn => { - const nodes = new Map<ChildNode, string>() - - /* Traverse text nodes and collect matches */ - const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT) - for (let node = it.nextNode(); node; node = it.nextNode()) { - if (node.parentElement?.offsetHeight) { - const original = node.textContent! - const replaced = fn(original) - if (replaced.length > original.length) - nodes.set(node as ChildNode, replaced) - } - } - - /* Replace original nodes with matches */ - for (const [node, text] of nodes) { - const { childNodes } = h("span", null, text) - node.replaceWith(...Array.from(childNodes)) - } - - /* Return component */ - return { ref: el, nodes } - }) - ) -} diff --git a/docs/src/assets/javascripts/components/search/index.ts b/docs/src/assets/javascripts/components/search/index.ts deleted file mode 100644 index 074d324b..00000000 --- a/docs/src/assets/javascripts/components/search/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./highlight" -export * from "./query" -export * from "./result" -export * from "./share" -export * from "./suggest" diff --git a/docs/src/assets/javascripts/components/search/query/index.ts b/docs/src/assets/javascripts/components/search/query/index.ts deleted file mode 100644 index 0241983d..00000000 --- a/docs/src/assets/javascripts/components/search/query/index.ts +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - combineLatest, - fromEvent, - merge -} from "rxjs" -import { - delay, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - finalize, - map, - take, - takeLast, - takeUntil, - tap -} from "rxjs/operators" - -import { - resetSearchQueryPlaceholder, - setSearchQueryPlaceholder -} from "~/actions" -import { - getLocation, - setElementFocus, - setToggle, - watchElementFocus -} from "~/browser" -import { - SearchMessageType, - SearchQueryMessage, - SearchWorker, - defaultTransform, - isSearchReadyMessage -} from "~/integrations" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search query - */ -export interface SearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch search query - * - * Note that the focus event which triggers re-reading the current query value - * is delayed by `1ms` so the input's empty state is allowed to propagate. - * - * @param el - Search query element - * @param worker - Search worker - * - * @returns Search query observable - */ -export function watchSearchQuery( - el: HTMLInputElement, { rx$ }: SearchWorker -): Observable<SearchQuery> { - const fn = __search?.transform || defaultTransform - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)) - ) - .pipe( - map(() => fn(el.value)), - distinctUntilChanged() - ) - - /* Intercept deep links */ - const location = getLocation() - if (location.searchParams.has("q")) { - setToggle("search", true) - rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - .subscribe(() => { - el.value = location.searchParams.get("q")! - setElementFocus(el) - }) - } - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ value, focus })) - ) -} - -/** - * Mount search query - * - * @param el - Search query element - * @param worker - Search worker - * - * @returns Search query component observable - */ -export function mountSearchQuery( - el: HTMLInputElement, { tx$, rx$ }: SearchWorker -): Observable<Component<SearchQuery, HTMLInputElement>> { - const internal$ = new Subject<SearchQuery>() - - /* Handle value changes */ - internal$ - .pipe( - distinctUntilKeyChanged("value"), - map(({ value }): SearchQueryMessage => ({ - type: SearchMessageType.QUERY, - data: value - })) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Handle focus changes */ - internal$ - .pipe( - distinctUntilKeyChanged("focus") - ) - .subscribe(({ focus }) => { - if (focus) { - setToggle("search", focus) - setSearchQueryPlaceholder(el, "") - } else { - resetSearchQueryPlaceholder(el) - } - }) - - /* Handle reset */ - fromEvent(el.form!, "reset") - .pipe( - takeUntil(internal$.pipe(takeLast(1))) - ) - .subscribe(() => setElementFocus(el)) - - /* Create and return component */ - return watchSearchQuery(el, { tx$, rx$ }) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/result/index.ts b/docs/src/assets/javascripts/components/search/result/index.ts deleted file mode 100644 index 4b91e3aa..00000000 --- a/docs/src/assets/javascripts/components/search/result/index.ts +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - merge, - of -} from "rxjs" -import { - bufferCount, - filter, - finalize, - map, - observeOn, - switchMap, - take, - tap, - withLatestFrom, - zipWith -} from "rxjs/operators" - -import { - addToSearchResultList, - resetSearchResultList, - resetSearchResultMeta, - setSearchResultMeta -} from "~/actions" -import { - getElementOrThrow, - watchElementThreshold -} from "~/browser" -import { - SearchResult, - SearchWorker, - isSearchReadyMessage, - isSearchResultMessage -} from "~/integrations" -import { renderSearchResultItem } from "~/templates" - -import { Component } from "../../_" -import { SearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - query$: Observable<SearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search result list - * - * This function performs a lazy rendering of the search results, depending on - * the vertical offset of the search result container. - * - * @param el - Search result list element - * @param worker - Search worker - * @param options - Options - * - * @returns Search result list component observable - */ -export function mountSearchResult( - el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions -): Observable<Component<SearchResult>> { - const internal$ = new Subject<SearchResult>() - const boundary$ = watchElementThreshold(el.parentElement!) - .pipe( - filter(Boolean) - ) - - /* Retrieve nested components */ - const meta = getElementOrThrow(":scope > :first-child", el) - const list = getElementOrThrow(":scope > :last-child", el) - - /* Update search result metadata when ready */ - rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - .subscribe(() => { - resetSearchResultMeta(meta) - }) - - /* Update search result metadata */ - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(query$) - ) - .subscribe(([{ items }, { value }]) => { - if (value) - setSearchResultMeta(meta, items.length) - else - resetSearchResultMeta(meta) - }) - - /* Update search result list */ - internal$ - .pipe( - observeOn(animationFrameScheduler), - tap(() => resetSearchResultList(list)), - switchMap(({ items }) => merge( - of(...items.slice(0, 10)), - of(...items.slice(10)) - .pipe( - bufferCount(4), - zipWith(boundary$), - switchMap(([chunk]) => of(...chunk)) - ) - )) - ) - .subscribe(result => { - addToSearchResultList(list, renderSearchResultItem(result)) - }) - - /* Filter search result message */ - const result$ = rx$ - .pipe( - filter(isSearchResultMessage), - map(({ data }) => data) - ) - - /* Create and return component */ - return result$ - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/share/index.ts b/docs/src/assets/javascripts/components/search/share/index.ts deleted file mode 100644 index 67056b77..00000000 --- a/docs/src/assets/javascripts/components/search/share/index.ts +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - fromEvent -} from "rxjs" -import { - finalize, - map, - tap -} from "rxjs/operators" - -import { getLocation } from "~/browser" - -import { Component } from "../../_" -import { SearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search sharing - */ -export interface SearchShare { - url: URL /* Deep link for sharing */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - query$: Observable<SearchQuery> /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - query$: Observable<SearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search sharing - * - * @param _el - Search sharing element - * @param options - Options - * - * @returns Search sharing observable - */ -export function watchSearchShare( - _el: HTMLElement, { query$ }: WatchOptions -): Observable<SearchShare> { - return query$ - .pipe( - map(({ value }) => { - const url = getLocation() - url.hash = "" - url.searchParams.delete("h") - url.searchParams.set("q", value) - return { url } - }) - ) -} - -/** - * Mount search sharing - * - * @param el - Search sharing element - * @param options - Options - * - * @returns Search sharing component observable - */ -export function mountSearchShare( - el: HTMLAnchorElement, options: MountOptions -): Observable<Component<SearchShare>> { - const internal$ = new Subject<SearchShare>() - internal$.subscribe(({ url }) => { - el.setAttribute("data-clipboard-text", el.href) - el.href = `${url}` - }) - - /* Prevent following of link */ - fromEvent(el, "click") - .subscribe(ev => ev.preventDefault()) - - /* Create and return component */ - return watchSearchShare(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/suggest/index.ts b/docs/src/assets/javascripts/components/search/suggest/index.ts deleted file mode 100644 index b743e547..00000000 --- a/docs/src/assets/javascripts/components/search/suggest/index.ts +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - asyncScheduler, - fromEvent -} from "rxjs" -import { - combineLatestWith, - distinctUntilChanged, - filter, - finalize, - map, - observeOn, - tap -} from "rxjs/operators" - -import { Keyboard } from "~/browser" -import { - SearchResult, - SearchWorker, - isSearchResultMessage -} from "~/integrations" - -import { Component, getComponentElement } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search suggestions - */ -export interface SearchSuggest {} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - keyboard$: Observable<Keyboard> /* Keyboard observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search suggestions - * - * This function will perform a lazy rendering of the search results, depending - * on the vertical offset of the search result container. - * - * @param el - Search result list element - * @param worker - Search worker - * @param options - Options - * - * @returns Search result list component observable - */ -export function mountSearchSuggest( - el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions -): Observable<Component<SearchSuggest>> { - const internal$ = new Subject<SearchResult>() - - /* Retrieve query component and track all changes */ - const query = getComponentElement("search-query") - const query$ = fromEvent(query, "keydown") - .pipe( - observeOn(asyncScheduler), - map(() => query.value), - distinctUntilChanged(), - ) - - /* Update search suggestions */ - internal$ - .pipe( - combineLatestWith(query$), - map(([{ suggestions }, value]) => { - const words = value.split(/([\s-]+)/) - if (suggestions?.length && words[words.length - 1]) { - const last = suggestions[suggestions.length - 1] - if (last.startsWith(words[words.length - 1])) - words[words.length - 1] = last - } else { - words.length = 0 - } - return words - }) - ) - .subscribe(words => el.innerHTML = words - .join("") - .replace(/\s/g, "&nbsp;") - ) - - /* Set up search keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "search") - ) - .subscribe(key => { - switch (key.type) { - - /* Right arrow: accept current suggestion */ - case "ArrowRight": - if ( - el.innerText.length && - query.selectionStart === query.value.length - ) - query.value = el.innerText - break - } - }) - - /* Filter search result message */ - const result$ = rx$ - .pipe( - filter(isSearchResultMessage), - map(({ data }) => data) - ) - - /* Create and return component */ - return result$ - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(() => ({ ref: el })) - ) -} diff --git a/docs/src/assets/javascripts/components/sidebar/index.ts b/docs/src/assets/javascripts/components/sidebar/index.ts deleted file mode 100644 index 5be71632..00000000 --- a/docs/src/assets/javascripts/components/sidebar/index.ts +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest -} from "rxjs" -import { - distinctUntilChanged, - finalize, - map, - observeOn, - tap, - withLatestFrom -} from "rxjs/operators" - -import { - resetSidebarHeight, - resetSidebarOffset, - setSidebarHeight, - setSidebarOffset -} from "~/actions" -import { Viewport } from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" -import { Main } from "../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sidebar - */ -export interface Sidebar { - height: number /* Sidebar height */ - locked: boolean /* User scrolled past header */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - main$: Observable<Main> /* Main area observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch sidebar - * - * This function returns an observable that computes the visual parameters of - * the sidebar which depends on the vertical viewport offset, as well as the - * height of the main area. When the page is scrolled beyond the header, the - * sidebar is locked and fills the remaining space. - * - * @param el - Sidebar element - * @param options - Options - * - * @returns Sidebar observable - */ -export function watchSidebar( - el: HTMLElement, { viewport$, main$ }: WatchOptions -): Observable<Sidebar> { - const adjust = - el.parentElement!.offsetTop - - el.parentElement!.parentElement!.offsetTop - - /* Compute the sidebar's available height and if it should be locked */ - return combineLatest([main$, viewport$]) - .pipe( - map(([{ offset, height }, { offset: { y } }]) => { - height = height - + Math.min(adjust, Math.max(0, y - offset)) - - adjust - return { - height, - locked: y >= offset + adjust - } - }), - distinctUntilChanged((a, b) => ( - a.height === b.height && - a.locked === b.locked - )) - ) -} - -/** - * Mount sidebar - * - * @param el - Sidebar element - * @param options - Options - * - * @returns Sidebar component observable - */ -export function mountSidebar( - el: HTMLElement, { header$, ...options }: MountOptions -): Observable<Component<Sidebar>> { - const internal$ = new Subject<Sidebar>() - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(header$) - ) - .subscribe({ - - /* Update height and offset */ - next([{ height }, { height: offset }]) { - setSidebarHeight(el, height) - setSidebarOffset(el, offset) - }, - - /* Reset on complete */ - complete() { - resetSidebarOffset(el) - resetSidebarHeight(el) - } - }) - - /* Create and return component */ - return watchSidebar(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/source/_/index.ts b/docs/src/assets/javascripts/components/source/_/index.ts deleted file mode 100644 index d99549f0..00000000 --- a/docs/src/assets/javascripts/components/source/_/index.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { NEVER, Observable, Subject, defer, of } from "rxjs" -import { - catchError, - filter, - finalize, - map, - shareReplay, - tap -} from "rxjs/operators" - -import { setSourceFacts, setSourceState } from "~/actions" -import { renderSourceFacts } from "~/templates" - -import { Component } from "../../_" -import { SourceFacts, fetchSourceFacts } from "../facts" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Repository information - */ -export interface Source { - facts: SourceFacts /* Repository facts */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Repository information observable - */ -let fetch$: Observable<Source> - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch repository information - * - * This function tries to read the repository facts from session storage, and - * if unsuccessful, fetches them from the underlying provider. - * - * @param el - Repository information element - * - * @returns Repository information observable - */ -export function watchSource( - el: HTMLAnchorElement -): Observable<Source> { - return fetch$ ||= defer(() => { - const data = sessionStorage.getItem(__prefix("__source")) - if (data) { - return of<SourceFacts>(JSON.parse(data)) - } else { - const value$ = fetchSourceFacts(el.href) - value$.subscribe(value => { - try { - sessionStorage.setItem(__prefix("__source"), JSON.stringify(value)) - } catch (err) { - /* Uncritical, just swallow */ - } - }) - - /* Return value */ - return value$ - } - }) - .pipe( - catchError(() => NEVER), - filter(facts => Object.keys(facts).length > 0), - map(facts => ({ facts })), - shareReplay(1) - ) -} - -/** - * Mount repository information - * - * @param el - Repository information element - * - * @returns Repository information component observable - */ -export function mountSource( - el: HTMLAnchorElement -): Observable<Component<Source>> { - const internal$ = new Subject<Source>() - internal$.subscribe(({ facts }) => { - setSourceFacts(el, renderSourceFacts(facts)) - setSourceState(el, "done") - }) - - /* Create and return component */ - return watchSource(el) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/source/facts/_/index.ts b/docs/src/assets/javascripts/components/source/facts/_/index.ts deleted file mode 100644 index 10ca37ba..00000000 --- a/docs/src/assets/javascripts/components/source/facts/_/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { NEVER, Observable } from "rxjs" - -import { fetchSourceFactsFromGitHub } from "../github" -import { fetchSourceFactsFromGitLab } from "../gitlab" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Repository facts for repositories - */ -export interface RepositoryFacts { - stars?: number /* Number of stars */ - forks?: number /* Number of forks */ - version?: string /* Latest version */ -} - -/** - * Repository facts for organizations - */ -export interface OrganizationFacts { - repositories?: number /* Number of repositories */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Repository facts - */ -export type SourceFacts = - | RepositoryFacts - | OrganizationFacts - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch repository facts - * - * @param url - Repository URL - * - * @returns Repository facts observable - */ -export function fetchSourceFacts( - url: string -): Observable<SourceFacts> { - const [type] = url.match(/(git(?:hub|lab))/i) || [] - switch (type.toLowerCase()) { - - /* GitHub repository */ - case "github": - const [, user, repo] = url.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i)! - return fetchSourceFactsFromGitHub(user, repo) - - /* GitLab repository */ - case "gitlab": - const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i)! - return fetchSourceFactsFromGitLab(base, slug) - - /* Everything else */ - default: - return NEVER - } -} diff --git a/docs/src/assets/javascripts/components/source/facts/github/index.ts b/docs/src/assets/javascripts/components/source/facts/github/index.ts deleted file mode 100644 index cdf325f4..00000000 --- a/docs/src/assets/javascripts/components/source/facts/github/index.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Repo, User } from "github-types" -import { Observable, zip } from "rxjs" -import { defaultIfEmpty, map } from "rxjs/operators" - -import { requestJSON } from "~/browser" - -import { SourceFacts } from "../_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * GitHub release (partial) - */ -interface Release { - tag_name: string /* Tag name */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch GitHub repository facts - * - * @param user - GitHub user - * @param repo - GitHub repository - * - * @returns Repository facts observable - */ -export function fetchSourceFactsFromGitHub( - user: string, repo?: string -): Observable<SourceFacts> { - if (typeof repo !== "undefined") { - const url = `https://api.github.com/repos/${user}/${repo}` - return zip( - - /* Fetch version */ - requestJSON<Release>(`${url}/releases/latest`) - .pipe( - map(release => ({ - version: release.tag_name - })), - defaultIfEmpty({}) - ), - - /* Fetch stars and forks */ - requestJSON<Repo>(url) - .pipe( - map(info => ({ - stars: info.stargazers_count, - forks: info.forks_count - })), - defaultIfEmpty({}) - ) - ) - .pipe( - map(([release, info]) => ({ ...release, ...info })) - ) - - /* User or organization */ - } else { - const url = `https://api.github.com/repos/${user}` - return requestJSON<User>(url) - .pipe( - map(info => ({ - repositories: info.public_repos - })), - defaultIfEmpty({}) - ) - } -} diff --git a/docs/src/assets/javascripts/components/source/facts/gitlab/index.ts b/docs/src/assets/javascripts/components/source/facts/gitlab/index.ts deleted file mode 100644 index 0d80e2fa..00000000 --- a/docs/src/assets/javascripts/components/source/facts/gitlab/index.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ProjectSchema } from "gitlab" -import { Observable } from "rxjs" -import { defaultIfEmpty, map } from "rxjs/operators" - -import { requestJSON } from "~/browser" - -import { SourceFacts } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch GitLab repository facts - * - * @param base - GitLab base - * @param project - GitLab project - * - * @returns Repository facts observable - */ -export function fetchSourceFactsFromGitLab( - base: string, project: string -): Observable<SourceFacts> { - const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}` - return requestJSON<ProjectSchema>(url) - .pipe( - map(({ star_count, forks_count }) => ({ - stars: star_count, - forks: forks_count - })), - defaultIfEmpty({}) - ) -} diff --git a/docs/src/assets/javascripts/components/source/facts/index.ts b/docs/src/assets/javascripts/components/source/facts/index.ts deleted file mode 100644 index 9d88a9c6..00000000 --- a/docs/src/assets/javascripts/components/source/facts/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./github" -export * from "./gitlab" diff --git a/docs/src/assets/javascripts/components/source/index.ts b/docs/src/assets/javascripts/components/source/index.ts deleted file mode 100644 index 64468ace..00000000 --- a/docs/src/assets/javascripts/components/source/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./facts" diff --git a/docs/src/assets/javascripts/components/tabs/index.ts b/docs/src/assets/javascripts/components/tabs/index.ts deleted file mode 100644 index d925e12e..00000000 --- a/docs/src/assets/javascripts/components/tabs/index.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - of -} from "rxjs" -import { - distinctUntilKeyChanged, - finalize, - map, - observeOn, - switchMap, - tap -} from "rxjs/operators" - -import { feature } from "~/_" -import { resetTabsState, setTabsState } from "~/actions" -import { - Viewport, - watchElementSize, - watchViewportAt -} from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Navigation tabs - */ -export interface Tabs { - hidden: boolean /* User scrolled past tabs */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch navigation tabs - * - * @param el - Navigation tabs element - * @param options - Options - * - * @returns Navigation tabs observable - */ -export function watchTabs( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<Tabs> { - return watchElementSize(document.body) - .pipe( - switchMap(() => watchViewportAt(el, { header$, viewport$ })), - map(({ offset: { y } }) => { - return { - hidden: y >= 10 - } - }), - distinctUntilKeyChanged("hidden") - ) -} - -/** - * Mount navigation tabs - * - * This function hides the navigation tabs when scrolling past the threshold - * and makes them reappear in a nice CSS animation when scrolling back up. - * - * @param el - Navigation tabs element - * @param options - Options - * - * @returns Navigation tabs component observable - */ -export function mountTabs( - el: HTMLElement, options: MountOptions -): Observable<Component<Tabs>> { - const internal$ = new Subject<Tabs>() - internal$ - .pipe( - observeOn(animationFrameScheduler) - ) - .subscribe({ - - /* Update state */ - next({ hidden }) { - if (hidden) - setTabsState(el, "hidden") - else - resetTabsState(el) - }, - - /* Reset on complete */ - complete() { - resetTabsState(el) - } - }) - - /* Create and return component */ - return ( - feature("navigation.tabs.sticky") - ? of({ hidden: false }) - : watchTabs(el, options) - ) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/toc/index.ts b/docs/src/assets/javascripts/components/toc/index.ts deleted file mode 100644 index 6969d70e..00000000 --- a/docs/src/assets/javascripts/components/toc/index.ts +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest -} from "rxjs" -import { - bufferCount, - distinctUntilChanged, - distinctUntilKeyChanged, - finalize, - map, - observeOn, - scan, - startWith, - switchMap, - tap -} from "rxjs/operators" - -import { - resetAnchorActive, - resetAnchorState, - setAnchorActive, - setAnchorState -} from "~/actions" -import { - Viewport, - getElement, - getElements, - watchElementSize -} from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Table of contents - */ -export interface TableOfContents { - prev: HTMLAnchorElement[][] /* Anchors (previous) */ - next: HTMLAnchorElement[][] /* Anchors (next) */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch table of contents - * - * This is effectively a scroll spy implementation which will account for the - * fixed header and automatically re-calculate anchor offsets when the viewport - * is resized. The returned observable will only emit if the table of contents - * needs to be repainted. - * - * This implementation tracks an anchor element's entire path starting from its - * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the - * Material theme currently doesn't make use of this information, it enables - * the styling of the entire hierarchy through customization. - * - * Note that the current anchor is the last item of the `prev` anchor list. - * - * @param anchors - Anchor elements - * @param options - Options - * - * @returns Table of contents observable - */ -export function watchTableOfContents( - anchors: HTMLAnchorElement[], { viewport$, header$ }: WatchOptions -): Observable<TableOfContents> { - const table = new Map<HTMLAnchorElement, HTMLElement>() - for (const anchor of anchors) { - const id = decodeURIComponent(anchor.hash.substring(1)) - const target = getElement(`[id="${id}"]`) - if (typeof target !== "undefined") - table.set(anchor, target) - } - - /* Compute necessary adjustment for header */ - const adjust$ = header$ - .pipe( - map(header => 24 + header.height) - ) - - /* Compute partition of previous and next anchors */ - const partition$ = watchElementSize(document.body) - .pipe( - distinctUntilKeyChanged("height"), - - /* Build index to map anchor paths to vertical offsets */ - map(() => { - let path: HTMLAnchorElement[] = [] - return [...table].reduce((index, [anchor, target]) => { - while (path.length) { - const last = table.get(path[path.length - 1])! - if (last.tagName >= target.tagName) { - path.pop() - } else { - break - } - } - - /* If the current anchor is hidden, continue with its parent */ - let offset = target.offsetTop - while (!offset && target.parentElement) { - target = target.parentElement - offset = target.offsetTop - } - - /* Map reversed anchor path to vertical offset */ - return index.set( - [...path = [...path, anchor]].reverse(), - offset - ) - }, new Map<HTMLAnchorElement[], number>()) - }), - - /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */ - map(index => new Map([...index].sort(([, a], [, b]) => a - b))), - - /* Re-compute partition when viewport offset changes */ - switchMap(index => combineLatest([adjust$, viewport$]) - .pipe( - scan(([prev, next], [adjust, { offset: { y } }]) => { - - /* Look forward */ - while (next.length) { - const [, offset] = next[0] - if (offset - adjust < y) { - prev = [...prev, next.shift()!] - } else { - break - } - } - - /* Look backward */ - while (prev.length) { - const [, offset] = prev[prev.length - 1] - if (offset - adjust >= y) { - next = [prev.pop()!, ...next] - } else { - break - } - } - - /* Return partition */ - return [prev, next] - }, [[], [...index]]), - distinctUntilChanged((a, b) => ( - a[0] === b[0] && - a[1] === b[1] - )) - ) - ) - ) - - /* Compute and return anchor list migrations */ - return partition$ - .pipe( - map(([prev, next]) => ({ - prev: prev.map(([path]) => path), - next: next.map(([path]) => path) - })), - - /* Extract anchor list migrations */ - startWith({ prev: [], next: [] }), - bufferCount(2, 1), - map(([a, b]) => { - - /* Moving down */ - if (a.prev.length < b.prev.length) { - return { - prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length), - next: [] - } - - /* Moving up */ - } else { - return { - prev: b.prev.slice(-1), - next: b.next.slice(0, b.next.length - a.next.length) - } - } - }) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount table of contents - * - * @param el - Anchor list element - * @param options - Options - * - * @returns Table of contents component observable - */ -export function mountTableOfContents( - el: HTMLElement, options: MountOptions -): Observable<Component<TableOfContents>> { - const internal$ = new Subject<TableOfContents>() - internal$ - .pipe( - observeOn(animationFrameScheduler), - ) - .subscribe(({ prev, next }) => { - - /* Look forward */ - for (const [anchor] of next) { - resetAnchorActive(anchor) - resetAnchorState(anchor) - } - - /* Look backward */ - for (const [index, [anchor]] of prev.entries()) { - setAnchorActive(anchor, index === prev.length - 1) - setAnchorState(anchor, "blur") - } - }) - - /* Create and return component */ - const anchors = getElements<HTMLAnchorElement>("[href^=\\#]", el) - return watchTableOfContents(anchors, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/top/index.ts b/docs/src/assets/javascripts/components/top/index.ts deleted file mode 100644 index 9b317f04..00000000 --- a/docs/src/assets/javascripts/components/top/index.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest -} from "rxjs" -import { - bufferCount, - distinctUntilChanged, - distinctUntilKeyChanged, - finalize, - map, - observeOn, - tap, - withLatestFrom -} from "rxjs/operators" - -import { - resetBackToTopOffset, - resetBackToTopState, - resetFocusable, - setBackToTopOffset, - setBackToTopState, - setFocusable -} from "~/actions" -import { Viewport, setElementFocus } from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" -import { Main } from "../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Back-to-top button - */ -export interface BackToTop { - hidden: boolean /* User scrolled up */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch back-to-top - * - * @param _el - Back-to-top element - * @param options - Options - * - * @returns Back-to-top observable - */ -export function watchBackToTop( - _el: HTMLElement, { viewport$, main$ }: WatchOptions -): Observable<BackToTop> { - - /* Compute direction */ - const direction$ = viewport$ - .pipe( - map(({ offset: { y } }) => y), - bufferCount(2, 1), - map(([a, b]) => a > b && b), - distinctUntilChanged() - ) - - /* Compute whether button should be hidden */ - const hidden$ = main$ - .pipe( - distinctUntilKeyChanged("active") - ) - - /* Compute threshold for hiding */ - return combineLatest([hidden$, direction$]) - .pipe( - map(([{ active }, direction]) => ({ - hidden: !(active && direction) - })), - distinctUntilChanged((a, b) => ( - a.hidden === b.hidden - )) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount back-to-top - * - * @param el - Back-to-top element - * @param options - Options - * - * @returns Back-to-top component observable - */ -export function mountBackToTop( - el: HTMLElement, { viewport$, header$, main$ }: MountOptions -): Observable<Component<BackToTop>> { - const internal$ = new Subject<BackToTop>() - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(header$ - .pipe( - distinctUntilKeyChanged("height") - ) - ) - ) - .subscribe({ - - /* Update state */ - next([{ hidden }, { height }]) { - setBackToTopOffset(el, height + 16) - if (hidden) { - setBackToTopState(el, "hidden") - setElementFocus(el, false) - setFocusable(el, -1) - } else { - resetBackToTopState(el) - resetFocusable(el) - } - }, - - /* Reset on complete */ - complete() { - resetBackToTopOffset(el) - resetBackToTopState(el) - resetFocusable(el) - } - }) - - /* Create and return component */ - return watchBackToTop(el, { viewport$, header$, main$ }) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/integrations/clipboard/index.ts b/docs/src/assets/javascripts/integrations/clipboard/index.ts deleted file mode 100644 index e27c2601..00000000 --- a/docs/src/assets/javascripts/integrations/clipboard/index.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import ClipboardJS from "clipboard" -import { Observable, Subject } from "rxjs" - -import { translation } from "~/_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - alert$: Subject<string> /* Alert subject */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up Clipboard.js integration - * - * @param options - Options - */ -export function setupClipboardJS( - { alert$ }: SetupOptions -): void { - if (ClipboardJS.isSupported()) { - new Observable<ClipboardJS.Event>(subscriber => { - new ClipboardJS("[data-clipboard-target], [data-clipboard-text]") - .on("success", ev => subscriber.next(ev)) - }) - .subscribe(() => alert$.next(translation("clipboard.copied"))) - } -} diff --git a/docs/src/assets/javascripts/integrations/index.ts b/docs/src/assets/javascripts/integrations/index.ts deleted file mode 100644 index 6a1e986b..00000000 --- a/docs/src/assets/javascripts/integrations/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./clipboard" -export * from "./instant" -export * from "./search" -export * from "./version" diff --git a/docs/src/assets/javascripts/integrations/instant/.eslintrc b/docs/src/assets/javascripts/integrations/instant/.eslintrc deleted file mode 100644 index 5adf108a..00000000 --- a/docs/src/assets/javascripts/integrations/instant/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-self-assign": "off", - "no-null/no-null": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/instant/index.ts b/docs/src/assets/javascripts/integrations/instant/index.ts deleted file mode 100644 index 63b81ee4..00000000 --- a/docs/src/assets/javascripts/integrations/instant/index.ts +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - EMPTY, - NEVER, - Observable, - Subject, - fromEvent, - merge, - of -} from "rxjs" -import { - bufferCount, - catchError, - concatMap, - debounceTime, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - map, - sample, - share, - skip, - skipUntil, - switchMap -} from "rxjs/operators" - -import { configuration, feature } from "~/_" -import { - Viewport, - ViewportOffset, - getElement, - getElements, - replaceElement, - request, - requestXML, - setLocation, - setLocationHash, - setViewportOffset -} from "~/browser" -import { getComponentElement } from "~/components" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * History state - */ -export interface HistoryState { - url: URL /* State URL */ - offset?: ViewportOffset /* State viewport offset */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - document$: Subject<Document> /* Document subject */ - location$: Subject<URL> /* Location subject */ - viewport$: Observable<Viewport> /* Viewport observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Preprocess a list of URLs - * - * This function replaces the `site_url` in the sitemap with the actual base - * URL, to allow instant loading to work in occasions like Netlify previews. - * - * @param urls - URLs - * - * @returns Processed URLs - */ -function preprocess(urls: string[]): string[] { - if (urls.length < 2) - return urls - - /* Take the first two URLs and remove everything after the last slash */ - const [root, next] = urls - .sort((a, b) => a.length - b.length) - .map(url => url.replace(/[^/]+$/, "")) - - /* Compute common prefix */ - let index = 0 - if (root === next) - index = root.length - else - while (root.charCodeAt(index) === next.charCodeAt(index)) - index++ - - /* Replace common prefix (i.e. base) with effective base */ - const config = configuration() - return urls.map(url => ( - url.replace(root.slice(0, index), config.base) - )) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up instant loading - * - * When fetching, theoretically, we could use `responseType: "document"`, but - * since all MkDocs links are relative, we need to make sure that the current - * location matches the document we just loaded. Otherwise any relative links - * in the document could use the old location. - * - * This is the reason why we need to synchronize history events and the process - * of fetching the document for navigation changes (except `popstate` events): - * - * 1. Fetch document via `XMLHTTPRequest` - * 2. Set new location via `history.pushState` - * 3. Parse and emit fetched document - * - * For `popstate` events, we must not use `history.pushState`, or the forward - * history will be irreversibly overwritten. In case the request fails, the - * location change is dispatched regularly. - * - * @param options - Options - */ -export function setupInstantLoading( - { document$, location$, viewport$ }: SetupOptions -): void { - const config = configuration() - if (location.protocol === "file:") - return - - /* Disable automatic scroll restoration */ - if ("scrollRestoration" in history) { - history.scrollRestoration = "manual" - - /* Hack: ensure that reloads restore viewport offset */ - fromEvent(window, "beforeunload") - .subscribe(() => { - history.scrollRestoration = "auto" - }) - } - - /* Hack: ensure absolute favicon link to omit 404s when switching */ - const favicon = getElement<HTMLLinkElement>("link[rel=icon]") - if (typeof favicon !== "undefined") - favicon.href = favicon.href - - /* Intercept internal navigation */ - const push$ = requestXML(new URL("sitemap.xml", config.base)) - .pipe( - map(sitemap => preprocess(getElements("loc", sitemap) - .map(node => node.textContent!) - )), - switchMap(urls => fromEvent<MouseEvent>(document.body, "click") - .pipe( - filter(ev => !ev.metaKey && !ev.ctrlKey), - switchMap(ev => { - - /* Handle HTML and SVG elements */ - if (ev.target instanceof Element) { - const el = ev.target.closest("a") - if (el && !el.target) { - const url = new URL(el.href) - - /* Canonicalize URL */ - url.search = "" - url.hash = "" - - /* Check if URL should be intercepted */ - if ( - url.pathname !== location.pathname && - urls.includes(url.toString()) - ) { - ev.preventDefault() - return of({ - url: new URL(el.href) - }) - } - } - } - return NEVER - }) - ) - ), - share<HistoryState>() - ) - - /* Intercept history back and forward */ - const pop$ = fromEvent<PopStateEvent>(window, "popstate") - .pipe( - filter(ev => ev.state !== null), - map(ev => ({ - url: new URL(location.href), - offset: ev.state - })), - share<HistoryState>() - ) - - /* Emit location change */ - merge(push$, pop$) - .pipe( - distinctUntilChanged((a, b) => a.url.href === b.url.href), - map(({ url }) => url) - ) - .subscribe(location$) - - /* Fetch document via `XMLHTTPRequest` */ - const response$ = location$ - .pipe( - distinctUntilKeyChanged("pathname"), - switchMap(url => request(url.href) - .pipe( - catchError(() => { - setLocation(url) - return NEVER - }) - ) - ), - share() - ) - - /* Set new location via `history.pushState` */ - push$ - .pipe( - sample(response$) - ) - .subscribe(({ url }) => { - history.pushState({}, "", `${url}`) - }) - - /* Parse and emit fetched document */ - const dom = new DOMParser() - response$ - .pipe( - switchMap(res => res.text()), - map(res => dom.parseFromString(res, "text/html")) - ) - .subscribe(document$) - - /* Replace meta tags and components */ - document$ - .pipe( - skip(1) - ) - .subscribe(replacement => { - for (const selector of [ - - /* Meta tags */ - "title", - "link[rel=canonical]", - "meta[name=author]", - "meta[name=description]", - - /* Components */ - "[data-md-component=announce]", - "[data-md-component=container]", - "[data-md-component=header-topic]", - "[data-md-component=logo], .md-logo", // compat - "[data-md-component=skip]", - ...feature("navigation.tabs.sticky") - ? ["[data-md-component=tabs]"] - : [] - ]) { - const source = getElement(selector) - const target = getElement(selector, replacement) - if ( - typeof source !== "undefined" && - typeof target !== "undefined" - ) { - replaceElement(source, target) - } - } - }) - - /* Re-evaluate scripts */ - document$ - .pipe( - skip(1), - map(() => getComponentElement("container")), - switchMap(el => of(...getElements("script", el))), - concatMap(el => { - const script = h("script") - if (el.src) { - for (const name of el.getAttributeNames()) - script.setAttribute(name, el.getAttribute(name)!) - replaceElement(el, script) - - /* Complete when script is loaded */ - return new Observable(observer => { - script.onload = () => observer.complete() - }) - - /* Complete immediately */ - } else { - script.textContent = el.textContent - replaceElement(el, script) - return EMPTY - } - }) - ) - .subscribe() - - /* Emit history state change */ - merge(push$, pop$) - .pipe( - sample(document$), - ) - .subscribe(({ url, offset }) => { - if (url.hash && !offset) { - setLocationHash(url.hash) - } else { - setViewportOffset(offset || { y: 0 }) - } - }) - - /* Debounce update of viewport offset */ - viewport$ - .pipe( - skipUntil(push$), - debounceTime(250), - distinctUntilKeyChanged("offset") - ) - .subscribe(({ offset }) => { - history.replaceState(offset, "") - }) - - /* Set viewport offset from history */ - merge(push$, pop$) - .pipe( - bufferCount(2, 1), - filter(([a, b]) => a.url.pathname === b.url.pathname), - map(([, state]) => state) - ) - .subscribe(({ offset }) => { - setViewportOffset(offset || { y: 0 }) - }) -} diff --git a/docs/src/assets/javascripts/integrations/search/_/.eslintrc b/docs/src/assets/javascripts/integrations/search/_/.eslintrc deleted file mode 100644 index fd92bace..00000000 --- a/docs/src/assets/javascripts/integrations/search/_/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "no-console": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/_/index.ts b/docs/src/assets/javascripts/integrations/search/_/index.ts deleted file mode 100644 index d3ed2108..00000000 --- a/docs/src/assets/javascripts/integrations/search/_/index.ts +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - SearchDocument, - SearchDocumentMap, - setupSearchDocumentMap -} from "../document" -import { - SearchHighlightFactoryFn, - setupSearchHighlighter -} from "../highlighter" -import { SearchOptions } from "../options" -import { - SearchQueryTerms, - getSearchQueryTerms, - parseSearchQuery -} from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search index configuration - */ -export interface SearchIndexConfig { - lang: string[] /* Search languages */ - separator: string /* Search separator */ -} - -/** - * Search index document - */ -export interface SearchIndexDocument { - location: string /* Document location */ - title: string /* Document title */ - text: string /* Document text */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search index - * - * This interfaces describes the format of the `search_index.json` file which - * is automatically built by the MkDocs search plugin. - */ -export interface SearchIndex { - config: SearchIndexConfig /* Search index configuration */ - docs: SearchIndexDocument[] /* Search index documents */ - index?: object /* Prebuilt index */ - options: SearchOptions /* Search options */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search metadata - */ -export interface SearchMetadata { - score: number /* Score (relevance) */ - terms: SearchQueryTerms /* Search query terms */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search result document - */ -export type SearchResultDocument = SearchDocument & SearchMetadata - -/** - * Search result item - */ -export type SearchResultItem = SearchResultDocument[] - -/* ------------------------------------------------------------------------- */ - -/** - * Search result - */ -export interface SearchResult { - items: SearchResultItem[] /* Search result items */ - suggestions?: string[] /* Search suggestions */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Compute the difference of two lists of strings - * - * @param a - 1st list of strings - * @param b - 2nd list of strings - * - * @returns Difference - */ -function difference(a: string[], b: string[]): string[] { - const [x, y] = [new Set(a), new Set(b)] - return [ - ...new Set([...x].filter(value => !y.has(value))) - ] -} - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -export class Search { - - /** - * Search document mapping - * - * A mapping of URLs (including hash fragments) to the actual articles and - * sections of the documentation. The search document mapping must be created - * regardless of whether the index was prebuilt or not, as Lunr.js itself - * only stores the actual index. - */ - protected documents: SearchDocumentMap - - /** - * Search highlight factory function - */ - protected highlight: SearchHighlightFactoryFn - - /** - * The underlying Lunr.js search index - */ - protected index: lunr.Index - - /** - * Search options - */ - protected options: SearchOptions - - /** - * Create the search integration - * - * @param data - Search index - */ - public constructor({ config, docs, index, options }: SearchIndex) { - this.options = options - - /* Set up document map and highlighter factory */ - this.documents = setupSearchDocumentMap(docs) - this.highlight = setupSearchHighlighter(config, false) - - /* Set separator for tokenizer */ - lunr.tokenizer.separator = new RegExp(config.separator) - - /* If no index was given, create it */ - if (typeof index === "undefined") { - this.index = lunr(function () { - - /* Set up multi-language support */ - if (config.lang.length === 1 && config.lang[0] !== "en") { - this.use((lunr as any)[config.lang[0]]) - } else if (config.lang.length > 1) { - this.use((lunr as any).multiLanguage(...config.lang)) - } - - /* Compute functions to be removed from the pipeline */ - const fns = difference([ - "trimmer", "stopWordFilter", "stemmer" - ], options.pipeline) - - /* Remove functions from the pipeline for registered languages */ - for (const lang of config.lang.map(language => ( - language === "en" ? lunr : (lunr as any)[language] - ))) { - for (const fn of fns) { - this.pipeline.remove(lang[fn]) - this.searchPipeline.remove(lang[fn]) - } - } - - /* Set up reference */ - this.ref("location") - - /* Set up fields */ - this.field("title", { boost: 1e3 }) - this.field("text") - - /* Index documents */ - for (const doc of docs) - this.add(doc) - }) - - /* Handle prebuilt index */ - } else { - this.index = lunr.Index.load(index) - } - } - - /** - * Search for matching documents - * - * The search index which MkDocs provides is divided up into articles, which - * contain the whole content of the individual pages, and sections, which only - * contain the contents of the subsections obtained by breaking the individual - * pages up at `h1` ... `h6`. As there may be many sections on different pages - * with identical titles (for example within this very project, e.g. "Usage" - * or "Installation"), they need to be put into the context of the containing - * page. For this reason, section results are grouped within their respective - * articles which are the top-level results that are returned. - * - * @param query - Query value - * - * @returns Search results - */ - public search(query: string): SearchResult { - if (query) { - try { - const highlight = this.highlight(query) - - /* Parse query to extract clauses for analysis */ - const clauses = parseSearchQuery(query) - .filter(clause => ( - clause.presence !== lunr.Query.presence.PROHIBITED - )) - - /* Perform search and post-process results */ - const groups = this.index.search(`${query}*`) - - /* Apply post-query boosts based on title and search query terms */ - .reduce<SearchResultItem>((item, { ref, score, matchData }) => { - const document = this.documents.get(ref) - if (typeof document !== "undefined") { - const { location, title, text, parent } = document - - /* Compute and analyze search query terms */ - const terms = getSearchQueryTerms( - clauses, - Object.keys(matchData.metadata) - ) - - /* Highlight title and text and apply post-query boosts */ - const boost = +!parent + +Object.values(terms).every(t => t) - item.push({ - location, - title: highlight(title), - text: highlight(text), - score: score * (1 + boost), - terms - }) - } - return item - }, []) - - /* Sort search results again after applying boosts */ - .sort((a, b) => b.score - a.score) - - /* Group search results by page */ - .reduce((items, result) => { - const document = this.documents.get(result.location) - if (typeof document !== "undefined") { - const ref = "parent" in document - ? document.parent!.location - : document.location - items.set(ref, [...items.get(ref) || [], result]) - } - return items - }, new Map<string, SearchResultItem>()) - - /* Generate search suggestions, if desired */ - let suggestions: string[] | undefined - if (this.options.suggestions) { - const titles = this.index.query(builder => { - for (const clause of clauses) - builder.term(clause.term, { - fields: ["title"], - presence: lunr.Query.presence.REQUIRED, - wildcard: lunr.Query.wildcard.TRAILING - }) - }) - - /* Retrieve suggestions for best match */ - suggestions = titles.length - ? Object.keys(titles[0].matchData.metadata) - : [] - } - - /* Return items and suggestions */ - return { - items: [...groups.values()], - ...typeof suggestions !== "undefined" && { suggestions } - } - - /* Log errors to console (for now) */ - } catch { - console.warn(`Invalid query: ${query} – see https://bit.ly/2s3ChXG`) - } - } - - /* Return nothing in case of error or empty query */ - return { items: [] } - } -} diff --git a/docs/src/assets/javascripts/integrations/search/document/index.ts b/docs/src/assets/javascripts/integrations/search/document/index.ts deleted file mode 100644 index 0bcd679a..00000000 --- a/docs/src/assets/javascripts/integrations/search/document/index.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import escapeHTML from "escape-html" - -import { SearchIndexDocument } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search document - */ -export interface SearchDocument extends SearchIndexDocument { - parent?: SearchIndexDocument /* Parent article */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search document mapping - */ -export type SearchDocumentMap = Map<string, SearchDocument> - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create a search document mapping - * - * @param docs - Search index documents - * - * @returns Search document map - */ -export function setupSearchDocumentMap( - docs: SearchIndexDocument[] -): SearchDocumentMap { - const documents = new Map<string, SearchDocument>() - const parents = new Set<SearchDocument>() - for (const doc of docs) { - const [path, hash] = doc.location.split("#") - - /* Extract location and title */ - const location = doc.location - const title = doc.title - - /* Escape and cleanup text */ - const text = escapeHTML(doc.text) - .replace(/\s+(?=[,.:;!?])/g, "") - .replace(/\s+/g, " ") - - /* Handle section */ - if (hash) { - const parent = documents.get(path)! - - /* Ignore first section, override article */ - if (!parents.has(parent)) { - parent.title = doc.title - parent.text = text - - /* Remember that we processed the article */ - parents.add(parent) - - /* Add subsequent section */ - } else { - documents.set(location, { - location, - title, - text, - parent - }) - } - - /* Add article */ - } else { - documents.set(location, { - location, - title, - text - }) - } - } - return documents -} diff --git a/docs/src/assets/javascripts/integrations/search/highlighter/index.ts b/docs/src/assets/javascripts/integrations/search/highlighter/index.ts deleted file mode 100644 index 5d13e198..00000000 --- a/docs/src/assets/javascripts/integrations/search/highlighter/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import escapeHTML from "escape-html" - -import { SearchIndexConfig } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search highlight function - * - * @param value - Value - * - * @returns Highlighted value - */ -export type SearchHighlightFn = (value: string) => string - -/** - * Search highlight factory function - * - * @param query - Query value - * - * @returns Search highlight function - */ -export type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create a search highlighter - * - * @param config - Search index configuration - * @param escape - Whether to escape HTML - * - * @returns Search highlight factory function - */ -export function setupSearchHighlighter( - config: SearchIndexConfig, escape: boolean -): SearchHighlightFactoryFn { - const separator = new RegExp(config.separator, "img") - const highlight = (_: unknown, data: string, term: string) => { - return `${data}<mark data-md-highlight>${term}</mark>` - } - - /* Return factory function */ - return (query: string) => { - query = query - .replace(/[\s*+\-:~^]+/g, " ") - .trim() - - /* Create search term match expression */ - const match = new RegExp(`(^|${config.separator})(${ - query - .replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&") - .replace(separator, "|") - })`, "img") - - /* Highlight string value */ - return value => ( - escape - ? escapeHTML(value) - : value - ) - .replace(match, highlight) - .replace(/<\/mark>(\s+)<mark[^>]*>/img, "$1") - } -} diff --git a/docs/src/assets/javascripts/integrations/search/index.ts b/docs/src/assets/javascripts/integrations/search/index.ts deleted file mode 100644 index 1a5430e9..00000000 --- a/docs/src/assets/javascripts/integrations/search/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./document" -export * from "./highlighter" -export * from "./options" -export * from "./query" -export * from "./worker" diff --git a/docs/src/assets/javascripts/integrations/search/options/index.ts b/docs/src/assets/javascripts/integrations/search/options/index.ts deleted file mode 100644 index ad1015a5..00000000 --- a/docs/src/assets/javascripts/integrations/search/options/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search pipeline function - */ -export type SearchPipelineFn = - | "trimmer" /* Trimmer */ - | "stopWordFilter" /* Stop word filter */ - | "stemmer" /* Stemmer */ - -/** - * Search pipeline - */ -export type SearchPipeline = SearchPipelineFn[] - -/* ------------------------------------------------------------------------- */ - -/** - * Search options - */ -export interface SearchOptions { - pipeline: SearchPipeline /* Search pipeline */ - suggestions: boolean /* Search suggestions */ -} diff --git a/docs/src/assets/javascripts/integrations/search/query/_/.eslintrc b/docs/src/assets/javascripts/integrations/search/query/_/.eslintrc deleted file mode 100644 index 8b8e4250..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/_/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/query/_/index.ts b/docs/src/assets/javascripts/integrations/search/query/_/index.ts deleted file mode 100644 index e9679a05..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/_/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search query clause - */ -export interface SearchQueryClause { - presence: lunr.Query.presence /* Clause presence */ - term: string /* Clause term */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search query terms - */ -export type SearchQueryTerms = Record<string, boolean> - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Parse a search query for analysis - * - * @param value - Query value - * - * @returns Search query clauses - */ -export function parseSearchQuery( - value: string -): SearchQueryClause[] { - const query = new (lunr as any).Query(["title", "text"]) - const parser = new (lunr as any).QueryParser(value, query) - - /* Parse and return query clauses */ - parser.parse() - return query.clauses -} - -/** - * Analyze the search query clauses in regard to the search terms found - * - * @param query - Search query clauses - * @param terms - Search terms - * - * @returns Search query terms - */ -export function getSearchQueryTerms( - query: SearchQueryClause[], terms: string[] -): SearchQueryTerms { - const clauses = new Set<SearchQueryClause>(query) - - /* Match query clauses against terms */ - const result: SearchQueryTerms = {} - for (let t = 0; t < terms.length; t++) - for (const clause of clauses) - if (terms[t].startsWith(clause.term)) { - result[clause.term] = true - clauses.delete(clause) - } - - /* Annotate unmatched query clauses */ - for (const clause of clauses) - result[clause.term] = false - - /* Return query terms */ - return result -} diff --git a/docs/src/assets/javascripts/integrations/search/query/index.ts b/docs/src/assets/javascripts/integrations/search/query/index.ts deleted file mode 100644 index 98442a55..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./transform" diff --git a/docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc b/docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc deleted file mode 100644 index 5645b172..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-control-regex": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/query/transform/index.ts b/docs/src/assets/javascripts/integrations/search/query/transform/index.ts deleted file mode 100644 index f498495c..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/transform/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search transformation function - * - * @param value - Query value - * - * @returns Transformed query value - */ -export type SearchTransformFn = (value: string) => string - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Default transformation function - * - * 1. Search for terms in quotation marks and prepend a `+` modifier to denote - * that the resulting document must contain all terms, converting the query - * to an `AND` query (as opposed to the default `OR` behavior). While users - * may expect terms enclosed in quotation marks to map to span queries, i.e. - * for which order is important, Lunr.js doesn't support them, so the best - * we can do is to convert the terms to an `AND` query. - * - * 2. Replace control characters which are not located at the beginning of the - * query or preceded by white space, or are not followed by a non-whitespace - * character or are at the end of the query string. Furthermore, filter - * unmatched quotation marks. - * - * 3. Trim excess whitespace from left and right. - * - * @param query - Query value - * - * @returns Transformed query value - */ -export function defaultTransform(query: string): string { - return query - .split(/"([^"]+)"/g) /* => 1 */ - .map((terms, index) => index & 1 - ? terms.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g, " +") - : terms - ) - .join("") - .replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g, "") /* => 2 */ - .trim() /* => 3 */ -} diff --git a/docs/src/assets/javascripts/integrations/search/worker/_/index.ts b/docs/src/assets/javascripts/integrations/search/worker/_/index.ts deleted file mode 100644 index 146f14a6..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/_/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ObservableInput, Subject, from } from "rxjs" -import { map, share } from "rxjs/operators" - -import { configuration, feature, translation } from "~/_" -import { WorkerHandler, watchWorker } from "~/browser" - -import { SearchIndex } from "../../_" -import { - SearchOptions, - SearchPipeline -} from "../../options" -import { - SearchMessage, - SearchMessageType, - SearchSetupMessage, - isSearchResultMessage -} from "../message" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search worker - */ -export type SearchWorker = WorkerHandler<SearchMessage> - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Set up search index - * - * @param data - Search index - * - * @returns Search index - */ -function setupSearchIndex( - { config, docs, index }: SearchIndex -): SearchIndex { - - /* Override default language with value from translation */ - if (config.lang.length === 1 && config.lang[0] === "en") - config.lang = [ - translation("search.config.lang") - ] - - /* Override default separator with value from translation */ - if (config.separator === "[\\s\\-]+") - config.separator = translation("search.config.separator") - - /* Set pipeline from translation */ - const pipeline = translation("search.config.pipeline") - .split(/\s*,\s*/) - .filter(Boolean) as SearchPipeline - - /* Determine search options */ - const options: SearchOptions = { - pipeline, - suggestions: feature("search.suggest") - } - - /* Return search index after defaulting */ - return { config, docs, index, options } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up search worker - * - * This function creates a web worker to set up and query the search index, - * which is done using Lunr.js. The index must be passed as an observable to - * enable hacks like _localsearch_ via search index embedding as JSON. - * - * @param url - Worker URL - * @param index - Search index observable input - * - * @returns Search worker - */ -export function setupSearchWorker( - url: string, index: ObservableInput<SearchIndex> -): SearchWorker { - const config = configuration() - const worker = new Worker(url) - - /* Create communication channels and resolve relative links */ - const tx$ = new Subject<SearchMessage>() - const rx$ = watchWorker(worker, { tx$ }) - .pipe( - map(message => { - if (isSearchResultMessage(message)) { - for (const result of message.data.items) - for (const document of result) - document.location = `${new URL(document.location, config.base)}` - } - return message - }), - share() - ) - - /* Set up search index */ - from(index) - .pipe( - map<SearchIndex, SearchSetupMessage>(data => ({ - type: SearchMessageType.SETUP, - data: setupSearchIndex(data) - })) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Return search worker */ - return { tx$, rx$ } -} diff --git a/docs/src/assets/javascripts/integrations/search/worker/index.ts b/docs/src/assets/javascripts/integrations/search/worker/index.ts deleted file mode 100644 index 22d729a7..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./message" diff --git a/docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc b/docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc deleted file mode 100644 index 09c57919..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-misused-promises": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/worker/main/index.ts b/docs/src/assets/javascripts/integrations/search/worker/main/index.ts deleted file mode 100644 index 435e5373..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/main/index.ts +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import lunr from "lunr" - -import { Search, SearchIndexConfig } from "../../_" -import { - SearchMessage, - SearchMessageType -} from "../message" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Add support for usage with `iframe-worker` polyfill - * - * While `importScripts` is synchronous when executed inside of a web worker, - * it's not possible to provide a synchronous polyfilled implementation. The - * cool thing is that awaiting a non-Promise is a noop, so extending the type - * definition to return a `Promise` shouldn't break anything. - * - * @see https://bit.ly/2PjDnXi - GitHub comment - */ -declare global { - function importScripts(...urls: string[]): Promise<void> | void -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -let index: Search - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch (= import) multi-language support through `lunr-languages` - * - * This function automatically imports the stemmers necessary to process the - * languages, which are defined through the search index configuration. - * - * If the worker runs inside of an `iframe` (when using `iframe-worker` as - * a shim), the base URL for the stemmers to be loaded must be determined by - * searching for the first `script` element with a `src` attribute, which will - * contain the contents of this script. - * - * @param config - Search index configuration - * - * @returns Promise resolving with no result - */ -async function setupSearchLanguages( - config: SearchIndexConfig -): Promise<void> { - let base = "../lunr" - - /* Detect `iframe-worker` and fix base URL */ - if (typeof parent !== "undefined" && "IFrameWorker" in parent) { - const worker = document.querySelector<HTMLScriptElement>("script[src]")! - const [path] = worker.src.split("/worker") - - /* Prefix base with path */ - base = base.replace("..", path) - } - - /* Add scripts for languages */ - const scripts = [] - for (const lang of config.lang) { - switch (lang) { - - /* Add segmenter for Japanese */ - case "ja": - scripts.push(`${base}/tinyseg.js`) - break - - /* Add segmenter for Hindi and Thai */ - case "hi": - case "th": - scripts.push(`${base}/wordcut.js`) - break - } - - /* Add language support */ - if (lang !== "en") - scripts.push(`${base}/min/lunr.${lang}.min.js`) - } - - /* Add multi-language support */ - if (config.lang.length > 1) - scripts.push(`${base}/min/lunr.multi.min.js`) - - /* Load scripts synchronously */ - if (scripts.length) - await importScripts( - `${base}/min/lunr.stemmer.support.min.js`, - ...scripts - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Message handler - * - * @param message - Source message - * - * @returns Target message - */ -export async function handler( - message: SearchMessage -): Promise<SearchMessage> { - switch (message.type) { - - /* Search setup message */ - case SearchMessageType.SETUP: - await setupSearchLanguages(message.data.config) - index = new Search(message.data) - return { - type: SearchMessageType.READY - } - - /* Search query message */ - case SearchMessageType.QUERY: - return { - type: SearchMessageType.RESULT, - data: index ? index.search(message.data) : { items: [] } - } - - /* All other messages */ - default: - throw new TypeError("Invalid message type") - } -} - -/* ---------------------------------------------------------------------------- - * Worker - * ------------------------------------------------------------------------- */ - -/* @ts-ignore - expose Lunr.js in global scope, or stemmers will not work */ -self.lunr = lunr - -/* Handle messages */ -addEventListener("message", async ev => { - postMessage(await handler(ev.data)) -}) diff --git a/docs/src/assets/javascripts/integrations/search/worker/message/index.ts b/docs/src/assets/javascripts/integrations/search/worker/message/index.ts deleted file mode 100644 index 2f6a3866..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/message/index.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { SearchIndex, SearchResult } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search message type - */ -export const enum SearchMessageType { - SETUP, /* Search index setup */ - READY, /* Search index ready */ - QUERY, /* Search query */ - RESULT /* Search results */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Message containing the data necessary to setup the search index - */ -export interface SearchSetupMessage { - type: SearchMessageType.SETUP /* Message type */ - data: SearchIndex /* Message data */ -} - -/** - * Message indicating the search index is ready - */ -export interface SearchReadyMessage { - type: SearchMessageType.READY /* Message type */ -} - -/** - * Message containing a search query - */ -export interface SearchQueryMessage { - type: SearchMessageType.QUERY /* Message type */ - data: string /* Message data */ -} - -/** - * Message containing results for a search query - */ -export interface SearchResultMessage { - type: SearchMessageType.RESULT /* Message type */ - data: SearchResult /* Message data */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Message exchanged with the search worker - */ -export type SearchMessage = - | SearchSetupMessage - | SearchReadyMessage - | SearchQueryMessage - | SearchResultMessage - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Type guard for search setup messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchSetupMessage( - message: SearchMessage -): message is SearchSetupMessage { - return message.type === SearchMessageType.SETUP -} - -/** - * Type guard for search ready messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchReadyMessage( - message: SearchMessage -): message is SearchReadyMessage { - return message.type === SearchMessageType.READY -} - -/** - * Type guard for search query messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchQueryMessage( - message: SearchMessage -): message is SearchQueryMessage { - return message.type === SearchMessageType.QUERY -} - -/** - * Type guard for search result messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchResultMessage( - message: SearchMessage -): message is SearchResultMessage { - return message.type === SearchMessageType.RESULT -} diff --git a/docs/src/assets/javascripts/integrations/version/index.ts b/docs/src/assets/javascripts/integrations/version/index.ts deleted file mode 100644 index 4be76ee8..00000000 --- a/docs/src/assets/javascripts/integrations/version/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { configuration } from "~/_" -import { getElementOrThrow, requestJSON } from "~/browser" -import { Version, renderVersionSelector } from "~/templates" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up version selector - */ -export function setupVersionSelector(): void { - const config = configuration() - requestJSON<Version[]>(new URL("../versions.json", config.base)) - .subscribe(versions => { - const topic = getElementOrThrow(".md-header__topic") - topic.appendChild(renderVersionSelector(versions)) - }) -} diff --git a/docs/src/assets/javascripts/patches/indeterminate/index.ts b/docs/src/assets/javascripts/patches/indeterminate/index.ts deleted file mode 100644 index 0397edc4..00000000 --- a/docs/src/assets/javascripts/patches/indeterminate/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, of } from "rxjs" -import { - mapTo, - mergeMap, - switchMap, - takeWhile, - tap, - withLatestFrom -} from "rxjs/operators" - -import { getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - document$: Observable<Document> /* Document observable */ - tablet$: Observable<boolean> /* Tablet breakpoint observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch indeterminate checkboxes - * - * This function replaces the indeterminate "pseudo state" with the actual - * indeterminate state, which is used to keep navigation always expanded. - * - * @param options - Options - */ -export function patchIndeterminate( - { document$, tablet$ }: PatchOptions -): void { - document$ - .pipe( - switchMap(() => of(...getElements<HTMLInputElement>( - "[data-md-state=indeterminate]" - ))), - tap(el => { - el.indeterminate = true - el.checked = false - }), - mergeMap(el => fromEvent(el, "change") - .pipe( - takeWhile(() => el.hasAttribute("data-md-state")), - mapTo(el) - ) - ), - withLatestFrom(tablet$) - ) - .subscribe(([el, tablet]) => { - el.removeAttribute("data-md-state") - if (tablet) - el.checked = false - }) -} diff --git a/docs/src/assets/javascripts/patches/index.ts b/docs/src/assets/javascripts/patches/index.ts deleted file mode 100644 index 3195e6e5..00000000 --- a/docs/src/assets/javascripts/patches/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./indeterminate" -export * from "./scrollfix" -export * from "./scrolllock" diff --git a/docs/src/assets/javascripts/patches/scrollfix/index.ts b/docs/src/assets/javascripts/patches/scrollfix/index.ts deleted file mode 100644 index 941464ca..00000000 --- a/docs/src/assets/javascripts/patches/scrollfix/index.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, of } from "rxjs" -import { - filter, - mapTo, - mergeMap, - switchMap, - tap -} from "rxjs/operators" - -import { getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - document$: Observable<Document> /* Document observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Check whether the given device is an Apple device - * - * @returns Test result - */ -function isAppleDevice(): boolean { - return /(iPad|iPhone|iPod)/.test(navigator.userAgent) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch all elements with `data-md-scrollfix` attributes - * - * This is a year-old patch which ensures that overflow scrolling works at the - * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon - * the start of a touch event. - * - * @see https://bit.ly/2SCtAOO - Original source - * - * @param options - Options - */ -export function patchScrollfix( - { document$ }: PatchOptions -): void { - document$ - .pipe( - switchMap(() => of(...getElements("[data-md-scrollfix]"))), - tap(el => el.removeAttribute("data-md-scrollfix")), - filter(isAppleDevice), - mergeMap(el => fromEvent(el, "touchstart") - .pipe( - mapTo(el) - ) - ) - ) - .subscribe(el => { - const top = el.scrollTop - - /* We're at the top of the container */ - if (top === 0) { - el.scrollTop = 1 - - /* We're at the bottom of the container */ - } else if (top + el.offsetHeight === el.scrollHeight) { - el.scrollTop = top - 1 - } - }) -} diff --git a/docs/src/assets/javascripts/patches/scrolllock/index.ts b/docs/src/assets/javascripts/patches/scrolllock/index.ts deleted file mode 100644 index 884c7612..00000000 --- a/docs/src/assets/javascripts/patches/scrolllock/index.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - animationFrameScheduler, - combineLatest, - of -} from "rxjs" -import { - delay, - map, - observeOn, - switchMap, - withLatestFrom -} from "rxjs/operators" - -import { resetScrollLock, setScrollLock } from "~/actions" -import { Viewport, watchToggle } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - tablet$: Observable<boolean> /* Tablet breakpoint observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch the document body to lock when search is open - * - * For mobile and tablet viewports, the search is rendered full screen, which - * leads to scroll leaking when at the top or bottom of the search result. This - * function locks the body when the search is in full screen mode, and restores - * the scroll position when leaving. - * - * @param options - Options - */ -export function patchScrolllock( - { viewport$, tablet$ }: PatchOptions -): void { - combineLatest([watchToggle("search"), tablet$]) - .pipe( - map(([active, tablet]) => active && !tablet), - switchMap(active => of(active) - .pipe( - delay(active ? 400 : 100), - observeOn(animationFrameScheduler) - ) - ), - withLatestFrom(viewport$) - ) - .subscribe(([active, { offset: { y }}]) => { - if (active) - setScrollLock(document.body, y) - else - resetScrollLock(document.body) - }) -} diff --git a/docs/src/assets/javascripts/templates/clipboard/index.tsx b/docs/src/assets/javascripts/templates/clipboard/index.tsx deleted file mode 100644 index fd54c316..00000000 --- a/docs/src/assets/javascripts/templates/clipboard/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a 'copy-to-clipboard' button - * - * @param id - Unique identifier - * - * @returns Element - */ -export function renderClipboardButton(id: string): HTMLElement { - return ( - <button - class="md-clipboard md-icon" - title={translation("clipboard.copy")} - data-clipboard-target={`#${id} > code`} - ></button> - ) -} diff --git a/docs/src/assets/javascripts/templates/index.ts b/docs/src/assets/javascripts/templates/index.ts deleted file mode 100644 index 416f29fb..00000000 --- a/docs/src/assets/javascripts/templates/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./clipboard" -export * from "./search" -export * from "./source" -export * from "./table" -export * from "./version" diff --git a/docs/src/assets/javascripts/templates/search/index.tsx b/docs/src/assets/javascripts/templates/search/index.tsx deleted file mode 100644 index d9e777b3..00000000 --- a/docs/src/assets/javascripts/templates/search/index.tsx +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { feature, translation } from "~/_" -import { - SearchDocument, - SearchMetadata, - SearchResultItem -} from "~/integrations/search" -import { h, truncate } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Render flag - */ -const enum Flag { - TEASER = 1, /* Render teaser */ - PARENT = 2 /* Render as parent */ -} - -/* ---------------------------------------------------------------------------- - * Helper function - * ------------------------------------------------------------------------- */ - -/** - * Render a search document - * - * @param document - Search document - * @param flag - Render flags - * - * @returns Element - */ -function renderSearchDocument( - document: SearchDocument & SearchMetadata, flag: Flag -): HTMLElement { - const parent = flag & Flag.PARENT - const teaser = flag & Flag.TEASER - - /* Render missing query terms */ - const missing = Object.keys(document.terms) - .filter(key => !document.terms[key]) - .map(key => [<del>{key}</del>, " "]) - .flat() - .slice(0, -1) - - /* Assemble query string for highlighting */ - const url = new URL(document.location) - if (feature("search.highlight")) - url.searchParams.set("h", Object.entries(document.terms) - .filter(([, match]) => match) - .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), "") - ) - - /* Render article or section, depending on flags */ - return ( - <a href={`${url}`} class="md-search-result__link" tabIndex={-1}> - <article - class={["md-search-result__article", ...parent - ? ["md-search-result__article--document"] - : [] - ].join(" ")} - data-md-score={document.score.toFixed(2)} - > - {parent > 0 && <div class="md-search-result__icon md-icon"></div>} - <h1 class="md-search-result__title">{document.title}</h1> - {teaser > 0 && document.text.length > 0 && - <p class="md-search-result__teaser"> - {truncate(document.text, 320)} - </p> - } - {teaser > 0 && missing.length > 0 && - <p class="md-search-result__terms"> - {translation("search.result.term.missing")}: {...missing} - </p> - } - </article> - </a> - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a search result - * - * @param result - Search result - * - * @returns Element - */ -export function renderSearchResultItem( - result: SearchResultItem -): HTMLElement { - const threshold = result[0].score - const docs = [...result] - - /* Find and extract parent article */ - const parent = docs.findIndex(doc => !doc.location.includes("#")) - const [article] = docs.splice(parent, 1) - - /* Determine last index above threshold */ - let index = docs.findIndex(doc => doc.score < threshold) - if (index === -1) - index = docs.length - - /* Partition sections */ - const best = docs.slice(0, index) - const more = docs.slice(index) - - /* Render children */ - const children = [ - renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)), - ...best.map(section => renderSearchDocument(section, Flag.TEASER)), - ...more.length ? [ - <details class="md-search-result__more"> - <summary tabIndex={-1}> - {more.length > 0 && more.length === 1 - ? translation("search.result.more.one") - : translation("search.result.more.other", more.length) - } - </summary> - {...more.map(section => renderSearchDocument(section, Flag.TEASER))} - </details> - ] : [] - ] - - /* Render search result */ - return ( - <li class="md-search-result__item"> - {children} - </li> - ) -} diff --git a/docs/src/assets/javascripts/templates/source/index.tsx b/docs/src/assets/javascripts/templates/source/index.tsx deleted file mode 100644 index f124188d..00000000 --- a/docs/src/assets/javascripts/templates/source/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { SourceFacts } from "~/components" -import { h, round } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render repository facts - * - * @param facts - Repository facts - * - * @returns Element - */ -export function renderSourceFacts(facts: SourceFacts): HTMLElement { - return ( - <ul class="md-source__facts"> - {Object.entries(facts).map(([key, value]) => ( - <li class={`md-source__fact md-source__fact--${key}`}> - {typeof value === "number" ? round(value) : value} - </li> - ))} - </ul> - ) -} diff --git a/docs/src/assets/javascripts/templates/table/index.tsx b/docs/src/assets/javascripts/templates/table/index.tsx deleted file mode 100644 index 012450d7..00000000 --- a/docs/src/assets/javascripts/templates/table/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a table inside a wrapper to improve scrolling on mobile - * - * @param table - Table element - * - * @returns Element - */ -export function renderTable(table: HTMLElement): HTMLElement { - return ( - <div class="md-typeset__scrollwrap"> - <div class="md-typeset__table"> - {table} - </div> - </div> - ) -} diff --git a/docs/src/assets/javascripts/templates/version/index.tsx b/docs/src/assets/javascripts/templates/version/index.tsx deleted file mode 100644 index 484f72dd..00000000 --- a/docs/src/assets/javascripts/templates/version/index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { configuration, translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Version - */ -export interface Version { - version: string /* Version identifier */ - title: string /* Version title */ - aliases: string[] /* Version aliases */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Render a version - * - * @param version - Version - * - * @returns Element - */ -function renderVersion(version: Version): HTMLElement { - const config = configuration() - - /* Ensure trailing slash, see https://bit.ly/3rL5u3f */ - const url = new URL(`../${version.version}/`, config.base) - return ( - <li class="md-version__item"> - <a href={url.toString()} class="md-version__link"> - {version.title} - </a> - </li> - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a version selector - * - * @param versions - Versions - * - * @returns Element - */ -export function renderVersionSelector(versions: Version[]): HTMLElement { - const config = configuration() - - /* Determine active version */ - const [, current] = config.base.match(/([^/]+)\/?$/)! - const active = - versions.find(({ version, aliases }) => ( - version === current || aliases.includes(current) - )) || versions[0] - - /* Render version selector */ - return ( - <div class="md-version"> - <button - class="md-version__current" - aria-label={translation("select.version.title")} - > - {active.title} - </button> - <ul class="md-version__list"> - {versions.map(renderVersion)} - </ul> - </div> - ) -} diff --git a/docs/src/assets/javascripts/utilities/h/.eslintrc b/docs/src/assets/javascripts/utilities/h/.eslintrc deleted file mode 100644 index d79b45b0..00000000 --- a/docs/src/assets/javascripts/utilities/h/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-namespace": "off", - "jsdoc/require-jsdoc": "off" - } -} diff --git a/docs/src/assets/javascripts/utilities/h/index.ts b/docs/src/assets/javascripts/utilities/h/index.ts deleted file mode 100644 index 3c6dbabc..00000000 --- a/docs/src/assets/javascripts/utilities/h/index.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { JSX as JSXInternal } from "preact" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * HTML attributes - */ -type Attributes = - & JSXInternal.HTMLAttributes - & JSXInternal.SVGAttributes - & Record<string, any> - -/** - * Child element - */ -type Child = - | HTMLElement - | Text - | string - | number - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Append a child node to an element - * - * @param el - Element - * @param child - Child node(s) - */ -function appendChild(el: HTMLElement, child: Child | Child[]): void { - - /* Handle primitive types (including raw HTML) */ - if (typeof child === "string" || typeof child === "number") { - el.innerHTML += child.toString() - - /* Handle nodes */ - } else if (child instanceof Node) { - el.appendChild(child) - - /* Handle nested children */ - } else if (Array.isArray(child)) { - for (const node of child) - appendChild(el, node) - } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * JSX factory - * - * @template T - Element type - * - * @param tag - HTML tag - * @param attributes - HTML attributes - * @param children - Child elements - * - * @returns Element - */ -export function h<T extends keyof HTMLElementTagNameMap>( - tag: T, attributes?: Attributes | null, ...children: Child[] -): HTMLElementTagNameMap[T] - -export function h<T extends h.JSX.Element>( - tag: string, attributes?: Attributes | null, ...children: Child[] -): T - -export function h<T extends h.JSX.Element>( - tag: string, attributes?: Attributes | null, ...children: Child[] -): T { - const el = document.createElement(tag) - - /* Set attributes, if any */ - if (attributes) - for (const attr of Object.keys(attributes)) - if (typeof attributes[attr] !== "boolean") - el.setAttribute(attr, attributes[attr]) - else if (attributes[attr]) - el.setAttribute(attr, "") - - /* Append child nodes */ - for (const child of children) - appendChild(el, child) - - /* Return element */ - return el as T -} - -/* ---------------------------------------------------------------------------- - * Namespace - * ------------------------------------------------------------------------- */ - -export declare namespace h { - namespace JSX { - type Element = HTMLElement - type IntrinsicElements = JSXInternal.IntrinsicElements - } -} diff --git a/docs/src/assets/javascripts/utilities/index.ts b/docs/src/assets/javascripts/utilities/index.ts deleted file mode 100644 index 7718f927..00000000 --- a/docs/src/assets/javascripts/utilities/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./h" -export * from "./string" diff --git a/docs/src/assets/javascripts/utilities/string/index.ts b/docs/src/assets/javascripts/utilities/string/index.ts deleted file mode 100644 index 7dc43461..00000000 --- a/docs/src/assets/javascripts/utilities/string/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Truncate a string after the given number of characters - * - * This is not a very reasonable approach, since the summaries kind of suck. - * It would be better to create something more intelligent, highlighting the - * search occurrences and making a better summary out of it, but this note was - * written three years ago, so who knows if we'll ever fix it. - * - * @param value - Value to be truncated - * @param n - Number of characters - * - * @returns Truncated value - */ -export function truncate(value: string, n: number): string { - let i = n - if (value.length > i) { - while (value[i] !== " " && --i > 0) { /* keep eating */ } - return `${value.substring(0, i)}...` - } - return value -} - -/** - * Round a number for display with repository facts - * - * This is a reverse-engineered version of GitHub's weird rounding algorithm - * for stars, forks and all other numbers. While all numbers below `1,000` are - * returned as-is, bigger numbers are converted to fixed numbers: - * - * - `1,049` => `1k` - * - `1,050` => `1.1k` - * - `1,949` => `1.9k` - * - `1,950` => `2k` - * - * @param value - Original value - * - * @returns Rounded value - */ -export function round(value: number): string { - if (value > 999) { - const digits = +((value - 950) % 1000 > 99) - return `${((value + 0.000001) / 1000).toFixed(digits)}k` - } else { - return value.toString() - } -} - -/** - * Simple hash function - * - * @see https://bit.ly/2wsVjJ4 - Original source - * - * @param value - Value to be hashed - * - * @returns Hash as 32bit integer - */ -export function hash(value: string): number { - let h = 0 - for (let i = 0, len = value.length; i < len; i++) { - h = ((h << 5) - h) + value.charCodeAt(i) - h |= 0 // Convert to 32bit integer - } - return h -} diff --git a/docs/src/assets/javascripts/workers/search.ts b/docs/src/assets/javascripts/workers/search.ts deleted file mode 100644 index db409938..00000000 --- a/docs/src/assets/javascripts/workers/search.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import "~/integrations/search/worker/main" diff --git a/docs/src/assets/stylesheets/_config.scss b/docs/src/assets/stylesheets/_config.scss deleted file mode 100644 index 4ab8cddb..00000000 --- a/docs/src/assets/stylesheets/_config.scss +++ /dev/null @@ -1,42 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Variables: breakpoints -// ---------------------------------------------------------------------------- - -// Device-specific breakpoints -$break-devices: ( - mobile: ( - portrait: px2em(220px) px2em(479px), - landscape: px2em(480px) px2em(719px) - ), - tablet: ( - portrait: px2em(720px) px2em(959px), - landscape: px2em(960px) px2em(1219px) - ), - screen: ( - small: px2em(1220px) px2em(1599px), - medium: px2em(1600px) px2em(1999px), - large: px2em(2000px) - ) -); diff --git a/docs/src/assets/stylesheets/main.scss b/docs/src/assets/stylesheets/main.scss deleted file mode 100644 index c8aa7610..00000000 --- a/docs/src/assets/stylesheets/main.scss +++ /dev/null @@ -1,75 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; -@import "material-shadows"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "main/reset"; -@import "main/colors"; -@import "main/icons"; -@import "main/typeset"; - -@import "main/layout/base"; -@import "main/layout/announce"; -@import "main/layout/clipboard"; -@import "main/layout/content"; -@import "main/layout/dialog"; -@import "main/layout/form"; -@import "main/layout/header"; -@import "main/layout/footer"; -@import "main/layout/nav"; -@import "main/layout/search"; -@import "main/layout/select"; -@import "main/layout/sidebar"; -@import "main/layout/source"; -@import "main/layout/tabs"; -@import "main/layout/top"; -@import "main/layout/version"; - -@import "main/extensions/markdown/admonition"; -@import "main/extensions/markdown/footnotes"; -@import "main/extensions/markdown/toc"; - -@import "main/extensions/pymdownx/arithmatex"; -@import "main/extensions/pymdownx/critic"; -@import "main/extensions/pymdownx/details"; -@import "main/extensions/pymdownx/emoji"; -@import "main/extensions/pymdownx/highlight"; -@import "main/extensions/pymdownx/keys"; -@import "main/extensions/pymdownx/tabbed"; -@import "main/extensions/pymdownx/tasklist"; - -@import "main/modifiers"; -@import "main/shame"; diff --git a/docs/src/assets/stylesheets/main/_colors.scss b/docs/src/assets/stylesheets/main/_colors.scss deleted file mode 100644 index 4513216e..00000000 --- a/docs/src/assets/stylesheets/main/_colors.scss +++ /dev/null @@ -1,107 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Color definitions -:root { - - // Default color shades - --md-default-fg-color: hsla(0, 0%, 0%, 0.87); - --md-default-fg-color--light: hsla(0, 0%, 0%, 0.54); - --md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32); - --md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07); - --md-default-bg-color: hsla(0, 0%, 100%, 1); - --md-default-bg-color--light: hsla(0, 0%, 100%, 0.7); - --md-default-bg-color--lighter: hsla(0, 0%, 100%, 0.3); - --md-default-bg-color--lightest: hsla(0, 0%, 100%, 0.12); - - // Primary color shades - --md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - --md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1); - --md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1); - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Accent color shades - --md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1); - --md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1); - --md-accent-bg-color: hsla(0, 0%, 100%, 1); - --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Light theme (default) - > * { - - // Code color shades - --md-code-fg-color: hsla(200, 18%, 26%, 1); - --md-code-bg-color: hsla(0, 0%, 96%, 1); - - // Code highlighting color shades - --md-code-hl-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); - --md-code-hl-number-color: hsla(0, 67%, 50%, 1); - --md-code-hl-special-color: hsla(340, 83%, 47%, 1); - --md-code-hl-function-color: hsla(291, 45%, 50%, 1); - --md-code-hl-constant-color: hsla(250, 63%, 60%, 1); - --md-code-hl-keyword-color: hsla(219, 54%, 51%, 1); - --md-code-hl-string-color: hsla(150, 63%, 30%, 1); - --md-code-hl-name-color: var(--md-code-fg-color); - --md-code-hl-operator-color: var(--md-default-fg-color--light); - --md-code-hl-punctuation-color: var(--md-default-fg-color--light); - --md-code-hl-comment-color: var(--md-default-fg-color--light); - --md-code-hl-generic-color: var(--md-default-fg-color--light); - --md-code-hl-variable-color: var(--md-default-fg-color--light); - - // Typeset color shades - --md-typeset-color: var(--md-default-fg-color); - - // Typeset `a` color shades - --md-typeset-a-color: var(--md-primary-fg-color); - - // Typeset `mark` color shades - --md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); - - // Typeset `del` and `ins` color shades - --md-typeset-del-color: hsla(6, 90%, 60%, 0.15); - --md-typeset-ins-color: hsla(150, 90%, 44%, 0.15); - - // Typeset `kbd` color shades - --md-typeset-kbd-color: hsla(0, 0%, 98%, 1); - --md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1); - --md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1); - - // Typeset `table` color shades - --md-typeset-table-color: hsla(0, 0%, 0%, 0.12); - - // Admonition color shades - --md-admonition-fg-color: var(--md-default-fg-color); - --md-admonition-bg-color: var(--md-default-bg-color); - - // Footer color shades - --md-footer-fg-color: hsla(0, 0%, 100%, 1); - --md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7); - --md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3); - --md-footer-bg-color: hsla(0, 0%, 0%, 0.87); - --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32); - } -} diff --git a/docs/src/assets/stylesheets/main/_icons.scss b/docs/src/assets/stylesheets/main/_icons.scss deleted file mode 100644 index 977804ac..00000000 --- a/docs/src/assets/stylesheets/main/_icons.scss +++ /dev/null @@ -1,37 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon -.md-icon { - - // SVG defaults - svg { - display: block; - width: px2rem(24px); - height: px2rem(24px); - fill: currentColor; - } -} diff --git a/docs/src/assets/stylesheets/main/_modifiers.scss b/docs/src/assets/stylesheets/main/_modifiers.scss deleted file mode 100644 index 69e64f45..00000000 --- a/docs/src/assets/stylesheets/main/_modifiers.scss +++ /dev/null @@ -1,63 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // [tablet +]: Allow for rendering content as sidebars - @include break-from-device(tablet) { - - // Modifier to float block elements - .inline { - float: left; - width: px2rem(234px); - margin-top: 0; - margin-right: px2rem(16px); - margin-bottom: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: right; - margin-right: 0; - margin-left: px2rem(16px); - } - - // Modifier to move to end (ltr: right, rtl: left) - &.end { - float: right; - margin-right: 0; - margin-left: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - margin-right: px2rem(16px); - margin-left: 0; - } - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/_reset.scss b/docs/src/assets/stylesheets/main/_reset.scss deleted file mode 100644 index de854ad2..00000000 --- a/docs/src/assets/stylesheets/main/_reset.scss +++ /dev/null @@ -1,113 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Enforce correct box model and prevent adjustments of font size after -// orientation changes in IE and iOS -html { - box-sizing: border-box; - text-size-adjust: none; -} - -// All elements shall inherit the document default -*, -*::before, -*::after { - box-sizing: inherit; -} - -// Remove margin in all browsers -body { - margin: 0; -} - -// Reset tap outlines on iOS and Android -a, -button, -label, -input { - -webkit-tap-highlight-color: transparent; -} - -// Reset link styles -a { - color: inherit; - text-decoration: none; -} - -// Normalize horizontal separator styles -hr { - display: block; - box-sizing: content-box; - height: px2rem(1px); - padding: 0; - overflow: visible; - border: 0; -} - -// Normalize font-size in all browsers -small { - font-size: 80%; -} - -// Prevent subscript and superscript from affecting line-height -sub, -sup { - line-height: 1em; -} - -// Remove border on image -img { - border-style: none; -} - -// Reset table styles -table { - border-collapse: separate; - border-spacing: 0; -} - -// Reset table cell styles -td, -th { - font-weight: 400; - vertical-align: top; -} - -// Reset button styles -button { - margin: 0; - padding: 0; - font-size: inherit; - font-family: inherit; - background: transparent; - border: 0; -} - -// Reset input styles -input { - border: 0; - outline: none; -} diff --git a/docs/src/assets/stylesheets/main/_shame.scss b/docs/src/assets/stylesheets/main/_shame.scss deleted file mode 100644 index a6acadab..00000000 --- a/docs/src/assets/stylesheets/main/_shame.scss +++ /dev/null @@ -1,25 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Nothing to see here, move along -// ---------------------------------------------------------------------------- diff --git a/docs/src/assets/stylesheets/main/_typeset.scss b/docs/src/assets/stylesheets/main/_typeset.scss deleted file mode 100644 index 5ee204a6..00000000 --- a/docs/src/assets/stylesheets/main/_typeset.scss +++ /dev/null @@ -1,640 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules: font definitions -// ---------------------------------------------------------------------------- - -// Enable font-smoothing in Webkit and FF -body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -// Define default fonts -body, -input { - color: var(--md-typeset-color); - font-feature-settings: "kern", "liga"; - font-family: - var(--md-text-font-family, _), - -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif; -} - -// Define monospaced fonts -code, -pre, -kbd { - color: var(--md-typeset-color); - font-feature-settings: "kern"; - font-family: - var(--md-code-font-family, _), - SFMono-Regular, Consolas, Menlo, monospace; -} - -// ---------------------------------------------------------------------------- -// Rules: typesetted content -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-typeset-table-sort-icon: svg-load("material/sort.svg"); - --md-typeset-table-sort-icon--asc: svg-load("material/sort-ascending.svg"); - --md-typeset-table-sort-icon--desc: svg-load("material/sort-descending.svg"); -} - -// ---------------------------------------------------------------------------- - -// Content that is typeset - if possible, all margins, paddings and font sizes -// should be set in ems, so nested blocks (e.g. admonitions) render correctly. -.md-typeset { - font-size: px2rem(16px); - line-height: 1.6; - color-adjust: exact; - - // [print]: We'll use a smaller `font-size` for printing, so code examples - // don't break too early, and `16px` looks too big anyway. - @media print { - font-size: px2rem(13.6px); - } - - // Default spacing - ul, - ol, - dl, - figure, - blockquote, - pre { - margin: 1em 0; - } - - // Headline on level 1 - h1 { - margin: 0 0 px2em(40px, 32px); - color: var(--md-default-fg-color--light); - font-weight: 300; - font-size: px2em(32px); - line-height: 1.3; - letter-spacing: -0.01em; - } - - // Headline on level 2 - h2 { - margin: px2em(40px, 25px) 0 px2em(16px, 25px); - font-weight: 300; - font-size: px2em(25px); - line-height: 1.4; - letter-spacing: -0.01em; - } - - // Headline on level 3 - h3 { - margin: px2em(32px, 20px) 0 px2em(16px, 20px); - font-weight: 400; - font-size: px2em(20px); - line-height: 1.5; - letter-spacing: -0.01em; - } - - // Headline on level 3 following level 2 - h2 + h3 { - margin-top: px2em(16px, 20px); - } - - // Headline on level 4 - h4 { - margin: px2em(16px) 0; - font-weight: 700; - letter-spacing: -0.01em; - } - - // Headline on level 5-6 - h5, - h6 { - margin: px2em(16px, 12.8px) 0; - color: var(--md-default-fg-color--light); - font-weight: 700; - font-size: px2em(12.8px); - letter-spacing: -0.01em; - } - - // Headline on level 5 - h5 { - text-transform: uppercase; - } - - // Horizontal separator - hr { - display: flow-root; - margin: 1.5em 0; - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - } - - // Text link - a { - color: var(--md-typeset-a-color); - word-break: break-word; - - // Also enable color transition on pseudo elements - &, - &::before { - transition: color 125ms; - } - - // Text link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - } - - // Code block - code, - pre, - kbd { - color: var(--md-code-fg-color); - direction: ltr; - - // [print]: Wrap text and hide scollbars - @media print { - white-space: pre-wrap; - } - } - - // Inline code block - code { - padding: 0 px2em(4px, 13.6px); - font-size: px2em(13.6px); - word-break: break-word; - background-color: var(--md-code-bg-color); - border-radius: px2rem(2px); - box-decoration-break: clone; - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - } - - // Code block in headline - h1 code, - h2 code, - h3 code, - h4 code, - h5 code, - h6 code { - margin: initial; - padding: initial; - background-color: transparent; - box-shadow: none; - } - - // Ensure link color in code blocks - a code { - color: currentColor; - } - - // Unformatted content - pre { - position: relative; - display: flow-root; - line-height: 1.4; - - // Code block - > code { - display: block; - margin: 0; - padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px); - overflow: auto; - word-break: normal; - box-shadow: none; - box-decoration-break: slice; - touch-action: auto; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Code block on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } - } - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - - // Unformatted text - > pre { - margin: 1em px2rem(-16px); - - // Code block - code { - border-radius: 0; - } - } - } - - // Keyboard key - kbd { - display: inline-block; - padding: 0 px2em(8px, 12px); - color: var(--md-default-fg-color); - font-size: px2em(12px); - vertical-align: text-top; - word-break: break-word; - background-color: var(--md-typeset-kbd-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(2px) 0 px2rem(1px) var(--md-typeset-kbd-border-color), - 0 px2rem(2px) 0 var(--md-typeset-kbd-border-color), - 0 px2rem(-2px) px2rem(4px) var(--md-typeset-kbd-accent-color) inset; - } - - // Text highlighting marker - mark { - color: inherit; - word-break: break-word; - background-color: var(--md-typeset-mark-color); - box-decoration-break: clone; - } - - // Abbreviation - abbr { - text-decoration: none; - border-bottom: px2rem(1px) dotted var(--md-default-fg-color--light); - cursor: help; - - // Show tooltip for touch devices - @media (hover: none) { - position: relative; - - // Tooltip - &[title]:focus::after, - &[title]:hover::after { - @include z-depth(2); - - position: absolute; - left: 0; - display: inline-block; - width: auto; - min-width: max-content; - max-width: 80%; - margin-top: 2em; - padding: px2rem(4px) px2rem(6px); - color: var(--md-default-bg-color); - font-size: px2rem(14px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - content: attr(title); - } - } - } - - // Small text - small { - opacity: 0.75; - } - - // Superscript and subscript - sup, - sub { - margin-left: px2em(1px, 12.8px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(1px, 12.8px); - margin-left: initial; - } - } - - // Blockquotes, possibly nested - blockquote { - padding-left: px2rem(12px); - color: var(--md-default-fg-color--light); - border-left: px2rem(4px) solid var(--md-default-fg-color--lighter); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: initial; - border-right: px2rem(4px) solid var(--md-default-fg-color--lighter); - border-left: initial; - } - } - - // Unordered list - ul { - list-style-type: disc; - } - - // Unordered and ordered list - ul, - ol { - display: flow-root; - margin-left: px2em(10px); - padding: 0; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(10px); - margin-left: initial; - } - - // Nested ordered list - ol { - list-style-type: lower-alpha; - - // Triply nested ordered list - ol { - list-style-type: lower-roman; - } - } - - // List element - li { - margin-bottom: 0.5em; - margin-left: px2em(20px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(20px); - margin-left: initial; - } - - // Adjust spacing - p, - blockquote { - margin: 0.5em 0; - } - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - - // Nested list - ul, - ol { - margin: 0.5em 0 0.5em px2em(10px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(10px); - margin-left: initial; - } - } - } - } - - // Definition list - dd { - margin: 1em 0 1.5em px2em(30px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(30px); - margin-left: initial; - } - } - - // Image or icon - img, - svg { - max-width: 100%; - height: auto; - - // Adjust spacing when left-aligned - &[align="left"] { - margin: 1em; - margin-left: 0; - } - - // Adjust spacing when right-aligned - &[align="right"] { - margin: 1em; - margin-right: 0; - } - - // Adjust spacing when sole children - &[align]:only-child { - margin-top: 0; - } - } - - // Figure - figure { - display: flow-root; - width: fit-content; - max-width: 100%; - margin: 0 auto; - text-align: center; - - // Figure images - img { - display: block; - } - } - - // Figure caption - figcaption { - max-width: px2rem(480px); - margin: 1em auto 2em; - font-style: italic; - } - - // Limit width to container - iframe { - max-width: 100%; - } - - // Data table - table:not([class]) { - display: inline-block; - max-width: 100%; - overflow: auto; - font-size: px2rem(12.8px); - background-color: var(--md-default-bg-color); - border: px2rem(1px) solid var(--md-typeset-table-color); - border-radius: px2rem(2px); - touch-action: auto; - - // [print]: Reset display mode so table header wraps when printing - @media print { - display: table; - } - - // Due to margin collapse because of the necessary inline-block hack, we - // cannot increase the bottom margin on the table, so we just increase the - // top margin on the following element - + * { - margin-top: 1.5em; - } - - // Elements in table heading and cell - th > *, - td > * { - - // Adjust spacing on first child - &:first-child { - margin-top: 0; - } - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - } - - // Table heading and cell - th:not([align]), - td:not([align]) { - text-align: left; - - // Adjust for right-to-left languages - [dir="rtl"] & { - text-align: right; - } - } - - // Table heading - th { - min-width: px2rem(100px); - padding: px2em(12px, 12.8px) px2em(16px, 12.8px); - font-weight: 700; - vertical-align: top; - - // Links in table headings - a { - color: inherit; - } - } - - // Table cell - td { - padding: px2em(12px, 12.8px) px2em(16px, 12.8px); - vertical-align: top; - border-top: px2rem(1px) solid var(--md-typeset-table-color); - } - - // Table body row - tbody tr { - transition: background-color 125ms; - - // Table row on hover - &:hover { - background-color: rgba(0, 0, 0, 0.035); - box-shadow: 0 px2rem(1px) 0 var(--md-default-bg-color) inset; - } - } - - // Text link in table - a { - word-break: normal; - } - } - - // Sortable table - table th[role="columnheader"] { - cursor: pointer; - - // Sort icon - &::after { - display: inline-block; - width: 1.2em; - height: 1.2em; - margin-left: 0.5em; - vertical-align: text-bottom; - mask-image: var(--md-typeset-table-sort-icon); - mask-repeat: no-repeat; - mask-size: contain; - transition: background-color 125ms; - content: ""; - } - - // Show sort icon on hover - &:hover::after { - background-color: var(--md-default-fg-color--lighter); - } - - // Sort ascending icon - &[aria-sort="ascending"]::after { - background-color: var(--md-default-fg-color--light); - mask-image: var(--md-typeset-table-sort-icon--asc); - } - - // Sort descending icon - &[aria-sort="descending"]::after { - background-color: var(--md-default-fg-color--light); - mask-image: var(--md-typeset-table-sort-icon--desc); - } - } - - // Data table scroll wrapper - &__scrollwrap { - margin: 1em px2rem(-16px); - overflow-x: auto; - touch-action: auto; - } - - // Data table wrapper - &__table { - display: inline-block; - margin-bottom: 0.5em; - padding: 0 px2rem(16px); - - // [print]: Reset display mode so table header wraps when printing - @media print { - display: block; - } - - // Data table - html & table { - display: table; - width: 100%; - margin: 0; - overflow: hidden; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss b/docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss deleted file mode 100644 index b707db33..00000000 --- a/docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss +++ /dev/null @@ -1,197 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Variables -// ---------------------------------------------------------------------------- - -/// Admonition flavours -$admonitions: ( - note: pencil $clr-blue-a200, - abstract summary tldr: clipboard-text $clr-light-blue-a400, - info todo: information $clr-cyan-a700, - tip hint important: fire $clr-teal-a700, - success check done: check-bold $clr-green-a700, - question help faq: help-circle $clr-light-green-a700, - warning caution attention: alert $clr-orange-a400, - failure fail missing: close-thick $clr-red-a200, - danger error: lightning-bolt $clr-red-a400, - bug: bug $clr-pink-a400, - example: format-list-numbered $clr-deep-purple-a200, - quote cite: format-quote-close $clr-grey -) !default; - -// ---------------------------------------------------------------------------- -// Rules: layout -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - @each $names, $props in $admonitions { - --md-admonition-icon--#{nth($names, 1)}: - svg-load("material/#{nth($props, 1)}.svg"); - } -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Admonition - .admonition { - margin: px2em(20px, 12.8px) 0; - padding: 0 px2rem(12px); - overflow: hidden; - color: var(--md-admonition-fg-color); - font-size: px2rem(12.8px); - page-break-inside: avoid; - background-color: var(--md-admonition-bg-color); - border-left: px2rem(4px) solid $clr-blue-a200; - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.05), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.05); - - // [print]: Omit shadow as it may lead to rendering errors - @media print { - box-shadow: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - border-right: px2rem(4px) solid $clr-blue-a200; - border-left: none; - } - - // Adjust vertical spacing for nested admonitions - .admonition { - margin-top: 1em; - margin-bottom: 1em; - } - - // Adjust spacing for contained table wrappers - .md-typeset__scrollwrap { - margin: 1em px2rem(-12px); - } - - // Adjust spacing for contained tables - .md-typeset__table { - padding: 0 px2rem(12px); - } - - // Adjust spacing for single-child tabbed block container - > .tabbed-set:only-child { - margin-top: 0; - } - - // Adjust spacing on last child - html & > :last-child { - margin-bottom: px2rem(12px); - } - } - - // Admonition title - .admonition-title { - position: relative; - margin: 0 px2rem(-12px) 0 px2rem(-16px); - padding: px2rem(8px) px2rem(12px) px2rem(8px) px2rem(40px); - font-weight: 700; - background-color: transparentize($clr-blue-a200, 0.9); - border-left: px2rem(4px) solid $clr-blue-a200; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin: 0 px2rem(-16px) 0 px2rem(-12px); - padding: px2rem(8px) px2rem(40px) px2rem(8px) px2rem(12px); - border-right: px2rem(4px) solid $clr-blue-a200; - border-left: none; - } - - // Adjust spacing for title-only admonitions - html &:last-child { - margin-bottom: 0; - } - - // Admonition icon - &::before { - position: absolute; - left: px2rem(12px); - width: px2rem(20px); - height: px2rem(20px); - background-color: $clr-blue-a200; - mask-image: var(--md-admonition-icon--note); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(12px); - left: initial; - } - } - - // Adjust spacing on last tabbed block container child - if the tabbed - // block container is the sole child, it looks better to omit the margin - + .tabbed-set:last-child { - margin-top: 0; - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: flavours -// ---------------------------------------------------------------------------- - -@each $names, $props in $admonitions { - $name: nth($names, 1); - $tint: nth($props, 2); - - // Admonition flavour - .md-typeset .admonition.#{$name} { - border-color: $tint; - } - - // Admonition flavour title - .md-typeset .#{$name} > .admonition-title { - background-color: transparentize($tint, 0.9); - border-color: $tint; - - // Admonition icon - &::before { - background-color: $tint; - mask-image: var(--md-admonition-icon--#{$name}); - mask-repeat: no-repeat; - mask-size: contain; - } - } - - // Define synonyms for flavours - @if length($names) > 1 { - @for $n from 2 through length($names) { - .#{nth($names, $n)} { - @extend .#{$name}; - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss b/docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss deleted file mode 100644 index b69dcf6e..00000000 --- a/docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss +++ /dev/null @@ -1,153 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-footnotes-icon: svg-load("material/keyboard-return.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Footnote container - .footnote { - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - - // Footnote list - omit left indentation - > ol { - margin-left: 0; - - // Footnote item - footnote items can contain lists, so we need to scope - // the spacing adjustments to the top-level footnote item. - > li { - transition: color 125ms; - - // Darken color on target - &:target { - color: var(--md-default-fg-color); - } - - // Show backreferences on footnote hover - &:hover .footnote-backref, - &:target .footnote-backref { - transform: translateX(0); - opacity: 1; - } - - // Adjust spacing on first child - > :first-child { - margin-top: 0; - } - } - } - } - - // Footnote reference - .footnote-ref { - font-weight: 700; - font-size: px2em(12px, 16px); - - // Hack: increase specificity to override default - html & { - outline-offset: px2rem(2px); - } - } - - // Footnote backreference - .footnote-backref { - display: inline-block; - color: var(--md-typeset-a-color); - // Hack: omit Unicode arrow for replacement with icon - font-size: 0; - vertical-align: text-bottom; - transform: translateX(px2rem(5px)); - opacity: 0; - transition: - color 250ms, - transform 250ms 250ms, - opacity 125ms 250ms; - - // [print]: Show footnote backreferences - @media print { - color: var(--md-typeset-a-color); - transform: translateX(0); - opacity: 1; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-5px)); - } - - // Adjust color on hover - &:hover { - color: var(--md-accent-fg-color); - } - - // Footnote backreference icon - &::before { - display: inline-block; - width: px2rem(16px); - height: px2rem(16px); - background-color: currentColor; - mask-image: var(--md-footnotes-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - } - - // Footnote reference wrapper - [id^="fnref:"]:target { - scroll-margin-top: initial; - margin-top: -1 * px2rem(48px + 24px - 4px); - padding-top: px2rem(48px + 24px - 4px); - - // Show outline for all devices - > .footnote-ref { - outline: auto; - } - } - - // Footnote wrapper - [id^="fn:"]:target { - scroll-margin-top: initial; - margin-top: -1 * px2rem(48px + 24px - 3px); - padding-top: px2rem(48px + 24px - 3px); - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss b/docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss deleted file mode 100644 index 78db25c3..00000000 --- a/docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss +++ /dev/null @@ -1,172 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Headerlink - .headerlink { - display: inline-block; - margin-left: px2rem(10px); - color: var(--md-default-fg-color--lighter); - opacity: 0; - transition: - color 250ms, - opacity 125ms; - - // [print]: Hide headerlinks - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(10px); - margin-left: initial; - } - } - - // Show headerlinks on parent hover - :hover > .headerlink, - :target > .headerlink, - .headerlink:focus { - opacity: 1; - transition: - color 250ms, - opacity 125ms; - } - - // Adjust color on parent target or focus/hover - :target > .headerlink, - .headerlink:focus, - .headerlink:hover { - color: var(--md-accent-fg-color); - } - - // Adjust scroll offset for all elements with `id` attributes - general scroll - // margin offset for anything that can be targeted. Browser support is pretty - // decent by now, but Edge <79 and Safari (iOS and macOS) still don't support - // it properly, so we settle with a cross-browser anchor correction solution. - :target { - scroll-margin-top: px2rem(48px + 24px); - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: px2rem(96px + 24px); - } - } - } - - // Adjust scroll offset for headlines of level 1-3 - h1:target, - h2:target, - h3:target { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - display: block; - margin-top: -1 * px2rem(48px + 24px - 4px); - padding-top: px2rem(48px + 24px - 4px); - content: ""; - } - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - margin-top: -1 * px2rem(96px + 24px - 4px); - padding-top: px2rem(96px + 24px - 4px); - } - } - } - } - - // Adjust scroll offset for headlines of level 4 - h4:target { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - display: block; - margin-top: -1 * px2rem(48px + 24px - 3px); - padding-top: px2rem(48px + 24px - 3px); - content: ""; - } - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - margin-top: -1 * px2rem(96px + 24px - 3px); - padding-top: px2rem(96px + 24px - 3px); - } - } - } - } - - // Adjust scroll offset for headlines of level 5-6 - h5:target, - h6:target { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - display: block; - margin-top: -1 * px2rem(48px + 24px); - padding-top: px2rem(48px + 24px); - content: ""; - } - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - margin-top: -1 * px2rem(96px + 24px); - padding-top: px2rem(96px + 24px); - } - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss deleted file mode 100644 index a96c9d44..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss +++ /dev/null @@ -1,48 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Arithmatex container - div.arithmatex { - overflow: auto; - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - margin: 0 px2rem(-16px); - } - - // Arithmatex content - > * { - width: min-content; - // stylelint-disable-next-line declaration-no-important - margin: 1em auto !important; - padding: 0 px2rem(16px); - touch-action: auto; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss deleted file mode 100644 index 08424723..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss +++ /dev/null @@ -1,81 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Deletion, addition or comment - del.critic, - ins.critic, - .critic.comment { - box-decoration-break: clone; - } - - // Deletion - del.critic { - background-color: var(--md-typeset-del-color); - } - - // Addition - ins.critic { - background-color: var(--md-typeset-ins-color); - } - - // Comment - .critic.comment { - color: var(--md-code-hl-comment-color); - - // Comment opening mark - &::before { - content: "/* "; - } - - // Comment closing mark - &::after { - content: " */"; - } - } - - // Critic block - .critic.block { - display: block; - margin: 1em 0; - padding-right: px2rem(16px); - padding-left: px2rem(16px); - overflow: auto; - box-shadow: none; - - // Adjust spacing on first child - > :first-child { - margin-top: 0.5em; - } - - // Adjust spacing on last child - > :last-child { - margin-bottom: 0.5em; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss deleted file mode 100644 index c26e08b4..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss +++ /dev/null @@ -1,128 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-details-icon: svg-load("material/chevron-right.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Details - details { - @extend .admonition; - - display: flow-root; - padding-top: 0; - overflow: visible; - - // Details title icon - rotate icon on transition to open state - &[open] > summary::after { - transform: rotate(90deg); - } - - // Adjust spacing for details in closed state - &:not([open]) { - padding-bottom: 0; - box-shadow: none; - - // Hack: we cannot set `overflow: hidden` on the `details` element (which - // is why we set it to `overflow: visible`, as the outline would not be - // visible when focusing. Therefore, we must set the border radius on the - // summary explicitly. - > summary { - border-radius: px2rem(2px); - } - } - - // Hack: omit margin collapse - &::after { - display: table; - content: ""; - } - } - - // Details title - summary { - @extend .admonition-title; - - display: block; - min-height: px2rem(20px); - padding: px2rem(8px) px2rem(36px) px2rem(8px) px2rem(40px); - border-top-left-radius: px2rem(2px); - border-top-right-radius: px2rem(2px); - cursor: pointer; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding: px2rem(8px) px2rem(44px) px2rem(8px) px2rem(36px); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Details marker - &::after { - position: absolute; - top: px2rem(8px); - right: px2rem(8px); - width: px2rem(20px); - height: px2rem(20px); - background-color: currentColor; - mask-image: var(--md-details-icon); - mask-repeat: no-repeat; - mask-size: contain; - transform: rotate(0deg); - transition: transform 250ms; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(8px); - transform: rotate(180deg); - } - } - - // Hide native details marker - &::marker, - &::-webkit-details-marker { - display: none; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss deleted file mode 100644 index 693fb7ce..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss +++ /dev/null @@ -1,45 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Emoji and icon container - .emojione, - .twemoji, - .gemoji { - display: inline-flex; - height: px2em(18px); - vertical-align: text-top; - - // Icon - inlined via mkdocs-material-extensions - svg { - width: px2em(18px); - max-height: 100%; - fill: currentColor; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss deleted file mode 100644 index 38289576..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss +++ /dev/null @@ -1,275 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules: syntax highlighting -// ---------------------------------------------------------------------------- - -// Code block -.highlight { - .o, // Operator - .ow { // Operator, word - color: var(--md-code-hl-operator-color); - } - - .p { // Punctuation - color: var(--md-code-hl-punctuation-color); - } - - .cpf, // Comment, preprocessor file - .l, // Literal - .s, // Literal, string - .sb, // Literal, string backticks - .sc, // Literal, string char - .s2, // Literal, string double - .si, // Literal, string interpol - .s1, // Literal, string single - .ss { // Literal, string symbol - color: var(--md-code-hl-string-color); - } - - .cp, // Comment, pre-processor - .se, // Literal, string escape - .sh, // Literal, string heredoc - .sr, // Literal, string regex - .sx { // Literal, string other - color: var(--md-code-hl-special-color); - } - - .m, // Number - .mb, // Number, binary - .mf, // Number, float - .mh, // Number, hex - .mi, // Number, integer - .il, // Number, integer long - .mo { // Number, octal - color: var(--md-code-hl-number-color); - } - - .k, // Keyword, - .kd, // Keyword, declaration - .kn, // Keyword, namespace - .kp, // Keyword, pseudo - .kr, // Keyword, reserved - .kt { // Keyword, type - color: var(--md-code-hl-keyword-color); - } - - .kc, // Keyword, constant - .n { // Name - color: var(--md-code-hl-name-color); - } - - .no, // Name, constant - .nb, // Name, builtin - .bp { // Name, builtin pseudo - color: var(--md-code-hl-constant-color); - } - - .nc, // Name, class - .ne, // Name, exception - .nf, // Name, function - .nn { // Name, namespace - color: var(--md-code-hl-function-color); - } - - .nd, // Name, decorator - .ni, // Name, entity - .nl, // Name, label - .nt { // Name, tag - color: var(--md-code-hl-keyword-color); - } - - .c, // Comment - .cm, // Comment, multiline - .c1, // Comment, single - .ch, // Comment, shebang - .cs, // Comment, special - .sd { // Literal, string doc - color: var(--md-code-hl-comment-color); - } - - .na, // Name, attribute - .nv, // Variable, - .vc, // Variable, class - .vg, // Variable, global - .vi { // Variable, instance - color: var(--md-code-hl-variable-color); - } - - .ge, // Generic, emph - .gr, // Generic, error - .gh, // Generic, heading - .go, // Generic, output - .gp, // Generic, prompt - .gs, // Generic, strong - .gu, // Generic, subheading - .gt { // Generic, traceback - color: var(--md-code-hl-generic-color); - } - - .gd, // Diff, delete - .gi { // Diff, insert - margin: 0 px2em(-2px); - padding: 0 px2em(2px); - border-radius: px2rem(2px); - } - - .gd { // Diff, delete - background-color: var(--md-typeset-del-color); - } - - .gi { // Diff, insert - background-color: var(--md-typeset-ins-color); - } - - // Highlighted line - .hll { - display: block; - margin: 0 px2em(-16px, 13.6px); - padding: 0 px2em(16px, 13.6px); - background-color: var(--md-code-hl-color); - } - - // Code block line numbers (inline) - [data-linenos]::before { - position: sticky; - left: px2em(-16px, 13.6px); - float: left; - margin-right: px2em(16px, 13.6px); - margin-left: px2em(-16px, 13.6px); - padding-left: px2em(16px, 13.6px); - color: var(--md-default-fg-color--light); - background-color: var(--md-code-bg-color); - box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset; - content: attr(data-linenos); - user-select: none; - } -} - -// ---------------------------------------------------------------------------- -// Rules: layout -// ---------------------------------------------------------------------------- - -// Code block with line numbers -.highlighttable { - display: flow-root; - overflow: hidden; - - // Set table elements to block layout, because otherwise the whole flexbox - // hacking won't work correctly - tbody, - td { - display: block; - padding: 0; - } - - // We need to use flexbox layout, because otherwise it's not possible to - // make the code container scroll while keeping the line numbers static - tr { - display: flex; - } - - // The pre tags are nested inside a table, so we need to omit the margin - // because it collapses below all the overflows - pre { - margin: 0; - } - - // Code block line numbers - disable user selection, so code can be easily - // copied without accidentally also copying the line numbers - .linenos { - padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px); - padding-right: 0; - font-size: px2em(13.6px); - background-color: var(--md-code-bg-color); - user-select: none; - } - - // Code block line numbers container - .linenodiv { - padding-right: px2em(8px, 13.6px); - box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset; - - // Adjust colors and alignment - pre { - color: var(--md-default-fg-color--light); - text-align: right; - } - } - - // Code block container - stretch to remaining space - .code { - flex: 1; - overflow: hidden; - } -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Code block with line numbers - .highlighttable { - margin: 1em 0; - direction: ltr; - border-radius: px2rem(2px); - - // Omit rounded borders on contained code block - code { - border-radius: 0; - } - } - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - - // Top-level code block - > .highlight { - margin: 1em px2rem(-16px); - - // Highlighted line - .hll { - margin: 0 px2rem(-16px); - padding: 0 px2rem(16px); - } - - // Omit rounded borders - code { - border-radius: 0; - } - } - - // Top-level code block with line numbers - > .highlighttable { - margin: 1em px2rem(-16px); - border-radius: 0; - - // Highlighted line - .hll { - margin: 0 px2rem(-16px); - padding: 0 px2rem(16px); - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss deleted file mode 100644 index 75785945..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss +++ /dev/null @@ -1,120 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Keyboard key - .keys { - - // Keyboard key icon - kbd::before, - kbd::after { - position: relative; - margin: 0; - color: inherit; - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - } - - // Surrounding text - span { - padding: 0 px2em(3.2px); - color: var(--md-default-fg-color--light); - } - - // Define keyboard keys with left icon - @each $name, $code in ( - - // Modifiers - "alt": "\2387", - "left-alt": "\2387", - "right-alt": "\2387", - "command": "\2318", - "left-command": "\2318", - "right-command": "\2318", - "control": "\2303", - "left-control": "\2303", - "right-control": "\2303", - "meta": "\25C6", - "left-meta": "\25C6", - "right-meta": "\25C6", - "option": "\2325", - "left-option": "\2325", - "right-option": "\2325", - "shift": "\21E7", - "left-shift": "\21E7", - "right-shift": "\21E7", - "super": "\2756", - "left-super": "\2756", - "right-super": "\2756", - "windows": "\229E", - "left-windows": "\229E", - "right-windows": "\229E", - - // Other keys - "arrow-down": "\2193", - "arrow-left": "\2190", - "arrow-right": "\2192", - "arrow-up": "\2191", - "backspace": "\232B", - "backtab": "\21E4", - "caps-lock": "\21EA", - "clear": "\2327", - "context-menu": "\2630", - "delete": "\2326", - "eject": "\23CF", - "end": "\2913", - "escape": "\238B", - "home": "\2912", - "insert": "\2380", - "page-down": "\21DF", - "page-up": "\21DE", - "print-screen": "\2399" - ) { - .key-#{$name} { - &::before { - padding-right: px2em(6.4px); - content: $code; - } - } - } - - // Define keyboard keys with right icon - @each $name, $code in ( - "tab": "\21E5", - "num-enter": "\2324", - "enter": "\23CE" - ) { - .key-#{$name} { - &::after { - padding-left: px2em(6.4px); - content: $code; - } - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss deleted file mode 100644 index 1727d15d..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss +++ /dev/null @@ -1,123 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Tabbed block content - .tabbed-content { - display: none; - order: 99; - width: 100%; - box-shadow: 0 px2rem(-1px) var(--md-default-fg-color--lightest); - - // [print]: Show all tabs (even hidden ones) when printing - @media print { - display: block; - order: initial; - } - - // Code block is the only child of a tab - remove margin and mirror - // previous (now deprecated) SuperFences code block grouping behavior - > pre:only-child, - > .highlight:only-child pre, - > .highlighttable:only-child { - margin: 0; - - // Omit rounded borders - > code { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - - // Adjust spacing for nested tab - > .tabbed-set { - margin: 0; - } - } - - // Tabbed block container - .tabbed-set { - position: relative; - display: flex; - flex-wrap: wrap; - margin: 1em 0; - border-radius: px2rem(2px); - - // Tab radio button - the Tabbed extension will generate radio buttons with - // labels, so tabs can be triggered without the necessity for JavaScript. - // This is pretty cool, as it has great accessibility out-of-the box, so - // we just hide the radio button and toggle the label color for indication. - > input { - position: absolute; - width: 0; - height: 0; - opacity: 0; - - // Tab label for checked radio button - &:checked + label { - color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - - // Show tabbed block content - + .tabbed-content { - display: block; - } - } - - // Tab label on focus - &:focus + label { - outline-style: auto; - outline-color: var(--md-accent-fg-color); - } - - // Hide outline for pointer devices - &:not(.focus-visible) + label { - outline: none; - -webkit-tap-highlight-color: transparent; - } - } - - // Tab label - > label { - z-index: 1; - width: auto; - padding: px2em(12px, 12.8px) 1.25em px2em(10px, 12.8px); - color: var(--md-default-fg-color--light); - font-weight: 700; - font-size: px2rem(12.8px); - border-bottom: px2rem(2px) solid transparent; - cursor: pointer; - transition: color 250ms; - - // Tab label on hover - &:hover { - color: var(--md-accent-fg-color); - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss deleted file mode 100644 index 6ee10486..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss +++ /dev/null @@ -1,91 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-tasklist-icon: - svg-load("octicons/check-circle-fill-24.svg"); - --md-tasklist-icon--checked: - svg-load("octicons/check-circle-fill-24.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Tasklist item - .task-list-item { - position: relative; - list-style-type: none; - - // Make checkbox items align with normal list items, but position - // everything in ems for correct layout at smaller font sizes - [type="checkbox"] { - position: absolute; - top: 0.45em; - left: -2em; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: -2em; - left: initial; - } - } - } - - // Hide native checkbox, when custom classes are enabled - .task-list-control [type="checkbox"] { - z-index: -1; - opacity: 0; - } - - // Tasklist indicator in unchecked state - .task-list-indicator::before { - position: absolute; - top: 0.15em; - left: px2em(-24px); - width: px2em(20px); - height: px2em(20px); - background-color: var(--md-default-fg-color--lightest); - mask-image: var(--md-tasklist-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2em(-24px); - left: initial; - } - } - - // Tasklist indicator in checked state - [type="checkbox"]:checked + .task-list-indicator::before { - background-color: $clr-green-a400; - mask-image: var(--md-tasklist-icon--checked); - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_announce.scss b/docs/src/assets/stylesheets/main/layout/_announce.scss deleted file mode 100644 index 4f2a13b9..00000000 --- a/docs/src/assets/stylesheets/main/layout/_announce.scss +++ /dev/null @@ -1,44 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Announcement bar -.md-announce { - overflow: auto; - background-color: var(--md-footer-bg-color); - - // [print]: Hide announcement bar - @media print { - display: none; - } - - // Announcement wrapper - &__inner { - margin: px2rem(12px) auto; - padding: 0 px2rem(16px); - color: var(--md-footer-fg-color); - font-size: px2rem(14px); - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_base.scss b/docs/src/assets/stylesheets/main/layout/_base.scss deleted file mode 100644 index 7863fec2..00000000 --- a/docs/src/assets/stylesheets/main/layout/_base.scss +++ /dev/null @@ -1,184 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules: base grid and containers -// ---------------------------------------------------------------------------- - -// Stretch container to viewport and set base `font-size` -html { - height: 100%; - overflow-x: hidden; - // Hack: normally, we would set the base `font-size` to `62.5%`, so we can - // base all calculations on `10px`, but Chromium and Chrome define a minimal - // `font-size` of `12px` if the system language is set to Chinese. For this - // reason we just double the `font-size` and set it to `20px`. - // - // See https://github.com/squidfunk/mkdocs-material/issues/911 - font-size: 125%; - - // [screen medium +]: Set base `font-size` to `11px` - @include break-from-device(screen medium) { - font-size: 137.5%; - } - - // [screen large +]: Set base `font-size` to `12px` - @include break-from-device(screen large) { - font-size: 150%; - } -} - -// Stretch body to container - flexbox is used, so the footer will always be -// aligned to the bottom of the viewport -body { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - min-height: 100%; - // Hack: reset `font-size` to `10px`, so the spacing for all inline elements - // is correct again. Otherwise the spacing would be based on `20px`. - font-size: px2rem(10px); - background-color: var(--md-default-bg-color); - - // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m) - @media print { - display: block; - } - - // Body in locked state - &[data-md-state="lock"] { - - // [tablet portrait -]: Omit scroll bubbling - @include break-to-device(tablet portrait) { - position: fixed; - } - } -} - -// ---------------------------------------------------------------------------- - -// Grid container - this class is applied to wrapper elements within the -// header, content area and footer, and makes sure that their width is limited -// to `1220px`, and they are rendered centered if the screen is larger. -.md-grid { - max-width: px2rem(1220px); - margin-right: auto; - margin-left: auto; -} - -// Main container -.md-container { - display: flex; - flex-direction: column; - flex-grow: 1; - - // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m) - @media print { - display: block; - } -} - -// Main area - stretch to remaining space of container -.md-main { - flex-grow: 1; - - // Main area wrapper - &__inner { - display: flex; - height: 100%; - margin-top: px2rem(24px + 6px); - } -} - -// Add ellipsis in case of overflowing text -.md-ellipsis { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -// ---------------------------------------------------------------------------- -// Rules: navigational elements -// ---------------------------------------------------------------------------- - -// Toggle - this class is applied to checkbox elements, which are used to -// implement the CSS-only drawer and navigation, as well as the search -.md-toggle { - display: none; -} - -// Option - this class is applied to radio elements, which are used to -// implement the color palette toggle -.md-option { - position: absolute; - width: 0; - height: 0; - opacity: 0; - - // Option label for checked radio button - &:checked + label:not([hidden]) { - display: block; - } - - // Show outline for keyboard devices - &.focus-visible + label { - outline-style: auto; - outline-color: var(--md-accent-fg-color); - } -} - -// Skip link -.md-skip { - position: fixed; - // Hack: if we don't set the negative `z-index`, the skip link will force the - // creation of new layers when code blocks are near the header on scrolling - z-index: -1; - margin: px2rem(10px); - padding: px2rem(6px) px2rem(10px); - color: var(--md-default-bg-color); - font-size: px2rem(12.8px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - outline-color: var(--md-accent-fg-color); - transform: translateY(px2rem(8px)); - opacity: 0; - - // Show skip link on focus - &:focus { - z-index: 10; - transform: translateY(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 175ms 75ms; - } -} - -// ---------------------------------------------------------------------------- -// Rules: print styles -// ---------------------------------------------------------------------------- - -// Add margins to page -@page { - margin: 25mm; -} diff --git a/docs/src/assets/stylesheets/main/layout/_clipboard.scss b/docs/src/assets/stylesheets/main/layout/_clipboard.scss deleted file mode 100644 index eff2c719..00000000 --- a/docs/src/assets/stylesheets/main/layout/_clipboard.scss +++ /dev/null @@ -1,103 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-clipboard-icon: svg-load("material/content-copy.svg"); -} - -// ---------------------------------------------------------------------------- - -// Button to copy to clipboard -.md-clipboard { - position: absolute; - top: px2em(8px); - right: px2em(8px); - z-index: 1; - width: px2em(24px); - height: px2em(24px); - color: var(--md-default-fg-color--lightest); - border-radius: px2rem(2px); - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(2px); - cursor: pointer; - transition: color 250ms; - - // [print]: Hide button - @media print { - display: none; - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Darken color on code block hover - :hover > & { - color: var(--md-default-fg-color--light); - } - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Button icon - the width and height are defined in `em`, so the size is - // automatically adjusted for nested code blocks (e.g. in admonitions) - &::after { - display: block; - width: px2em(18px); - height: px2em(18px); - margin: 0 auto; - background-color: currentColor; - mask-image: var(--md-clipboard-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Inline button - &--inline { - cursor: pointer; - - // Code block - code { - transition: - color 250ms, - background-color 250ms; - } - - // Code block on focus/hover - &:focus code, - &:hover code { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_content.scss b/docs/src/assets/stylesheets/main/layout/_content.scss deleted file mode 100644 index e53f76cc..00000000 --- a/docs/src/assets/stylesheets/main/layout/_content.scss +++ /dev/null @@ -1,119 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Content area -.md-content { - flex-grow: 1; - // Hack: we must use `overflow: hidden`, so the content area is capped by - // the dimensions of its parent. Otherwise, long code blocks might lead to - // a wider content area which will break everything. This, however, induces - // margin collapse, which will break scroll margins. Adding a large enough - // scroll padding seems to do the trick, at least in Chrome and Firefox. - overflow: hidden; - scroll-padding-top: px2rem(1024px); - - // Content wrapper - &__inner { - margin: 0 px2rem(16px) px2rem(24px); - padding-top: px2rem(12px); - - // [screen +]: Adjust spacing between content area and sidebars - @include break-from-device(screen) { - - // Sidebar with navigation is visible - .md-sidebar--primary:not([hidden]) ~ .md-content > & { - margin-left: px2rem(24px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(24px); - margin-left: px2rem(16px); - } - } - - // Sidebar with table of contents is visible - .md-sidebar--secondary:not([hidden]) ~ .md-content > & { - margin-right: px2rem(24px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(16px); - margin-left: px2rem(24px); - } - } - } - - // Hack: add pseudo element for spacing, as the overflow of the content - // container may not be hidden due to an imminent offset error on targets - &::before { - display: block; - height: px2rem(8px); - content: ""; - } - - // Adjust spacing on last child - > :last-child { - margin-bottom: 0; - } - } - - // Button inside of the content area - these buttons are meant for actions on - // a document-level, i.e. linking to related source code files, printing etc. - &__button { - float: right; - margin: px2rem(8px) 0; - margin-left: px2rem(8px); - padding: 0; - - // [print]: Hide buttons - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - margin-right: px2rem(8px); - margin-left: initial; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - - // Adjust default link color for icons - .md-typeset & { - color: var(--md-default-fg-color--lighter); - } - - // Align with body copy located next to icon - svg { - display: inline; - vertical-align: top; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_dialog.scss b/docs/src/assets/stylesheets/main/layout/_dialog.scss deleted file mode 100644 index e522aba3..00000000 --- a/docs/src/assets/stylesheets/main/layout/_dialog.scss +++ /dev/null @@ -1,73 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Dialog -.md-dialog { - @include z-depth(2); - - position: fixed; - right: px2rem(16px); - bottom: px2rem(16px); - left: initial; - z-index: 3; - min-width: px2rem(222px); - padding: px2rem(8px) px2rem(12px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - transform: translateY(100%); - opacity: 0; - transition: - transform 0ms 400ms, - opacity 400ms; - pointer-events: none; - - // [print]: Hide dialog - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(16px); - } - - // Dialog in open state - &[data-md-state="open"] { - transform: translateY(0); - opacity: 1; - transition: - transform 400ms cubic-bezier(0.075, 0.85, 0.175, 1), - opacity 400ms; - pointer-events: initial; - } - - // Dialog wrapper - &__inner { - color: var(--md-default-bg-color); - font-size: px2rem(14px); - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_footer.scss b/docs/src/assets/stylesheets/main/layout/_footer.scss deleted file mode 100644 index 97a53b7e..00000000 --- a/docs/src/assets/stylesheets/main/layout/_footer.scss +++ /dev/null @@ -1,211 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Footer -.md-footer { - color: var(--md-footer-fg-color); - background-color: var(--md-footer-bg-color); - - // [print]: Hide footer - @media print { - display: none; - } - - // Footer wrapper - &__inner { - padding: px2rem(4px); - overflow: auto; - } - - // Footer link to previous and next page - &__link { - display: flex; - padding-top: px2rem(28px); - padding-bottom: px2rem(8px); - outline-color: var(--md-accent-fg-color); - transition: opacity 250ms; - - // [tablet +]: Adjust width to 50/50 - @include break-from-device(tablet) { - width: 50%; - } - - // Footer link on focus/hover - &:focus, - &:hover { - opacity: 0.7; - } - - // Footer link to previous page - &--prev { - float: left; - - // [mobile -]: Adjust width to 25/75 and hide title - @include break-to-device(mobile) { - width: 25%; - - // Hide footer title - .md-footer__title { - display: none; - } - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: right; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - - // Footer link to next page - &--next { - float: right; - text-align: right; - - // [mobile -]: Adjust width to 25/75 - @include break-to-device(mobile) { - width: 75%; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - text-align: left; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - } - - // Footer title - &__title { - position: relative; - flex-grow: 1; - max-width: calc(100% - #{px2rem(48px)}); - padding: 0 px2rem(20px); - font-size: px2rem(18px); - line-height: px2rem(48px); - } - - // Footer link button - &__button { - margin: px2rem(4px); - padding: px2rem(8px); - } - - // Footer link direction (i.e. prev and next) - &__direction { - position: absolute; - right: 0; - left: 0; - margin-top: px2rem(-20px); - padding: 0 px2rem(20px); - font-size: px2rem(12.8px); - opacity: 0.7; - } -} - -// Footer metadata -.md-footer-meta { - background-color: var(--md-footer-bg-color--dark); - - // Footer metadata wrapper - &__inner { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - padding: px2rem(4px); - } - - // Lighten color for non-hovered text links - html &.md-typeset a { - color: var(--md-footer-fg-color--light); - - // Text link on focus/hover - &:focus, - &:hover { - color: var(--md-footer-fg-color); - } - } -} - -// Footer copyright and theme information -.md-footer-copyright { - width: 100%; - margin: auto px2rem(12px); - padding: px2rem(8px) 0; - color: var(--md-footer-fg-color--lighter); - font-size: px2rem(12.8px); - - // [tablet portrait +]: Show copyright and social links in one line - @include break-from-device(tablet portrait) { - width: auto; - } - - // Footer copyright highlight - this is the upper part of the copyright and - // theme information, which will include a darker color than the theme link - &__highlight { - color: var(--md-footer-fg-color--light); - } -} - -// Footer social links -.md-footer-social { - margin: 0 px2rem(8px); - padding: px2rem(4px) 0 px2rem(12px); - - // [tablet portrait +]: Show copyright and social links in one line - @include break-from-device(tablet portrait) { - padding: px2rem(12px) 0; - } - - // Footer social link - &__link { - display: inline-block; - width: px2rem(32px); - height: px2rem(32px); - text-align: center; - - // Adjust line-height to match height for correct alignment - &::before { - line-height: 1.9; - } - - // Fill icon with current color - svg { - max-height: px2rem(16px); - vertical-align: -25%; - fill: currentColor; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_form.scss b/docs/src/assets/stylesheets/main/layout/_form.scss deleted file mode 100644 index e525fa7a..00000000 --- a/docs/src/assets/stylesheets/main/layout/_form.scss +++ /dev/null @@ -1,84 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Form button - .md-button { - display: inline-block; - padding: px2em(10px) px2em(32px); - color: var(--md-primary-fg-color); - font-weight: 700; - border: px2rem(2px) solid currentColor; - border-radius: px2rem(2px); - cursor: pointer; - transition: - color 125ms, - background-color 125ms, - border-color 125ms; - - // Primary button - &--primary { - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - border-color: var(--md-primary-fg-color); - } - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - } - } - - // Form input - .md-input { - height: px2rem(36px); - padding: 0 px2rem(12px); - font-size: px2rem(16px); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.1); - transition: box-shadow 250ms; - - // Input on focus/hover - &:focus, - &:hover { - box-shadow: - 0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15); - } - - // Stretch to full width - &--stretch { - width: 100%; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_header.scss b/docs/src/assets/stylesheets/main/layout/_header.scss deleted file mode 100644 index c189d437..00000000 --- a/docs/src/assets/stylesheets/main/layout/_header.scss +++ /dev/null @@ -1,272 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Header - by default, the header will be sticky and stay always on top of the -// viewport. If this behavior is not desired, just set `position: static`. -.md-header { - position: sticky; - top: 0; - right: 0; - left: 0; - z-index: 3; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - // Hack: reduce jitter by adding a transparent box shadow of the same size - // so the size of the layer doesn't change during animation - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0); - - // [print]: Hide header - @media print { - display: none; - } - - // Header in shadow state, i.e. shadow is visible - &[data-md-state="shadow"] { - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0.1), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0.2); - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - box-shadow 250ms; - } - - // Header in hidden state, i.e. moved out of sight - &[data-md-state="hidden"] { - transform: translateY(-100%); - transition: - transform 250ms cubic-bezier(0.8, 0, 0.6, 1), - box-shadow 250ms; - } - - // Header wrapper - &__inner { - display: flex; - align-items: center; - padding: 0 px2rem(4px); - } - - // Header button - &__button { - position: relative; - z-index: 1; - margin: px2rem(4px); - padding: px2rem(8px); - color: currentColor; - vertical-align: middle; - outline-color: var(--md-accent-fg-color); - cursor: pointer; - transition: opacity 250ms; - - // Button on hover - &:hover { - opacity: 0.7; - } - - // Header button is visible - &:not([hidden]) { - display: inline-block; - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Button with logo, pointing to `config.site_url` - &.md-logo { - margin: px2rem(4px); - padding: px2rem(8px); - - // [tablet -]: Hide button - @include break-to-device(tablet) { - display: none; - } - - // Image or icon - img, - svg { - display: block; - width: px2rem(24px); - height: px2rem(24px); - fill: currentColor; - } - } - - // Button for search - &[for="__search"] { - - // [tablet landscape +]: Hide button - @include break-from-device(tablet landscape) { - display: none; - } - - // [no-js]: Hide button - .no-js & { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - - // Button for drawer - &[for="__drawer"] { - - // [screen +]: Hide button - @include break-from-device(screen) { - display: none; - } - } - } - - // Header topic - &__topic { - position: absolute; - display: flex; - max-width: 100%; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Second header topic - title of the current page - & + & { - z-index: -1; - transform: translateX(px2rem(25px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1), - opacity 150ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-25px)); - } - } - } - - // Header title - &__title { - flex-grow: 1; - height: px2rem(48px); - margin-right: px2rem(8px); - margin-left: px2rem(20px); - font-size: px2rem(18px); - line-height: px2rem(48px); - - // Header title in active state, i.e. page title is visible - &[data-md-state="active"] .md-header__topic { - z-index: -1; - transform: translateX(px2rem(-25px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1), - opacity 150ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(25px)); - } - - // Second header topic - title of the current page - + .md-header__topic { - z-index: 0; - transform: translateX(0); - opacity: 1; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - pointer-events: initial; - } - } - - // Add ellipsis in case of overflowing text - > .md-header__ellipsis { - position: relative; - width: 100%; - height: 100%; - } - } - - // Header option - &__option { - display: flex; - flex-shrink: 0; - max-width: 100%; - white-space: nowrap; - transition: - max-width 0ms 250ms, - opacity 250ms 250ms; - - // Hide toggle when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - max-width: 0; - opacity: 0; - transition: - max-width 0ms, - opacity 0ms; - } - } - - // Repository information container - &__source { - display: none; - - // [tablet landscape +]: Show repository information - @include break-from-device(tablet landscape) { - display: block; - width: px2rem(234px); - max-width: px2rem(234px); - margin-left: px2rem(20px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(20px); - margin-left: initial; - } - } - - // [screen +]: Adjust spacing of search bar - @include break-from-device(screen) { - margin-left: px2rem(28px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(28px); - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_nav.scss b/docs/src/assets/stylesheets/main/layout/_nav.scss deleted file mode 100644 index 6a8886a9..00000000 --- a/docs/src/assets/stylesheets/main/layout/_nav.scss +++ /dev/null @@ -1,687 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-nav-icon--prev: svg-load("material/arrow-left.svg"); - --md-nav-icon--next: svg-load("material/chevron-right.svg"); - --md-toc-icon: svg-load("material/table-of-contents.svg"); -} - -// ---------------------------------------------------------------------------- - -// Navigation -.md-nav { - font-size: px2rem(14px); - line-height: 1.3; - - // Navigation title - &__title { - display: block; - padding: 0 px2rem(12px); - overflow: hidden; - font-weight: 700; - text-overflow: ellipsis; - - // Navigaton button - .md-nav__button { - display: none; - - // Stretch images based on height, as it's the smaller dimension - img { - width: auto; - height: 100%; - } - - // Button with logo, pointing to `config.site_url` - &.md-logo { - - // Image or icon - img, - svg { - display: block; - width: px2rem(48px); - height: px2rem(48px); - fill: currentColor; - } - } - } - } - - // Navigation list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Navigation item - &__item { - padding: 0 px2rem(12px); - - // Navigation item on level 2 - & & { - padding-right: 0; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: 0; - } - } - } - - // Navigation link - &__link { - display: block; - margin-top: 0.625em; - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - transition: color 125ms; - scroll-snap-align: start; - - // Link in blurred state - &[data-md-state="blur"] { - color: var(--md-default-fg-color--light); - } - - // Active link - .md-nav__item &--active { - color: var(--md-typeset-a-color); - } - - // Navigation link in nested list - .md-nav__item--nested > & { - color: inherit; - } - - // Navigation link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - - // Navigation link to table of contents - .md-nav--primary &[for="__toc"] { - display: none; - - // Table of contents icon - .md-icon::after { - display: block; - width: 100%; - height: 100%; - mask-image: var(--md-toc-icon); - background-color: currentColor; - } - - // Hide table of contents - ~ .md-nav { - display: none; - } - } - } - - // Repository information container - &__source { - display: none; - } - - // [tablet -]: Layered navigation - @include break-to-device(tablet) { - - // Primary and nested navigation - &--primary, - &--primary & { - position: absolute; - top: 0; - right: 0; - left: 0; - z-index: 1; - display: flex; - flex-direction: column; - height: 100%; - background-color: var(--md-default-bg-color); - } - - // Primary navigation - &--primary { - - // Navigation title and item - .md-nav__title, - .md-nav__item { - font-size: px2rem(16px); - line-height: 1.5; - } - - // Navigation title - .md-nav__title { - position: relative; - height: px2rem(112px); - padding: px2rem(60px) px2rem(16px) px2rem(4px); - color: var(--md-default-fg-color--light); - font-weight: 400; - line-height: px2rem(48px); - white-space: nowrap; - background-color: var(--md-default-fg-color--lightest); - cursor: pointer; - - // Navigation icon - .md-nav__icon { - position: absolute; - top: px2rem(8px); - left: px2rem(8px); - display: block; - width: px2rem(24px); - height: px2rem(24px); - margin: px2rem(4px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(8px); - left: initial; - } - - // Navigation icon in link to previous level - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentColor; - mask-image: var(--md-nav-icon--prev); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - - // Navigation list - ~ .md-nav__list { - overflow-y: auto; - background-color: var(--md-default-bg-color); - box-shadow: - 0 px2rem(1px) 0 var(--md-default-fg-color--lightest) inset; - scroll-snap-type: y mandatory; - touch-action: pan-y; - - // Omit border on first child - > :first-child { - border-top: 0; - } - } - - // Top-level navigation title - &[for="__drawer"] { - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - } - - // Button with logo, pointing to `config.site_url` - .md-logo { - position: absolute; - top: px2rem(4px); - left: px2rem(4px); - display: block; - margin: px2rem(4px); - padding: px2rem(8px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(4px); - left: initial; - } - } - } - - // Navigation list - .md-nav__list { - flex: 1; - } - - // Navigation item - .md-nav__item { - padding: 0; - border-top: px2rem(1px) solid var(--md-default-fg-color--lightest); - - // Navigation link in nested navigation - &--nested > .md-nav__link { - padding-right: px2rem(48px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(16px); - padding-left: px2rem(48px); - } - } - - // Navigation link in active navigation - &--active > .md-nav__link { - color: var(--md-typeset-a-color); - - // Navigation link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - } - } - - // Navigation link - .md-nav__link { - position: relative; - margin-top: 0; - padding: px2rem(12px) px2rem(16px); - - // Navigation icon - .md-nav__icon { - position: absolute; - top: 50%; - right: px2rem(12px); - width: px2rem(24px); - height: px2rem(24px); - margin-top: px2rem(-12px); - color: inherit; - font-size: px2rem(24px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(12px); - } - - // Navigation icon in link to next level - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentColor; - mask-image: var(--md-nav-icon--next); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - } - - // Flip icon vertically - .md-nav__icon { - - // Adjust for right-to-left languages - [dir="rtl"] &::after { - transform: scale(-1); - } - } - - // Table of contents contained in primary navigation - .md-nav--secondary { - - // Navigation link - omit unnecessary layering - .md-nav__link { - position: static; - } - - // Navigation on level 2-6 - .md-nav { - position: static; - background-color: transparent; - - // Navigation link on level 3 - .md-nav__link { - padding-left: px2rem(28px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(28px); - padding-left: initial; - } - } - - // Navigation link on level 4 - .md-nav .md-nav__link { - padding-left: px2rem(40px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(40px); - padding-left: initial; - } - } - - // Navigation link on level 5 - .md-nav .md-nav .md-nav__link { - padding-left: px2rem(52px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(52px); - padding-left: initial; - } - } - - // Navigation link on level 6 - .md-nav .md-nav .md-nav .md-nav__link { - padding-left: px2rem(64px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(64px); - padding-left: initial; - } - } - } - } - } - - // Table of contents - &--secondary { - background-color: transparent; - } - - // Toggle for nested navigation - &__toggle ~ & { - display: flex; - transform: translateX(100%); - opacity: 0; - transition: - transform 250ms cubic-bezier(0.8, 0, 0.6, 1), - opacity 125ms 50ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(-100%); - } - } - - // Show nested navigation when toggle is active - &__toggle:checked ~ & { - transform: translateX(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 125ms 125ms; - - // Navigation list - > .md-nav__list { - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - } - } - } - - // [tablet portrait -]: Layered navigation with table of contents - @include break-to-device(tablet portrait) { - - // Show link to table of contents - &--primary &__link[for="__toc"] { - display: block; - padding-right: px2rem(48px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(16px); - padding-left: px2rem(48px); - } - - // Show table of contents icon - .md-icon::after { - content: ""; - } - - // Hide navigation link to current page - + .md-nav__link { - display: none; - } - - // Show table of contents - ~ .md-nav { - display: flex; - } - } - - // Repository information container - &__source { - display: block; - padding: 0 px2rem(4px); - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color--dark); - } - } - - // [tablet landscape]: Layered navigation with table of contents - @include break-at-device(tablet landscape) { - - // Show link to integrated table of contents - &--integrated &__link[for="__toc"] { - display: block; - padding-right: px2rem(48px); - scroll-snap-align: initial; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(16px); - padding-left: px2rem(48px); - } - - // Show table of contents icon - .md-icon::after { - content: ""; - } - - // Hide navigation link to current page - + .md-nav__link { - display: none; - } - - // Show table of contents - ~ .md-nav { - display: flex; - } - } - } - - // [tablet landscape +]: Tree-like table of contents - @include break-from-device(tablet landscape) { - - // Navigation title - &--secondary &__title { - - // Adjust snapping behavior - &[for="__toc"] { - scroll-snap-align: start; - } - - // Hide navigation icon - .md-nav__icon { - display: none; - } - } - } - - // [screen +]: Tree-like navigation - @include break-from-device(screen) { - transition: max-height 250ms cubic-bezier(0.86, 0, 0.07, 1); - - // Navigation title - &--primary &__title { - - // Adjust snapping behavior - &[for="__drawer"] { - scroll-snap-align: start; - } - - // Hide navigation icon - .md-nav__icon { - display: none; - } - } - - // Hide toggle for nested navigation - &__toggle ~ & { - display: none; - } - - // Show nested navigation when toggle is active or indeterminate - &__toggle:checked ~ &, - &__toggle:indeterminate ~ & { - display: block; - } - - // Hide navigation title in nested navigation - &__item--nested > & > &__title { - display: none; - } - - // Navigation section - &__item--section { - display: block; - margin: 1.25em 0; - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - - // Hide navigation link, as sections are always expanded - > .md-nav__link { - display: none; - } - - // Navigation - > .md-nav { - display: block; - - // Navigation title - > .md-nav__title { - display: block; - padding: 0; - pointer-events: none; - scroll-snap-align: start; - } - - // Adjust spacing on next level item - > .md-nav__list > .md-nav__item { - padding: 0; - } - } - } - - // Navigation icon - &__icon { - float: right; - width: px2rem(18px); - height: px2rem(18px); - transition: transform 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - transform: rotate(180deg); - } - - // Navigation icon content - &::after { - display: inline-block; - width: 100%; - height: 100%; - vertical-align: px2rem(-2px); - background-color: currentColor; - mask-image: var(--md-nav-icon--next); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Navigation icon - rotate icon when toggle is active or indeterminate - .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link &, - .md-nav__item--nested .md-nav__toggle:indeterminate ~ .md-nav__link & { - transform: rotate(90deg); - } - } - - // Modifier for when navigation tabs are rendered - &--lifted { - - // Hide nested level 0 items and site title - > .md-nav__list > .md-nav__item--nested, - > .md-nav__title { - display: none; - } - - // Hide level 0 items - > .md-nav__list > .md-nav__item { - display: none; - - // Active parent navigation item - &--active { - display: block; - padding: 0; - - // Hide nested links - > .md-nav__link { - display: none; - } - - // Show title and adjust spacing - > .md-nav > .md-nav__title { - display: block; - padding: 0 px2rem(12px); - pointer-events: none; - scroll-snap-align: start; - } - } - } - - // Hack: Always show active navigation tab on breakpoint screen, despite - // of checkbox being checked or not. Fixes #1655. - .md-nav[data-md-level="1"] { - display: block; - - // Adjust spacing for level 1 items - > .md-nav__list > .md-nav__item { - padding-right: px2rem(12px); - } - } - } - - // Modifier for when table of contents is rendered in primary navigation - &--integrated &__link[for="__toc"] ~ .md-nav { - display: block; - margin-bottom: 1.25em; - border-left: px2rem(1px) solid var(--md-primary-fg-color); - - // Hide navigation title - > .md-nav__title { - display: none; - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_search.scss b/docs/src/assets/stylesheets/main/layout/_search.scss deleted file mode 100644 index cf35874a..00000000 --- a/docs/src/assets/stylesheets/main/layout/_search.scss +++ /dev/null @@ -1,790 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-search-result-icon: svg-load("material/file-search-outline.svg"); -} - -// ---------------------------------------------------------------------------- - -// Search -.md-search { - position: relative; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding: px2rem(4px) 0; - } - - // [no-js]: Hide search - .no-js & { - display: none; - } - - // Search overlay - &__overlay { - z-index: 1; - opacity: 0; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - position: absolute; - top: px2rem(-20px); - left: px2rem(-44px); - width: px2rem(40px); - height: px2rem(40px); - overflow: hidden; - background-color: var(--md-default-bg-color); - border-radius: px2rem(20px); - transform-origin: center; - transition: - transform 300ms 100ms, - opacity 200ms 200ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(-44px); - left: initial; - } - - // Show overlay when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - opacity: 1; - transition: - transform 400ms, - opacity 100ms; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - position: fixed; - top: 0; - left: 0; - width: 0; - height: 0; - background-color: hsla(0, 0%, 0%, 0.54); - cursor: pointer; - transition: - width 0ms 250ms, - height 0ms 250ms, - opacity 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: 0; - left: initial; - } - - // Show overlay when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - width: 100%; - // Hack: when the header is translated upon scrolling, a new layer is - // induced, which means that the height will now refer to the height of - // the header, albeit positioning is fixed. This should be mitigated - // in all cases when setting the height to 2x the viewport. - height: 200vh; - opacity: 1; - transition: - width 0ms, - height 0ms, - opacity 250ms; - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - - // [mobile portrait -]: Scale up 45 times - @include break-to-device(mobile portrait) { - transform: scale(45); - } - - // [mobile landscape]: Scale up 60 times - @include break-at-device(mobile landscape) { - transform: scale(60); - } - - // [tablet portrait]: Scale up 75 times - @include break-at-device(tablet portrait) { - transform: scale(75); - } - } - } - - // Search wrapper - &__inner { - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - position: fixed; - top: 0; - left: 0; - z-index: 2; - width: 0; - height: 0; - overflow: hidden; - transform: translateX(5%); - opacity: 0; - transition: - width 0ms 300ms, - height 0ms 300ms, - transform 150ms 150ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 150ms 150ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: 0; - left: initial; - transform: translateX(-5%); - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - width: 100%; - height: 100%; - transform: translateX(0); - opacity: 1; - transition: - width 0ms 0ms, - height 0ms 0ms, - transform 150ms 150ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms 150ms; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - position: relative; - float: right; - width: px2rem(234px); - padding: px2rem(2px) 0; - transition: width 250ms cubic-bezier(0.1, 0.7, 0.1, 1); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - - // [tablet landscape]: Omit overlaying header title - @include break-at-device(tablet landscape) { - width: px2rem(468px); - } - - // [screen +]: Match width of content area - @include break-from-device(screen) { - width: px2rem(688px); - } - } - } - - // Search form - &__form { - position: relative; - z-index: 2; - height: px2rem(48px); - background-color: var(--md-default-bg-color); - box-shadow: 0 0 px2rem(12px) transparent; - transition: - color 250ms, - background-color 250ms; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - height: px2rem(36px); - background-color: hsla(0, 0%, 0%, 0.26); - border-radius: px2rem(2px); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 100%, 0.12); - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px) px2rem(2px) 0 0; - box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07); - } - } - - // Search input - &__input { - position: relative; - z-index: 2; - width: 100%; - height: 100%; - padding: 0 px2rem(44px) 0 px2rem(72px); - font-size: px2rem(18px); - text-overflow: ellipsis; - background: transparent; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding: 0 px2rem(72px) 0 px2rem(44px); - } - - // Search placeholder - &::placeholder { - transition: color 250ms; - } - - // Search icon and placeholder - ~ .md-search__icon, - &::placeholder { - color: var(--md-default-fg-color--light); - } - - // Remove the "x" rendered by Internet Explorer - &::-ms-clear { - display: none; - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - width: 100%; - height: px2rem(48px); - font-size: px2rem(18px); - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - color: inherit; - font-size: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - } - - // Search placeholder - &::placeholder { - color: var(--md-primary-bg-color--light); - } - - // Search icon - + .md-search__icon { - color: var(--md-primary-bg-color); - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - text-overflow: clip; - - // Search icon and placeholder - + .md-search__icon, - &::placeholder { - color: var(--md-default-fg-color--light); - } - } - } - } - - // Search icon - &__icon { - display: inline-block; - width: px2rem(24px); - height: px2rem(24px); - cursor: pointer; - transition: - color 250ms, - opacity 250ms; - - // Search icon on hover - &:hover { - opacity: 0.7; - } - - // Search focus button - &[for="__search"] { - position: absolute; - top: px2rem(6px); - left: px2rem(10px); - z-index: 2; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(10px); - left: initial; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(12px); - left: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(16px); - left: initial; - } - - // Hide the magnifying glass - svg:first-child { - display: none; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - pointer-events: none; - - // Hide the back arrow - svg:last-child { - display: none; - } - } - } - } - - // Search options - &__options { - position: absolute; - top: px2rem(6px); - right: px2rem(10px); - z-index: 2; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(10px); - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(12px); - right: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(16px); - } - } - - // Search option buttons - > * { - margin-left: px2rem(4px); - color: var(--md-default-fg-color--light); - transform: scale(0.75); - opacity: 0; - transition: - transform 150ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Show reset button when search is active and input non-empty - [data-md-toggle="search"]:checked ~ .md-header - .md-search__input:valid ~ & { - transform: scale(1); - opacity: 1; - pointer-events: initial; - - // Search focus icon - &:hover { - opacity: 0.7; - } - } - } - } - - // Search suggestions - &__suggest { - position: absolute; - top: 0; - display: flex; - align-items: center; - width: 100%; - height: 100%; - padding: 0 px2rem(44px) 0 px2rem(72px); - color: var(--md-default-fg-color--lighter); - font-size: px2rem(18px); - white-space: nowrap; - opacity: 0; - transition: opacity 50ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding: 0 px2rem(72px) 0 px2rem(44px); - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - font-size: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - } - } - - // Show suggestions when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - opacity: 1; - transition: opacity 300ms 100ms; - } - } - - // Search output - &__output { - position: absolute; - z-index: 1; - width: 100%; - overflow: hidden; - border-radius: 0 0 px2rem(2px) px2rem(2px); - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(48px); - bottom: 0; - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - top: px2rem(38px); - opacity: 0; - transition: opacity 400ms; - - // Show output when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - @include z-depth(6); - - opacity: 1; - } - } - } - - // Search scroll wrapper - &__scrollwrap { - height: 100%; - overflow-y: auto; - background-color: var(--md-default-bg-color); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - // Hack: Chrome 88+ has weird overscroll behavior. Overall, scroll snapping - // seems to be something that is not ready for prime time on some browsers. - // scroll-snap-type: y mandatory; - touch-action: pan-y; - - // Mitigiate excessive repaints on non-retina devices - @media (max-resolution: 1dppx) { - transform: translateZ(0); - } - - // [tablet landscape]: Set fixed width to omit unnecessary reflow - @include break-at-device(tablet landscape) { - width: px2rem(468px); - } - - // [screen +]: Set fixed width to omit unnecessary reflow - @include break-from-device(screen) { - width: px2rem(688px); - } - - // [tablet landscape +]: Limit height to viewport - @include break-from-device(tablet landscape) { - max-height: 0; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Show scroll wrapper when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - max-height: 75vh; - } - - // Search scroll wrapper on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } - } -} - -// Search result -.md-search-result { - color: var(--md-default-fg-color); - word-break: break-word; - - // Search result metadata - &__meta { - padding: 0 px2rem(16px); - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - line-height: px2rem(36px); - background-color: var(--md-default-fg-color--lightest); - scroll-snap-align: start; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - padding-left: initial; - } - } - } - - // Search result list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Search result item - &__item { - box-shadow: 0 px2rem(-1px) 0 var(--md-default-fg-color--lightest); - - // Omit border on first child - &:first-child { - box-shadow: none; - } - } - - // Search result link - &__link { - display: block; - outline: none; - transition: background-color 250ms; - scroll-snap-align: start; - - // Search result link on focus/hover - &:focus, - &:hover { - background-color: var(--md-accent-fg-color--transparent); - } - - // Adjust spacing on last child of last link - &:last-child p:last-child { - margin-bottom: px2rem(12px); - } - } - - // Search result more link - &__more summary { - display: block; - padding: px2em(12px) px2rem(16px); - color: var(--md-typeset-a-color); - font-size: px2rem(12.8px); - outline: none; - cursor: pointer; - transition: - color 250ms, - background-color 250ms; - scroll-snap-align: start; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - padding-left: px2rem(16px); - } - } - - // Search result more link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - - // Hide native details marker - &::marker, - &::-webkit-details-marker { - display: none; - } - - // Adjust transparency of less relevant results - ~ * > * { - opacity: 0.65; - } - } - - // Search result article - &__article { - position: relative; - padding: 0 px2rem(16px); - overflow: hidden; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - padding-left: px2rem(16px); - } - } - - // Search result article document - &--document { - - // Search result title - .md-search-result__title { - margin: px2rem(11px) 0; - font-weight: 400; - font-size: px2rem(16px); - line-height: 1.4; - } - } - } - - // Search result icon - &__icon { - position: absolute; - left: 0; - width: px2rem(24px); - height: px2rem(24px); - margin: px2rem(10px); - color: var(--md-default-fg-color--light); - - // [tablet portrait -]: Hide icon - @include break-to-device(tablet portrait) { - display: none; - } - - // Search result icon content - &::after { - display: inline-block; - width: 100%; - height: 100%; - background-color: currentColor; - mask-image: var(--md-search-result-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: 0; - left: initial; - - // Flip icon vertically - &::after { - transform: scaleX(-1); - } - } - } - - // Search result title - &__title { - margin: 0.5em 0; - font-weight: 700; - font-size: px2rem(12.8px); - line-height: 1.6; - } - - // Search result teaser - &__teaser { - display: -webkit-box; - max-height: px2rem(40px); - margin: 0.5em 0; - overflow: hidden; - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - line-height: 1.6; - text-overflow: ellipsis; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - - // [mobile -]: Adjust number of lines - @include break-to-device(mobile) { - max-height: px2rem(60px); - -webkit-line-clamp: 3; - } - - // [tablet landscape]: Adjust number of lines - @include break-at-device(tablet landscape) { - max-height: px2rem(60px); - -webkit-line-clamp: 3; - } - - // Search term highlighting - mark { - text-decoration: underline; - background-color: transparent; - } - } - - // Search result terms - &__terms { - margin: 0.5em 0; - font-size: px2rem(12.8px); - font-style: italic; - } - - // Search term highlighting - mark { - color: var(--md-accent-fg-color); - background-color: transparent; - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_select.scss b/docs/src/assets/stylesheets/main/layout/_select.scss deleted file mode 100644 index 1ca64102..00000000 --- a/docs/src/assets/stylesheets/main/layout/_select.scss +++ /dev/null @@ -1,126 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Selection -.md-select { - position: relative; - z-index: 1; - - // Selection bubble - &__inner { - position: absolute; - top: calc(100% - #{px2rem(4px)}); - left: 50%; - max-height: 0; - margin-top: px2rem(4px); - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25); - transform: translate3d(-50%, px2rem(6px), 0); - opacity: 0; - transition: - transform 250ms 375ms, - opacity 250ms 250ms, - max-height 0ms 500ms; - - // Selection bubble on parent focus/hover - .md-select:focus-within &, - .md-select:hover & { - max-height: px2rem(200px); - transform: translate3d(-50%, 0, 0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms, - max-height 0ms; - } - - // Selection bubble handle - &::after { - position: absolute; - top: 0; - left: 50%; - width: 0; - height: 0; - margin-top: px2rem(-4px); - margin-left: px2rem(-4px); - border: px2rem(4px) solid transparent; - border-top: 0; - border-bottom-color: var(--md-default-bg-color); - content: ""; - } - } - - // Selection list - &__list { - max-height: inherit; - margin: 0; - padding: 0; - overflow: auto; - font-size: px2rem(16px); - list-style-type: none; - border-radius: px2rem(2px); - } - - // Selection item - &__item { - line-height: px2rem(36px); - } - - // Selection link - &__link { - display: block; - width: 100%; - padding-right: px2rem(24px); - padding-left: px2rem(12px); - outline: none; - cursor: pointer; - transition: - background-color 250ms, - color 250ms; - scroll-snap-align: start; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: px2rem(24px); - } - - // Link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Link on focus - &:focus { - background-color: var(--md-default-fg-color--lightest); - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_sidebar.scss b/docs/src/assets/stylesheets/main/layout/_sidebar.scss deleted file mode 100644 index a8cff6eb..00000000 --- a/docs/src/assets/stylesheets/main/layout/_sidebar.scss +++ /dev/null @@ -1,191 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Sidebar -.md-sidebar { - position: sticky; - top: px2rem(48px); - flex-shrink: 0; - align-self: flex-start; - width: px2rem(242px); - padding: px2rem(24px) 0; - - // [print]: Hide sidebar - @media print { - display: none; - } - - // [tablet -]: Show navigation as drawer - @include break-to-device(tablet) { - - // Primary sidebar with navigation - &--primary { - position: fixed; - top: 0; - left: px2rem(-242px); - z-index: 4; - display: block; - width: px2rem(242px); - height: 100%; - background-color: var(--md-default-bg-color); - transform: translateX(0); - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - box-shadow 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(-242px); - left: initial; - } - - // Show sidebar when drawer is active - [data-md-toggle="drawer"]:checked ~ .md-container & { - @include z-depth(8); - - transform: translateX(px2rem(242px)); - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-242px)); - } - } - - // Stretch scroll wrapper for primary sidebar - .md-sidebar__scrollwrap { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - margin: 0; - scroll-snap-type: none; - overflow: hidden; - } - } - } - - // [screen +]: Show navigation as sidebar - @include break-from-device(screen) { - height: 0; - - // [no-js]: Switch to native sticky behavior - .no-js & { - height: auto; - } - } - - // Secondary sidebar with table of contents - &--secondary { - display: none; - order: 2; - - // [tablet landscape +]: Show table of contents as sidebar - @include break-from-device(tablet landscape) { - height: 0; - - // [no-js]: Switch to native sticky behavior - .no-js & { - height: auto; - } - - // Sidebar is visible - &:not([hidden]) { - display: block; - } - - // Ensure smooth scrolling on iOS - .md-sidebar__scrollwrap { - touch-action: pan-y; - } - } - } - - // Sidebar scroll wrapper - &__scrollwrap { - margin: 0 px2rem(4px); - overflow-y: auto; - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - // Hack: Chrome 81+ exhibits a strange bug, where it scrolls the container - // to the bottom if `scroll-snap-type` is set on the initial render. For - // this reason, we disable scroll snapping until this is resolved (#1667). - // scroll-snap-type: y mandatory; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Sidebar scroll wrapper on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } -} - -// [tablet -]: Show overlay on active drawer -@include break-to-device(tablet) { - - // Sidebar overlay - .md-overlay { - position: fixed; - top: 0; - z-index: 4; - width: 0; - height: 0; - background-color: hsla(0, 0%, 0%, 0.54); - opacity: 0; - transition: - width 0ms 250ms, - height 0ms 250ms, - opacity 250ms; - - // Show overlay when drawer is active - [data-md-toggle="drawer"]:checked ~ & { - width: 100%; - height: 100%; - opacity: 1; - transition: - width 0ms, - height 0ms, - opacity 250ms; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_source.scss b/docs/src/assets/stylesheets/main/layout/_source.scss deleted file mode 100644 index 7dfd5023..00000000 --- a/docs/src/assets/stylesheets/main/layout/_source.scss +++ /dev/null @@ -1,203 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Show repository facts -@keyframes facts { - 0% { - height: 0; - } - - 100% { - height: px2rem(13px); - } -} - -// Show repository fact -@keyframes fact { - 0% { - transform: translateY(100%); - opacity: 0; - } - - 50% { - opacity: 0; - } - - 100% { - transform: translateY(0%); - opacity: 1; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-source-forks-icon: svg-load("octicons/repo-forked-16.svg"); - --md-source-repositories-icon: svg-load("octicons/repo-16.svg"); - --md-source-stars-icon: svg-load("octicons/star-16.svg"); - --md-source-version-icon: svg-load("octicons/tag-16.svg"); -} - -// ---------------------------------------------------------------------------- - -// Repository information -.md-source { - display: block; - font-size: px2rem(13px); - line-height: 1.2; - white-space: nowrap; - outline-color: var(--md-accent-fg-color); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - transition: opacity 250ms; - - // Repository information on hover - &:hover { - opacity: 0.7; - } - - // Repository icon - &__icon { - display: inline-block; - width: px2rem(40px); - height: px2rem(48px); - vertical-align: middle; - - // Align with margin only (as opposed to normal button alignment) - svg { - margin-top: px2rem(12px); - margin-left: px2rem(12px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(12px); - margin-left: initial; - } - } - - // Adjust spacing if icon is present - + .md-source__repository { - margin-left: px2rem(-40px); - padding-left: px2rem(40px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(-40px); - margin-left: initial; - padding-right: px2rem(40px); - padding-left: initial; - } - } - } - - // Repository name - &__repository { - display: inline-block; - max-width: calc(100% - #{px2rem(24px)}); - margin-left: px2rem(12px); - overflow: hidden; - text-overflow: ellipsis; - vertical-align: middle; - } - - // Repository facts - &__facts { - margin: px2rem(2px) 0 0; - padding: 0; - overflow: hidden; - font-size: px2rem(11px); - list-style-type: none; - opacity: 0.75; - - // Show after the data was loaded - [data-md-state="done"] & { - animation: facts 250ms ease-in; - } - } - - // Repository fact - &__fact { - display: inline-block; - - // Show after the data was loaded - [data-md-state="done"] & { - animation: fact 400ms ease-out; - } - - // Repository fact icon - &::before { - display: inline-block; - width: px2rem(12px); - height: px2rem(12px); - margin-right: px2rem(2px); - vertical-align: text-top; - background-color: currentColor; - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Adjust spacing for repository fact icon - &:nth-child(1n+2)::before { - margin-left: px2rem(8px); - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: initial; - margin-left: px2rem(2px); - - // Adjust spacing for repository fact icon - &:nth-child(1n+2)::before { - margin-right: px2rem(8px); - margin-left: initial; - } - } - - // Repository fact: version - &--version::before { - mask-image: var(--md-source-version-icon); - } - - // Repository fact: stars - &--stars::before { - mask-image: var(--md-source-stars-icon); - } - - // Repository fact: forks - &--forks::before { - mask-image: var(--md-source-forks-icon); - } - - // Repository fact: repositories - &--repositories::before { - mask-image: var(--md-source-repositories-icon); - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_tabs.scss b/docs/src/assets/stylesheets/main/layout/_tabs.scss deleted file mode 100644 index 2567e09c..00000000 --- a/docs/src/assets/stylesheets/main/layout/_tabs.scss +++ /dev/null @@ -1,113 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Navigation tabs -.md-tabs { - width: 100%; - overflow: auto; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - - // [print]: Hide tabs - @media print { - display: none; - } - - // [tablet -]: Hide tabs - @include break-to-device(tablet) { - display: none; - } - - // Tabs in hidden state, i.e. when scrolling down - &[data-md-state="hidden"] { - pointer-events: none; - } - - // Navigation tabs list - &__list { - margin: 0; - margin-left: px2rem(4px); - padding: 0; - white-space: nowrap; - list-style: none; - contain: content; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(4px); - margin-left: initial; - } - } - - // Navigation tabs item - &__item { - display: inline-block; - height: px2rem(48px); - padding-right: px2rem(12px); - padding-left: px2rem(12px); - } - - // Navigation tabs link - could be defined as block elements and aligned via - // line height, but this would imply more repaints when scrolling - &__link { - display: block; - margin-top: px2rem(16px); - font-size: px2rem(14px); - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - // Hack: save a repaint when tabs are appearing on scrolling up - backface-visibility: hidden; - opacity: 0.7; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms; - - // Active link and link on focus/hover - &--active, - &:focus, - &:hover { - color: inherit; - opacity: 1; - } - - // Delay transitions by a small amount - @for $i from 2 through 16 { - .md-tabs__item:nth-child(#{$i}) & { - transition-delay: 20ms * ($i - 1); - } - } - - // Hide tabs upon scrolling - disable transition to minimizes repaints - // while scrolling down, while scrolling up seems to be okay - .md-tabs[data-md-state="hidden"] & { - transform: translateY(50%); - opacity: 0; - transition: - transform 0ms 100ms, - opacity 100ms; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_top.scss b/docs/src/assets/stylesheets/main/layout/_top.scss deleted file mode 100644 index 51ce4954..00000000 --- a/docs/src/assets/stylesheets/main/layout/_top.scss +++ /dev/null @@ -1,79 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Back-to-top button -.md-top { - position: fixed; - top: px2rem(48px + 16px); - z-index: 2; - margin-left: 50%; - padding: px2rem(8px) px2rem(16px); - color: var(--md-default-fg-color--light); - font-size: px2rem(14px); - background-color: var(--md-default-bg-color); - border-radius: px2rem(32px); - outline: none; - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25); - transform: translate(-50%, 0); - transition: - color 125ms, - background-color 125ms, - transform 125ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 125ms; - - // [print]: Hide back-to-top button - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - - // Back-to-top button in hidden state - &[data-md-state="hidden"] { - transform: translate(-50%, px2rem(4px)); - opacity: 0; - transition-duration: 0ms; - pointer-events: none; - } - - // Back-to-top button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - } - - // Inline icon - svg { - display: inline-block; - vertical-align: -0.5em; - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_version.scss b/docs/src/assets/stylesheets/main/layout/_version.scss deleted file mode 100644 index 5f813bc5..00000000 --- a/docs/src/assets/stylesheets/main/layout/_version.scss +++ /dev/null @@ -1,173 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// See https://github.com/squidfunk/mkdocs-material/issues/2429 -@keyframes hoverfix { - 0% { - pointer-events: none; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-version-icon: svg-load("fontawesome/solid/caret-down.svg"); -} - -// ---------------------------------------------------------------------------- - -// Version selection -.md-version { - flex-shrink: 0; - height: px2rem(48px); - font-size: px2rem(16px); - - // Current selection - &__current { - position: relative; - // Hack: in general, we would use `vertical-align` to align the version at - // the bottom with the title, but since the list uses absolute positioning, - // this won't work consistently. Furthermore, we would need to use inline - // positioning to align the links, which looks jagged. - top: px2rem(1px); - margin-right: px2rem(8px); - margin-left: px2rem(28px); - color: inherit; - outline: none; - cursor: pointer; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(28px); - margin-left: px2rem(8px); - } - - // Version selection icon - &::after { - display: inline-block; - width: px2rem(8px); - height: px2rem(12px); - margin-left: px2rem(8px); - background-color: currentColor; - mask-image: var(--md-version-icon); - mask-repeat: no-repeat; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(8px); - margin-left: initial; - } - } - } - - // Version selection list - &__list { - position: absolute; - top: px2rem(3px); - z-index: 1; - max-height: 0; - margin: px2rem(4px) px2rem(16px); - padding: 0; - overflow: auto; - color: var(--md-default-fg-color); - list-style-type: none; - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25); - opacity: 0; - transition: - max-height 0ms 500ms, - opacity 250ms 250ms; - scroll-snap-type: y mandatory; - - // Version selection list on parent focus/hover - .md-version:focus-within &, - .md-version:hover & { - max-height: px2rem(200px); - opacity: 1; - transition: - max-height 0ms, - opacity 250ms; - } - - // Fix hover on touch devices - @media (pointer: coarse) { - - // Switch off on hover - .md-version:hover & { - animation: hoverfix 250ms forwards; - } - - // Enable on focus - .md-version:focus-within & { - animation: none; - } - } - } - - // Version selection item - &__item { - line-height: px2rem(36px); - } - - // Version selection link - &__link { - display: block; - width: 100%; - padding-right: px2rem(24px); - padding-left: px2rem(12px); - white-space: nowrap; - outline: none; - cursor: pointer; - transition: - color 250ms, - background-color 250ms; - scroll-snap-align: start; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: px2rem(24px); - } - - // Link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Link on focus - &:focus { - background-color: var(--md-default-fg-color--lightest); - } - } -} diff --git a/docs/src/assets/stylesheets/palette.scss b/docs/src/assets/stylesheets/palette.scss deleted file mode 100644 index 6da9d2c6..00000000 --- a/docs/src/assets/stylesheets/palette.scss +++ /dev/null @@ -1,40 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "palette/accent"; -@import "palette/primary"; -@import "palette/scheme"; diff --git a/docs/src/assets/stylesheets/palette/_accent.scss b/docs/src/assets/stylesheets/palette/_accent.scss deleted file mode 100644 index e8c21403..00000000 --- a/docs/src/assets/stylesheets/palette/_accent.scss +++ /dev/null @@ -1,60 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -@each $name, $color in ( - "red": $clr-red-a400, - "pink": $clr-pink-a400, - "purple": $clr-purple-a200, - "deep-purple": $clr-deep-purple-a200, - "indigo": $clr-indigo-a200, - "blue": $clr-blue-a200, - "light-blue": $clr-light-blue-a700, - "cyan": $clr-cyan-a700, - "teal": $clr-teal-a700, - "green": $clr-green-a700, - "light-green": $clr-light-green-a700, - "lime": $clr-lime-a700, - "yellow": $clr-yellow-a700, - "amber": $clr-amber-a700, - "orange": $clr-orange-a400, - "deep-orange": $clr-deep-orange-a200 -) { - - // Color palette - [data-md-color-accent="#{$name}"] { - --md-accent-fg-color: hsla(#{hex2hsl($color)}, 1); - --md-accent-fg-color--transparent: hsla(#{hex2hsl($color)}, 0.1); - - // Inverted text for lighter shades - @if index("lime" "yellow" "amber" "orange", $name) { - --md-accent-bg-color: hsla(0, 0%, 0%, 0.87); - --md-accent-bg-color--light: hsla(0, 0%, 0%, 0.54); - } @else { - --md-accent-bg-color: hsla(0, 0%, 100%, 1); - --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); - } - } -} diff --git a/docs/src/assets/stylesheets/palette/_primary.scss b/docs/src/assets/stylesheets/palette/_primary.scss deleted file mode 100644 index 2ddccdbd..00000000 --- a/docs/src/assets/stylesheets/palette/_primary.scss +++ /dev/null @@ -1,170 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -@each $name, $colors in ( - "red": $clr-red-400 $clr-red-300 $clr-red-600, - "pink": $clr-pink-500 $clr-pink-400 $clr-pink-700, - "purple": $clr-purple-400 $clr-purple-300 $clr-purple-600, - "deep-purple": $clr-deep-purple-400 $clr-deep-purple-300 $clr-deep-purple-500, - "indigo": $clr-indigo-500 $clr-indigo-400 $clr-indigo-700, - "blue": $clr-blue-500 $clr-blue-400 $clr-blue-700, - "light-blue": $clr-light-blue-500 $clr-light-blue-400 $clr-light-blue-700, - "cyan": $clr-cyan-500 $clr-cyan-400 $clr-cyan-700, - "teal": $clr-teal-500 $clr-teal-400 $clr-teal-700, - "green": $clr-green-500 $clr-green-400 $clr-green-700, - "light-green": $clr-light-green-500 $clr-light-green-400 $clr-light-green-700, - "lime": $clr-lime-500 $clr-lime-400 $clr-lime-700, - "yellow": $clr-yellow-500 $clr-yellow-400 $clr-yellow-700, - "amber": $clr-amber-500 $clr-amber-400 $clr-amber-700, - "orange": $clr-orange-400 $clr-orange-400 $clr-orange-600, - "deep-orange": $clr-deep-orange-400 $clr-deep-orange-300 $clr-deep-orange-600, - "brown": $clr-brown-500 $clr-brown-400 $clr-brown-700, - "grey": $clr-grey-600 $clr-grey-500 $clr-grey-700, - "blue-grey": $clr-blue-grey-600 $clr-blue-grey-500 $clr-blue-grey-700 -) { - - // Color palette - [data-md-color-primary="#{$name}"] { - --md-primary-fg-color: hsla(#{hex2hsl(nth($colors, 1))}, 1); - --md-primary-fg-color--light: hsla(#{hex2hsl(nth($colors, 2))}, 1); - --md-primary-fg-color--dark: hsla(#{hex2hsl(nth($colors, 3))}, 1); - - // Inverted text for lighter shades - @if index("lime" "yellow" "amber" "orange", $name) { - --md-primary-bg-color: hsla(0, 0%, 0%, 0.87); - --md-primary-bg-color--light: hsla(0, 0%, 0%, 0.54); - } @else { - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: white -// ---------------------------------------------------------------------------- - -// Color palette -[data-md-color-primary="white"] { - --md-primary-fg-color: hsla(0, 0%, 100%, 1); - --md-primary-fg-color--light: hsla(0, 0%, 100%, 0.7); - --md-primary-fg-color--dark: hsla(0, 0%, 0%, 0.07); - --md-primary-bg-color: hsla(0, 0%, 0%, 0.87); - --md-primary-bg-color--light: hsla(0, 0%, 0%, 0.54); - - // Typeset color shades - --md-typeset-a-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - - // [tablet portrait +]: Header-embedded search - @include break-from-device(tablet landscape) { - - // Search form - .md-search__form { - background-color: hsla(0, 0%, 0%, 0.07); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 0%, 0.32); - } - } - - // Search icon - .md-search__input + .md-search__icon { - color: hsla(0, 0%, 0%, 0.87); - } - } - - // [screen +]: Add bottom border for tabs - @include break-from-device(screen) { - - // Navigation tabs - .md-tabs { - border-bottom: px2rem(1px) solid hsla(0, 0%, 0%, 0.07); - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: black -// ---------------------------------------------------------------------------- - -// Color palette -[data-md-color-primary="black"] { - --md-primary-fg-color: hsla(0, 0%, 0%, 1); - --md-primary-fg-color--light: hsla(0, 0%, 0%, 0.54); - --md-primary-fg-color--dark: hsla(0, 0%, 0%, 1); - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Text color shades - --md-typeset-a-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - - // Header - .md-header { - background-color: hsla(0, 0%, 0%, 1); - } - - // [tablet portrait -]: Layered navigation - @include break-to-device(tablet portrait) { - - // Repository information container - .md-nav__source { - background-color: hsla(0, 0%, 0%, 0.87); - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - - // Search form - .md-search__form { - background-color: hsla(0, 0%, 100%, 0.12); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 100%, 0.3); - } - } - } - - // [tablet -]: Layered navigation - @include break-to-device(tablet) { - - // Site title in main navigation - html & .md-nav--primary .md-nav__title[for="__drawer"] { - background-color: hsla(0, 0%, 0%, 1); - } - } - - // [screen +]: Set background color for tabs - @include break-from-device(screen) { - - // Navigation tabs - .md-tabs { - background-color: hsla(0, 0%, 0%, 1); - } - } -} diff --git a/docs/src/assets/stylesheets/palette/_scheme.scss b/docs/src/assets/stylesheets/palette/_scheme.scss deleted file mode 100644 index 5ef7dc18..00000000 --- a/docs/src/assets/stylesheets/palette/_scheme.scss +++ /dev/null @@ -1,99 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Only use dark mode on screens -@media screen { - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] { - - // Slate's hue in the range [0,360] - change this variable to alter the tone - // of the theme, e.g. to make it more redish or greenish. This is a slate- - // specific variable, but the same approach may be adapted to custom themes. - --md-hue: 232; - - // Default color shades - --md-default-fg-color: hsla(var(--md-hue), 75%, 95%, 1); - --md-default-fg-color--light: hsla(var(--md-hue), 75%, 90%, 0.62); - --md-default-fg-color--lighter: hsla(var(--md-hue), 75%, 90%, 0.32); - --md-default-fg-color--lightest: hsla(var(--md-hue), 75%, 90%, 0.12); - --md-default-bg-color: hsla(var(--md-hue), 15%, 21%, 1); - --md-default-bg-color--light: hsla(var(--md-hue), 15%, 21%, 0.54); - --md-default-bg-color--lighter: hsla(var(--md-hue), 15%, 21%, 0.26); - --md-default-bg-color--lightest: hsla(var(--md-hue), 15%, 21%, 0.07); - - // Code color shades - --md-code-fg-color: hsla(var(--md-hue), 18%, 86%, 1); - --md-code-bg-color: hsla(var(--md-hue), 15%, 15%, 1); - - // Code highlighting color shades - --md-code-hl-color: hsla(#{hex2hsl($clr-blue-a200)}, 0.15); - --md-code-hl-number-color: hsla(6, 74%, 63%, 1); - --md-code-hl-special-color: hsla(340, 83%, 66%, 1); - --md-code-hl-function-color: hsla(291, 57%, 65%, 1); - --md-code-hl-constant-color: hsla(250, 62%, 70%, 1); - --md-code-hl-keyword-color: hsla(219, 66%, 64%, 1); - --md-code-hl-string-color: hsla(150, 58%, 44%, 1); - --md-code-hl-name-color: var(--md-code-fg-color); - --md-code-hl-operator-color: var(--md-default-fg-color--light); - --md-code-hl-punctuation-color: var(--md-default-fg-color--light); - --md-code-hl-comment-color: var(--md-default-fg-color--light); - --md-code-hl-generic-color: var(--md-default-fg-color--light); - --md-code-hl-variable-color: var(--md-default-fg-color--light); - - // Typeset color shades - --md-typeset-color: var(--md-default-fg-color); - - // Typeset `a` color shades - --md-typeset-a-color: var(--md-primary-fg-color); - - // Typeset `mark` color shades - --md-typeset-mark-color: hsla(#{hex2hsl($clr-blue-a200)}, 0.3); - - // Typeset `kbd` color shades - --md-typeset-kbd-color: hsla(var(--md-hue), 15%, 94%, 0.12); - --md-typeset-kbd-accent-color: hsla(var(--md-hue), 15%, 94%, 0.2); - --md-typeset-kbd-border-color: hsla(var(--md-hue), 15%, 14%, 1); - - // Typeset `table` color shades - --md-typeset-table-color: hsla(var(--md-hue), 75%, 95%, 0.12); - - // Admonition color shades - --md-admonition-bg-color: hsla(var(--md-hue), 0%, 100%, 0.025); - - // Footer color shades - --md-footer-bg-color: hsla(var(--md-hue), 15%, 12%, 0.87); - --md-footer-bg-color--dark: hsla(var(--md-hue), 15%, 10%, 1); - - // Black and white primary colors - &[data-md-color-primary="black"], - &[data-md-color-primary="white"] { - - // Typeset color shades - --md-typeset-a-color: hsla(#{hex2hsl($clr-indigo-400)}, 1); - } - } -} diff --git a/docs/src/assets/stylesheets/utilities/_break.scss b/docs/src/assets/stylesheets/utilities/_break.scss deleted file mode 100644 index 0bf63c79..00000000 --- a/docs/src/assets/stylesheets/utilities/_break.scss +++ /dev/null @@ -1,215 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Variables -// ---------------------------------------------------------------------------- - -/// -/// Device-specific breakpoints -/// -/// @example -/// $break-devices: ( -/// mobile: ( -/// portrait: 220px 479px, -/// landscape: 480px 719px -/// ), -/// tablet: ( -/// portrait: 720px 959px, -/// landscape: 960px 1219px -/// ), -/// screen: ( -/// small: 1220px 1599px, -/// medium: 1600px 1999px, -/// large: 2000px -/// ) -/// ); -/// -$break-devices: () !default; - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -/// -/// Choose minimum and maximum device widths -/// -@function break-select-min-max($devices) { - $min: 1000000; - $max: 0; - @each $key, $value in $devices { - @while type-of($value) == map { - $value: break-select-min-max($value); - } - @if type-of($value) == list { - @each $number in $value { - @if type-of($number) == number { - $min: min($number, $min); - @if $max { - $max: max($number, $max); - } - } @else { - @error "Invalid number: #{$number}"; - } - } - } @else if type-of($value) == number { - $min: min($value, $min); - $max: null; - } @else { - @error "Invalid value: #{$value}"; - } - } - @return $min, $max; -} - -/// -/// Select minimum and maximum widths for a device breakpoint -/// -@function break-select-device($device) { - $current: $break-devices; - @for $n from 1 through length($device) { - @if type-of($current) == map { - $current: map-get($current, nth($device, $n)); - } @else { - @error "Invalid device map: #{$devices}"; - } - } - @if type-of($current) == list or type-of($current) == number { - $current: (default: $current); - } - @return break-select-min-max($current); -} - -// ---------------------------------------------------------------------------- -// Mixins -// ---------------------------------------------------------------------------- - -/// -/// A minimum-maximum media query breakpoint -/// -@mixin break-at($breakpoint) { - @if type-of($breakpoint) == number { - @media screen and (min-width: $breakpoint) { - @content; - } - } @else if type-of($breakpoint) == list { - $min: nth($breakpoint, 1); - $max: nth($breakpoint, 2); - @if type-of($min) == number and type-of($max) == number { - @media screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// An orientation media query breakpoint -/// -@mixin break-at-orientation($breakpoint) { - @if type-of($breakpoint) == string { - @media screen and (orientation: $breakpoint) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// A maximum-aspect-ratio media query breakpoint -/// -@mixin break-at-ratio($breakpoint) { - @if type-of($breakpoint) == number { - @media screen and (max-aspect-ratio: $breakpoint) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// A minimum-maximum media query device breakpoint -/// -@mixin break-at-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - @if nth($breakpoint, 2) { - $min: nth($breakpoint, 1); - $max: nth($breakpoint, 2); - - @media screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } - } @else { - @error "Invalid device: #{$device}"; - } -} - -/// -/// A minimum media query device breakpoint -/// -@mixin break-from-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $min: nth($breakpoint, 1); - - @media screen and (min-width: $min) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } -} - -/// -/// A maximum media query device breakpoint -/// -@mixin break-to-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $max: nth($breakpoint, 2); - - @media screen and (max-width: $max) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } -} diff --git a/docs/src/assets/stylesheets/utilities/_convert.scss b/docs/src/assets/stylesheets/utilities/_convert.scss deleted file mode 100644 index a95fcbc7..00000000 --- a/docs/src/assets/stylesheets/utilities/_convert.scss +++ /dev/null @@ -1,79 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -@use "sass:math"; - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -/// -/// Strip units from a number -/// -@function strip-units($number) { - @return math.div($number, ($number * 0 + 1)); -} - -/// -/// Convert color in HEX to HSL -/// -/// Note, that we need to strip the `deg` units from the `hue` value, as they -/// were added in Color Level 4, which not all browsers support. -/// -@function hex2hsl($color) { - @return - round(strip-units(hue($color))), - round(saturation($color)), - round(lightness($color)); -} - -// ---------------------------------------------------------------------------- - -/// -/// Convert font size in px to em -/// -@function px2em($size, $base: 16px) { - @if unit($size) == px { - @if unit($base) == px { - @return math.div($size, $base) * 1em; - } @else { - @error "Invalid base: #{$base} - unit must be 'px'"; - } - } @else { - @error "Invalid size: #{$size} - unit must be 'px'"; - } -} - -/// -/// Convert font size in px to rem -/// -@function px2rem($size, $base: 20px) { - @if unit($size) == px { - @if unit($base) == px { - @return math.div($size, $base) * 1rem; - } @else { - @error "Invalid base: #{$base} - unit must be 'px'"; - } - } @else { - @error "Invalid size: #{$size} - unit must be 'px'"; - } -} diff --git a/docs/src/base.html b/docs/src/base.html deleted file mode 100644 index c68ed07b..00000000 --- a/docs/src/base.html +++ /dev/null @@ -1,411 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% import "partials/language.html" as lang with context %} - -<!doctype html> -<html lang="{{ lang.t('language') }}" class="no-js"> - <head> - - <!-- Meta tags --> - {% block site_meta %} - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width,initial-scale=1" /> - - <!-- Page description --> - {% if page and page.meta and page.meta.description %} - <meta name="description" content="{{ page.meta.description }}" /> - {% elif config.site_description %} - <meta name="description" content="{{ config.site_description }}" /> - {% endif %} - - <!-- Page keywords --> - {% if page and page.meta and page.meta.keywords %} - <meta name="keywords" content="{{ page.meta.keywords }}" /> - {% elif config.site_keywords %} - <meta name="keywords" content="{{ config.site_keywords }}" /> - {% endif %} - - <!-- Page author --> - {% if page and page.meta and page.meta.author %} - <meta name="author" content="{{ page.meta.author }}" /> - {% elif config.site_author %} - <meta name="author" content="{{ config.site_author }}" /> - {% endif %} - - <!-- Canonical --> - {% if page.canonical_url %} - <link rel="canonical" href="{{ page.canonical_url }}" /> - {% endif %} - - <!-- Favicon --> - <link rel="icon" href="{{ config.theme.favicon | url }}" /> - - <!-- Generator banner --> - <meta - name="generator" - content="mkdocs-{{ mkdocs_version }}, $md-name$-$md-version$" - /> - {% endblock %} - - <!-- Site title --> - {% block htmltitle %} - {% if page and page.meta and page.meta.title %} - <title>{{ page.meta.title }} - {{ config.site_name }}</title> - {% elif page and page.title and not page.is_homepage %} - <title>{{ page.title | striptags }} - {{ config.site_name }}</title> - {% else %} - <title>{{ config.site_name }}</title> - {% endif %} - {% endblock %} - - <!-- Theme-related stylesheets --> - {% block styles %} - <link rel="stylesheet" href="{{ 'assets/stylesheets/main.css' | url }}" /> - - <!-- Extra color palette --> - {% if config.theme.palette %} - {% set palette = config.theme.palette %} - <link - rel="stylesheet" - href="{{ 'assets/stylesheets/palette.css' | url }}" - /> - - <!-- Theme-color meta tag for Android --> - {% if palette.primary %} - {% import "partials/palette.html" as map %} - {% set primary = map.primary( - palette.primary | replace(" ", "-") | lower - ) %} - <meta name="theme-color" content="{{ primary }}" /> - {% endif %} - {% endif %} - {% endblock %} - - <!-- JavaScript libraries --> - {% block libs %}{% endblock %} - - <!-- Webfonts --> - {% block fonts %} - - <!-- Load fonts from Google --> - {% if config.theme.font != false %} - {% set font = config.theme.font %} - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> - <link - rel="stylesheet" - href="https://fonts.googleapis.com/css?family={{ - font.text | replace(' ', '+') + ':300,400,400i,700%7C' + - font.code | replace(' ', '+') - }}&display=fallback" - /> - <style> - :root { - --md-text-font-family: "{{ font.text }}"; - --md-code-font-family: "{{ font.code }}"; - } - </style> - {% endif %} - {% endblock %} - - <!-- Progressive Web App Manifest --> - {% if config.extra.manifest %} - <link - rel="manifest" - href="{{ config.extra.manifest | url }}" - crossorigin="use-credentials" - /> - {% endif %} - - <!-- Custom stylesheets --> - {% for path in config["extra_css"] %} - <link rel="stylesheet" href="{{ path | url }}" /> - {% endfor %} - - <!-- Analytics --> - {% block analytics %} - {% include "partials/integrations/analytics.html" %} - {% endblock %} - - <!-- Custom front matter --> - {% block extrahead %}{% endblock %} - </head> - - <!-- Set text direction and color palette, if defined --> - {% set direction = config.theme.direction or lang.t('direction') %} - {% if config.theme.palette %} - {% set palette = config.theme.palette %} - {% if not palette is mapping %} - {% set palette = palette | first %} - {% endif %} - {% set scheme = palette.scheme | replace(" ", "-") | lower %} - {% set primary = palette.primary | replace(" ", "-") | lower %} - {% set accent = palette.accent | replace(" ", "-") | lower %} - <body - dir="{{ direction }}" - data-md-color-scheme="{{ scheme }}" - data-md-color-primary="{{ primary }}" - data-md-color-accent="{{ accent }}" - > - {% else %} - <body dir="{{ direction }}"> - {% endif %} - - <!-- Retrieve features from configuration --> - {% set features = config.theme.features or [] %} - {% include "partials/javascripts/base.html" %} - - <!-- User preference: color palette --> - {% if not config.theme.palette is mapping %} - {% include "partials/javascripts/palette.html" %} - {% endif %} - - <!-- - State toggles - we need to set autocomplete="off" in order to reset the - drawer on back button invocation in some browsers - --> - <input - class="md-toggle" - data-md-toggle="drawer" - type="checkbox" - id="__drawer" - autocomplete="off" - /> - <input - class="md-toggle" - data-md-toggle="search" - type="checkbox" - id="__search" - autocomplete="off" - /> - - <!-- Overlay for expanded drawer --> - <label class="md-overlay" for="__drawer"></label> - - <!-- Skip to content --> - <div data-md-component="skip"> - {% if page.toc | first is defined %} - {% set skip = page.toc | first %} - <a href="{{ skip.url | url }}" class="md-skip"> - {{ lang.t('skip.link.title') }} - </a> - {% endif %} - </div> - - <!-- Announcement bar --> - <div data-md-component="announce"> - {% if self.announce() %} - <aside class="md-banner md-announce"> - <div class="md-banner__inner md-announce__inner md-grid md-typeset"> - {% block announce %}{% endblock %} - </div> - </aside> - {% endif %} - </div> - - <!-- Header --> - {% block header %} - {% include "partials/header.html" %} - {% endblock %} - - <!-- Container --> - <div class="md-container" data-md-component="container"> - - <!-- Hero teaser --> - {% block hero %}{% endblock %} - - <!-- Navigation tabs (collapsing) --> - {% block tabs %} - {% if not "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} - {% endblock %} - - <!-- Main area --> - <main class="md-main" data-md-component="main"> - <div class="md-main__inner md-grid"> - - <!-- Navigation --> - {% block site_nav %} - - <!-- Main navigation --> - {% if nav %} - {% if page and page.meta and page.meta.hide %} - {% set hidden = "hidden" if "navigation" in page.meta.hide %} - {% endif %} - <div - class="md-sidebar md-sidebar--primary" - data-md-component="sidebar" - data-md-type="navigation" - {{ hidden }} - > - <div class="md-sidebar__scrollwrap"> - <div class="md-sidebar__inner"> - {% include "partials/nav.html" %} - </div> - </div> - </div> - {% endif %} - - <!-- Table of contents --> - {% if page.toc and not "toc.integrate" in features %} - {% if page and page.meta and page.meta.hide %} - {% set hidden = "hidden" if "toc" in page.meta.hide %} - {% endif %} - <div - class="md-sidebar md-sidebar--secondary" - data-md-component="sidebar" - data-md-type="toc" - {{ hidden }} - > - <div class="md-sidebar__scrollwrap"> - <div class="md-sidebar__inner"> - {% include "partials/toc.html" %} - </div> - </div> - </div> - {% endif %} - {% endblock %} - - <!-- Article --> - <div class="md-content" data-md-component="content"> - <article class="md-content__inner md-typeset"> - - <!-- Content --> - {% block content %} - - <!-- Edit button --> - {% if page.edit_url %} - <a - href="{{ page.edit_url }}" - title="{{ lang.t('edit.link.title') }}" - class="md-content__button md-icon" - > - {% include ".icons/material/pencil.svg" %} - </a> - {% endif %} - - <!-- - Hack: check whether the content contains a h1 headline. If it - doesn't, the page title (or respectively site name) is used - as the main headline. - --> - {% if not "\x3ch1" in page.content %} - <h1>{{ page.title | d(config.site_name, true)}}</h1> - {% endif %} - - <!-- Markdown content --> - {{ page.content }} - - <!-- Last update of source file --> - {% if page and page.meta %} - {% if page.meta.git_revision_date_localized or - page.meta.revision_date - %} - {% include "partials/source-file.html" %} - {% endif %} - {% endif %} - {% endblock %} - - <!-- Disqus integration --> - {% block disqus %} - {% include "partials/integrations/disqus.html" %} - {% endblock %} - </article> - </div> - </div> - - <!-- Back-to-top button --> - {% if "navigation.top" in features %} - <a - href="#" - class="md-top md-icon" - data-md-component="top" - data-md-state="hidden" - > - {% include ".icons/material/arrow-up.svg" %} - {{ lang.t('top.title') }} - </a> - {% endif %} - </main> - - <!-- Footer --> - {% block footer %} - {% include "partials/footer.html" %} - {% endblock %} - </div> - - <!-- Dialog --> - <div class="md-dialog" data-md-component="dialog"> - <div class="md-dialog__inner md-typeset"></div> - </div> - - <!-- Theme-related configuration --> - {% block config %} - {%- set app = { - "base": base_url, - "features": features, - "translations": {}, - "search": "assets/javascripts/workers/search.js" | url, - "version": config.extra.version or None - } -%} - - <!-- Translations --> - {%- set translations = app.translations -%} - {%- for key in [ - "clipboard.copy", - "clipboard.copied", - "search.config.lang", - "search.config.pipeline", - "search.config.separator", - "search.placeholder", - "search.result.placeholder", - "search.result.none", - "search.result.one", - "search.result.other", - "search.result.more.one", - "search.result.more.other", - "search.result.term.missing", - "select.version.title" - ] -%} - {%- set _ = translations.update({ key: lang.t(key) }) -%} - {%- endfor -%} - - <!-- Configuration --> - <script id="__config" type="application/json"> - {{- app | tojson -}} - </script> - {% endblock %} - - <!-- Theme-related JavaScript --> - {% block scripts %} - <script src="{{ 'assets/javascripts/bundle.js' | url }}"></script> - - <!-- Custom JavaScript --> - {% for path in config["extra_javascript"] %} - <script src="{{ path | url }}"></script> - {% endfor %} - {% endblock %} - </body> -</html> diff --git a/docs/src/main.html b/docs/src/main.html deleted file mode 100644 index 37d79e55..00000000 --- a/docs/src/main.html +++ /dev/null @@ -1,23 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% extends "base.html" %} diff --git a/docs/src/mkdocs_theme.yml b/docs/src/mkdocs_theme.yml deleted file mode 100644 index ab57f819..00000000 --- a/docs/src/mkdocs_theme.yml +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# Language for theme localization -language: en - -# Text direction (can be ltr or rtl), default: ltr -direction: - -# Feature flags for functionality that alters behavior significantly, and thus -# may be a matter of taste -features: [] - -# Sets the primary and accent color palettes as defined in the Material Design -# documentation - possible values can be looked up in the getting started guide -palette: - - # Primary color used for header, sidebar and links, default: indigo - primary: - - # Accent color for highlighting user interaction, default: indigo - accent: - -# Fonts used by Material, automatically loaded from Google Fonts - see the site -# for a list of available fonts -font: - - # Default font for text - text: Roboto - - # Fixed-width font for code listings - code: Roboto Mono - -# From Material 5.x on, icons are inlined into the HTML and CSS as SVGs. Some -# icons that are part of the HTML can be configured and replaced -icon: - -# Favicon to be rendered -favicon: assets/images/favicon.png - -# Material includes the search in the header as a partial, not as a separate -# template, so it's correct that search.html is missing -include_search_page: false - -# Material doesn't use MkDocs search functionality but provides its own. For -# this reason, only the search index needs to be built -search_index_only: true - -# Static pages to build -static_templates: - - 404.html diff --git a/docs/src/overrides/assets/javascripts/bundle.ts b/docs/src/overrides/assets/javascripts/bundle.ts deleted file mode 100644 index 45f918b2..00000000 --- a/docs/src/overrides/assets/javascripts/bundle.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { merge } from "rxjs" -import { switchMap } from "rxjs/operators" - -import { - getComponentElements, - mountIconSearch, - mountSponsorship -} from "./components" -import { setupAnalytics } from "./integrations" - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/* Set up extra analytics events */ -setupAnalytics() - -/* Set up extra component observables */ -const component$ = document$ - .pipe( - switchMap(() => merge( - - /* Icon search */ - ...getComponentElements("iconsearch") - .map(el => mountIconSearch(el)), - - /* Sponsorship */ - ...getComponentElements("sponsorship") - .map(el => mountSponsorship(el)) - )) - ) - -/* Subscribe to all components */ -component$.subscribe() diff --git a/docs/src/overrides/assets/javascripts/components/_/index.ts b/docs/src/overrides/assets/javascripts/components/_/index.ts deleted file mode 100644 index 4060302a..00000000 --- a/docs/src/overrides/assets/javascripts/components/_/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { getElementOrThrow, getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Component type - */ -export type ComponentType = - | "iconsearch" /* Icon search */ - | "iconsearch-query" /* Icon search input */ - | "iconsearch-result" /* Icon search results */ - | "sponsorship" /* Sponsorship */ - | "sponsorship-count" /* Sponsorship count */ - | "sponsorship-total" /* Sponsorship total */ - -/** - * Component - * - * @template T - Component type - * @template U - Reference type - */ -export type Component< - T extends {} = {}, - U extends HTMLElement = HTMLElement -> = - T & { - ref: U /* Component reference */ - } - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Component type map - */ -interface ComponentTypeMap { - "iconsearch": HTMLElement /* Icon search */ - "iconsearch-query": HTMLInputElement /* Icon search input */ - "iconsearch-result": HTMLElement /* Icon search results */ - "sponsorship": HTMLElement /* Sponsorship */ - "sponsorship-count": HTMLElement /* Sponsorship count */ - "sponsorship-total": HTMLElement /* Sponsorship total */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the element for a given component or throw a reference error - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Element - */ -export function getComponentElement<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T] { - return getElementOrThrow(`[data-mdx-component=${type}]`, node) -} - -/** - * Retrieve all elements for a given component - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Elements - */ -export function getComponentElements<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T][] { - return getElements(`[data-mdx-component=${type}]`, node) -} diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts deleted file mode 100644 index 38b88e37..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, merge } from "rxjs" - -import { configuration } from "~/_" -import { requestJSON } from "~/browser" - -import { Component, getComponentElement } from "../../_" -import { - IconSearchQuery, - mountIconSearchQuery -} from "../query" -import { - IconSearchResult, - mountIconSearchResult -} from "../result" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon category - */ -export interface IconCategory { - base: string /* Category base URL */ - data: Record<string, string> /* Category data */ -} - -/** - * Icon search index - */ -export interface IconSearchIndex { - icons: IconCategory /* Icons */ - emojis: IconCategory /* Emojis */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Icon search - */ -export type IconSearch = - | IconSearchQuery - | IconSearchResult - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search - * - * @param el - Icon search element - * - * @returns Icon search component observable - */ -export function mountIconSearch( - el: HTMLElement -): Observable<Component<IconSearch>> { - const config = configuration() - const index$ = requestJSON<IconSearchIndex>( - new URL("overrides/assets/javascripts/iconsearch_index.json", config.base) - ) - - /* Retrieve query and result components */ - const query = getComponentElement("iconsearch-query", el) - const result = getComponentElement("iconsearch-result", el) - - /* Create and return component */ - const query$ = mountIconSearchQuery(query) - const result$ = mountIconSearchResult(result, { index$, query$ }) - return merge(query$, result$) -} diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/index.ts deleted file mode 100644 index ad7fe77b..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./query" -export * from "./result" diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts deleted file mode 100644 index 0e1f6c66..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - combineLatest, - fromEvent, - merge -} from "rxjs" -import { - delay, - distinctUntilChanged, - filter, - map, - withLatestFrom -} from "rxjs/operators" - -import { watchElementFocus } from "~/browser" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search query - */ -export interface IconSearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search query - * - * @param el - Icon search query element - * - * @returns Icon search query component observable - */ -export function mountIconSearchQuery( - el: HTMLInputElement -): Observable<Component<IconSearchQuery, HTMLInputElement>> { - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)) - ) - .pipe( - map(() => el.value), - distinctUntilChanged() - ) - - /* Log search on blur */ - focus$ - .pipe( - filter(active => !active), - withLatestFrom(value$) - ) - .subscribe(([, value]) => { - const path = document.location.pathname - if (value.length) - ga("send", "pageview", `${path}?q=[icon]+${value}`) - }) - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ ref: el, value, focus })), - ) -} diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts deleted file mode 100644 index 91e0ca3c..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { filter as search } from "fuzzaldrin-plus" -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest, - merge, - of -} from "rxjs" -import { - bufferCount, - distinctUntilKeyChanged, - filter, - finalize, - map, - observeOn, - switchMap, - tap, - withLatestFrom, - zipWith -} from "rxjs/operators" - -import { - addToSearchResultList, - resetSearchResultList, - resetSearchResultMeta, - setSearchResultMeta -} from "~/actions" -import { - getElementOrThrow, - watchElementThreshold -} from "~/browser" - -import { Icon, renderIconSearchResult } from "_/templates" - -import { Component } from "../../_" -import { IconSearchIndex } from "../_" -import { IconSearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search result - */ -export interface IconSearchResult { - data: Icon[] /* Search result data */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - index$: Observable<IconSearchIndex> /* Search index observable */ - query$: Observable<IconSearchQuery> /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - index$: Observable<IconSearchIndex> /* Search index observable */ - query$: Observable<IconSearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch icon search result - * - * @param _el - Icon search result element - * @param options - Options - * - * @returns Icon search result observable - */ -export function watchIconSearchResult( - _el: HTMLElement, { index$, query$ }: WatchOptions -): Observable<IconSearchResult> { - return combineLatest([ - query$.pipe(distinctUntilKeyChanged("value")), - index$ - .pipe( - map(({ icons, emojis }) => [ - ...Object.keys(icons.data), - ...Object.keys(emojis.data) - ]) - ) - ]) - .pipe( - map(([{ value }, data]) => search(data, value)), - switchMap(shortcodes => index$.pipe( - map(({ icons, emojis }) => ({ - data: shortcodes.map<Icon>(shortcode => { - const category = - shortcode in icons.data - ? icons - : emojis - return { - shortcode, - url: [ - category.base, - category.data[shortcode] - ].join("") - } - }) - })) - )) - ) -} - -/** - * Mount icon search result - * - * @param el - Icon search result element - * @param options - Options - * - * @returns Icon search result component observable - */ -export function mountIconSearchResult( - el: HTMLElement, { index$, query$ }: MountOptions -): Observable<Component<IconSearchResult, HTMLElement>> { - const internal$ = new Subject<IconSearchResult>() - const boundary$ = watchElementThreshold(el) - .pipe( - filter(Boolean) - ) - - /* Update search result metadata */ - const meta = getElementOrThrow(":scope > :first-child", el) - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(query$) - ) - .subscribe(([{ data }, { value }]) => { - if (value) - setSearchResultMeta(meta, data.length) - else - resetSearchResultMeta(meta) - }) - - /* Update icon search result list */ - const list = getElementOrThrow(":scope > :last-child", el) - internal$ - .pipe( - observeOn(animationFrameScheduler), - tap(() => resetSearchResultList(list)), - switchMap(({ data }) => merge( - of(...data.slice(0, 10)), - of(...data.slice(10)) - .pipe( - bufferCount(10), - zipWith(boundary$), - switchMap(([chunk]) => of(...chunk)) - ) - )), - withLatestFrom(query$) - ) - .subscribe(([result, { value }]) => { - addToSearchResultList(list, renderIconSearchResult(result, value)) - }) - - /* Create and return component */ - return watchIconSearchResult(el, { query$, index$ }) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/overrides/assets/javascripts/components/index.ts b/docs/src/overrides/assets/javascripts/components/index.ts deleted file mode 100644 index fdeed26c..00000000 --- a/docs/src/overrides/assets/javascripts/components/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./iconsearch" -export * from "./sponsorship" diff --git a/docs/src/overrides/assets/javascripts/components/sponsorship/index.ts b/docs/src/overrides/assets/javascripts/components/sponsorship/index.ts deleted file mode 100644 index 171e3369..00000000 --- a/docs/src/overrides/assets/javascripts/components/sponsorship/index.ts +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable } from "rxjs" -import { map } from "rxjs/operators" - -import { getElementOrThrow, requestJSON } from "~/browser" - -import { renderPrivateSponsor, renderPublicSponsor } from "_/templates" - -import { Component, getComponentElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sponsor type - */ -export type SponsorType = - | "user" /* Sponsor is a user */ - | "organization" /* Sponsor is an organization */ - -/** - * Sponsor visibility - */ -export type SponsorVisibility = - | "public" /* Sponsor is a user */ - | "private" /* Sponsor is an organization */ - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsor user - */ -export interface SponsorUser { - type: SponsorType /* Sponsor type */ - name: string /* Sponsor login name */ - image: string /* Sponsor image URL */ - url: string /* Sponsor URL */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Public sponsor - */ -export interface PublicSponsor { - type: "public" /* Sponsor visibility */ - user: SponsorUser /* Sponsor user */ -} - -/** - * Private sponsor - */ -export interface PrivateSponsor { - type: "private" /* Sponsor visibility */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsor - */ -export type Sponsor = - | PublicSponsor - | PrivateSponsor - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsorship - */ -export interface Sponsorship { - sponsors: Sponsor[] /* Sponsors */ - total: number /* Total amount */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount sponsorship - * - * @param el - Sponsorship element - * - * @returns Sponsorship component observable - */ -export function mountSponsorship( - el: HTMLElement -): Observable<Component<Sponsorship>> { - const sponsorship$ = requestJSON<Sponsorship>( - "https://3if8u9o552.execute-api.us-east-1.amazonaws.com/_/" - ) - - /* Retrieve adjacent components */ - const count = getComponentElement("sponsorship-count") - const total = getComponentElement("sponsorship-total") - - /* Render sponsorship */ - sponsorship$.subscribe(sponsorship => { - el.removeAttribute("hidden") - - /* Render public sponsors with avatar and links */ - const list = getElementOrThrow(":scope > :first-child", el) - for (const sponsor of sponsorship.sponsors) - if (sponsor.type === "public") - list.appendChild(renderPublicSponsor(sponsor.user)) - - /* Render combined private sponsors */ - list.appendChild(renderPrivateSponsor( - sponsorship.sponsors.filter(({ type }) => ( - type === "private" - )).length - )) - - /* Render sponsorship count and total */ - count.innerText = `${sponsorship.sponsors.length}` - total.innerText = `$ ${sponsorship.total - .toString() - .replace(/\B(?=(\d{3})+(?!\d))/g, ",") - }` - }) - - // /* Create and return component */ - return sponsorship$ - .pipe( - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/overrides/assets/javascripts/integrations/analytics/index.ts b/docs/src/overrides/assets/javascripts/integrations/analytics/index.ts deleted file mode 100644 index f7efd853..00000000 --- a/docs/src/overrides/assets/javascripts/integrations/analytics/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { fromEvent } from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up extra analytics events - */ -export function setupAnalytics(): void { - const { origin } = new URL(location.href) - fromEvent(document.body, "click") - .subscribe(ev => { - if (ev.target instanceof HTMLElement) { - const el = ev.target.closest("a") - if (el && el.origin !== origin) - ga("send", "event", "outbound", "click", el.href) - } - }) -} diff --git a/docs/src/overrides/assets/javascripts/integrations/index.ts b/docs/src/overrides/assets/javascripts/integrations/index.ts deleted file mode 100644 index 3093cb03..00000000 --- a/docs/src/overrides/assets/javascripts/integrations/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./analytics" diff --git a/docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx b/docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx deleted file mode 100644 index 5dac49b4..00000000 --- a/docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { wrap } from "fuzzaldrin-plus" - -import { translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon - */ -export interface Icon { - shortcode: string /* Icon shortcode */ - url: string /* Icon URL */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Highlight an icon search result - * - * @param icon - Icon - * @param query - Search query - * - * @returns Highlighted result - */ -function highlight(icon: Icon, query: string): string { - return wrap(icon.shortcode, query, { - wrap: { - tagOpen: "<b>", - tagClose: "</b>" - } - }) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render an icon search result - * - * @param icon - Icon - * @param query - Search query - * - * @returns Element - */ -export function renderIconSearchResult( - icon: Icon, query: string -): HTMLElement { - return ( - <li class="mdx-iconsearch-result__item"> - <span class="twemoji"> - <img src={icon.url} /> - </span> - <button - class="md-clipboard--inline" - title={translation("clipboard.copy")} - data-clipboard-text={`:${icon.shortcode}:`} - > - <code>{`:${highlight(icon, query)}:`}</code> - </button> - </li> - ) -} diff --git a/docs/src/overrides/assets/javascripts/templates/index.ts b/docs/src/overrides/assets/javascripts/templates/index.ts deleted file mode 100644 index 8bd18b91..00000000 --- a/docs/src/overrides/assets/javascripts/templates/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./iconsearch" -export * from "./sponsorship" diff --git a/docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx b/docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx deleted file mode 100644 index 7e61433e..00000000 --- a/docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { h } from "~/utilities" - -import { SponsorUser } from "_/components" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render public sponsor - * - * @param user - Sponsor user - * - * @returns Element - */ -export function renderPublicSponsor( - user: SponsorUser -): HTMLElement { - const title = `@${user.name}` - return ( - <a href={user.url} title={title} class="mdx-sponsorship__item"> - <img src={user.image} /> - </a> - ) -} - -/** - * Render private sponsor - * - * @param count - Number of private sponsors - * - * @returns Element - */ -export function renderPrivateSponsor( - count: number -): HTMLElement { - return ( - <a - href="https://github.com/sponsors/squidfunk" - class="mdx-sponsorship__item mdx-sponsorship__item--private" - > - +{count} - </a> - ) -} diff --git a/docs/src/overrides/assets/stylesheets/main.scss b/docs/src/overrides/assets/stylesheets/main.scss deleted file mode 100644 index b30bbe0f..00000000 --- a/docs/src/overrides/assets/stylesheets/main.scss +++ /dev/null @@ -1,46 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; -@import "material-shadows"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "main/typeset"; - -@import "main/layout/announce"; -@import "main/layout/hero"; -@import "main/layout/iconsearch"; -@import "main/layout/sponsorship"; - -@import "main/shame"; diff --git a/docs/src/overrides/assets/stylesheets/main/_shame.scss b/docs/src/overrides/assets/stylesheets/main/_shame.scss deleted file mode 100644 index a6acadab..00000000 --- a/docs/src/overrides/assets/stylesheets/main/_shame.scss +++ /dev/null @@ -1,25 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Nothing to see here, move along -// ---------------------------------------------------------------------------- diff --git a/docs/src/overrides/assets/stylesheets/main/_typeset.scss b/docs/src/overrides/assets/stylesheets/main/_typeset.scss deleted file mode 100644 index 6dec25f0..00000000 --- a/docs/src/overrides/assets/stylesheets/main/_typeset.scss +++ /dev/null @@ -1,148 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Pumping heart animation -@keyframes mdx-heart { - 0%, - 40%, - 80%, - 100% { - transform: scale(1); - } - - 20%, - 60% { - transform: scale(1.15); - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Twitter icon - .twitter { - color: #00acee; - } - - // Insiders video - .mdx-video { - width: auto; - - // Insiders video container - &__inner { - position: relative; - width: 100%; - height: 0; - padding-bottom: 56.138%; - } - - // Insiders video iframe - iframe { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - border: none; - } - } - - // Pumping heart - .mdx-heart { - animation: mdx-heart 1000ms infinite; - } - - // Insiders color (for links, etc.) - .mdx-insiders { - color: $clr-pink-500; - } - - // Switch buttons - .mdx-switch button { - cursor: pointer; - transition: opacity 250ms; - - // Button on focus/hover - &:focus, - &:hover { - opacity: 0.75; - } - - // Code block - > code { - display: block; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - } - } - - // Two-column layout - .mdx-columns { - - // Column - ol, - ul { - columns: 2; - - // [mobile portrait -]: Reset columns on mobile - @include break-to-device(mobile portrait) { - columns: initial; - } - } - - // Column item - li { - break-inside: avoid; - } - } - - // Blog author - .mdx-author { - display: flex; - font-size: px2rem(13.6px); - - // Blog author image - img { - height: px2rem(40px); - border-radius: 100%; - } - - // Blog author content - p { - margin-right: px2rem(16px); - - // Blog metadata - > span { - display: block; - } - } - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_announce.scss b/docs/src/overrides/assets/stylesheets/main/layout/_announce.scss deleted file mode 100644 index a4d6831c..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_announce.scss +++ /dev/null @@ -1,46 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Announcement bar -.md-announce { - - // Text link, also on focus/hover - a, - a:focus, - a:hover { - color: currentColor; - } - - // Don't wrap name of blog article - strong { - white-space: nowrap; - } - - // Twitter icon - .twitter { - margin-left: 0.2em; - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_hero.scss b/docs/src/overrides/assets/stylesheets/main/layout/_hero.scss deleted file mode 100644 index c0af9120..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_hero.scss +++ /dev/null @@ -1,124 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Landing page container -.mdx-container { - padding-top: px2rem(20px); - background: - url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1123 258'><path d='M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style='fill: hsla(0, 0%, 100%, 1)' /></svg>") no-repeat bottom, - linear-gradient( - to bottom, - var(--md-primary-fg-color), - hsla(280, 67%, 55%, 1) 99%, - var(--md-default-bg-color) 99% - ); - - // Adjust background for slate theme - [data-md-color-scheme="slate"] & { - background: - url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1123 258'><path d='M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style='fill: hsla(232, 15%, 21%, 1)' /></svg>") no-repeat bottom, - linear-gradient( - to bottom, - var(--md-primary-fg-color), - hsla(280, 67%, 55%, 1) 99%, - var(--md-default-bg-color) 99% - ); - } -} - -// Landing page hero -.mdx-hero { - margin: 0 px2rem(16px); - color: var(--md-primary-bg-color); - - // Hero headline - h1 { - margin-bottom: px2rem(20px); - color: currentColor; - font-weight: 700; - - // [mobile portrait -]: Larger hero headline - @include break-to-device(mobile portrait) { - font-size: px2rem(28px); - } - } - - // Hero content - &__content { - padding-bottom: px2rem(120px); - } - - // [tablet landscape +]: Columnar display - @include break-from-device(tablet landscape) { - display: flex; - align-items: stretch; - - // Adjust spacing and set dimensions - &__content { - max-width: px2rem(380px); - margin-top: px2rem(70px); - padding-bottom: 14vw; - } - - // Hero image - &__image { - order: 1; - width: px2rem(760px); - transform: translateX(#{px2rem(80px)}); - } - } - - // [screen +]: Columnar display and adjusted spacing - @include break-from-device(screen) { - - // Hero image - &__image { - transform: translateX(#{px2rem(160px)}); - } - } - - // Button - .md-button { - margin-top: px2rem(10px); - margin-right: px2rem(10px); - color: var(--md-primary-bg-color); - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - } - - // Primary button - &--primary { - color: hsla(280deg, 37%, 48%, 1); - background-color: var(--md-primary-bg-color); - border-color: var(--md-primary-bg-color); - } - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss b/docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss deleted file mode 100644 index 910130bf..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss +++ /dev/null @@ -1,130 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Icon search - .mdx-iconsearch { - position: relative; - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.1); - transition: box-shadow 125ms; - - // Icon search on focus/hover - &:focus-within, - &:hover { - box-shadow: - 0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15); - } - - // Icon search input - .md-input { - background: var(--md-default-bg-color); - box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07); - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] & { - background: var(--md-code-bg-color); - } - } - } - - // Icon search result - .mdx-iconsearch-result { - max-height: 50vh; - overflow-y: auto; - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - touch-action: pan-y; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - - // Icon search result metadata - &__meta { - position: absolute; - top: px2rem(8px); - right: px2rem(12px); - color: var(--md-default-fg-color--lighter); - font-size: px2rem(12.8px); - } - - // Icon search result list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Icon search result item - &__item { - margin: 0; - padding: px2rem(4px) px2rem(12px); - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - - // Omit border on last child - &:last-child { - border-bottom: none; - } - - // Item content - > * { - margin-right: px2rem(12px); - } - - // Set icon dimensions to fit - img { - width: px2rem(18px); - height: px2rem(18px); - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] &[src*=squidfunk] { - filter: invert(1); - } - } - } - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss b/docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss deleted file mode 100644 index 54a75f8c..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss +++ /dev/null @@ -1,110 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Premium sponsors - .mdx-premium { - - // Paragraphs - p { - margin: 2em 0; - text-align: center; - } - - // Images - img { - height: px2rem(40px); - } - } - - // Sponsorship - .mdx-sponsorship { - - // Sponsorship list - &__list { - margin: 2em 0; - overflow: auto; - } - - // Sponsorship item - &__item { - display: block; - float: left; - width: px2rem(60px); - height: px2rem(60px); - margin: px2rem(4px); - overflow: hidden; - border-radius: 100%; - transform: scale(1); - transition: - color 125ms, - transform 125ms; - - // Sponsor item on focus/hover - &:focus, - &:hover { - transform: scale(1.1); - - // Sponsor avatar - img { - filter: grayscale(0%); - } - } - - // Private sponsor - &--private { - color: var(--md-default-fg-color--lighter); - font-weight: 700; - font-size: px2rem(24px); - line-height: px2rem(60px); - text-align: center; - background: var(--md-default-fg-color--lightest); - } - - // Sponsor avatar - img { - display: block; - width: 100%; - height: auto; - filter: grayscale(100%); - transition: filter 125ms; - } - } - } - - // Sponsorship button - .mdx-sponsorship-button { - font-weight: 400; - } - - // Sponsorship count and total - .mdx-sponsorship-count, - .mdx-sponsorship-total { - font-weight: 700; - } -} diff --git a/docs/src/overrides/home.html b/docs/src/overrides/home.html deleted file mode 100644 index 95c6b94c..00000000 --- a/docs/src/overrides/home.html +++ /dev/null @@ -1,106 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% extends "overrides/main.html" %} - -<!-- Render hero under tabs --> -{% block tabs %} - {{ super() }} - - <!-- Additional styles for landing page --> - <style> - - /* Application header should be static for the landing page */ - .md-header { - position: initial; - } - - /* Remove spacing, as we cannot hide it completely */ - .md-main__inner { - margin: 0; - } - - /* Hide main content for now */ - .md-content { - display: none; - } - - /* Hide table of contents */ - @media screen and (min-width: 60em) { - .md-sidebar--secondary { - display: none; - } - } - - /* Hide navigation */ - @media screen and (min-width: 76.25em) { - .md-sidebar--primary { - display: none; - } - } - </style> - - <!-- Hero for landing page --> - <section class="mdx-container"> - <div class="md-grid md-typeset"> - <div class="mdx-hero"> - - <!-- Hero image --> - <div class="mdx-hero__image"> - <img - src="assets/images/illustration.png" - alt="" - width="1659" - height="1200" - draggable="false" - > - </div> - - <!-- Hero content --> - <div class="mdx-hero__content"> - <h1>Technical documentation that just works</h1> - <p>{{ config.site_description }}. Set up in 5 minutes.</p> - <a - href="{{ page.next_page.url | url }}" - title="{{ page.next_page.title | e }}" - class="md-button md-button--primary" - > - Quick start - </a> - <a - href="{{ 'insiders/' | url }}" - title="Material for MkDocs Insiders" - class="md-button" - > - Get Insiders - </a> - </div> - </div> - </div> - </section> -{% endblock %} - -<!-- Content --> -{% block content %}{% endblock %} - -<!-- Application footer --> -{% block footer %}{% endblock %} diff --git a/docs/src/overrides/main.html b/docs/src/overrides/main.html deleted file mode 100644 index 9f715940..00000000 --- a/docs/src/overrides/main.html +++ /dev/null @@ -1,53 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% extends "base.html" %} - -<!-- Custom front matter --> -{% block extrahead %} - - <!-- Extra stylesheets (can't be set in mkdocs.yml due to content hash) --> - <link - rel="stylesheet" - href="{{ 'overrides/assets/stylesheets/main.css' | url }}" - /> -{% endblock %} - -<!-- Announcement bar --> -{% block announce %} - <a href="https://twitter.com/squidfunk"> - For updates follow <strong>@squidfunk</strong> on - <span class="twemoji twitter"> - {% include ".icons/fontawesome/brands/twitter.svg" %} - </span> - <strong>Twitter</strong> - </a> -{% endblock %} - -<!-- Theme-related JavaScript --> -{% block scripts %} - {{ super() }} - - <!-- Extra JavaScript (can't be set in mkdocs.yml due to content hash) --> - <script src="{{ 'overrides/assets/javascripts/bundle.js' | url }}"></script> -{% endblock %} - diff --git a/docs/src/partials/footer.html b/docs/src/partials/footer.html deleted file mode 100644 index 4b0a16a5..00000000 --- a/docs/src/partials/footer.html +++ /dev/null @@ -1,110 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% import "partials/language.html" as lang with context %} - -<!-- Footer --> -<footer class="md-footer"> - - <!-- Link to previous and/or next page --> - {% if page.previous_page or page.next_page %} - <nav - class="md-footer__inner md-grid" - aria-label="{{ lang.t('footer.title') }}" - > - - <!-- Link to previous page --> - {% if page.previous_page %} - {% set direction = lang.t("footer.previous") %} - <a - href="{{ page.previous_page.url | url }}" - class="md-footer__link md-footer__link--prev" - aria-label="{{ direction }}: {{ page.previous_page.title | e }}" - rel="prev" - > - <div class="md-footer__button md-icon"> - {% include ".icons/material/arrow-left.svg" %} - </div> - <div class="md-footer__title"> - <div class="md-ellipsis"> - <span class="md-footer__direction"> - {{ direction }} - </span> - {{ page.previous_page.title }} - </div> - </div> - </a> - {% endif %} - - <!-- Link to next page --> - {% if page.next_page %} - {% set direction = lang.t("footer.next") %} - <a - href="{{ page.next_page.url | url }}" - class="md-footer__link md-footer__link--next" - aria-label="{{ direction }}: {{ page.next_page.title | e }}" - rel="next" - > - <div class="md-footer__title"> - <div class="md-ellipsis"> - <span class="md-footer__direction"> - {{ direction }} - </span> - {{ page.next_page.title }} - </div> - </div> - <div class="md-footer__button md-icon"> - {% include ".icons/material/arrow-right.svg" %} - </div> - </a> - {% endif %} - </nav> - {% endif %} - - <!-- Further information --> - <div class="md-footer-meta md-typeset"> - <div class="md-footer-meta__inner md-grid"> - - <!-- Copyright and theme information --> - <div class="md-footer-copyright"> - {% if config.copyright %} - <div class="md-footer-copyright__highlight"> - {{ config.copyright }} - </div> - {% endif %} - {% if not config.extra.generator == false %} - Made with - <a - href="https://squidfunk.github.io/mkdocs-material/" - target="_blank" rel="noopener" - > - Material for MkDocs - </a> - {% endif %} - {{ extracopyright }} - </div> - - <!-- Social links --> - {% include "partials/social.html" %} - </div> - </div> -</footer> diff --git a/docs/src/partials/header.html b/docs/src/partials/header.html deleted file mode 100644 index f5cf2060..00000000 --- a/docs/src/partials/header.html +++ /dev/null @@ -1,161 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Determine class according to configuration --> -{% set class = "md-header" %} -{% if "navigation.tabs.sticky" in features %} - {% set class = class ~ " md-header--lifted" %} -{% endif %} - -<!-- Header --> -<header class="{{ class }}" data-md-component="header"> - <nav - class="md-header__inner md-grid" - aria-label="{{ lang.t('header.title') }}" - > - - <!-- Link to home --> - <a - href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}" - title="{{ config.site_name | e }}" - class="md-header__button md-logo" - aria-label="{{ config.site_name }}" - data-md-component="logo" - > - {% include "partials/logo.html" %} - </a> - - <!-- Button to open drawer --> - <label class="md-header__button md-icon" for="__drawer"> - {% include ".icons/material/menu" ~ ".svg" %} - </label> - - <!-- Header title --> - <div class="md-header__title" data-md-component="header-title"> - <div class="md-header__ellipsis"> - <div class="md-header__topic"> - <span class="md-ellipsis"> - {{ config.site_name }} - </span> - </div> - <div class="md-header__topic" data-md-component="header-topic"> - <span class="md-ellipsis"> - {% if page and page.meta and page.meta.title %} - {{ page.meta.title }} - {% else %} - {{ page.title }} - {% endif %} - </span> - </div> - </div> - </div> - - <!-- Color palette --> - {% if not config.theme.palette is mapping %} - <form class="md-header__option" data-md-component="palette"> - {% for option in config.theme.palette %} - {% set primary = option.primary | replace(" ", "-") | lower %} - {% set accent = option.accent | replace(" ", "-") | lower %} - <input - class="md-option" - data-md-color-media="{{ option.media }}" - data-md-color-scheme="{{ option.scheme }}" - data-md-color-primary="{{ primary }}" - data-md-color-accent="{{ accent }}" - {% if option.toggle %} - aria-label="{{ option.toggle.name }}" - {% else %} - aria-hidden="true" - {% endif %} - type="radio" - name="__palette" - id="__palette_{{ loop.index }}" - /> - {% if option.toggle %} - <label - class="md-header__button md-icon" - title="{{ option.toggle.name }}" - for="__palette_{{ loop.index0 or loop.length }}" - hidden - > - {% include ".icons/" ~ option.toggle.icon ~ ".svg" %} - </label> - {% endif %} - {% endfor %} - </form> - {% endif %} - - <!-- Site language selector --> - {% if config.extra.alternate %} - <div class="md-header__option"></form> - <div class="md-select"> - {% set icon = config.theme.icon.alternate or "material/translate" %} - <button - class="md-header__button md-icon" - aria-label="{{ lang.t('select.language.title') }}" - > - {% include ".icons/" ~ icon ~ ".svg" %} - </button> - <div class="md-select__inner"> - <ul class="md-select__list"> - {% for alt in config.extra.alternate %} - <li class="md-select__item"> - <a - href="{{ alt.link | url }}" - hreflang="{{ alt.lang }}" - class="md-select__link" - > - {{ alt.name }} - </a> - </li> - {% endfor %} - </ul> - </div> - </div> - </div> - {% endif %} - - <!-- Button to open search modal --> - {% if "search" in config["plugins"] %} - <label class="md-header__button md-icon" for="__search"> - {% include ".icons/material/magnify.svg" %} - </label> - - <!-- Search interface --> - {% include "partials/search.html" %} - {% endif %} - - <!-- Repository information --> - {% if config.repo_url %} - <div class="md-header__source"> - {% include "partials/source.html" %} - </div> - {% endif %} - </nav> - - <!-- Navigation tabs (sticky) --> - {% if "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} -</header> diff --git a/docs/src/partials/integrations/analytics.html b/docs/src/partials/integrations/analytics.html deleted file mode 100644 index dfc367cf..00000000 --- a/docs/src/partials/integrations/analytics.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Determine analytics provider (deprecated, removed in v8) --> -{% if config.google_analytics %} - {% set provider = "google" %} -{% endif %} - -<!-- Determine analytics provider --> -{% if config.extra.analytics %} - {% set provider = config.extra.analytics.provider %} -{% endif %} - -<!-- Set up analytics provider --> -{% if provider %} - {% include "partials/integrations/analytics/" ~ provider ~ ".html" %} -{% endif %} diff --git a/docs/src/partials/integrations/analytics/google.html b/docs/src/partials/integrations/analytics/google.html deleted file mode 100644 index 632558e4..00000000 --- a/docs/src/partials/integrations/analytics/google.html +++ /dev/null @@ -1,93 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Determine analytics property (deprecated, removed in v8) --> -{% if config.google_analytics %} - {% set property = config.google_analytics[0] %} -{% endif %} - -<!-- Determine analytics property --> -{% if config.extra.analytics %} - {% set property = config.extra.analytics.property | d("", true) %} -{% endif %} - -<!-- Google Analytics 4 (G-XXXXXXXXXX) --> -{% if property.startswith("G-") %} - <script> - window.dataLayer = window.dataLayer || [] - function gtag() { dataLayer.push(arguments) } - - /* Set up integration and send page view */ - gtag("js", new Date()) - gtag("config", "{{ property }}") - - /* Register virtual event handlers */ - document.addEventListener("DOMContentLoaded", function() { - - /* Send page view on location change */ - if (typeof location$ !== "undefined") - location$.subscribe(function(url) { - gtag("config", "{{ property }}", { - page_path: url.pathname - }) - }) - }) - </script> - <script async src="https://www.googletagmanager.com/gtag/js?id={{ property }}"> - </script> - -<!-- Google Analytics (UA-XXXXXXXX-X) --> -{% elif property.startswith("UA-") %} - <script> - window.ga = window.ga || function() { - (ga.q = ga.q || []).push(arguments) - } - ga.l = +new Date() - - /* Set up integration and send page view */ - ga("create", "{{ property }}", "auto") - ga("set", "anonymizeIp", true) - ga("send", "pageview") - - /* Register virtual event handlers */ - document.addEventListener("DOMContentLoaded", function() { - if (document.forms.search) { - var query = document.forms.search.query - query.addEventListener("blur", function() { - if (this.value) { - var path = document.location.pathname; - ga("send", "pageview", path + "?q=" + this.value) - } - }) - } - - /* Send page view on location change */ - if (typeof location$ !== "undefined") - location$.subscribe(function(url) { - ga("send", "pageview", url.pathname) - }) - }) - </script> - <script async src="https://www.google-analytics.com/analytics.js"></script> -{% endif %} - - diff --git a/docs/src/partials/integrations/disqus.html b/docs/src/partials/integrations/disqus.html deleted file mode 100644 index 0eaeb9a1..00000000 --- a/docs/src/partials/integrations/disqus.html +++ /dev/null @@ -1,46 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Set from config but allow override --> -{% set disqus = config.extra.disqus %} -{% if page and page.meta and page.meta.disqus is string %} - {% set disqus = page.meta.disqus %} -{% endif %} - -<!-- Disqus integration --> -{% if not page.is_homepage and disqus %} - <h2 id="__comments">{{ lang.t("meta.comments") }}</h2> - <div id="disqus_thread"></div> - <script> - var disqus_config = function () { - this.page.url = "{{ page.canonical_url }}"; - this.page.identifier = - "{{ page.canonical_url | replace(config.site_url, '') }}"; - }; - window.addEventListener("load", function() { - var d = document, s = d.createElement("script"); - s.src = "//{{ disqus }}.disqus.com/embed.js"; - s.setAttribute("data-timestamp", +new Date()); - (d.head || d.body).appendChild(s); - }) - </script> -{% endif %} diff --git a/docs/src/partials/javascripts/base.html b/docs/src/partials/javascripts/base.html deleted file mode 100644 index db6d4a24..00000000 --- a/docs/src/partials/javascripts/base.html +++ /dev/null @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- - A collection of functions used from within some partials to allow the usage - of state saved in local or session storage, e.g. to model preferences. ---> -<script> - - /* Prepend the base path to the given key to ensure uniqueness */ - function __prefix(key) { - var prefix = new URL("{{ base_url }}", location) - return prefix.pathname + "." + key - } - - /* Fetch the given key from the given storage */ - function __get(key, storage = localStorage) { - return JSON.parse(storage.getItem(__prefix(key))) - } -</script> diff --git a/docs/src/partials/javascripts/palette.html b/docs/src/partials/javascripts/palette.html deleted file mode 100644 index 99479329..00000000 --- a/docs/src/partials/javascripts/palette.html +++ /dev/null @@ -1,29 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- User preference: color palette --> -<script> - var palette = __get("__palette") - if (palette !== null && typeof palette.color === "object") - for (var key in palette.color) - document.body.setAttribute("data-md-color-" + key, palette.color[key]) -</script> diff --git a/docs/src/partials/language.html b/docs/src/partials/language.html deleted file mode 100644 index c91bc43e..00000000 --- a/docs/src/partials/language.html +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Import translations for given language and fallback --> -{% import "partials/languages/" ~ config.theme.language ~ ".html" as lang %} -{% import "partials/languages/en.html" as fallback %} - -<!-- Re-export translations --> -{% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %} diff --git a/docs/src/partials/languages/af.html b/docs/src/partials/languages/af.html deleted file mode 100644 index abae5296..00000000 --- a/docs/src/partials/languages/af.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Afrikaans --> -{% macro t(key) %}{{ { - "language": "af", - "clipboard.copy": "Kopieer na knipbord", - "clipboard.copied": "gekopieer na knipbord", - "edit.link.title": "Wysig hierdie bladsy", - "footer.previous": "Vorige", - "footer.next": "Volgende", - "meta.comments": "Kommentaar", - "meta.source": "Bron", - "search.config.lang": "nl", - "search.placeholder": "Soek", - "search.result.placeholder": "Tik om te begin soek", - "search.result.none": "Geen ooreenstemmende dokumente", - "search.result.one": "1 ooreenstemmende dokument", - "search.result.other": "# ooreenstemmende dokumente", - "skip.link.title": "Slaan oor na inhoud", - "source.link.title": "Slaan oor na inhoud", - "source.revision.date": "Laaste opdatering", - "source.file.date.updated": "Laaste opdatering", - "source.file.date.created": "Geskep", - "toc.title": "Inhoudsopgawe" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ar.html b/docs/src/partials/languages/ar.html deleted file mode 100644 index 254f6f21..00000000 --- a/docs/src/partials/languages/ar.html +++ /dev/null @@ -1,46 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Arabic --> -{% macro t(key) %}{{ { - "language": "ar", - "direction": "rtl", - "clipboard.copy": "نسخ إلى الحافظة", - "clipboard.copied": "تم النسخ الى الحافظة", - "edit.link.title": "عدل الصفحة", - "footer.previous": "السابقة", - "footer.next": "التالية", - "meta.comments": "التعليقات", - "meta.source": "المصدر", - "search.config.pipeline": " ", - "search.placeholder": "بحث", - "search.result.placeholder": "اكتب لبدء البحث", - "search.result.none": "لا توجد نتائج", - "search.result.one": "نتائج البحث مستند واحد", - "search.result.other": "نتائج البحث # مستندات", - "skip.link.title": "انتقل إلى المحتوى", - "source.link.title": "اذهب إلى المصدر", - "source.revision.date": "اخر تحديث", - "source.file.date.updated": "اخر تحديث", - "source.file.date.created": "خلقت", - "toc.title": "جدول المحتويات" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/bg.html b/docs/src/partials/languages/bg.html deleted file mode 100644 index 2204b625..00000000 --- a/docs/src/partials/languages/bg.html +++ /dev/null @@ -1,52 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Bulgarian --> -{% macro t(key) %}{{ { - "language": "bg", - "clipboard.copy": "Копирай", - "clipboard.copied": "Копирано", - "edit.link.title": "Редактирай тази страница", - "footer.previous": "Предишна", - "footer.next": "Следваща", - "footer.title": "Долен колонтитул", - "header.title": "Горен колонтитул", - "meta.comments": "Коментари", - "meta.source": "Код", - "nav.title": "Навигация", - "search.config.lang": "ru", - "search.placeholder": "Търси", - "search.reset": "Изчисти", - "search.result.placeholder": "Започнете да пишете, за да търсите", - "search.result.none": "Няма резултати", - "search.result.one": "1 резултат", - "search.result.other": "# резултата", - "search.result.more.one": "още 1 на тази страница", - "search.result.more.other": "още # на тази страница", - "skip.link.title": "Към съдържанието", - "source.link.title": "Към хранилището", - "source.revision.date": "Последна промяна", - "source.file.date.updated": "Последна промяна", - "source.file.date.created": "Създаден", - "tabs.title": "Табове", - "toc.title": "Съдържание" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/bn.html b/docs/src/partials/languages/bn.html deleted file mode 100644 index 9acec3c1..00000000 --- a/docs/src/partials/languages/bn.html +++ /dev/null @@ -1,50 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Bengali (Bangla) --> -{% macro t(key) %}{{ { - "language": "bn", - "clipboard.copy": "ক্লিপবোর্ডে কপি করুন", - "clipboard.copied": "ক্লিপবোর্ডে কপি হয়েছে", - "edit.link.title": "এই পেজ এডিট করুন", - "footer.previous": "পূর্ববর্তী", - "footer.next": "পরে", - "footer.title": "ফুটার", - "header.title": "হেডার", - "meta.comments": "কমেন্ট", - "meta.source": "সোর্স", - "nav.title": "ন্যাভিগেশন", - "search.config.pipeline": " ", - "search.placeholder": "সার্চ", - "search.reset": "মুছে ফেলুন", - "search.result.placeholder": "সার্চ টাইপ করুন", - "search.result.none": "কিছু পাওয়া যায়নি", - "search.result.one": "১ টা ডকুমেন্ট", - "search.result.other": "# টা ডকুমেন্ট", - "skip.link.title": "কনটেন্টে যান", - "source.link.title": "রিপোজিটরিতে যান", - "source.revision.date": "শেষ আপডেট", - "source.file.date.updated": "শেষ আপডেট", - "source.file.date.created": "তৈরি হয়েছে", - "tabs.title": "ট্যাব", - "toc.title": "টেবিল অফ কনটেন্ট" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ca.html b/docs/src/partials/languages/ca.html deleted file mode 100644 index 898072ee..00000000 --- a/docs/src/partials/languages/ca.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Catalan --> -{% macro t(key) %}{{ { - "language": "ca", - "clipboard.copy": "Còpia al porta-retalls", - "clipboard.copied": "Copiat al porta-retalls", - "edit.link.title": "Edita aquesta pàgina", - "footer.previous": "Anterior", - "footer.next": "Següent", - "meta.comments": "Comentaris", - "meta.source": "Codi font", - "search.placeholder": "Cerca", - "search.result.placeholder": "Escriu per a començar a cercar", - "search.result.none": "Cap document coincideix", - "search.result.one": "1 document coincident", - "search.result.other": "# documents coincidents", - "skip.link.title": "Salta el contingut", - "source.link.title": "Ves al repositori", - "source.revision.date": "Darrera actualització", - "source.file.date.updated": "Darrera actualització", - "source.file.date.created": "Creada", - "toc.title": "Taula de continguts" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/cs.html b/docs/src/partials/languages/cs.html deleted file mode 100644 index e5d555a8..00000000 --- a/docs/src/partials/languages/cs.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Czech --> -{% macro t(key) %}{{ { - "language": "cs", - "clipboard.copy": "Kopírovat do schránky", - "clipboard.copied": "Zkopírováno do schránky", - "edit.link.title": "Upravit tuto stránku", - "footer.previous": "Předchozí", - "footer.next": "Další", - "meta.comments": "Komentáře", - "meta.source": "Zdroj", - "search.placeholder": "Hledat", - "search.result.placeholder": "Pište co se má vyhledat", - "search.result.none": "Nenalezeny žádné dokumenty", - "search.result.one": "Nalezený dokument: 1", - "search.result.other": "Nalezené dokumenty: #", - "skip.link.title": "Přeskočit obsah", - "source.link.title": "Přejít do repozitáře", - "source.revision.date": "Poslední aktualizace", - "source.file.date.updated": "Poslední aktualizace", - "source.file.date.created": "Vytvořeno", - "toc.title": "Obsah" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/da.html b/docs/src/partials/languages/da.html deleted file mode 100644 index 3b161a6a..00000000 --- a/docs/src/partials/languages/da.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Danish --> -{% macro t(key) %}{{ { - "language": "da", - "clipboard.copy": "Kopiér til udklipsholderen", - "clipboard.copied": "Kopieret til udklipsholderen", - "edit.link.title": "Redigér denne side", - "footer.previous": "Forrige", - "footer.next": "Næste", - "meta.comments": "Kommentarer", - "meta.source": "Kilde", - "search.config.lang": "da", - "search.placeholder": "Søg", - "search.result.placeholder": "Indtast søgeord", - "search.result.none": "Ingen resultater fundet", - "search.result.one": "1 resultat", - "search.result.other": "# resultater", - "skip.link.title": "Gå til indholdet", - "source.link.title": "Åbn arkiv", - "source.revision.date": "Sidste ændring", - "source.file.date.updated": "Sidste ændring", - "source.file.date.created": "Oprettet", - "toc.title": "Indholdsfortegnelse" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/de.html b/docs/src/partials/languages/de.html deleted file mode 100644 index e7891678..00000000 --- a/docs/src/partials/languages/de.html +++ /dev/null @@ -1,55 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: German --> -{% macro t(key) %}{{ { - "language": "de", - "clipboard.copy": "In Zwischenablage kopieren", - "clipboard.copied": "In Zwischenablage kopiert", - "edit.link.title": "Seite editieren", - "footer.previous": "Zurück", - "footer.next": "Weiter", - "meta.comments": "Kommentare", - "meta.source": "Quellcode", - "search.config.lang": "de", - "search.placeholder": "Suche", - "search.share": "Teilen", - "search.reset": "Zurücksetzen", - "search.result.initializer": "Suche wird initialisiert", - "search.result.placeholder": "Suchbegriff eingeben", - "search.result.none": "Keine Suchergebnisse", - "search.result.one": "1 Suchergebnis", - "search.result.other": "# Suchergebnisse", - "search.result.more.one": "1 weiteres Suchergebnis auf dieser Seite", - "search.result.more.other": "# weitere Suchergebnisse auf dieser Seite", - "search.result.term.missing": "Es fehlt", - "search.title": "Suche", - "select.language.title": "Sprache wechseln", - "select.version.title": "Version auswählen", - "skip.link.title": "Zum Inhalt", - "source.link.title": "Quellcode", - "source.revision.date": "Letztes Update", - "source.file.date.updated": "Letztes Update", - "source.file.date.created": "Erstellt", - "toc.title": "Inhaltsverzeichnis", - "top.title": "Zurück zum Seitenanfang" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/en.html b/docs/src/partials/languages/en.html deleted file mode 100644 index 2fc412b2..00000000 --- a/docs/src/partials/languages/en.html +++ /dev/null @@ -1,62 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: English --> -{% macro t(key) %}{{ { - "language": "en", - "direction": "ltr", - "clipboard.copy": "Copy to clipboard", - "clipboard.copied": "Copied to clipboard", - "edit.link.title": "Edit this page", - "footer.previous": "Previous", - "footer.next": "Next", - "footer.title": "Footer", - "header.title": "Header", - "meta.comments": "Comments", - "meta.source": "Source", - "nav.title": "Navigation", - "search.config.lang": "en", - "search.config.pipeline": "trimmer, stopWordFilter", - "search.config.separator": "[\s\-]+", - "search.placeholder": "Search", - "search.share": "Share", - "search.reset": "Clear", - "search.result.initializer": "Initializing search", - "search.result.placeholder": "Type to start searching", - "search.result.none": "No matching documents", - "search.result.one": "1 matching document", - "search.result.other": "# matching documents", - "search.result.more.one": "1 more on this page", - "search.result.more.other": "# more on this page", - "search.result.term.missing": "Missing", - "search.title": "Search", - "select.language.title": "Select language", - "select.version.title": "Select version", - "skip.link.title": "Skip to content", - "source.link.title": "Go to repository", - "source.revision.date": "Last update", - "source.file.date.updated": "Last update", - "source.file.date.created": "Created", - "tabs.title": "Tabs", - "toc.title": "Table of contents", - "top.title": "Back to top" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/eo.html b/docs/src/partials/languages/eo.html deleted file mode 100644 index 07af949a..00000000 --- a/docs/src/partials/languages/eo.html +++ /dev/null @@ -1,50 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Esperanto --> -{% macro t(key) %}{{ { - "language": "eo", - "clipboard.copy": "Kopii al tondujo", - "clipboard.copied": "Kopiado al klipo", - "edit.link.title": "Redakti ĉi tiun paĝon", - "footer.previous": "Antaŭa", - "footer.next": "Sekva", - "footer.title": "Piedlinio", - "header.title": "Kaplinio", - "meta.comments": "Komentoj", - "meta.source": "Fontkodo", - "nav.title": "Navigado", - "search.config.lang": "es", - "search.placeholder": "Serĉo", - "search.reset": "Klara", - "search.result.placeholder": "Tajpu por komenci serĉadon", - "search.result.none": "Neniuj kongruaj dokumentoj", - "search.result.one": "1 kongrua dokumento", - "search.result.other": "# kongruaj dokumentoj", - "skip.link.title": "Saltu al enhavo", - "source.link.title": "Iru al deponejo", - "source.revision.date": "Lasta ĝisdatigo", - "source.file.date.updated": "Lasta ĝisdatigo", - "source.file.date.created": "Kreita", - "tabs.title": "Langetoj", - "toc.title": "Enhavtabelo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/es.html b/docs/src/partials/languages/es.html deleted file mode 100644 index caede33d..00000000 --- a/docs/src/partials/languages/es.html +++ /dev/null @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Spanish --> -{% macro t(key) %}{{ { - "language": "es", - "clipboard.copy": "Copiar al portapapeles", - "clipboard.copied": "Copiado al portapapeles", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Siguiente", - "footer.title": "Pie", - "header.title": "Cabecera", - "meta.comments": "Comentarios", - "meta.source": "Fuente", - "nav.title": "Navegación", - "search.config.lang": "es", - "search.placeholder": "Búsqueda", - "search.reset": "Limpiar", - "search.result.initializer": "Inicializando búsqueda", - "search.result.placeholder": "Teclee para comenzar búsqueda", - "search.result.none": "No se encontraron documentos", - "search.result.one": "1 documento encontrado", - "search.result.other": "# documentos encontrados", - "search.result.more.one": "1 más en esta página", - "search.result.more.other": "# más en esta página", - "search.result.term.missing": "Falta", - "select.language.title": "Seleccionar idioma", - "select.version.title": "Seleccionar versión", - "skip.link.title": "Saltar a contenido", - "source.link.title": "Ir al repositorio", - "source.revision.date": "Última actualización", - "source.file.date.updated": "Última actualización", - "source.file.date.created": "Creado", - "tabs.title": "Pestañas", - "toc.title": "Tabla de contenidos", - "top.title": "Volver al principio" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/et.html b/docs/src/partials/languages/et.html deleted file mode 100644 index eac90dcb..00000000 --- a/docs/src/partials/languages/et.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Estonian --> -{% macro t(key) %}{{ { - "language": "et", - "clipboard.copy": "Kopeeri lõikelauale", - "clipboard.copied": "Kopeeritud", - "edit.link.title": "Muuda seda lehte", - "footer.previous": "Eelmine", - "footer.next": "Järgmine", - "meta.comments": "Kommentaarid", - "meta.source": "Lähtekood", - "search.placeholder": "Otsi", - "search.result.placeholder": "Otsimiseks kirjuta siia", - "search.result.none": "Otsingule ei leitud ühtegi vastet", - "search.result.one": "Leiti üks tulemus", - "search.result.other": "Leiti # tulemust", - "skip.link.title": "Keri sisuni", - "source.link.title": "Ava repositooriumis", - "source.revision.date": "Viimane uuendus", - "source.file.date.updated": "Viimane uuendus", - "source.file.date.created": "Loodud", - "toc.title": "Sisukord" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/fa.html b/docs/src/partials/languages/fa.html deleted file mode 100644 index 77fc6fb2..00000000 --- a/docs/src/partials/languages/fa.html +++ /dev/null @@ -1,46 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Persian (Farsi) --> -{% macro t(key) %}{{ { - "language": "fa", - "direction": "rtl", - "clipboard.copy": "کپی کردن", - "clipboard.copied": "کپی شد", - "edit.link.title": "این صفحه را ویرایش کنید", - "footer.previous": "قبلی", - "footer.next": "بعدی", - "meta.comments": "نظرات", - "meta.source": "منبع", - "search.config.pipeline": " ", - "search.placeholder": "جستجو", - "search.result.placeholder": "برای شروع جستجو تایپ کنید", - "search.result.none": "سندی یافت نشد", - "search.result.one": "1 سند یافت شد", - "search.result.other": "# سند یافت شد", - "skip.link.title": "پرش به محتویات", - "source.link.title": "رفتن به مخزن", - "source.revision.date": "اخرین بروزرسانی", - "source.file.date.updated": "اخرین بروزرسانی", - "source.file.date.created": "ایجاد شده", - "toc.title": "فهرست موضوعات" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/fi.html b/docs/src/partials/languages/fi.html deleted file mode 100644 index 9ad2e3c8..00000000 --- a/docs/src/partials/languages/fi.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Finnish --> -{% macro t(key) %}{{ { - "language": "fi", - "clipboard.copy": "Kopioi leikepöydälle", - "clipboard.copied": "Kopioitu leikepöydälle", - "edit.link.title": "Muokkaa tätä sivua", - "footer.previous": "Edellinen", - "footer.next": "Seuraava", - "meta.comments": "Kommentit", - "meta.source": "Lähdekodi", - "search.config.lang": "fi", - "search.placeholder": "Hae", - "search.result.placeholder": "Kirjoita aloittaaksesi haun", - "search.result.none": "Ei täsmääviä dokumentteja", - "search.result.one": "1 täsmäävä dokumentti", - "search.result.other": "# täsmäävää dokumenttia", - "skip.link.title": "Hyppää sisältöön", - "source.link.title": "Mene repositoryyn", - "source.revision.date": "Viimeisin päivitys", - "source.file.date.updated": "Viimeisin päivitys", - "source.file.date.created": "Luotu", - "toc.title": "Sisällysluettelo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/fr.html b/docs/src/partials/languages/fr.html deleted file mode 100644 index a9b7f3ef..00000000 --- a/docs/src/partials/languages/fr.html +++ /dev/null @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: French --> -{% macro t(key) %}{{ { - "language": "fr", - "clipboard.copy": "Copier dans le presse-papier", - "clipboard.copied": "Copié dans le presse-papier", - "edit.link.title": "Editer cette page", - "footer.previous": "Précédent", - "footer.next": "Suivant", - "footer.title": "Pied de page", - "header.title": "En-tête", - "meta.comments": "Commentaires", - "meta.source": "Source", - "nav.title": "Navigation", - "search.config.lang": "fr", - "search.placeholder": "Rechercher", - "search.reset": "Effacer", - "search.result.initializer": "Initialisation de la recherche", - "search.result.placeholder": "Taper pour démarrer la recherche", - "search.result.none": "Aucun document trouvé", - "search.result.one": "1 document trouvé", - "search.result.other": "# documents trouvés", - "search.result.more.one": "1 de plus sur cette page", - "search.result.more.other": "# de plus sur cette page", - "search.result.term.missing": "Non trouvé", - "select.language.title": "Sélectionner la langue", - "select.version.title": "Sélectionner la version", - "skip.link.title": "Aller au contenu", - "source.link.title": "Aller au dépôt", - "source.revision.date": "Dernière mise à jour", - "source.file.date.updated": "Dernière mise à jour", - "source.file.date.created": "Créé", - "tabs.title": "Onglets", - "toc.title": "Table des matières", - "top.title": "Retour en haut de la page" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/gl.html b/docs/src/partials/languages/gl.html deleted file mode 100644 index 7d4d9ab6..00000000 --- a/docs/src/partials/languages/gl.html +++ /dev/null @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Galician --> -{% macro t(key) %}{{ { - "language": "gl", - "clipboard.copy": "Copiar no cortapapeis", - "clipboard.copied": "Copiado no cortapapeis", - "edit.link.title": "Editar esta páxina", - "footer.previous": "Anterior", - "footer.next": "Seguinte", - "footer.title": "Pé", - "header.title": "Cabeceira", - "meta.comments": "Comentarios", - "meta.source": "Fonte", - "nav.title": "Navegación", - "search.config.lang": "es", - "search.placeholder": "Procura", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando procura", - "search.result.placeholder": "Insira un termo", - "search.result.none": "Sen resultados", - "search.result.one": "1 resultado atopado", - "search.result.other": "# resultados atopados", - "search.result.more.one": "1 máis nesta páxina", - "search.result.more.other": "# máis nesta páxina", - "search.result.term.missing": "Falta", - "select.language.title": "Seleccionar idioma", - "select.version.title": "Seleccionar version", - "skip.link.title": "Ir ao contido", - "source.link.title": "Ir ao repositorio", - "source.revision.date": "Última actualización", - "source.file.date.updated": "Última actualización", - "source.file.date.created": "Creada", - "tabs.title": "Pestanas", - "toc.title": "Táboa de contidos", - "top.title": "Volver ao principio" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/gr.html b/docs/src/partials/languages/gr.html deleted file mode 100644 index 0edc3e4d..00000000 --- a/docs/src/partials/languages/gr.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Greek --> -{% macro t(key) %}{{ { - "language": "gr", - "clipboard.copy": "Αντιγραφή", - "clipboard.copied": "Αντιγράφηκε", - "edit.link.title": "Επεξεργασία αυτής της σελίδας", - "footer.previous": "Επόμενη", - "footer.next": "Προηγούμενη", - "meta.comments": "Σχόλια", - "meta.source": "Πηγή", - "search.config.pipeline": " ", - "search.placeholder": "Αναζήτηση", - "search.result.placeholder": "Πληκτρολογήστε για να αρχίσει η αναζήτηση", - "search.result.none": "Δε βρέθηκαν αντίστοιχα αρχεία", - "search.result.one": "1 αντίστοιχο αρχείο", - "search.result.other": "# αντίστοιχα αρχεία", - "skip.link.title": "Μετάβαση στο περιεχόμενο", - "source.link.title": "Μετάβαση στο αποθετήριο", - "source.revision.date": "τελευταία ενημέρωση", - "source.file.date.updated": "τελευταία ενημέρωση", - "source.file.date.created": "Δημιουργήθηκε", - "toc.title": "Πίνακας περιεχομένων" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/he.html b/docs/src/partials/languages/he.html deleted file mode 100644 index 79bbf3ea..00000000 --- a/docs/src/partials/languages/he.html +++ /dev/null @@ -1,46 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Hebrew --> -{% macro t(key) %}{{ { - "language": "he", - "direction": "rtl", - "clipboard.copy": "העתק ללוח", - "clipboard.copied": "הועתק ללוח", - "edit.link.title": "ערוך דף זה", - "footer.previous": "קודם", - "footer.next": "הַבָּא", - "meta.comments": "הערות", - "meta.source": "מָקוֹר", - "search.config.pipeline": " ", - "search.placeholder": "לחפש", - "search.result.placeholder": "הקלד כדי להתחיל לחפש", - "search.result.none": "אין מסמכים תואמים", - "search.result.one": "1 מסמך תואם", - "search.result.other": "# מסמך תואם", - "skip.link.title": "דלג לתוכן", - "source.link.title": "עבור אל מאגר", - "source.revision.date": "העדכון אחרון", - "source.file.date.updated": "העדכון אחרון", - "source.file.date.created": "נוצר", - "toc.title": "תוכן העניינים" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/hi.html b/docs/src/partials/languages/hi.html deleted file mode 100644 index fca93740..00000000 --- a/docs/src/partials/languages/hi.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Hindi --> -{% macro t(key) %}{{ { - "language": "hi", - "clipboard.copy": "क्लिपबोर्ड पर कॉपी करें", - "clipboard.copied": "क्लिपबोर्ड पर कॉपी कर दिया गया", - "edit.link.title": "इस पृष्ठ को संपादित करें", - "footer.previous": "पिछला", - "footer.next": "आगामी", - "meta.comments": "टिप्पणियाँ", - "meta.source": "स्रोत", - "search.config.lang": "hi", - "search.placeholder": "खोज", - "search.result.placeholder": "खोज शुरू करने के लिए टाइप करें", - "search.result.none": "कोई मिलान डॉक्यूमेंट नहीं", - "search.result.one": "1 मिलान डॉक्यूमेंट", - "search.result.other": "# मिलान डाक्यूमेंट्स", - "skip.link.title": "विषय पर बढ़ें", - "source.link.title": "रिपॉजिटरी पर जाएं", - "source.revision.date": "आखिरी अपडेट", - "source.file.date.updated": "आखिरी अपडेट", - "source.file.date.created": "बनाया था", - "toc.title": "विषय - सूची" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/hr.html b/docs/src/partials/languages/hr.html deleted file mode 100644 index 6fa4118c..00000000 --- a/docs/src/partials/languages/hr.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Croatian --> -{% macro t(key) %}{{ { - "language": "hr", - "clipboard.copy": "Kopirajte u međuspremnik", - "clipboard.copied": "Kopirano u međuspremnik", - "edit.link.title": "Uredi stranicu", - "footer.previous": "Prethodno", - "footer.next": "Sljedeće", - "meta.comments": "Komentari", - "meta.source": "Izvor", - "search.placeholder": "Pretraživanje", - "search.result.placeholder": "Unesite pojam pretraživanja", - "search.result.none": "Ništa nije pronađeno", - "search.result.one": "1 rezultat pretraživanja", - "search.result.other": "# rezultata pretraživanja", - "skip.link.title": "Preskočite na sadržaj", - "source.link.title": "Idite u repozitorij", - "source.revision.date": "Zadnje ažuriranje", - "source.file.date.updated": "Zadnje ažuriranje", - "source.file.date.created": "Stvoreno", - "toc.title": "Sadržaj" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/hu.html b/docs/src/partials/languages/hu.html deleted file mode 100644 index 2eeb3112..00000000 --- a/docs/src/partials/languages/hu.html +++ /dev/null @@ -1,54 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Hungarian --> -{% macro t(key) %}{{ { - "language": "hu", - "clipboard.copy": "Másolás vágólapra", - "clipboard.copied": "Vágólapra másolva", - "edit.link.title": "Oldal szerkesztése", - "footer.previous": "Előző", - "footer.next": "Következő", - "footer.title": "Élőláb", - "header.title": "Élőfej", - "meta.comments": "Hozzászólások", - "meta.source": "Forrás", - "nav.title": "Navigáció", - "search.config.lang": "hu", - "search.placeholder": "Keresés", - "search.reset": "Törlés", - "search.result.initializer": "Keresés inicializálása", - "search.result.placeholder": "Kereséshez írj ide valamit", - "search.result.none": "Nincs találat", - "search.result.one": "1 egyező dokumentum", - "search.result.other": "# egyező dokumentum", - "search.result.more.one": "1 további találat az oldalon", - "search.result.more.other": "# további találat az oldalon", - "search.result.term.missing": "Üres", - "skip.link.title": "Kihagyás", - "source.link.title": "Főoldalra ugrás", - "source.revision.date": "Utolsó frissítés", - "source.file.date.updated": "Utolsó frissítés", - "source.file.date.created": "Létrehozva", - "tabs.title": "Lapok", - "toc.title": "Tartalomjegyzék" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/id.html b/docs/src/partials/languages/id.html deleted file mode 100644 index 2d68bd5f..00000000 --- a/docs/src/partials/languages/id.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Indonesian --> -{% macro t(key) %}{{ { - "language": "id", - "clipboard.copy": "Salin ke memori", - "clipboard.copied": "Tersalin ke memori", - "edit.link.title": "Ubah halaman ini", - "footer.previous": "Sebelumnya", - "footer.next": "Selanjutnya", - "meta.comments": "Komentar", - "meta.source": "Sumber", - "search.config.pipeline": " ", - "search.placeholder": "Cari", - "search.result.placeholder": "Ketik untuk mulai pencarian", - "search.result.none": "Tidak ada dokumen yang sesuai", - "search.result.one": "1 dokumen ditemukan", - "search.result.other": "# dokumen ditemukan", - "skip.link.title": "Lewati ke isi", - "source.link.title": "Menuju repositori", - "source.revision.date": "Pembaharuan Terakhir", - "source.revision.date": "Pembaharuan Terakhir", - "source.file.date.created": "Dibuat", - "toc.title": "Daftar isi" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/is.html b/docs/src/partials/languages/is.html deleted file mode 100644 index b3943e42..00000000 --- a/docs/src/partials/languages/is.html +++ /dev/null @@ -1,51 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Icelandic --> -{% macro t(key) %}{{ { - "language": "is", - "clipboard.copy": "Afrita í klemmuspjald", - "clipboard.copied": "Afritað í klemmuspjald", - "edit.link.title": "Ritvinna þessa síðu", - "footer.previous": "Fyrra", - "footer.next": "Næsta", - "footer.title": "Síðufótur", - "header.title": "Haus", - "meta.comments": "Athugasemdir", - "meta.source": "Grunnur", - "nav.title": "Valmynd", - "search.placeholder": "Leit", - "search.reset": "Hreinsa", - "search.result.placeholder": "Sláðu inn til að hefja leit", - "search.result.none": "Engin skjöl fundust", - "search.result.one": "1 skjal fannst", - "search.result.other": "# skjöl fundust", - "search.result.more.one": "1 til viðbótar á þessari síðu", - "search.result.more.other": "# til viðbótar á þessari síðu", - "skip.link.title": "Hoppa yfir í efni", - "source.link.title": "Fara í gagnahirslu (e. repository)", - "source.revision.date": "Síðasta uppfærsla", - "source.file.date.updated": "Síðasta uppfærsla", - "source.file.date.created": "Búið til", - "tabs.title": "Flipar", - "toc.title": "Efnisyfirlit" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/it.html b/docs/src/partials/languages/it.html deleted file mode 100644 index 6be33aac..00000000 --- a/docs/src/partials/languages/it.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Italian --> -{% macro t(key) %}{{ { - "language": "it", - "clipboard.copy": "Copia", - "clipboard.copied": "Copiato", - "edit.link.title": "Modifica", - "footer.previous": "Precedente", - "footer.next": "Prossimo", - "meta.comments": "Commenti", - "meta.source": "Sorgente", - "search.config.lang": "it", - "search.placeholder": "Cerca", - "search.result.placeholder": "Scrivi per iniziare a cercare", - "search.result.none": "Nessun documento trovato", - "search.result.one": "1 documento trovato", - "search.result.other": "# documenti trovati", - "skip.link.title": "Vai al contenuto", - "source.link.title": "Apri repository", - "source.revision.date": "Ultimo aggiornamento", - "source.file.date.updated": "Ultimo aggiornamento", - "source.file.date.created": "Creata", - "toc.title": "Indice" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ja.html b/docs/src/partials/languages/ja.html deleted file mode 100644 index 6710293b..00000000 --- a/docs/src/partials/languages/ja.html +++ /dev/null @@ -1,56 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Japanese --> -{% macro t(key) %}{{ { - "language": "ja", - "clipboard.copy": "クリップボードへコピー", - "clipboard.copied": "コピーしました", - "edit.link.title": "編集", - "footer.previous": "前", - "footer.next": "次", - "footer.title": "フッター", - "header.title": "ヘッダー", - "meta.comments": "コメント", - "meta.source": "ソース", - "nav.title": "ナビゲーション", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\s\- 、。,.]+", - "search.placeholder": "検索", - "search.reset": "クリア", - "search.result.initializer": "検索を初期化", - "search.result.placeholder": "検索キーワードを入力してください", - "search.result.none": "何も見つかりませんでした", - "search.result.one": "1件見つかりました", - "search.result.other": "#件見つかりました", - "search.result.more.one": "このページ内にもう1件見つかりました", - "search.result.more.other": "このページ内にあと#件見つかりました", - "search.result.term.missing": "検索に含まれない", - "skip.link.title": "コンテンツにスキップ", - "source.link.title": "リポジトリへ", - "source.revision.date": "最終更新日", - "source.file.date.updated": "最終更新日", - "source.file.date.created": "作成した", - "tabs.title": "タブ", - "toc.title": "目次" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ka.html b/docs/src/partials/languages/ka.html deleted file mode 100644 index c3711a48..00000000 --- a/docs/src/partials/languages/ka.html +++ /dev/null @@ -1,50 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Georgian --> -{% macro t(key) %}{{ { - "language": "ka", - "clipboard.copy": "კოპირება", - "clipboard.copied": "კოპირებულია", - "edit.link.title": "გვერდის რედარქირება", - "footer.previous": "წინა", - "footer.next": "შემდეგი", - "meta.comments": "კომენტარები", - "meta.source": "წყარო", - "nav.title": "ნავიგაცია", - "search.config.pipeline": " ", - "search.placeholder": "ძებნა", - "search.reset": "გასუფთავება", - "search.result.placeholder": "ჩაწერე ძებნის დასაწყებად", - "search.result.none": "დოკუმენტი ვერ მოიძებნა", - "search.result.one": "მოიძებნა 1 დოკუმენტი", - "search.result.other": "მოიძებნა # დოკუმენტი", - "search.result.more.one": "კიდევ 1 ამ გვერდზე", - "search.result.more.other": "კიდევ # ამ გვერდზე", - "skip.link.title": "კონტენტზე გადასვლა", - "source.link.title": "საცავში გადასვლა", - "source.revision.date": "ბოლო განახლება", - "source.file.date.updated": "ბოლო განახლება", - "source.file.date.created": "შეიქმნა", - "tabs.title": "ტაბები", - "toc.title": "სარჩევი" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/kr.html b/docs/src/partials/languages/kr.html deleted file mode 100644 index 17aa91b5..00000000 --- a/docs/src/partials/languages/kr.html +++ /dev/null @@ -1,55 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Korean --> -{% macro t(key) %}{{ { - "language": "kr", - "clipboard.copy": "클립보드로 복사", - "clipboard.copied": "클립보드에 복사됨", - "edit.link.title": "이 페이지를 편집", - "footer.previous": "이전", - "footer.next": "다음", - "meta.comments": "댓글", - "meta.source": "출처", - "search.config.pipeline": " ", - "search.placeholder": "검색", - "search.share": "공유", - "search.reset": "지우기", - "search.result.initializer": "검색 초기화", - "search.result.placeholder": "검색어를 입력하세요", - "search.result.none": "검색어와 일치하는 문서가 없습니다", - "search.result.one": "1개의 일치하는 문서", - "search.result.other": "#개의 일치하는 문서", - "search.result.more.one": "이 문서에서 1개의 검색 결과 더 보기", - "search.result.more.other": "이 문서에서 #개의 검색 결과 더 보기", - "search.result.term.missing": "포함되지 않은 검색어", - "search.title": "검색", - "select.language.title": "언어설정", - "select.version.title": "버전 선택", - "skip.link.title": "콘텐츠로 이동", - "source.link.title": "저장소로 이동", - "source.revision.date": "마지막 업데이트", - "source.file.date.updated": "마지막 업데이트", - "source.file.date.created": "작성일", - "toc.title": "목차", - "top.title": "맨위로" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/mn.html b/docs/src/partials/languages/mn.html deleted file mode 100644 index 498c8e70..00000000 --- a/docs/src/partials/languages/mn.html +++ /dev/null @@ -1,51 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Mongolian --> -{% macro t(key) %}{{ { - "language": "mn", - "clipboard.copy": "Хуулах", - "clipboard.copied": "Санах ойд хуулах", - "edit.link.title": "Хуудас засварлах", - "footer.previous": "Өмнөх", - "footer.next": "Дараах", - "footer.title": "Хөл", - "header.title": "Толгой", - "meta.comments": "Сэтгэгдэл", - "meta.source": "Эх үүсвэр", - "nav.title": "Чиглүүлэгч", - "search.config.lang": "ru", - "search.placeholder": "Хайлт", - "search.reset": "Цэвэрлэх", - "search.result.placeholder": "Хайлтын үгээ бичнэ үү", - "search.result.none": "Таарц илэрсэнгүй", - "search.result.one": "1 таарц илэрлээ", - "search.result.other": "# Тохирох баримт бичиг", - "search.result.more.one": "1 илүү хуудас байна", - "search.result.more.other": "# илүү хуудас байна", - "skip.link.title": "Агуулгыг алгасах", - "source.link.title": "Хадгалах сан руу очих", - "source.file.date.updated": "Сүүлийн шинэчлэлт", - "source.file.date.created": "Үүсгэсэн", - "tabs.title": "Табууд", - "toc.title": "Агуулга" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/my.html b/docs/src/partials/languages/my.html deleted file mode 100644 index aa52360d..00000000 --- a/docs/src/partials/languages/my.html +++ /dev/null @@ -1,50 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Burmese --> -{% macro t(key) %}{{ { - "language": "my", - "clipboard.copy": "ကလစ်ဘုတ် သို့ ကူးယူရန်", - "clipboard.copied": "ကလစ်ဘုတ် သို့ ကူယူပြီး", - "edit.link.title": "ဤ စာမျက်နှာကို ပြင်ရန်", - "footer.previous": "နောက်သို့", - "footer.next": "ရှေ့သို့", - "footer.title": "အောက်ခြေ", - "header.title": "ခေါင်းပိုင်း", - "meta.comments": "မှတ်ချက်များ", - "meta.source": "ရင်းမြစ်", - "nav.title": "လမ်းညွှန်", - "search.config.pipeline": " ", - "search.placeholder": "ရှာရန်", - "search.reset": "ရှင်းလင်း", - "search.result.placeholder": "ရှာဖွေခြင်းစရန် စာရိုက်ပါ", - "search.result.none": "တူညီသော စာရွက်စာတမ်းများ မရှိပါ", - "search.result.one": "စာရွက်စာတမ်း ၁ ခု တူညီသည်", - "search.result.other": "စာရွက်စာတမ်း # ခု တူညီသည်", - "skip.link.title": "မာတိကာ သို့ သွားရန်", - "source.link.title": "repository သို့ သွားရန်", - "source.revision.date": "နောက်ဆုံး ထုတ်ပြန်ချက်", - "source.file.date.updated": "နောက်ဆုံး ထုတ်ပြန်ချက်", - "source.file.date.created": "နေပြည်တော်", - "tabs.title": "တက်များ", - "toc.title": "ပါဝင်အကြောင်းအရာများ" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/nl.html b/docs/src/partials/languages/nl.html deleted file mode 100644 index 2b392043..00000000 --- a/docs/src/partials/languages/nl.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Dutch --> -{% macro t(key) %}{{ { - "language": "nl", - "clipboard.copy": "Kopiëren naar klembord", - "clipboard.copied": "Gekopieerd naar klembord", - "edit.link.title": "Wijzig deze pagina", - "footer.previous": "Vorige", - "footer.next": "Volgende", - "meta.comments": "Reacties", - "meta.source": "Bron", - "search.config.lang": "nl", - "search.placeholder": "Zoeken", - "search.result.placeholder": "Typ om te beginnen met zoeken", - "search.result.none": "Geen overeenkomende documenten", - "search.result.one": "1 overeenkomende document", - "search.result.other": "# overeenkomende documenten", - "skip.link.title": "Ga naar inhoud", - "source.link.title": "Ga naar repository", - "source.revision.date": "Laatst geüpdatet", - "source.file.date.updated": "Laatst geüpdatet", - "source.file.date.created": "Gecreëerd", - "toc.title": "Inhoudsopgave" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/nn.html b/docs/src/partials/languages/nn.html deleted file mode 100644 index b7f83b3c..00000000 --- a/docs/src/partials/languages/nn.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Norwegian Nynorsk --> -{% macro t(key) %}{{ { - "language": "nn", - "clipboard.copy": "Kopier til utklippstavla", - "clipboard.copied": "Kopiert til utklippstavla", - "edit.link.title": "Rediger denne sida", - "footer.previous": "Førre", - "footer.next": "Neste", - "meta.comments": "Kommentarar", - "meta.source": "Kjelde", - "search.config.lang": "no", - "search.placeholder": "Søk", - "search.result.placeholder": "Skriv søkeord", - "search.result.none": "Ingen treff", - "search.result.one": "1 treff", - "search.result.other": "# treff", - "skip.link.title": "Gå til innhald", - "source.link.title": "Gå til kjelde", - "source.revision.date": "Siste oppdatering", - "source.file.date.updated": "Siste oppdatering", - "source.file.date.created": "Laget", - "toc.title": "Innhaldsliste" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/no.html b/docs/src/partials/languages/no.html deleted file mode 100644 index b034679f..00000000 --- a/docs/src/partials/languages/no.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Norwegian Bokmål --> -{% macro t(key) %}{{ { - "language": "no", - "clipboard.copy": "Kopier til utklippstavlen", - "clipboard.copied": "Kopiert til utklippstavlen", - "edit.link.title": "Rediger denne siden", - "footer.previous": "Forrige", - "footer.next": "Neste", - "meta.comments": "Kommentarer", - "meta.source": "Kilde", - "search.config.lang": "no", - "search.placeholder": "Søk", - "search.result.placeholder": "Skriv søkeord", - "search.result.none": "Ingen treff", - "search.result.one": "1 treff", - "search.result.other": "# treff", - "skip.link.title": "Gå til innhold", - "source.link.title": "Gå til kilde", - "source.revision.date": "Siste oppdatering", - "source.file.date.updated": "Siste oppdatering", - "source.file.date.created": "Created", - "toc.title": "Innholdsfortegnelse" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/pl.html b/docs/src/partials/languages/pl.html deleted file mode 100755 index cdb7ba3a..00000000 --- a/docs/src/partials/languages/pl.html +++ /dev/null @@ -1,54 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Polish --> -{% macro t(key) %}{{ { - "language": "pl", - "clipboard.copy": "Kopiuj do schowka", - "clipboard.copied": "Skopiowane", - "edit.link.title": "Edytuj tę stronę", - "footer.previous": "Poprzednia strona", - "footer.next": "Następna strona", - "footer.title": "Stopka", - "header.title": "Nagłówek", - "meta.comments": "Komentarze", - "meta.source": "Kod źródłowy", - "search.config.pipeline": " ", - "nav.title": "Nawigacja", - "search.placeholder": "Szukaj", - "search.reset": "Wyczyść", - "search.result.initializer": "Inicjowanie wyszukiwania", - "search.result.placeholder": "Zacznij pisać, aby szukać", - "search.result.none": "Brak wyników wyszukiwania", - "search.result.one": "Wyniki wyszukiwania: 1", - "search.result.other": "Wyniki wyszukiwania: #", - "search.result.more.one": "1 więcej na tej stronie", - "search.result.more.other": "# więcej na tej stronie", - "search.result.term.missing": "Brak", - "skip.link.title": "Przejdź do treści", - "source.link.title": "Idź do repozytorium", - "source.revision.date": "Ostatnia aktualizacja", - "source.file.date.updated": "Ostatnia aktualizacja", - "source.file.date.created": "Utworzony", - "tabs.title": "Zakładki", - "toc.title": "Spis treści" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/pt.html b/docs/src/partials/languages/pt.html deleted file mode 100644 index 9aca375c..00000000 --- a/docs/src/partials/languages/pt.html +++ /dev/null @@ -1,59 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Portuguese --> -{% macro t(key) %}{{ { - "language": "pt", - "clipboard.copy": "Copiar para área de transferência", - "clipboard.copied": "Copiado para área de transferência", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Próximo", - "footer.title": "Rodapé", - "header.title": "Cabeçalho", - "meta.comments": "Comentários", - "meta.source": "Fonte", - "nav.title": "Navegação", - "search.config.lang": "pt", - "search.placeholder": "Buscar", - "search.share": "Compartilhar", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando a pesquisa", - "search.result.placeholder": "Digite para iniciar a busca", - "search.result.none": "Nenhum resultado encontrado", - "search.result.one": "1 resultado encontrado", - "search.result.other": "# resultados encontrados", - "search.result.more.one": "Mais 1 nesta página", - "search.result.more.other": "Mais # nesta página", - "search.result.term.missing": "Ausente", - "search.title": "Pesquisar", - "select.language.title": "Selecione o idioma", - "select.version.title": "Selecione a versão", - "skip.link.title": "Ir para o conteúdo", - "source.link.title": "Ir ao repositório", - "source.revision.date": "Última atualização", - "source.file.date.updated": "Última atualização", - "source.file.date.created": "Criada", - "tabs.title": "Abas", - "toc.title": "Índice", - "top.title": "Voltar ao topo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ro.html b/docs/src/partials/languages/ro.html deleted file mode 100644 index caac19f2..00000000 --- a/docs/src/partials/languages/ro.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Romanian --> -{% macro t(key) %}{{ { - "language": "ro", - "clipboard.copy": "Copiază în clipboard", - "clipboard.copied": "Copiat în clipboard", - "edit.link.title": "Editeaza această pagină", - "footer.previous": "Anterior", - "footer.next": "Următor", - "meta.comments": "Comentarii", - "meta.source": "Sursă", - "search.config.lang": "ro", - "search.placeholder": "Căutare", - "search.result.placeholder": "Tastează pentru a începe căutarea", - "search.result.none": "Nu a fost găsit niciun document", - "search.result.one": "1 document găsit", - "search.result.other": "# documente găsite", - "skip.link.title": "Sari la conținut", - "source.link.title": "Accesează repository-ul", - "source.revision.date": "Ultima actualizare", - "source.file.date.updated": "Ultima actualizare", - "source.file.date.created": "Creată", - "toc.title": "Cuprins" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ru.html b/docs/src/partials/languages/ru.html deleted file mode 100644 index 69dd7ce2..00000000 --- a/docs/src/partials/languages/ru.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Russian --> -{% macro t(key) %}{{ { - "language": "ru", - "clipboard.copy": "Копировать в буфер", - "clipboard.copied": "Скопировано в буфер", - "edit.link.title": "Редактировать страницу", - "footer.previous": "Назад", - "footer.next": "Вперед", - "meta.comments": "Комментарии", - "meta.source": "Исходный код", - "search.config.lang": "ru", - "search.placeholder": "Поиск", - "search.result.placeholder": "Начните печатать для поиска", - "search.result.none": "Совпадений не найдено", - "search.result.one": "Найдено 1 совпадение", - "search.result.other": "Найдено # совпадений", - "skip.link.title": "Перейти к содержанию", - "source.link.title": "Перейти к репозиторию", - "source.revision.date": "Последнее обновление", - "source.file.date.updated": "Последнее обновление", - "source.file.date.created": "Созданный", - "toc.title": "Содержание" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sh.html b/docs/src/partials/languages/sh.html deleted file mode 100644 index f0f7efa8..00000000 --- a/docs/src/partials/languages/sh.html +++ /dev/null @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Serbo-Croatian --> -{% macro t(key) %}{{ { - "language": "sh", - "clipboard.copy": "Kopiraj u klipbord", - "clipboard.copied": "Iskopirano u klipbord", - "edit.link.title": "Ažuriraj stranicu", - "footer.previous": "Prethodno", - "footer.next": "Sledeće", - "footer.title": "Podnožje", - "header.title": "Zaglavlje", - "meta.comments": "Komentari", - "meta.source": "Izvor", - "nav.title": "Navigacija", - "search.placeholder": "Pretraga", - "search.share": "Deljenje", - "search.reset": "Očisti", - "search.result.initializer": "Inicijalizujem pretragu", - "search.result.placeholder": "Unesite pojam pretrage", - "search.result.none": "Ništa nije pronađeno", - "search.result.one": "1 rezultat pretrage", - "search.result.other": "# rezultata pretrage", - "search.result.more.one": "još 1 na ovoj strani", - "search.result.more.other": "još # na ovoj strani", - "search.result.term.missing": "Nedostaje", - "search.title": "Pretraga", - "select.language.title": "Izaberi jezik", - "select.version.title": "Izaberi verziju", - "skip.link.title": "Idi na tekst", - "source.link.title": "Idi u repozitorijum", - "source.revision.date": "Ažuriran", - "source.file.date.updated": "Ažuriran", - "source.file.date.created": "Kreiran", - "tabs.title": "Tabovi", - "toc.title": "Sadržaj" - "top.title": "Nazad na vrh" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/si.html b/docs/src/partials/languages/si.html deleted file mode 100644 index 2dc89dcd..00000000 --- a/docs/src/partials/languages/si.html +++ /dev/null @@ -1,52 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Sinhalese --> -{% macro t(key) %}{{ { - "language": "si", - "clipboard.copy": "කොපි කරන්න", - "clipboard.copied": "කොපි කළා", - "edit.link.title": "පිටුව සංස්කරණය", - "footer.previous": "පසුගිය", - "footer.next": "මීළඟ", - "footer.title": "පාදම", - "header.title": "ශීර්ෂය", - "meta.comments": "ප්‍රතිචාර", - "meta.source": "මූලාශ්‍රය", - "nav.title": "යාත්‍රණය", - "search.config.pipeline": " ", - "search.placeholder": "සොයන්න", - "search.reset": "මකන්න", - "search.result.placeholder": "සෙවීමට ටයිප් කරන්න", - "search.result.none": "කිසිවක් හමු නොවුණි", - "search.result.one": "1 ගැලපෙන ගොනුවක්", - "search.result.other": "ගැලපෙන ගොනු # ක්", - "search.result.more.one": "තව 1 ප්‍රතිඵලයක්", - "search.result.more.other": "තව ප්‍රතිඵල # ක්", - "skip.link.title": "අන්තර්ගතය වෙත යන්න", - "source.link.title": "රිපොසිටරියට යන්න", - "source.revision.date": "අවසන් යාවත්කාලීන වීම", - "source.file.date.updated": "අවසන් යාවත්කාලීන වීම", - "source.file.date.created": "ٺاھيو ويو", - "tabs.title": "ටැබ්ස්", - "toc.title": "පටුන" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sk.html b/docs/src/partials/languages/sk.html deleted file mode 100644 index 21d4870d..00000000 --- a/docs/src/partials/languages/sk.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Slovak --> -{% macro t(key) %}{{ { - "language": "sk", - "clipboard.copy": "Kopírovať do schránky", - "clipboard.copied": "Skopírované do schránky", - "edit.link.title": "Upraviť túto stránku", - "footer.previous": "Späť", - "footer.next": "Ďalej", - "meta.comments": "Komentáre", - "meta.source": "Zdroj", - "search.placeholder": "Hľadať", - "search.result.placeholder": "Pre vyhľadávanie začni písať", - "search.result.none": "Žiadne vyhovujúce dokumenty", - "search.result.one": "Vyhovujúci dokument: 1", - "search.result.other": "Vyhovujúce dokumenty: #", - "skip.link.title": "Preskočiť na obsah", - "source.link.title": "Zobraziť repozitár", - "source.revision.date": "Posledná aktualizácia", - "source.file.date.updated": "Posledná aktualizácia", - "source.file.date.created": "Vytvorené", - "toc.title": "Obsah" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sl.html b/docs/src/partials/languages/sl.html deleted file mode 100644 index 312bcb85..00000000 --- a/docs/src/partials/languages/sl.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Slovenian --> -{% macro t(key) %}{{ { - "language": "sl", - "clipboard.copy": "Kopiraj v odložišče", - "clipboard.copied": "Kopirano v odložišče", - "edit.link.title": "Uredi stran", - "footer.previous": "Prejšnja stran", - "footer.next": "Naslednja stran", - "meta.comments": "Komentarji", - "meta.source": "Izvorna koda", - "search.placeholder": "Išči", - "search.result.placeholder": "Vpiši iskalni niz", - "search.result.none": "Ni zadetkov", - "search.result.one": "1 zadetek", - "search.result.other": "# zadetkov", - "skip.link.title": "Skoči na vsebino", - "source.link.title": "Pojdi na repozitorij", - "source.revision.date": "Zadnja posodobitev", - "source.file.date.updated": "Zadnja posodobitev", - "source.file.date.created": "Ustvarjeno", - "toc.title": "Kazalo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sr.html b/docs/src/partials/languages/sr.html deleted file mode 100644 index 877b7bff..00000000 --- a/docs/src/partials/languages/sr.html +++ /dev/null @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -% macro t(key) %}{{ { - "language": "sh", - "clipboard.copy": "Копирај у клипборд", - "clipboard.copied": "Ископирано у клипборд", - "edit.link.title": "Ажурирај страницу", - "footer.previous": "Претходно", - "footer.next": "Следеће", - "footer.title": "Подножје", - "header.title": "Заглавље", - "meta.comments": "Коментари", - "meta.source": "Извор", - "nav.title": "Навигација", - "search.placeholder": "Претрага", - "search.share": "Дељење", - "search.reset": "Очисти", - "search.result.initializer": "Иницијализујем претрагу", - "search.result.placeholder": "Унесите појам претраге", - "search.result.none": "Ништа није пронађено", - "search.result.one": "1 резултат претраге", - "search.result.other": "# резултата претраге", - "search.result.more.one": "још 1 на овој страни", - "search.result.more.other": "још # на овој страни", - "search.result.term.missing": "Недостаје", - "search.title": "Претрага", - "select.language.title": "Изабери језик", - "select.version.title": "Изабери верзију", - "skip.link.title": "Иди на текст", - "source.link.title": "Иди у репозиторијум", - "source.revision.date": "Ажуриран", - "source.file.date.updated": "Ажуриран", - "source.file.date.created": "Креиран", - "tabs.title": "Табови", - "toc.title": "Садржај" - "top.title": "Назад на врх" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sv.html b/docs/src/partials/languages/sv.html deleted file mode 100644 index d2f09d87..00000000 --- a/docs/src/partials/languages/sv.html +++ /dev/null @@ -1,54 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Swedish --> -{% macro t(key) %}{{ { - "language": "sv", - "clipboard.copy": "Kopiera till urklipp", - "clipboard.copied": "Kopierat till urklipp", - "edit.link.title": "Redigera sidan", - "footer.previous": "Föregående", - "footer.next": "Nästa", - "footer.title": "Sidfot", - "header.title": "Sidhuvud", - "meta.comments": "Kommentarer", - "meta.source": "Källa", - "nav.title": "Navigation", - "search.config.lang": "sv", - "search.placeholder": "Sök", - "search.reset": "Rensa", - "search.result.initializer": "Initialiserar sök", - "search.result.placeholder": "Skriv sökord", - "search.result.none": "Inga sökresultat", - "search.result.one": "1 sökresultat", - "search.result.other": "# sökresultat", - "search.result.more.one": "1 till på denna sidan", - "search.result.more.other": "# till på denna sidan", - "search.result.term.missing": "Saknas", - "skip.link.title": "Gå till innehållet", - "source.link.title": "Gå till datakatalog", - "source.revision.date": "Senaste uppdateringen", - "source.file.date.updated": "Senaste uppdateringen", - "source.file.date.created": "Skapad", - "tabs.title": "Flikar", - "toc.title": "Innehållsförteckning" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/th.html b/docs/src/partials/languages/th.html deleted file mode 100644 index 6c7831cb..00000000 --- a/docs/src/partials/languages/th.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Thai --> -{% macro t(key) %}{{ { - "language": "th", - "clipboard.copy": "คัดลอก", - "clipboard.copied": "คัดลอกแล้ว", - "edit.link.title": "แก้ไขหน้านี้", - "footer.previous": "ก่อนหน้า", - "footer.next": "ต่อไป", - "meta.comments": "ความคิดเห็น", - "meta.source": "แหล่งที่มา", - "search.config.lang": "th", - "search.placeholder": "ค้นหา", - "search.result.placeholder": "พิมพ์เพื่อเริ่มค้นหา", - "search.result.none": "ไม่พบเอกสารที่ตรงกัน", - "search.result.one": "พบเอกสารที่ตรงกัน", - "search.result.other": "พบ # เอกสารที่ตรงกัน", - "skip.link.title": "ข้ามไปที่เนื้อหา", - "source.link.title": "ไปที่ Repository", - "source.revision.date": "สร้าง", - "source.file.date.updated": "สร้าง", - "source.file.date.created": "สร้าง", - "toc.title": "สารบัญ" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/tr.html b/docs/src/partials/languages/tr.html deleted file mode 100644 index 28645b88..00000000 --- a/docs/src/partials/languages/tr.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Turkish --> -{% macro t(key) %}{{ { - "language": "tr", - "clipboard.copy": "Kopyala", - "clipboard.copied": "Kopyalandı", - "edit.link.title": "Düzenle", - "footer.previous": "Önceki", - "footer.next": "Sonraki", - "meta.comments": "Yorumlar", - "meta.source": "Kaynak", - "search.config.lang": "tr", - "search.placeholder": "Ara", - "search.result.placeholder": "Aramaya başlamak için yazın", - "search.result.none": "Eşleşen doküman bulunamadı", - "search.result.one": "1 doküman bulundu", - "search.result.other": "# doküman bulundu", - "skip.link.title": "Ana içeriğe geç", - "source.link.title": "Depoya git", - "source.revision.date": "Son Güncelleme", - "source.file.date.updated": "Son Güncelleme", - "source.file.date.created": "Oluşturuldu", - "toc.title": "İçindekiler" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/uk.html b/docs/src/partials/languages/uk.html deleted file mode 100644 index 266b0c93..00000000 --- a/docs/src/partials/languages/uk.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Ukrainian --> -{% macro t(key) %}{{ { - "language": "uk", - "clipboard.copy": "Скопіювати в буфер", - "clipboard.copied": "Скопійовано в буфер", - "edit.link.title": "Редагувати сторінку", - "footer.previous": "Назад", - "footer.next": "Вперед", - "meta.comments": "Коментарі", - "meta.source": "Вихідний код", - "search.config.lang": "ru", - "search.placeholder": "Пошук", - "search.result.placeholder": "Розпочніть писати для пошуку", - "search.result.none": "Збігів не знайдено", - "search.result.one": "Знайдено 1 збіг", - "search.result.other": "Знайдено # збігів", - "skip.link.title": "Перейти до змісту", - "source.link.title": "Перейти до репозиторію", - "source.revision.date": "Останнє оновлення", - "source.file.date.updated": "Останнє оновлення", - "source.file.date.created": "Створено", - "toc.title": "Зміст" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/vi.html b/docs/src/partials/languages/vi.html deleted file mode 100644 index 006eb6c5..00000000 --- a/docs/src/partials/languages/vi.html +++ /dev/null @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Vietnamese --> -{% macro t(key) %}{{ { - "language": "vi", - "clipboard.copy": "Sao chép vào bộ nhớ", - "clipboard.copied": "Sao chép xong", - "edit.link.title": "Chỉnh sửa", - "footer.previous": "Trước", - "footer.next": "Sau", - "meta.comments": "Bình luận", - "meta.source": "Mã nguồn", - "search.config.lang": "vi", - "search.placeholder": "Tìm kiếm", - "search.result.placeholder": "Nhập để bắt đầu tìm kiếm", - "search.result.none": "Không tìm thấy tài liệu liên quan", - "search.result.one": "1 tài liệu liên quan", - "search.result.other": "# tài liệu liên quan", - "skip.link.title": "Vào thẳng nội dung", - "source.link.title": "Đến kho lưu trữ mã nguồn", - "source.revision.date": "Cập nhật cuối cùng", - "source.file.date.updated": "Cập nhật cuối cùng", - "source.file.date.created": "Tạo", - "toc.title": "Mục lục" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/zh-Hant.html b/docs/src/partials/languages/zh-Hant.html deleted file mode 100644 index 0efe77d4..00000000 --- a/docs/src/partials/languages/zh-Hant.html +++ /dev/null @@ -1,48 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Chinese (Traditional) --> -{% macro t(key) %}{{ { - "language": "zh-Hant", - "clipboard.copy": "拷貝", - "clipboard.copied": "已拷貝", - "edit.link.title": "編輯此頁", - "footer.previous": "上一頁", - "footer.next": "下一頁", - "meta.comments": "評論", - "meta.source": "來源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\,\。]+", - "search.placeholder": "搜尋", - "search.result.initializer": "正在初始化搜尋引擎", - "search.result.placeholder": "鍵入以開始檢索", - "search.result.none": "沒有找到符合條件的結果", - "search.result.one": "找到 1 个符合條件的結果", - "search.result.other": "# 個符合條件的結果", - "skip.link.title": "跳轉至", - "source.link.title": "前往倉庫", - "source.revision.date": "最後更新", - "source.file.date.updated": "最後更新", - "source.file.date.created": "建立日期", - "toc.title": "目錄" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/zh-TW.html b/docs/src/partials/languages/zh-TW.html deleted file mode 100644 index 18503d74..00000000 --- a/docs/src/partials/languages/zh-TW.html +++ /dev/null @@ -1,48 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Chinese (Taiwanese) --> -{% macro t(key) %}{{ { - "language": "zh-Hant", - "clipboard.copy": "複製", - "clipboard.copied": "已複製", - "edit.link.title": "編輯此頁", - "footer.previous": "上一頁", - "footer.next": "下一頁", - "meta.comments": "留言", - "meta.source": "來源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\s\- 、。,.?;]+", - "search.placeholder": "搜尋", - "search.result.initializer": "正在初始化搜尋引擎", - "search.result.placeholder": "打字進行搜尋", - "search.result.none": "沒有符合的項目", - "search.result.one": "找到 1 個符合的項目", - "search.result.other": "找到 # 個符合的項目", - "skip.link.title": "跳轉到", - "source.link.title": "前往倉庫", - "source.revision.date": "最後更新", - "source.file.date.updated": "最後更新", - "source.file.date.created": "建立日期", - "toc.title": "目錄" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/zh.html b/docs/src/partials/languages/zh.html deleted file mode 100644 index eeebacf6..00000000 --- a/docs/src/partials/languages/zh.html +++ /dev/null @@ -1,48 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Translations: Chinese (Simplified) --> -{% macro t(key) %}{{ { - "language": "zh", - "clipboard.copy": "复制", - "clipboard.copied": "已复制", - "edit.link.title": "编辑此页", - "footer.previous": "上一页", - "footer.next": "下一页", - "meta.comments": "评论", - "meta.source": "来源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\,\。]+", - "search.placeholder": "搜索", - "search.result.initializer": "正在初始化搜索引擎", - "search.result.placeholder": "键入以开始搜索", - "search.result.none": "没有找到符合条件的结果", - "search.result.one": "找到 1 个符合条件的结果", - "search.result.other": "# 个符合条件的结果", - "skip.link.title": "跳转至", - "source.link.title": "前往仓库", - "source.revision.date": "最后更新", - "source.file.date.updated": "最后更新", - "source.file.date.created": "创建日期", - "toc.title": "目录" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/logo.html b/docs/src/partials/logo.html deleted file mode 100644 index 9cb0d0a3..00000000 --- a/docs/src/partials/logo.html +++ /dev/null @@ -1,29 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Logo --> -{% if config.theme.logo %} - <img src="{{ config.theme.logo | url }}" alt="logo" /> -{% else %} - {% set icon = config.theme.icon.logo or "material/library" %} - {% include ".icons/" ~ icon ~ ".svg" %} -{% endif %} diff --git a/docs/src/partials/nav-item.html b/docs/src/partials/nav-item.html deleted file mode 100644 index a96d7855..00000000 --- a/docs/src/partials/nav-item.html +++ /dev/null @@ -1,169 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Wrap everything with a macro to reduce file roundtrips (see #2213) --> -{% macro render(nav_item, path, level) %} - - <!-- Determine class according to state --> - {% set class = "md-nav__item" %} - {% if nav_item.active %} - {% set class = class ~ " md-nav__item--active" %} - {% endif %} - - <!-- Main navigation item with nested items --> - {% if nav_item.children %} - - <!-- Determine whether to render item as a section --> - {% if "navigation.sections" in features and level == 1 + ( - "navigation.tabs" in features - ) %} - {% set class = class ~ " md-nav__item--section" %} - {% endif %} - - <!-- Render item with nested items --> - <li class="{{ class }} md-nav__item--nested"> - - <!-- Active checkbox expands items contained within nested section --> - {% set checked = "checked" if nav_item.active %} - {% if "navigation.expand" in features and not checked %} - <input - class="md-nav__toggle md-toggle" - data-md-toggle="{{ path }}" - data-md-state="indeterminate" - type="checkbox" - id="{{ path }}" - checked - /> - {% else %} - <input - class="md-nav__toggle md-toggle" - data-md-toggle="{{ path }}" - type="checkbox" - id="{{ path }}" - {{ checked }} - /> - {% endif %} - - <!-- Determine all nested items that are index pages --> - {% set indexes = [] %} - {% if "navigation.indexes" in features %} - {% for item in nav_item.children %} - {% if item.is_index and not index is defined %} - {% set _ = indexes.append(item) %} - {% endif %} - {% endfor %} - {% endif %} - - <!-- Render toggle to expand nested items --> - {% if not indexes %} - <label class="md-nav__link" for="{{ path }}"> - {{ nav_item.title }} - <span class="md-nav__icon md-icon"></span> - </label> - - <!-- Render link to index page + toggle --> - {% else %} - {% set index = indexes | first %} - {% set class = "md-nav__link--active" if index == page %} - <div class="md-nav__link md-nav__link--container {{ class }}"> - <a href="{{ index.url | url }}">{{ nav_item.title }}</a> - <label for="{{ path }}"> - <span class="md-nav__icon md-icon"></span> - </label> - </div> - {% endif %} - - <!-- Render nested navigation --> - <nav - class="md-nav" - aria-label="{{ nav_item.title }}" - data-md-level="{{ level }}" - > - <label class="md-nav__title" for="{{ path }}"> - <span class="md-nav__icon md-icon"></span> - {{ nav_item.title }} - </label> - <ul class="md-nav__list" data-md-scrollfix> - - <!-- Render nested item list --> - {% for nav_item in nav_item.children %} - {% if "navigation.indexes" in features and nav_item.is_index %} - <!-- Render nothing --> - {% else %} - {{ render(nav_item, path ~ "_" ~ loop.index, level + 1) }} - {% endif %} - {% endfor %} - </ul> - </nav> - </li> - - <!-- Currently active page --> - {% elif nav_item == page %} - <li class="{{ class }}"> - {% set toc = page.toc %} - - <!-- Active checkbox expands items contained within nested section --> - <input - class="md-nav__toggle md-toggle" - data-md-toggle="toc" - type="checkbox" - id="__toc" - /> - - <!-- Hack: see partials/toc.html for more information --> - {% set first = toc | first %} - {% if first and first.level == 1 %} - {% set toc = first.children %} - {% endif %} - - <!-- Render table of contents, if not empty --> - {% if toc %} - <label class="md-nav__link md-nav__link--active" for="__toc"> - {{ nav_item.title }} - <span class="md-nav__icon md-icon"></span> - </label> - {% endif %} - <a - href="{{ nav_item.url | url }}" - class="md-nav__link md-nav__link--active" - > - {{ nav_item.title }} - </a> - - <!-- Show table of contents --> - {% if toc %} - {% include "partials/toc.html" %} - {% endif %} - </li> - - <!-- Main navigation item --> - {% else %} - <li class="{{ class }}"> - <a href="{{ nav_item.url | url }}" class="md-nav__link"> - {{ nav_item.title }} - </a> - </li> - {% endif %} -{% endmacro %} - -<!-- Render current and nested navigation items --> -{{ render(nav_item, path, level) }} diff --git a/docs/src/partials/nav.html b/docs/src/partials/nav.html deleted file mode 100644 index d64112ff..00000000 --- a/docs/src/partials/nav.html +++ /dev/null @@ -1,68 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Determine class according to configuration --> -{% set class = "md-nav md-nav--primary" %} -{% if "navigation.tabs" in features %} - {% set class = class ~ " md-nav--lifted" %} -{% endif %} -{% if "toc.integrate" in features %} - {% set class = class ~ " md-nav--integrated" %} -{% endif %} - -<!-- Main navigation --> -<nav - class="{{ class }}" - aria-label="{{ lang.t('nav.title') }}" - data-md-level="0" -> - - <!-- Site title --> - <label class="md-nav__title" for="__drawer"> - <a - href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}" - title="{{ config.site_name | e }}" - class="md-nav__button md-logo" - aria-label="{{ config.site_name }}" - data-md-component="logo" - > - {% include "partials/logo.html" %} - </a> - {{ config.site_name }} - </label> - - <!-- Repository information --> - {% if config.repo_url %} - <div class="md-nav__source"> - {% include "partials/source.html" %} - </div> - {% endif %} - - <!-- Render item list --> - <ul class="md-nav__list" data-md-scrollfix> - {% for nav_item in nav %} - {% set path = "__nav_" ~ loop.index %} - {% set level = 1 %} - {% include "partials/nav-item.html" %} - {% endfor %} - </ul> -</nav> diff --git a/docs/src/partials/palette.html b/docs/src/partials/palette.html deleted file mode 100644 index 5ee428b0..00000000 --- a/docs/src/partials/palette.html +++ /dev/null @@ -1,66 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Primary colors --> -{% macro primary(key) %}{{ { - "red": "#ef5552", - "pink": "#e92063", - "purple": "#ab47bd", - "deep-purple": "#7e56c2", - "indigo": "#4051b5", - "blue": "#2094f3", - "light-blue": "#02a6f2", - "cyan": "#00bdd6", - "teal": "#009485", - "green": "#4cae4f", - "light-green": "#8bc34b", - "lime": "#cbdc38", - "yellow": "#ffec3d", - "amber": "#ffc105", - "orange": "#ffa724", - "deep-orange": "#ff6e42", - "brown": "#795649", - "grey": "#757575", - "blue-grey": "#546d78", - "black": "#000000", - "white": "#ffffff" -}[key] }}{% endmacro %} - -<!-- Accent colors --> -{% macro accent(key) %}{{ { - "red": "#ff1a47", - "pink": "#f50056", - "purple": "#df41fb", - "deep-purple": "#7c4dff", - "indigo": "#526cfe", - "blue": "#4287ff", - "light-blue": "#0091eb", - "cyan": "#00bad6", - "teal": "#00bda4", - "green": "#00c753", - "light-green": "#63de17", - "lime": "#b0eb00", - "yellow": "#ffd500", - "amber": "#ffaa00", - "orange": "#ff9100", - "deep-orange": "#ff6e42" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/search.html b/docs/src/partials/search.html deleted file mode 100644 index 40c1a075..00000000 --- a/docs/src/partials/search.html +++ /dev/null @@ -1,105 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% import "partials/language.html" as lang with context %} - -<!-- Search interface --> -<div class="md-search" data-md-component="search" role="dialog"> - <label class="md-search__overlay" for="__search"></label> - <div class="md-search__inner" role="search"> - <form class="md-search__form" name="search"> - - <!-- Search input --> - <input - type="text" - class="md-search__input" - name="query" - aria-label="{{ lang.t('search.placeholder') }}" - placeholder="{{ lang.t('search.placeholder') }}" - autocapitalize="off" - autocorrect="off" - autocomplete="off" - spellcheck="false" - data-md-component="search-query" - required - /> - - <!-- Button to open search --> - <label class="md-search__icon md-icon" for="__search"> - {% include ".icons/material/magnify.svg" %} - {% include ".icons/material/arrow-left.svg" %} - </label> - - <!-- Search options --> - <nav - class="md-search__options" - aria-label="{{ lang.t('search.title') }}" - > - - <!-- Button to share search --> - {% if "search.share" in features %} - <a - href="javascript:void(0)" - class="md-search__icon md-icon" - aria-label="{{ lang.t('search.share') }}" - data-clipboard - data-clipboard-text="" - data-md-component="search-share" - tabindex="-1" - > - {% include ".icons/material/share-variant.svg" %} - </a> - {% endif %} - - <!-- Button to reset search --> - <button - type="reset" - class="md-search__icon md-icon" - aria-label="{{ lang.t('search.reset') }}" - tabindex="-1" - > - {% include ".icons/material/close.svg" %} - </button> - </nav> - - <!-- Search suggestions --> - {% if "search.suggest" in features %} - <div - class="md-search__suggest" - data-md-component="search-suggest" - ></div> - {% endif %} - </form> - <div class="md-search__output"> - <div class="md-search__scrollwrap" data-md-scrollfix> - - <!-- Search results --> - <div class="md-search-result" data-md-component="search-result"> - <div class="md-search-result__meta"> - {{ lang.t("search.result.initializer") }} - </div> - <ol class="md-search-result__list"></ol> - </div> - </div> - </div> - </div> -</div> diff --git a/docs/src/partials/social.html b/docs/src/partials/social.html deleted file mode 100644 index 1dddddcf..00000000 --- a/docs/src/partials/social.html +++ /dev/null @@ -1,42 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Social links in footer --> -{% if config.extra.social %} - <div class="md-footer-social"> - {% for social in config.extra.social %} - {% set title = social.name %} - {% if not title and "//" in social.link %} - {% set _,url = social.link.split("//") %} - {% set title = url.split("/")[0] %} - {% endif %} - <a - href="{{ social.link }}" - target="_blank" rel="noopener" - title="{{ title | e }}" - class="md-footer-social__link" - > - {% include ".icons/" ~ social.icon ~ ".svg" %} - </a> - {% endfor %} - </div> -{% endif %} diff --git a/docs/src/partials/source-date.html b/docs/src/partials/source-date.html deleted file mode 100644 index 5b1a197a..00000000 --- a/docs/src/partials/source-date.html +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Kept for backward compatibility. This file will be removed in v8 --> -{% include "partials/source-file.html" %} diff --git a/docs/src/partials/source-file.html b/docs/src/partials/source-file.html deleted file mode 100644 index d1ce0b66..00000000 --- a/docs/src/partials/source-file.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% import "partials/language.html" as lang with context %} - -<!-- Last updated date --> -{% set label = lang.t("source.file.date.updated") %} -<hr /> -<div class="md-source-date"> - <small> - - <!-- mkdocs-git-revision-date-localized-plugin --> - {% if page.meta.git_revision_date_localized %} - {{ label }}: {{ page.meta.git_revision_date_localized }} - - {% if page.meta.git_creation_date_localized %} - <br />{{ lang.t("source.file.date.created") }}: {{ page.meta.git_creation_date_localized }} - {% endif %} - - <!-- mkdocs-git-revision-date-plugin --> - {% elif page.meta.revision_date %} - {{ label }}: {{ page.meta.revision_date }} - {% endif %} - </small> -</div> diff --git a/docs/src/partials/source.html b/docs/src/partials/source.html deleted file mode 100644 index a69244a0..00000000 --- a/docs/src/partials/source.html +++ /dev/null @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% import "partials/language.html" as lang with context %} - -<!-- Repository information --> -<a - href="{{ config.repo_url }}" - title="{{ lang.t('source.link.title') }}" - class="md-source" - data-md-component="source" -> - <div class="md-source__icon md-icon"> - {% set icon = config.theme.icon.repo or "fontawesome/brands/git-alt" %} - {% include ".icons/" ~ icon ~ ".svg" %} - </div> - <div class="md-source__repository"> - {{ config.repo_name }} - </div> -</a> diff --git a/docs/src/partials/tabs-item.html b/docs/src/partials/tabs-item.html deleted file mode 100644 index 248af88b..00000000 --- a/docs/src/partials/tabs-item.html +++ /dev/null @@ -1,56 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Determine class according to state --> -{% if not class %} - {% set class = "md-tabs__link" %} - {% if nav_item.active %} - {% set class = class ~ " md-tabs__link--active" %} - {% endif %} -{% endif %} - -<!-- Main navigation item with nested items --> -{% if nav_item.children %} - {% set title = title | d(nav_item.title) %} - {% set nav_item = nav_item.children | first %} - - <!-- Recurse, if the first item has further nested items --> - {% if nav_item.children %} - {% include "partials/tabs-item.html" %} - - <!-- Render item --> - {% else %} - <li class="md-tabs__item"> - <a href="{{ nav_item.url | url }}" class="{{ class }}"> - {{ title }} - </a> - </li> - {% endif %} - -<!-- Main navigation item --> -{% else %} - <li class="md-tabs__item"> - <a href="{{ nav_item.url | url }}" class="{{ class }}"> - {{ nav_item.title }} - </a> - </li> -{% endif %} diff --git a/docs/src/partials/tabs.html b/docs/src/partials/tabs.html deleted file mode 100644 index 325a1459..00000000 --- a/docs/src/partials/tabs.html +++ /dev/null @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Hack: unset variable, as we're using it recursively in tabs-item.html --> -{% set class = "" %} - -<!-- Navigation tabs --> -<nav - class="md-tabs" - aria-label="{{ lang.t('tabs.title') }}" - data-md-component="tabs" -> - <div class="md-tabs__inner md-grid"> - <ul class="md-tabs__list"> - {% for nav_item in nav %} - {% include "partials/tabs-item.html" %} - {% endfor %} - </ul> - </div> -</nav> diff --git a/docs/src/partials/toc-item.html b/docs/src/partials/toc-item.html deleted file mode 100644 index f90ca7c8..00000000 --- a/docs/src/partials/toc-item.html +++ /dev/null @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -<!-- Table of contents item --> -<li class="md-nav__item"> - <a href="{{ toc_item.url }}" class="md-nav__link"> - {{ toc_item.title }} - </a> - - <!-- Render nested item list --> - {% if toc_item.children %} - <nav class="md-nav" aria-label="{{ toc_item.title }}"> - <ul class="md-nav__list"> - {% for toc_item in toc_item.children %} - {% include "partials/toc-item.html" %} - {% endfor %} - </ul> - </nav> - {% endif %} -</li> diff --git a/docs/src/partials/toc.html b/docs/src/partials/toc.html deleted file mode 100644 index c4c6d735..00000000 --- a/docs/src/partials/toc.html +++ /dev/null @@ -1,52 +0,0 @@ -<!-- - Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. ---> - -{% import "partials/language.html" as lang with context %} - -<!-- Table of contents --> -<nav class="md-nav md-nav--secondary" aria-label="{{ lang.t('toc.title') }}"> - {% set toc = page.toc %} - - <!-- - Hack: check whether the content contains a h1 headline. If it does, the - top-level anchor must be skipped, since it would be redundant to the link - to the current page that is located just above the anchor. Therefore we - directly continue with the children of the anchor. - --> - {% set first = toc | first %} - {% if first and first.level == 1 %} - {% set toc = first.children %} - {% endif %} - - <!-- Render item list --> - {% if toc %} - <label class="md-nav__title" for="__toc"> - <span class="md-nav__icon md-icon"></span> - {{ lang.t("toc.title") }} - </label> - <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> - {% for toc_item in toc %} - {% include "partials/toc-item.html" %} - {% endfor %} - </ul> - {% endif %} -</nav> diff --git a/electron-builder.yml b/electron-builder.yml index 7d437250..a53473e3 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -19,6 +19,8 @@ releaseInfo: --- + - Refactoring software homepage + #### Optimize ---- From f6afbb1a7fd9f3bc596365ce04da1b5e353ca97c Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Thu, 26 May 2022 17:41:53 +0800 Subject: [PATCH 12/17] [UI] Remove unset style --- docs/docs/stylesheets/extra.css | 177 ++++++++++++++++++++++++++- docs/material/overrides/home.html | 4 +- docs/material/overrides/home.zh.html | 4 +- 3 files changed, 179 insertions(+), 6 deletions(-) diff --git a/docs/docs/stylesheets/extra.css b/docs/docs/stylesheets/extra.css index 5366ea78..d3ec020a 100644 --- a/docs/docs/stylesheets/extra.css +++ b/docs/docs/stylesheets/extra.css @@ -6,10 +6,183 @@ color: #1890ff; } -@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:transparent;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root,[data-md-color-scheme=default]{--md-default-fg-color:rgba(0,0,0,.87);--md-default-fg-color--light:rgba(0,0,0,.54);--md-default-fg-color--lighter:rgba(0,0,0,.32);--md-default-fg-color--lightest:rgba(0,0,0,.07);--md-default-bg-color:#fff;--md-default-bg-color--light:hsla(0,0%,100%,.7);--md-default-bg-color--lighter:hsla(0,0%,100%,.3);--md-default-bg-color--lightest:hsla(0,0%,100%,.12);--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.05),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.35)}:root>*,[data-md-color-scheme=default]>*{--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:rgba(255,255,0,.5);--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:rgba(255,255,0,.5);--md-typeset-del-color:rgba(245,80,61,.15);--md-typeset-ins-color:rgba(11,213,112,.15);--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:rgba(0,0,0,.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:hsla(0,0%,100%,.7);--md-footer-fg-color--lighter:hsla(0,0%,100%,.3);--md-footer-bg-color:rgba(0,0,0,.87);--md-footer-bg-color--dark:rgba(0,0,0,.32)}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root,[data-md-color-scheme=default]{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m18 21-4-4h3V7h-3l4-4 4 4h-3v10h3M2 19v-2h10v2M2 13v-2h7v2M2 7V5h4v2H2Z"/></svg>');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 17h3l-4 4-4-4h3V3h2M2 17h10v2H2M6 5v2H2V5m0 6h7v2H2v-2Z"/></svg>');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7h3l-4-4-4 4h3v14h2M2 17h10v2H2M6 5v2H2V5m0 6h7v2H2v-2Z"/></svg>')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg{height:auto;max-width:100%}.md-typeset img[align=left],.md-typeset svg[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right],.md-typeset svg[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child,.md-typeset svg[align]:only-child{margin-top:0}.md-typeset img[src$="#gh-dark-mode-only"],.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) th a{color:inherit}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:rgba(0,0,0,.035);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}.md-banner__button{color:inherit;cursor:pointer;float:right;transition:opacity .25s}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.9375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root,[data-md-color-scheme=default]{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"/></svg>')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}@-webkit-keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes overlay{0%{opacity:0}to{opacity:1}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{-webkit-animation:overlay .25s both;animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:rgba(0,0,0,.54);height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{-webkit-animation:consent .5s cubic-bezier(.1,.7,.1,1) both;animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.9375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{float:right;margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}[dir=rtl] .md-content__button{float:left}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{align-content:baseline;display:flex;flex-wrap:wrap;justify-content:center;min-height:2.4rem;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__name{color:var(--md-default-fg-color--light);font-size:.68rem;opacity:0;position:absolute;top:1.2rem;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;width:100%}:disabled .md-feedback__name{display:none}.md-feedback__icon:hover+.md-feedback__name{opacity:1;transform:translateX(0)}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{display:flex;justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,:hover){color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem transparent,0 .2rem .4rem transparent;color:var(--md-primary-bg-color);left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header--shadow{box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header--hidden{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}:root,[data-md-color-scheme=default]{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z"/></svg>');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 9h14V7H3v2m0 4h14v-2H3v2m0 4h14v-2H3v2m16 0h2v-2h-2v2m0-10v2h2V7h-2m0 6h2v-2h-2v2Z"/></svg>')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{flex-grow:1;position:relative}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}[dir=ltr] .md-nav__link svg+*{margin-left:.4rem}[dir=rtl] .md-nav__link svg+*{margin-right:.4rem}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest);padding:0}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.9375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);font-weight:700;margin-top:0;padding:0 .6rem;position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}:root,[data-md-color-scheme=default]{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h7c-.41-.25-.8-.56-1.14-.9-.33-.33-.61-.7-.86-1.1H6V4h7v5h5v1.18c.71.16 1.39.43 2 .82V8l-6-6m6.31 16.9c1.33-2.11.69-4.9-1.4-6.22-2.11-1.33-4.91-.68-6.22 1.4-1.34 2.11-.69 4.89 1.4 6.22 1.46.93 3.32.93 4.79.02L22 23.39 23.39 22l-3.08-3.1m-3.81.1a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5Z"/></svg>')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:rgba(0,0,0,.54);cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){.md-search__inner{float:right;padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}[dir=rtl] .md-search__inner{float:left}}@media screen and (min-width:60em) and (max-width:76.1875em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem transparent;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:rgba(0,0,0,.26);border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:hsla(0,0%,100%,.12)}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem rgba(0,0,0,.07);color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:transparent;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::-moz-placeholder{-moz-transition:color .25s;transition:color .25s}.md-search__input::-ms-input-placeholder{-ms-transition:color .25s;transition:color .25s}.md-search__input::placeholder{transition:color .25s}.md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.9375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::-moz-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.9375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:-webkit-sticky;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:-webkit-any(:focus,:hover)>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more>summary:-moz-any(:focus,:hover)>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more>summary:is(:focus,:hover)>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.9375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid transparent;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid transparent;border-right:.2rem solid transparent;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;-ms-scroll-snap-type:none;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media screen and (max-width:76.1875em){.md-overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@-webkit-keyframes facts{0%{height:0}to{height:.65rem}}@keyframes facts{0%{height:0}to{height:.65rem}}@-webkit-keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root,[data-md-color-scheme=default]{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm0 2.122a2.25 2.25 0 1 0-1.5 0v.878A2.25 2.25 0 0 0 5.75 8.5h1.5v2.128a2.251 2.251 0 1 0 1.5 0V8.5h1.5a2.25 2.25 0 0 0 2.25-2.25v-.878a2.25 2.25 0 1 0-1.5 0v.878a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 5 6.25v-.878zm3.75 7.378a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm3-8.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z"/></svg>');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 1 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 0 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8zM5 12.25v3.25a.25.25 0 0 0 .4.2l1.45-1.087a.25.25 0 0 1 .3 0L8.6 15.7a.25.25 0 0 0 .4-.2v-3.25a.25.25 0 0 0-.25-.25h-3.5a.25.25 0 0 0-.25.25z"/></svg>');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694v.001z"/></svg>');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2.5 7.775V2.75a.25.25 0 0 1 .25-.25h5.025a.25.25 0 0 1 .177.073l6.25 6.25a.25.25 0 0 1 0 .354l-5.025 5.025a.25.25 0 0 1-.354 0l-6.25-6.25a.25.25 0 0 1-.073-.177zm-1.5 0V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.75 1.75 0 0 1 1 7.775zM6 5a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/></svg>')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{font-size:.55rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0}.md-source__repository--active .md-source__facts{-webkit-animation:facts .25s ease-in;animation:facts .25s ease-in}.md-source__fact{display:inline-block}.md-source__repository--active .md-source__fact{-webkit-animation:fact .4s ease-out;animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}[dir=ltr] .md-source__fact:nth-child(1n+2):before{margin-left:.4rem}[dir=rtl] .md-source__fact:nth-child(1n+2):before{margin-right:.4rem}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);line-height:1.3;overflow:auto;width:100%}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs--hidden{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs.md-tabs--hidden .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root,[data-md-color-scheme=default]{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m5.41 21 .71-4h-4l.35-2h4l1.06-6h-4l.35-2h4l.71-4h2l-.71 4h6l.71-4h2l-.71 4h4l-.35 2h-4l-1.06 6h4l-.35 2h-4l-.71 4h-2l.71-4h-6l-.71 4h-2M9.53 9l-1.06 6h6l1.06-6h-6Z"/></svg>')}.md-tags{margin-bottom:.75em}[dir=ltr] .md-tag{margin-right:.5em}[dir=rtl] .md-tag{margin-left:.5em}.md-tag{background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-block;font-size:.64rem;font-weight:700;letter-spacing:normal;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-tag[href]:focus,.md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-tag{vertical-align:text-top}.md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;margin-right:.4em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.2em}.md-tag-icon:-webkit-any(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}.md-tag-icon:-moz-any(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}.md-tag-icon:is(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}:root,[data-md-color-scheme=default]{--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}:-webkit-any(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}:-moz-any(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}:is(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation__index{cursor:pointer;font-family:var(--md-code-font-family);font-size:.85em;margin:0 1ch;outline:none;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0}.md-annotation .md-annotation__index{color:#fff;transition:z-index .25s}.md-annotation .md-annotation__index:-webkit-any(:focus,:hover){color:#fff}.md-annotation .md-annotation__index:-moz-any(:focus,:hover){color:#fff}.md-annotation .md-annotation__index:is(:focus,:hover){color:#fff}.md-annotation__index:after{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.125em;margin:0 -.4ch;padding:0 .4ch;position:absolute;top:0;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media (prefers-reduced-motion){.md-annotation__index:after{-webkit-animation:none;animation:none}}.md-tooltip--active+.md-annotation__index:after{-webkit-animation:none;animation:none;transition:color .25s,background-color .25s}code .md-annotation__index{font-family:var(--md-code-font-family);font-size:inherit}:-webkit-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:-moz-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:is(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:-webkit-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}:-moz-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}:is(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}.md-tooltip--active+.md-annotation__index{-webkit-animation:none;animation:none;transition:none;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top--hidden{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top--hidden{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@-webkit-keyframes hoverfix{0%{pointer-events:none}}@keyframes hoverfix{0%{pointer-events:none}}:root,[data-md-color-scheme=default]{--md-version-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="m310.6 246.6-127.1 128c-7.1 6.3-15.3 9.4-23.5 9.4s-16.38-3.125-22.63-9.375l-127.1-128C.224 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75s3.12 25.75-6.08 34.85z"/></svg>')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{-webkit-animation:hoverfix .25s forwards;animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{-webkit-animation:none;animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root,[data-md-color-scheme=default]{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25Z"/></svg>');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2Z"/></svg>');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2Z"/></svg>');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.66 11.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33 7.26 13 4.85 13.95 3c-.95.23-1.78.75-2.49 1.32-2.59 2.08-3.61 5.75-2.39 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.23.1-.47.04-.66-.12a.58.58 0 0 1-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78 10 4.87 12.3 5 14.47c.06.5.12 1 .29 1.5.14.6.41 1.2.71 1.73 1.08 1.73 2.95 2.97 4.96 3.22 2.14.27 4.43-.12 6.07-1.6 1.83-1.66 2.47-4.32 1.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16 6.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82 1.19-.28 1.9-1.16 2.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63 1.06.77 1 1.98 1.44 2.24 2.8.04.14.06.28.06.43.03.82-.33 1.72-.93 2.27Z"/></svg>');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m9 20.42-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42Z"/></svg>');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m15.07 11.25-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 0 0-2-2 2 2 0 0 0-2 2H8a4 4 0 0 1 4-4 4 4 0 0 1 4 4 3.2 3.2 0 0 1-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10c0-5.53-4.5-10-10-10Z"/></svg>');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2V9h2m0 9h-2v-2h2M1 21h22L12 2 1 21Z"/></svg>');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 6.91 17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91Z"/></svg>');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11 15H6l7-14v8h5l-7 14v-8Z"/></svg>');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 0 0-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8Z"/></svg>');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 0 1 .75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25Z"/></svg>');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4Z"/></svg>')}.md-typeset :-webkit-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}.md-typeset :-moz-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}[dir=ltr] .md-typeset :-webkit-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition,details){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition,details){border-right-width:.2rem}.md-typeset :is(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}@media print{.md-typeset :-webkit-any(.admonition,details){box-shadow:none}.md-typeset :-moz-any(.admonition,details){box-shadow:none}.md-typeset :is(.admonition,details){box-shadow:none}}.md-typeset :-webkit-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :-moz-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :is(.admonition,details)>*{box-sizing:border-box}.md-typeset :-webkit-any(.admonition,details) :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-moz-any(.admonition,details) :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :is(.admonition,details) :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-webkit-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :is(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-webkit-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :is(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-webkit-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :-moz-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :is(.admonition,details)>.tabbed-set:only-child{margin-top:0}html .md-typeset :-webkit-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :-moz-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :is(.admonition,details)>:last-child{margin-bottom:.6rem}.md-typeset :-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}.md-typeset :-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-right-width:.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}.md-typeset :is(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset :-webkit-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :-moz-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :is(.admonition-title,summary):last-child{margin-bottom:0}.md-typeset :-webkit-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-moz-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain;position:absolute;top:.625em;width:1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :is(.admonition-title,summary):before{left:.8rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary):before{right:.8rem}.md-typeset :is(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}:root,[data-md-color-scheme=default]{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2Z"/></svg>')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root,[data-md-color-scheme=default]{--md-details-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z"/></svg>')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji){--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset :-webkit-any(.lg,.xl,.xxl,.xxxl){vertical-align:text-bottom}.md-typeset :-moz-any(.lg,.xl,.xxl,.xxxl){vertical-align:text-bottom}.md-typeset :is(.lg,.xl,.xxl,.xxxl){vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color);display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,td){display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root,[data-md-color-scheme=default]{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.41 16.58 10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.42Z"/></svg>');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z"/></svg>')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;-ms-scroll-snap-type:x proximity;scroll-snap-type:x proximity;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid transparent;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;scroll-snap-align:start;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-accent-fg-color)}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,transparent);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,transparent);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.9375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-accent-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){background-color:var(--md-accent-fg-color--transparent)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root,[data-md-color-scheme=default]{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm16.28-2.72a.75.75 0 0 0-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l6.5-6.5z"/></svg>');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm16.28-2.72a.75.75 0 0 0-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l6.5-6.5z"/></svg>')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*,[data-md-color-scheme=default]>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));margin:1em 0}.md-typeset .grid.cards>:-webkit-any(ul,ol){display:contents}.md-typeset .grid.cards>:-moz-any(ul,ol){display:contents}.md-typeset .grid.cards>:is(ul,ol){display:contents}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;-webkit-transition:border .25s,box-shadow .25s;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>:-moz-any(ul,ol)>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;-moz-transition:border .25s,box-shadow .25s;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>:is(ul,ol)>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li:-webkit-any(:focus-within,:hover),.md-typeset .grid>.card:-webkit-any(:focus-within,:hover){border-color:transparent;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>:-moz-any(ul,ol)>li:-moz-any(:focus-within,:hover),.md-typeset .grid>.card:-moz-any(:focus-within,:hover){border-color:transparent;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>:is(ul,ol)>li:is(:focus-within,:hover),.md-typeset .grid>.card:is(:focus-within,:hover){border-color:transparent;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>:-moz-any(ul,ol)>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>:is(ul,ol)>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>:-moz-any(ul,ol)>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>:is(ul,ol)>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>:-webkit-any(ul,ol)>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid.cards>:-moz-any(ul,ol)>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid.cards>:is(ul,ol)>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*{margin-bottom:0;margin-top:0}.md-typeset .grid>:-webkit-any(.admonition,details){margin-bottom:0;margin-top:0}.md-typeset .grid>:-moz-any(.admonition,details){margin-bottom:0;margin-top:0}.md-typeset .grid>:is(.admonition,details){margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{float:left;margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}.md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}} +.md-typeset .grid { + grid-gap: .4rem; + display: grid; + grid-template-columns:repeat(auto-fit, minmax(16rem, 1fr)); + margin: 1em 0 +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) { + display: contents +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) { + display: contents +} + +.md-typeset .grid.cards > :is(ul,ol) { + display: contents +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li, .md-typeset .grid > .card { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + margin: 0; + padding: .8rem; + -webkit-transition: border .25s, box-shadow .25s; + transition: border .25s, box-shadow .25s +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li, .md-typeset .grid > .card { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + margin: 0; + padding: .8rem; + -moz-transition: border .25s, box-shadow .25s; + transition: border .25s, box-shadow .25s +} + +.md-typeset .grid.cards > :is(ul,ol) > li, .md-typeset .grid > .card { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + margin: 0; + padding: .8rem; + transition: border .25s, box-shadow .25s +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li:-webkit-any(:focus-within,:hover), .md-typeset .grid > .card:-webkit-any(:focus-within,:hover) { + border-color: transparent; + box-shadow: 0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25); +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li:-moz-any(:focus-within,:hover), .md-typeset .grid > .card:-moz-any(:focus-within,:hover) { + border-color: transparent; + box-shadow: 0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25); +} + +.md-typeset .grid.cards > :is(ul,ol) > li:is(:focus-within,:hover), .md-typeset .grid > .card:is(:focus-within,:hover) { + border-color: transparent; + box-shadow: 0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25); +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li > hr, .md-typeset .grid > .card > hr { + margin-bottom: 1em; + margin-top: 1em +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li > hr, .md-typeset .grid > .card > hr { + margin-bottom: 1em; + margin-top: 1em +} + +.md-typeset .grid.cards > :is(ul,ol) > li > hr, .md-typeset .grid > .card > hr { + margin-bottom: 1em; + margin-top: 1em +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li > :first-child, .md-typeset .grid > .card > :first-child { + margin-top: 0 +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li > :first-child, .md-typeset .grid > .card > :first-child { + margin-top: 0 +} + +.md-typeset .grid.cards > :is(ul,ol) > li > :first-child, .md-typeset .grid > .card > :first-child { + margin-top: 0 +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li > :last-child, .md-typeset .grid > .card > :last-child { + margin-bottom: 0 +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li > :last-child, .md-typeset .grid > .card > :last-child { + margin-bottom: 0 +} + +.md-typeset .grid.cards > :is(ul,ol) > li > :last-child, .md-typeset .grid > .card > :last-child { + margin-bottom: 0 +} + +.md-typeset .grid > * { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > :-webkit-any(.admonition,details) { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > :-moz-any(.admonition,details) { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > :is(.admonition,details) { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > .highlight > *, .md-typeset .grid > .highlighttable, .md-typeset .grid > pre { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > .highlight > pre:only-child, .md-typeset .grid > .highlight > pre > code, .md-typeset .grid > .highlighttable, .md-typeset .grid > .highlighttable > tbody, .md-typeset .grid > .highlighttable > tbody > tr, .md-typeset .grid > .highlighttable > tbody > tr > .code, .md-typeset .grid > .highlighttable > tbody > tr > .code > .highlight, .md-typeset .grid > .highlighttable > tbody > tr > .code > .highlight > pre, .md-typeset .grid > .highlighttable > tbody > tr > .code > .highlight > pre > code { + height: 100% +} + +.md-typeset .grid > .tabbed-set { + margin-bottom: 0; + margin-top: 0 +} + +@media screen and (min-width: 45em) { + [dir=ltr] .md-typeset .inline { + margin-right: .8rem + } + + [dir=rtl] .md-typeset .inline { + margin-left: .8rem + } + + .md-typeset .inline { + float: left; + margin-bottom: .8rem; + margin-top: 0; + width: 11.7rem + } + + [dir=rtl] .md-typeset .inline { + float: right + } + + [dir=ltr] .md-typeset .inline.end { + margin-left: .8rem; + margin-right: 0 + } + + [dir=rtl] .md-typeset .inline.end { + margin-left: 0; + margin-right: .8rem + } + + .md-typeset .inline.end { + float: right + } + + [dir=rtl] .md-typeset .inline.end { + float: left + } +} .mdx-container { - background: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1123 258'><path d='M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style='fill: hsla(0, 0%, 100%, 1)' /></svg>) no-repeat bottom,linear-gradient(to bottom,var(--md-primary-fg-color),#a63fd9 99%,var(--md-default-bg-color) 99%); + background: url(data:image/svg+xml;utf8,<svg xmlns= 'http://www.w3.org/2000/svg' viewBox= '0 0 1123 258' ><path d= 'M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style= 'fill: hsla(0, 0%, 100%, 1)' /></svg>) no-repeat bottom, linear-gradient(to bottom, var(--md-primary-fg-color), #a63fd9 99 %, var(--md-default-bg-color) 99 %); padding-top: 1rem; max-height: 600px; } diff --git a/docs/material/overrides/home.html b/docs/material/overrides/home.html index e850a2e2..33f3c746 100644 --- a/docs/material/overrides/home.html +++ b/docs/material/overrides/home.html @@ -21,7 +21,7 @@ <h3 class="lead">DBM is a set of open source database management desktop softwar </div> <div> - <h1 class="font-center">Overview?</h1> + <h1 class="font-center">Overview</h1> <div class="grid cards"> <ul> <li> @@ -64,7 +64,7 @@ <h1 class="font-center">Overview?</h1> <br /> <div> - <h1 class="font-center">Supported Databases?</h1> + <h1 class="font-center">Supported Databases</h1> <div class="grid cards"> <ul> <li> diff --git a/docs/material/overrides/home.zh.html b/docs/material/overrides/home.zh.html index e1f21955..6b929dfc 100644 --- a/docs/material/overrides/home.zh.html +++ b/docs/material/overrides/home.zh.html @@ -21,7 +21,7 @@ <h3 class="lead">DBM is a set of open source database management desktop softwar </div> <div> - <h1 class="font-center">Overview?</h1> + <h1 class="font-center">Overview</h1> <div class="grid cards"> <ul> <li> @@ -64,7 +64,7 @@ <h1 class="font-center">Overview?</h1> <br /> <div> - <h1 class="font-center">Supported Databases?</h1> + <h1 class="font-center">Supported Databases</h1> <div class="grid cards"> <ul> <li> From 8e249f4793a467dba0c9ae5b0a383c4610646285 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Thu, 26 May 2022 18:49:21 +0800 Subject: [PATCH 13/17] [Docs] Add clickhouse datasource docs --- .../management/datasource/clickhouse/img.png | Bin 0 -> 17529 bytes .../datasource/clickhouse/img_1.png | Bin 0 -> 49660 bytes .../management/datasource/datasource_type.png | Bin 0 -> 60339 bytes .../management/datasource/clickhouse.md | 88 ++++++++++++++++++ docs/docs/stylesheets/extra.css | 4 + docs/mkdocs.yml | 3 +- 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 docs/docs/assets/images/others/management/datasource/clickhouse/img.png create mode 100644 docs/docs/assets/images/others/management/datasource/clickhouse/img_1.png create mode 100644 docs/docs/assets/images/others/management/datasource/datasource_type.png create mode 100644 docs/docs/reference/management/datasource/clickhouse.md diff --git a/docs/docs/assets/images/others/management/datasource/clickhouse/img.png b/docs/docs/assets/images/others/management/datasource/clickhouse/img.png new file mode 100644 index 0000000000000000000000000000000000000000..4cb1f0bcc07386e5555053f946477c785319f1aa GIT binary patch literal 17529 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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/others/management/datasource/clickhouse/img_1.png b/docs/docs/assets/images/others/management/datasource/clickhouse/img_1.png new file mode 100644 index 0000000000000000000000000000000000000000..129c9dc2b64c89a3389a97ca9d0318e837492b7e GIT binary patch literal 49660 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%0DDE{%eEfHMj#4;82LWEY_y3A23hUA6T;?+04F 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 QqburZ)pIJjN*4qF3&#OkaR2}S literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/others/management/datasource/datasource_type.png b/docs/docs/assets/images/others/management/datasource/datasource_type.png new file mode 100644 index 0000000000000000000000000000000000000000..0be5cfff5c0a24c207ca4934e626ee2627ff53a2 GIT binary patch literal 60339 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 N-R#!Ya+AkV{{dHdX`}!E literal 0 HcmV?d00001 diff --git a/docs/docs/reference/management/datasource/clickhouse.md b/docs/docs/reference/management/datasource/clickhouse.md new file mode 100644 index 00000000..7689c76f --- /dev/null +++ b/docs/docs/reference/management/datasource/clickhouse.md @@ -0,0 +1,88 @@ +--- +template: overrides/main.html +--- + +!!! note "ClickHouse" + + It is mainly used to describe how the software builds the ClickHouse data source for subsequent operations. + +!!! warning "System requirements" + + \>= `1.0.0-SNAPSHOT` + +### Supported Versions + +--- + +| Version | Tested? | +|-----------|---------------------------------------------| +| `19.10.x` | :material-checkbox-marked-circle:{.success} | +| `20.11.x` | :material-checkbox-marked-circle:{.success} | +| `21.3.x` | :material-checkbox-marked-circle:{.success} | +| `22.12.x` | :material-checkbox-marked-circle:{.success} | + +!!! note "Supported versions" + + Most versions have been tested, please submit issues for non-adapted versions. + +### Created a Source + +--- + +After entering the data source management page, click the Add data source button. + +![img.png](../../../assets/images/others/management/datasource/datasource_type.png) + +Select the ClickHouse icon in the `Basic` type (the first one). + +After selecting the type, click the `Next` button at the bottom to configure the relevant information. + +![img_1.png](../../../assets/images/others/management/datasource/clickhouse/img_1.png) + +!!! note "Supported protocols" + + - [x] `HTTP` + - [x] `SSH` + +#### HTTP Protocol + +--- + +!!! note "HTTP Protocol" + + Use the HTTP interface provided by ClickHouse to connect to the service. + +| Parameter | Description | Required | Unique | Default | +|-------------|-----------------------------------------------------------------------------------------------------|----------|--------|---------| +| `Alias` | The alias of the data source, which will be displayed later in the selected data source on the page | Yes | Yes | | +| `Host` | The host of the ClickHouse server | Yes | Yes | | +| `Port` | The port of the ClickHouse server | Yes | Yes | `8123` | +| `User Name` | The user name of the ClickHouse server | Yes | No | | +| `Password` | The password of the ClickHouse server | Yes | No | | + +When we have configured the above parameters, click the `Test` button at the bottom. If the service can be accessed normally, the `OK` button can be used. Click it and it will be saved. + +#### SSH Protocol + +--- + +!!! note "SSH Protocol" + + The SSH protocol will remotely access the target ClickHouse service through the springboard machine (configured SSH server). + +The SSH protocol first needs to fill in the relevant configuration information in the HTTP protocol. + +![img.png](../../../assets/images/others/management/datasource/clickhouse/img.png) + +!!! warning "SSH Configuration" + + The difference is that the SSH protocol has the following configurations. + +| Parameter | Description | Required | Unique | Default | +|-------------|---------------------------------|----------|--------|----------| +| `SSH Host` | The host of the SSH server | Yes | Yes | | +| `SSH Port` | The port of the SSH server | Yes | Yes | `22` | +| `User Name` | The user name of the SSH server | Yes | Yes | `root` | +| `Password` | The password of the SSH server | Yes | Yes | `123456` | + +When we have configured the above parameters, click the `Test` button at the bottom. If the service can be accessed normally, the `OK` button can be used. Click it and it will be saved. diff --git a/docs/docs/stylesheets/extra.css b/docs/docs/stylesheets/extra.css index d3ec020a..5e40b791 100644 --- a/docs/docs/stylesheets/extra.css +++ b/docs/docs/stylesheets/extra.css @@ -6,6 +6,10 @@ color: #1890ff; } +.success { + color: #52c41a; +} + .md-typeset .grid { grid-gap: .4rem; display: grid; diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 77f4003b..c10d91af 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -154,7 +154,8 @@ nav: - History: reference/query/query_history.md - Snippet: reference/query/snippet/snippet.md - Management: - - Datasource: reference/management/management_datasource.md + - Datasource: + - ClickHouse: reference/management/datasource/clickhouse.md - Monitor: - Processor: reference/monitor/monitor-processor.md - Connection: reference/monitor/monitor_connection.md From 4b2e80a4f9a26380debe94dd10ebb8b253c3d20b Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Fri, 27 May 2022 10:30:42 +0800 Subject: [PATCH 14/17] [Docs] Add presto & trino datasource docs --- .../datasource/presto_trino/img.png | Bin 0 -> 34051 bytes .../development/version/1.17.0-development.md | 2 + .../management/datasource/presto_trino.md | 58 ++++++++++++++++++ docs/mkdocs.yml | 2 + electron-builder.yml | 2 + 5 files changed, 64 insertions(+) create mode 100644 docs/docs/assets/images/others/management/datasource/presto_trino/img.png create mode 100644 docs/docs/reference/management/datasource/presto_trino.md diff --git a/docs/docs/assets/images/others/management/datasource/presto_trino/img.png b/docs/docs/assets/images/others/management/datasource/presto_trino/img.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b808b912b2438c28251f26e1df146fc9dd55ea GIT binary patch literal 34051 zcmeFYXIPV4_dbYv6h$eDiiZ|C7F3#wpaLNZM^O=ipoE$TNbemI5-gOX2zW$6siHza zN@$@cC<q8hLJy%zCkY|6B#;o8C%*50W`1Ah!+e>U>l!~jhGg&c?6vn^_geS8o|~B( ziHpgKiHL}Z-@f&?xroRvu87Ev&AoeoPu`3nPKk&-7P<ZR_4{G)h0)Lm`F_IoHVZMn zvaXNeVtkQ1Pd<@4e(iXL$iA~tC!=0pJJfR~`<c?4S5a@|Y}|66?Td1Gx#RK+8hCK< zewyRm3oRxA|Ef`w`%e`tEY4kKkr%8JB~+{{Pri<(B%umNshZ_=<>fVe{kfm-w;ccj zL_|J(6eNc2`2Cot8io4(a87<gQTXs!%&1ya`0%0e;NtJ^<oW%-`YV^${jx51SSJRb z+CKVvxGifEvRh*dQKpA5>z@u$(sQiT-k8I`wGW}B@2Ly&h|54C>I4BjHo9S(HoA`- z(-gF7`bo$_s!uBQVQ+!0mvihuPbK@MOUCWxIrjF?sv=6#9gq3v_yfW<+4JF7{*BU) zt;VuvYQe7a|7M<yJQIIdZ}YQ<?tad~<Y_t0@@^8Qtoi0huVX{%ppPhYzQXWzgy!To zZQW3t@_3T~vMt_wz{V=&-CCmSNkQ)?@1vWgi<3^KrKk7Z&u|~y*)AJV&D~Y5e06=r zy_&4z6-xKxKD#g409wDQP#T^%iC4H<=W0pFz`!yxuJ}C92;SaV$By2E+8mWYRn|7a zt$KXOYRnSlqxfM$xh<0gRmDSIA|ADl-*c4_ly|!nS=s840(W~Oh6fO6T4Rb5TE7tt zyxHR?W<g8q3*e;Mw=v$%f8K~Io+j$Z;O_>HTT$IpOst(wEZR9VC|n*_M+Ll(PaAcF z-p5k|<8&8tPGxW!CrKygDu$VwvdntXIjX<(QL6hCjQTkx%`4n?%&<PQ_?2F4S$uNd zzHj9Zu9JJq7o7_kZGVh8ElrF`mQ)0*2(X%0<#h?LQOznv%l-EQ>NGbrCpvHHI*#n* z_fAK1+z!pAR56SXU98@Ez_4OHvoxkB#kv&IOAB%-!`)SCmHV@-TmsY9R5vO@Oc7-v zkYBy9&(9#te&J4jyu)IML%Ka`su}-Rs1g%eb*l4f-NJJnUF5>fy4m+OX%B|IO=|A? zM%>n+UqSg=$5N;E>n=2atlW&oh=VPJ0WY=Y;3T*E3)Ks^4b86G=Q48_jZevyfq9zq zemDme%wEPB4g`F=1S(n*R?E%YeA?+rFVzGURwcEnmFC9{7v)s!K>J60#jHGN+t~ZK z0{^pTmrZlSDfeAZiKhKUyX!*Q19ZK9n%A+IoSuj8Bd+gy(Dw`{F2xicKd-$xqPyu` z(fNOOzip8vAHB+-(=7^VEQ(ubJgeem8h6piN{dBpmD?re{_>u>4a4buaC^z22zB(= z!_-c=-GFoCot18CC}k);X0d{H9OrsJC8zO$>{{>VH{?ob5!QuyKLp*CtF%Nj+f3K! z5>&Vf@I#8a0bY1}%_5R)Z%gqSYD(18f7iqy`vy-VOP<0zbU5o9gRwv9X1I6wY>$MT zf8g6uJ%av5k6S4*0-Rg!Bxb`Rn79JQi<l)}yj6U7_H8h-uxUsyHcvBh?WGI9e_l4N zHm_;b=!z&p;Y|j{w#Q`$B(&jO;)^)FYSi-FJ&y~XcPwRBy`E)6Oqrv?-DRiik|@7! z-#PN)eT!54oa%@A?ETy^*_=ndaItW_;|#NZC|%+GA4|5bS~7C^jWz2!Bf*OiLnpF0 zm7?wi?|9q6ZYb2d$flk(TyWise6)|@SVC>!lhN}<BxHrXmK*JAKwHWwDEU7p;a<qn z4`xPUb3)To^SGU1NeU2`_XKO)y05!7ts8Vo)>*RXqeWCd0(X6r5s+X&r00}BJ3D-M zD*kLcb~sC~u2TX;_zt&84soGhJ-kHOeF~}G-Ech?1*zWzWf^D){+jNgF3f4O2Q_>V zUZFodmXuECSgJ_Q>nsIdVZ7@9wAE=v`SL)|C)iBJs5or77g3Q*^x7hH45ug8D?mbO z;v@6h7)RGS+uaLj<-%3|dTsrTqq8I^Vd28qB8JeGAWs+>gMX^%esEwd)y&S2iOw;{ z)|=mB9m|YCo;sQ3jMzBIWUh_$X1pO8@a{_f^r@WkwQ_k7O#5@oJv86vtj5{P7t}#$ zxu9x|Xn)As3-C;Ih^MK<TKOWv`!bktF5^7zgC$OpRlvRdSK~okAT+{ccL?4srwBny z?#Whd_J!F5!N4o$zRWeP1#(*G^$MEEQbM(zv}vJ9rb;-tSx0Dg3C3MwS!p@bVny52 zxk@2r`sJT0FM1z)s-F+Oc&_S9>-_!cr@ZlC+?B~e&0B8_U&Ot5o<FEGp5%q?tX+{U zN<W?1&`{B`6$Z<|yIYkd#+VxIaf>cdHzRdL@t-1=NZb1Z`^VWKNg2qwzdViQ>Nfvf zlTYpvDe;k>Sgd_rgN3g<YQB3~OG35L_RknKkP67Qu<OtsZ!XybZ_%nzTANwnIvzVC zxwH-?$A<elU8@FZ2rrbSZy)79c684mFR2n+Ws}aVv_9|f9(j3mRg(^mdc-LB94|rx z3&gKO?*9nSy_Y$^B0+xYdMx8kp)q5o=!CVCw+#eVGCS?QbtSvSC$)bzF;|*5L%>EJ z7jUR|dnwH9!*hA-7%R)Ojh<u~Nco+M>wdTqW^7P^q2|@ox*v))T^s(a`;mJ;_&fe` zIt!{WK+mQuy-5f*TuCy^;!@YyGi|nk0TtUmJppx*A?3JK%%41&$gpM6clO1@!iCp= z_eL=&fpB`&{1s+0<Fu~R$e~`h&8Iq&6gkeD=Y4;_YT5LI*e8?Z28#HpS`h4n!2QIv z)XP0{uVhj}hq|3S3Uk%K+wf1xghr7lJ?VhEKh8J3b#7c`zs)I26sLF|Q(xw9gkC;5 zp|4=j^F9JeyT3j)?o|mHD<8DMYwW2ptnfA|sPeh<e68oOcWusuMzi&DofvIe2CD8+ z4jC!^o~osD+B@Lb#kZV^oq)Z^uCPKi;625so@+NWcs>E2uR4n^G)iO_BP?}ZQF|;B z1v^7BZ|jZCHQk!KFT2ruEoW?_*m0ME=gQ!2NmcxFjT~~3{A;)=Yg|L#wF$jGJTl@1 z2I~i=;wvhw)UmxXd&*X~z(GMlgF|=>xbnqCq2(bx%<FJzgLEBtJovl@;lS8K$*&a? z$GrvS*7wJ~x6@(1`)vnuHO-I4E-;KgoPHehDEi=(hj+`zwTQ=TlRQdS*F&iO#%J)> z`V{B8G<2Qm)qN3c`QX73oDdiO+I4!3L@uUPBF1Zedi2NT-A%H<VeZ$+CxYA?VK4Sc zKaaiEoBAkaF8LC5wO@Q7`!;`bW&BH)X&?3#?!em5kNA+5!JD3}eYWP%O`hm%Xh_IV zU%mx%$P<STBwcO2887QhhHP(^a8hI88~nvOvV{Kn!{I<O7;HokaE3WWzUYpd3G#p9 zR(uPJi%Ak!r=@f`gH9^yza(#0!?MEn{#vyR8S?c(I2uR%P29=hNq)u9I^IH+lOmjg zNtoc#i@J+3p+&jfb+d75*T(v09`tL6bQ+t4j7qCeq!|{PuA~ZRB(Il~4@I|c`;@hv z=1|F)fo(dm-AI4sAiou|br44{Q!}GZoTfJTpH=o*em$|dQ|Rt9pWZe3rdKwqzlUeJ zh)K@U+I}#wS}!z*QSk21;TgFqNZP+?F51ImG9-MY9^of)lZ)}+BXEp@?uz(k8FX}^ zDztA<r9-y|OR4Nx>NnPQQnjz`OVFX8Azw`MCDt&jrxGe@xoOCa4#bwDi3#K8&PS9u zO_K<ZfEqjLtbt9EE^APxVf_Z5M``epfrn*xW<kbXe!iQ)O;z-oGT3^{fvzm$!H}y| zcH?*e?(CRP4U@1jo5rCuZ1r#N(bCeYY*j=JJ`q)%KOyxrfUNBA5|^c03`ySuT8u+8 zkjAy_ueK&3Ti`(OOaA8&XNj-kA6M_a)-X2-9m8DBCUNSKrJZ?f6@8m3NzZQ097OsW z^jogFd)at=Bt`kF6$t%MgRu4*6o#u`c`+I??9Hhmqe)w9SO~R4qhX<gy`HM&Ir-qS zRgK0?RaF-2u`usAfA@9PFCD`APt@#i(khJq@lp@=dVS=b6Z8U@vMX`$3GO!Ul3Lie zOuIpEMD53J)2#X)BY7-4E`_9W*hp0-@NuU5v>|JViR+IwN%6MXyOE8@_hXjh5MguE zf4ZhSl)I8EPZ=kNxz6rWPXCqhz7-T%&%Mcgd*f+9_(_S<*XYgcSj93ZW+f?PTfj|8 zcE7SU*&K&<!)VW~VH+rK`^Q6gsLTZv#d8a{&C@`wPsF17txFxFi)`>;f*NoFyb>#a zglFizw-LSkTB<oxBV+7Q6(mdXanAc?(d&j5I<Mo?x5+O26=#)&gsR|tT?Oh@&{63< zwd*piS*pJKQ;`dA_8EI$UyXtA3vfibn*HUmFeluMFM*vbsq!3BU0JE^`-fGf*ZatO za1>Juax5s}x$J&L)WU_x`T`ZO$?>g+{f#+FDo}`^qN>7~@twRISlEYQv=m-XNV!Ez z|Ii38$n-+S7Q=9kBG<JRh73lsrd2tQ&+V%puqw$KEotWv@|%xV9MwG&_vg)Q!j)jS z>|)&V>>^CgYdWbjv!LQQY?fwN`R=^KQ_=PDEl!o<m-0*Zw||^STszpNGjqlG&%dqz zuDM~ITc?XAD~*sdbSbkx-%oAaw5D|%f$+dy{U#^<H~Z~d_3B?cK|8=93s&O^I|(cQ z%Kmw&51jVQve=G>l{h1sAB$L%Z@>AacWi9Y`cBO`mFc3HjuaF)!?B1o*wS*-_lMan zisymGDJ0oO5jn{o8$)yL>v;46^!+9+irrLVfgy}<ny6-1T|)7+%uLhrOlDytw^p;p z+z#d?aAGU(ArP$L_ZOXCKyYKQJk60Ek$~4+k-vBh)j@a3{-GvT#fE)iuHh2Ti0o12 zeY3b?f9|FCi5xCtgnROoLRp#m2$r1s2&Ef7Vvec_5zO6+Qjp*Jl7cDk)GlY>8i*Bk zpe5jynN2od3JOsD4csvl;ljg}>9$I@?!Sf|VigvCYLY7sp18TbR|F471Ez7=!DgZ! zhr6U+6;%#>3A*#uRF^q@LbMFL2{=(?48&s>Jr?+&Q!*}Al4K*kmV6|vm}DRG8!+7X z7Qw5#6t8?6?F=KCzN_d7sr}dthubU^s=ARbs`zMTT(e7A8OT|WSRp>51+MBaLqjjW zLrB;iY`CkpH+<%w6A2|6Xqxeul668%re{!@0oE-e&8N04gzB8q<KAxTRT}N9{0GeW zHDYTeg)_>+P=FgqkF50tdu?+Hv^}VMMXPUHcYGrOlIyh^tr77J1bg<R@>4cXtozAM z)@9<d_&CW`fA!B{;3{DD7;E5x3!V&|v#hX;^WPzLnP+^x8w8w??i(^2=x8r6%i1-= z8NnZ-EI_tbA%ug5Yx)gb0xSI4vrJ>GsGGh>v^P^T1BM&HQtD@tZF!!SP@=&mw_zI% z+I`S1k7yd&wY3lH6FH-TC}kAa6<_lI@U$V*@J}fJCON;XQ+s&uEeyVqxhG}fJdm41 zaoz8TeNPo4DHqdh><@5tT;fC@@{B}F3~Fq!LI2Qq;H`2dBD|F{*l@}DLx+(OcTB#8 z)YVcYvZ`C?=!^TktF8<?`cHY-Ex9Xi>K!vF#NK8n4;yz3^(v2xcu>1V)5N&}WH5I< zRui+iZf+0G?JAbE{DvN@4<8fx@NDYCGl?=<FBZj!k7<qomXjN3(in@oeX4>W4b|(; zM02ctcksVSVt$Ec5%(J2z-1a_o1Hl<7HzO`{>`^u%K&Z92Pq0yL*C<MD*o=Mjrhwq z%L|$^N%EZCoIJp3R|3-`DlTP)S<+VCeOmbR_eu&)jnizLOjX0>U}dnwKZ%Z~B3MP2 z;_nUw(z@Sw=rW^p=@BO%BlZ>A)k5>IR?-w^9gCQg$tBYF(9`cP-pjMps6`GQNj*|6 z30~{!c@$7vBvt6GvU%?N)&@DU5*jfnJ!bV`k4UsXd!!)HBI7OH9ySltHy>=6e4!Fy zOBaX5=E^E9)~}kPrs6N_A(-{6B*k<f5@#X7@khG^K!m7YL*AHxGw3ycPr%7F>;c<h z(Du3!Xy1o>f3&+G1aug>E_5_FrQtF`UF+E9f-7Y8-vdZ*4?Q!ZBIF`F6%Xp)SJ3jZ ztLsB;dxY3pB!75(Qvg~0sfjTqCcE<wH4<d^Z!N__!ipp4`Pc|sq=sxKcqHcdNWt}U z;PvVGeOlUR|79MBcX9oC&V11lbC*e>T1|LIFJ9X*g3xJ`{|t(FojHwq9pP}v>5)Fz z$l1Xug?Sknui)2o5mi78!^A~Czx4TfXwP}vc8?zdX`}11DTczdbw#5Tj@L0O(*!`^ zR>#-6&Br!w=3_JI++edvAlO%qhK`SZ`SPVl{Pd;5zts#q@ZCF#9M0%;1uePQ`d!*I zRJ+$IANUf&;t^l%TAouLT2P)!U6_+jg{(XO6%Fi*_T=?QjkAZvW_DR&bck)3Z7ZGo z5mPzTnHiwKG|%kt8olz+`Hi1XeZcLi2mPT#w5gQA91FR^Y-N+vw0%wVXma>0WneLV z)JHeb&U+5hJsH27F-M-Pav2C2y65B>XUrps(yc8e>z{^oAu`P#K46uV#a_Jof!D50 z_q%VDlQ##?NRge8cl#lzY7lr!Zf38VE7@PYGq*0<ewpfrQ}o*HxSLrBxaQ|cF)o$8 zGaAKSb8RBXo(MW;kSu%jaG{K<RhMVYO;~}yQo4iy2rOZ-1v)mn#Bs31NH@2z<z^Xz z|I`}`Q(Ev)g{iWcGAj|Yc4Ax<*RWN~x~!!bh5pM!>Ym{bX4N>{M%xYmG)I2LMY75F zq#3XMa7Xhm1z;&5cU^m-4Jz(rUSI)o!IsiLblr*W1@|n?Y1i2Oul64moWlzhC|R#M z6_17G8?=<Z*!1<3QvxXCb6wT??j>E?VT{q;Jp9~IT%;AI(5_k%^f6|b@$gG=F^BJw zbI&+Y;#{|s<nAzqOUt#F$0N!?S3G9AWemyLN+)zaT%vt{CaFJfxY>XHgM*sG>5gwh zTn?Vo{V$V4>-c@Hf#dx~(r3eJC5=1mq`k?FysAM79?A|?<&Kz7`WrUQ2J^hCMA;04 zM>*4|xFjyOD%|jK%s@daoWT1cFgHnL`m@jJx-7_gcK_{2s2Yq7vJXGCj~hFF52gcx zs3y|n*X%<_`!VbS#D+kM&KKj#n&Mg>XKioJVIad&A3B~e`X;+S8S&BLP|A5^21Swn zBGY&W;yU6m{H=cwm2f-?6^*>7oU3D4@a4-UW-ys#K`G&N*%Fl|;PJa<oz*gBG&8WN zhoLy5xk+g1r8bExzeFO(mB?qGo&7}fm5Sxt`V#sXQMb8e{5uK_V(UZOvKKzwd|Xgm z+YZ`))$Eh>rP^yLC*^&fNpO{1u%b3&ro^i5%oWcO?1VnL<Vtpw5C6vz1&#|@)uW<F z16OrWQrkL765MSjsK=jT7rz^D7>18LqI7zxWZ*us3=<=j`W}8z+M?l46P)krRv%l` zLT;DbR`I^sd5x$?c)OoF(Uhj`of^C0Kh?5<7ALRIUT(0~>FTHFIQ*ppI#npAe;+>> zwach!kuCqFpj+e|?;;&1A%SkQ#F@Iz$`{rY=ra2OgJgwgQ0T*z9qPPJK8YSQ$bU#E zwV_la9K0Qt{Fbx2{NGb<O-;LEps(+d&~A9|@C}bT*UUqvRavfu37w%fft(~;%3x@* zZ^>mC_C!*k4jBX1L#+q1Iy3Ei+*|M3F!%kifcb~t4gXsqN_MAWOs{L;-Mio+`kPGw zE0V=6XJ4wfd$0UQfU|V8J)7goP{gcHV9s6J%MBgzk9Czdsg(H+T&-ugZl9k-c}K5u zv{J9}_H&25t42|cgtFwQnvP2Wyw}F+%X2*;mo$blQHwP3UG%&0O@dvLdQzE_;0d@P z=YeuPZehet=g2keAM?RyM;L<GoBx^_1uD2%5i2!EVor`=gFYNt@J+0ueunjWUdWy6 zW%$aD;8nqrk)u+)G{j=XsKyt(XQpRq<)q~zx~@6oSWP=ABCn0yMB$~zeeB3mW4-N( zdA4@wV2&Sa_~&pt=cxiXe_-s3M&x;}^4b^AfIr$K2wkECvOa(Pk(kc$Bj1~zoKhNL zm`lGF7({2HGRPly8H!F&U9*^mYyCZ+K2ndfVdXk5u>nFfbqu2jeqHwAtgmuH0X{W( zt*U<eGq<`s<7DE=JQ-{`Wpe0biM(FvSV)b}+fH~cd@8-@c4LQs5^R{0QdFWmo8wT| z+j<;_Nd44vVCCyDlY=#qMW+Yo9IB0|hPhk?5>@niz03QQS2qk4yQf3iPp0}oYYegb zVsB5CWxS@>z<lo6->W8T%l;9o5MqVPL;?4pUF!rKcQz_0K5C#Vxbtdq&cni2@;mVX zZw)q_Q|xECO{l%`yM@`_xa5TXT74{%?o2^l5v=tJB2eN@lzEZP&|HU&{{DVAG#kz~ zn0g%L2Qoc)Ow;9M;-jvAJlhs6O!V{a<_YqpaNNiawW>Fjr-sJGxJSAJL1BZYBNxis z)FT~hxIeKIx&*1eWryqfaf^ag{VR~GSB6)w>T;i)=F^*lL&zf`D0gQPXN!N4-|Vg8 zT^jk`;2O;Ei9v+FZS>@Ekw{f>-Zw_aF!QqXQ5$b0yGHy_EUFFjIJNIO=!4DEpbst@ zcqvlNxKkpy5QudZ^`Aa9N#5TbnGuK+!Fjt`Z=UKtDJ84)3QhWUZ1d<jqboMT6V+2E z@-_CGnShm1D;+E$$U3cFCX<rS@0Q7JAUDyzMqi4}Gq%{6WowOAlJm4Ut7*dv865RG z`i9T2!=q>RtBxrDL;B+VP)n6iwYq@K`_AQ_*uKGdjl$&{;7sxMSk%3*{Tp*SY*<pG z^Vz^Nn+)?XF{0Q?`(N~KQf44-M(lgLq0-}6KM-<pS2X_#XC&4Sckrj!R~@K*qWcPD z<^(v_0J*nsqT<O^f^KnzTK5vFzk`&VrC<qKNxEt78Bn+Ic2@=T(te_>mH~jAxH@2+ zf11$MsY7kbS(}*~J#T23^(Ig<sfNrM5%s9fOZQ{($)ecx(Ug>m!8Yl+;X9*hXGoz( zY^#FIWa6NwtQY#BTh=3%B`175%g|fhkH+OjAB}JD1G2swNUD5AY4vk2th=AMzHX3{ zm9@36bAMZ`ejRlyWP7vXiNmgjS^sKDCEbcgw5Dz|sm_W#Nj*6dySYoWaF-RR3`x`a zi721(JhZzr8Mn(|xc6>c>UD%@p+o?B-=)GSClLP~=%t~|Vz1}E|3FdT)&s>{yh6L> z;5|c+Jv!J~PVcpd>b>UZ@JE0S3jO+Vy(mOHBC*rj6H)hZ0CS<ZKcxQSC}#U%0Y3cn zIhRxYz4A_se-mDkY@Jr-Ue+BQtk|tIf~B538u0At%5CM0=^8_6Mt-l^6N{8gi(jxa z1A8BdTc@0Vo^iU_;?{uIqU_s3q(fzdH|(43r<5r_NSDI~T}r%Z<;c_E{3}`pc^3DT zY?64)hV89N3LM2w&4!Z;%nCc$G(4@(t@AN1bK8rI9$8g)YE58|h3pQ{GCz~z4w^3u zr#fr^&^^5YVIq6Qx&1Ii%Z9Hkw^&|2qk^U3&ot1q80Zl+cN7lAYR(H{4@zEljz&Qq z9vSc5<^90uP@l4TCCu_Dx$O*m_yTzK@BM2~*A;AUY)+VK#LA#bL9JIJ!`7Q&Z0ogR zt3Y!>gT>MNG%Y-AX|E209aAd}Qc{;(&zTInx<cX3-1=^FyR9*eYmtW++25R-(0e%( zl@gB>{?_Sg47gWK`Ic`Cl8@Y6#w^YMvbbk#&C%g@c6MTDd+pC%7mX%)b~CrPSlgU| zj|(B9CTSbz4~tw2U*3kBpE=wvT65q|>4^)=<f}#6lf)yKvvrPFF62l-)U3!B3l#@; z#o;%HWaJh!Ws2~im)`iRYRGGIvvULr!Ki$Jf0xgglB>E*M=ku&O&Ju!OC9csTYTFg zO0EAG$a;ID?_mDRY*V9|qq`SY$&dyZsY^%fBfZV?%!817l6V8ZcP4Q5;Q*~oI3<$Y z6NN-<^C-p>@FzCpBS7+@dKl4T>R|WHR(j!VDD91FZ~|Rt?a9qs484e%lP0&Y5|;L4 zc;N1+tE9t={SK)aQqVPhJg5(a<K}*h$ZZj~XWqr0`3GKSnm@pS@VXOu=h0fP7YN+3 zoYn0cCvg2|3y?$5q0GuaAQ4G6#SSn!Gf7fzYmW!Iow+f?ADYlZuiyU7e>#Ng8C&bf zEUuEn7B2C@(TgXaVnqY5i)LVh@G&_}?EST-pU1UPE+h|>n@c>m8ap>zfT>Lg<;Y|~ z6S1Cde?M+)IBnXMlJjtt5;SzdNoJ_tva_aP!aG#9ID7SCka~m^_oJtFgo0h_6(v1& z-mgoypT%U%8xCx!*A_l4et#_T&z%ZOI%oP*KX;rJMz3{>nLh1Y4Bwf#TX(rKhjY^# zmI{4i^yc2$2kx&}38PU{6ie>)17DQOb3)BW!m*a#hsA}Tb9V@^GxRqH?BBRI((cMh zRlJ|<Z*I|txt;(OtPa!iN%Rek;xfhdQ}p)~DSx(V0r!eZn)jtYw%)sDmIC#{pMkF$ zy^~`)Rm#7M?{7CqT~|NwfO3^7dsa$T>TkmKP%h~<g-2hwFInSKN;VI(Jn_sWi);?9 z)j<SX>w>f3X=8EpIGwxfbcd&_s#<V2h?_mT($k(Gq1NG2z9g$Pd5v`)X91K8US_Uj zxDY9~_A+r@B8T!?5yQ{N(@eVukko{+iHq}otYxa?V9Dp!u|h^gl8?3Hs!h;(2sRtu zzmlp{cEzqGtvYBS7xt|0d{WO*F`LZH-kv1+dESd0BNWfsCR8G_RzW<rn|=BLqwH)v zhuaF<fSqJ%E=ij1<($Lg@mr_v8NValXwyGkdpMI+K-pLqF8R4QBevsH%9Uvbwz$GL z=`pjr-t0hB`?;+wu1#*~_o-{CPy_Sj9X~Ur8xMJ(K!4p1TmCggHPTEvA}0HOgekti zHPPA;r)sQx4qEl8m8~bIyjZdcGlTcI?aUDS@T%}%GEk6Sb70Zg16>%edVq~n$Qv_U zG|FhK9D4gx9qEX-Ukl1$&tEa^L53=&aDJgWEQdN4!He{6?&Hi#M_TGDp20@s?#?s$ z$z?&gg0&x(_e^{TRy5)vp_A-dQ{Cm+Q<Wve!PB{xpOthl{T@NTo`~|USB+!%;ro*T zNNC6~N|3j<(eM#DqpX*i@g4-c^w)-Kr66;xf`%Ju_#fL@WhL8ZtG&0s5y;@_Lo>%C zPukxT7fCf3sna0rx-Yjs7`$`i$D<qJzI$#-69+D3%#S3UJRR%}*Tqw}I9;i0Z$y^& zJX!nriy<9glzyGpaiWaadfBpC&pr$+t!%pXCnI?1@l7xzA}Bc1!?Y}{%>U0@nRIAK z<bj-T^|?a7<ElP2>4E)vONyKybdH9sy}Q8~nUuh#sLY%7f0o`2dEDz({6NfIhnvkC zi)9V3jA5AP*~D0Mu3Rm1f6wX?SW-DOEf5?sYp)eD7Z*SF3}*<zC2K?`f9v%_XFSU` zHgv0wc_ex1i1_txzXYIETt8R3rN6$VxC>Z|C4KW_YV#FSmyjcTk53tw9HNWvZ-0g^ zWVjs6+U}U^fCfH4dbVjAjVbk6&0g1OzH*<Et9I#+uqqdwcUQ%4<S<Qb$DEDg;VyBE zI4lTD8wY`ImHl~Z>&MWmS~<gE5?l`6m@hKbnph<yLt?*iPt_B{<aXhSf^G^>wv#)z zHF`j2gufIzYUYd7S1^4|3iRdts8iz<T-d+B)@r74`jRp=ia+h9J!j`U150mE(EIM} zgWL9p^P8RNZ@5ZZqxz3#+w%(+*4pB{O-g4}z}q?1YQnvJOe9#Hx357=v2B}1A92;M zZX}^Ra`32QERNzD>FHBUY;;F3R`dChU3V*6^$!<$q{iLl_SS#&F@uPI2zy>npG{W? zW$2-n;!ii=EK+;7c;{`trX74-wnt&H_aR~v`+=iu->fhAYyN!wM$S=Pq!*sh|4#8A zchBSmSA5uENgnZV!(N>=t*_0ZxOMK0{dl%z0W{fOmq0bGCJY?)yxDHxCR%>CL+A&Q z!dS<f#aBeebd`D+%-??IS+u~Y;!y3>*%<D-kL8bpiS-7trdpLjCFmdL2`^TYpG<~; z`_^kGevX{W*y(44x92Xr2x=)cC|%dN3fhsu?cRAU97r_JDzv}OL`=rpW&Y~Dz377} z?oX%-t|3?gM-AJw-tY02gTp0izpaGP_&E-IUhR=WC5qDtY~S!crxfbu9>|JdbE^Wg zKDjn@SZL)N?82|40PM55x5`0^1ang3$%t*t!kxP5?meFKrqUZj20Fw+RNvbt$mm4w zXB2CsuSBpG-WWFZlt3u!FjcT{N`ZQ=wCplDusHXHuVeE;{&U=O8H9{k%daMaMA)|6 zP$sg+b2wDxd+58_I@tNFHIFz2{n~*RVvmP6<}UJnmHGbUl;d@G)f}3CEjq1Gc%3j0 zT_#r=HcU-QwhlH%651rt*7e`6i4sXQl&a(9)<U!A4O30uSk%U0MLj2%@B{V>Z|nd* z)pZQ!goRqUX!Ly!jLX@u-*>W8)BPcL$2$B@4c1Dd^HM%%dNGQU#$2*Z87k70E$n2R z%&F@Lh_>vVo>C&OPxhpKMTzT=xPESRT>i?o%P>{G_k(f%r}7g$U**yAzJz*I&FJL@ zs_ZA@2EM<o&V27{I9cDm7}xTXXR7Pzk)(h&jyDN&kH^bEb-O)~5u?YRPF4x+71?v9 zQ@YvIAW>V%;Z~xS@<haDL1)NFXB@Lf8AdG#&cG~2xbJSLQ73=4XEl4<=tQrlo~+iZ zEa@~Q6bzVx8U|hZ=BH;T15v>_@6Us%Iw$4VTyHg@uj;hI4Qajpyl~H33Ei<{K9!oS zFzWLvTp5tFmSDfgdixkAY6W>B_1KNrluplE16G6gN>V&hy(brtfFua1J5ebs$6gCa z8-IoQty24iwvbnD_?+KboK@DCK=iK3(5d;h7)I!J8K|I64m{PG?S*qHw#Vu%0v%q@ zBdq!!QA~U*oLY;@4oW9e(Y}|g(TS3MT#IBi5F4{o?%`k)A*O{tExDy|=JTn0Sy7vF zDWTNyENl13)atLMa#f894dnv~vM^7hv6`NQS^_EIwgfM!rGGeIT4rcm@x7-cvEQ*H zwRb>0WArs#UdU?#97E<e!AN++`OF9SBMVPz6hama;}+iB?$@3qX@!hr1mDih$2Ton zIm9LwlsdI&R3)A6r?O6WR&_)B2P<+iDh-n8p3gRXRHkcHvwGityLEXmjAdA@k#Mv7 z$5D;cQ<0;O4=E6fZd<2suFih(L51JIcG_hEyK%Jg!v)_qkZ<Q5nr#;|>Fzr1+)EST zvMmwKN^WZyr<fjBj2Xsa_u}XmQB@aQefv&XyKLB?icSmoA+H0!ysrQBZyTfX&Fa05 zcCCRVs4Go*_@Pt`cti%OcH6KTw5hY8<w;cch1tE)x3Y0oP+Q%9eH~mxGhB}A7u0f{ zDZ-oOadxg>mdmSGCVKf{LmFGmKrjEH;e1V6aP)<Y7YhY${z@4ki3NjB=YetOB8U+J z$^%uMH@zpWFvFpeQ}AW|2<1&w_Md;TPu=kh-Z<LJPnOhN6b}4#$vnZDp)88qKSPTq z>gwfx-l1=z-F%fBCoUqU-L55z#GR}C4qtK0R_VNvTlguC?tWLZ#2=Uj>uv6SoKnNh zX(@a)+Y~04oa}NuGE~vyFW^D?dj)H+4-wQ=es3?<F6UHpqemC8dAb(<`ULq*Xrhdw zYV+Hm0fD2k>oRdNa-Mj%jzz0$ZIR>nv0A<Mt}2ztOx4|)4XavvEt&m!JGcC9F`x4} zxQX)Qp(J4SFZ47O?mt3)r=eyG6LUZ7{4V&ai~Y_!47%lz>MN>5$-gm>5o6l%&P)DB zj9F8cRS}^Y;GZZBl~6h0*CJz*Iq-G%>DOZ$r&Vbz{gTqLEI;9}A|f&3|4%A8AtC^E zlK<Nf{fNEXBkFPss~ZuU=Y^mAGJNcZn3ym6tuK{YgoxPK*en2CQE6pm<+_sa8((8Z zCNO)W##U!%T~PDcv0jZ)`$ERiT&jRO&Wg;!@Z4=n9)3g7U1R%FRA%UpqWN=~sABJ0 zT5bqXxlT!L9saQ;<YYx6N~9J=Z$G)3&d~QA(;N1wV=icBZM;MSG)N^BO}Bt+Qy)qH zrU?Ohq<mmtpzH}4J^*Xecddp5OyA-Iq=#n;0u#>rcyTzcN?bVP`Y)vsNptN-1)-P} z`;bzgqBpR$oESL>)a@P$>5>dUcR{?Xv<*lw*tLRaX226-`jQnCny6-5`E$D^@%KK` zU*F4pb{N@xV*-QC2q`0QhB^ict$Pc`fMsyc+MHHq0vdu~+zg;0;H*z24$pUgLhs#9 zzZ!TaG5YaXceeu|>Zl*}Z&lF7Y=)s|IVpv8b#?b$w>CF`nph(B<BhmGj61=>_)!## z5VG2NnU7=<`98ST-;;w5MDdlR4AvW?_k%|wr{u;<csw3FxaH-aPFd^Um4%F{sv2so z+lZia&2YWxJchkA9@J}++%Z#6TAAr!&VNeeIB*@Rw`bFQeXyCxFVN4*vdP<^?PX91 zyC0TPS#%zE?+*{NE**eRYGtY*HeQ&dUdmrX(nfy^F(vmj3Z#C-@H0Zks3D`lFkw-c z`=(*JMNToVVT+9uy2%BQ5pZgQgM*0+t6AIi_Ceh@w9&jEmIHvKnaur&^{2p^dBRzR z<)pGi^nz2!&kL>VFV`)wrg#uQI&r!aF@16ereCNOFU33o*hvzLoPM>pa>zr)_m6de zOm&0mEk|WZlmM(3f3-7JtAi1J@b`Xv+^#)60dH!qtF1kkJI|KTo_1*>JQW<Z^>P^Y zDvuWp-tECo_54T}_H7_kB*ZWw>^_SeDNuSq``NKx40kk?k7f@sFnd?ZJo?Y2U39+V z{thj_xDD`N>pIvh4ANae$h3I_o0$zqw~=H@lp5_sbXp-}Swgb$zno*ZZyV`fZTT3z z5uAP90Io{$g-a|8_lS|K;xDNF&Yn6%NsOaMDJ{vV$SpQSAzic3m9akdnWj(dJC3Yt z1?ls%Jz~)I7ol?_iLzSl9I7h_^c2@Ydmc0I`Io+T;P-zHY6Fr06r-r>4#Rjamx72S zj6;^b?(!DW>dILWJ*?RC#XVzVJ{cJqIWuy`40<_y+*OLj`tRh%b`bUd-ID+RKa|A( z`)lCUZRgSC{-a3{`~GxaZ#YwDj+mXDO>xq6`B|b6I?^56QP64+s+Scxyx!kY+yIco zb+KXMSjh?abvr}4;XLK)+EB|xEXXHLMuVfHG~yY9VYje=gcHu4NkMR0k9?o%-d79K z_zmjsp9W5zSosXYjyE)9gGgp7K;}O@i!j$?=XoAQ?Ph}n^G5p8Tdz+UN91iiSI(Rd zK5d$AWdpqwJ_d*_7Qvh2g2hmD08x{4r3n-lI|GVX`X-c6@%|Cnrv%3yFSM)aslt~U zuKd1dwlRCThG%{z<NR=|ljVnh^%ral1xlzsjk<-4lH3$H(mg-nDWKS3F%9Wj`?5@B zj$QUi=l<{<*u0kVv$qz)r;;}@@{1aPh$V6pP+~<(HpzG!C#||SHu#ai{|RsU$AC$0 zfw`$>(4=_*r>X%D6u`zwSLft)0m+>=Q1@RF!2ltIS96p*5}3&CD%d)eV&@1*em+4% zssLRBa@XTV0+OO-OjHlVDq^Ao#3|#E+X8UCXEOSE6M-~Exw@qT+fHfN%&`yb)Cy_b zr@U^4CP-)*?EOD1cy{>om!yr=xfGWU*eigyeWC7+9gDD^BIf3{Fgz~mL`P;g;a=g8 z4I7=l5j}d*D}E$FnRAEUJBA+LF9VfPhkMQo8Y7+=QCW!H$DRi06#OoUD_`ZrDl*ld zaG!xTzozW}_Pa4d|B5hj7?f>!tkm6zI~x8&@&;j^-c6S1C7V9N!h^)AlmqLjHxTSg z6L2Rdr~HKESY+xujZ0GhWQMZo{o0|6b_F;btAFrAAR{=R;NF`{1;R>UO-)UOViHa0 zx38k26PQ<xch{(9qgiH=$EAnZRh>&#@;!VT#YZ5P=Wp%k<935;&`v=#za#>E%Iid3 zQ3;{i2a(v!?RdMupcnl1zlfRjUZCLx_;>%x@9qK-ks}HJK_}OuPmKKDk!BPBFZ&Ab z{+YwbBY@2Zz!+bLGg6B?*75--0u)O9eHhH*ztnL|$^7L3AQtZ99y<iI#h`n(o7~;q zON)!u84C-a|68p;aIc%CA|RRnkZA<(iSv{E02Sl%BK3f=k0CuN#rWnpnUqE8#S6!T zBbXas6mF-7VP{5SGf@vqfMwzREo{L#rXPhmaH<jfSpRn;PK@M)qTzGlV8V8s#}kIt zt!96X>=Lvo=R6!p8u>wsSuD7v<T~1RF^lsV=#kLgE%tld_3zU39nY>;i}I$j?Y{vq z8X?9N<AHBikT-e^N~e>Y8D-m|N;GL<v(NvUW9@`E{SM7N0`?u|OE9SCPR|9j8P?{^ zc>Hmu=iKjZptWayiP?aeyl!`~<>tth7fTs!ou>9teN8Ch2ZxR5lY?o&?_yX5nRkYc znbCf`x+(U*Klyhyh~0$^)oYh|t(%cyX;t2`0uJvuJMH-$Q<^|g%S&lc7T@;R+x2mB z+|Tw@R$<=jBjejJ;9UXVfKK-{{eEq;D^&*2L*MI)Z2xR{N46bLbqbE;B^|LG$Pui1 zh%AZGOfupSU0(%`k0rn9rx>R=rxf({_ft<K>N$#wi(|Go=CZ2tEwCI9sdd=#{|wy- zjyW`;I3Fv@eM+ieRb)>47Uy(cS|>U!9w>m!Tq)<#Kbxl=NtJzVHtwx(`!nn?=T>pZ z6UTp2fG|2rWEc5T^X`4x#O&p)^jScur_;O~ee0KFG=_mF?S&(7$^c9oxrvAt9)$A% zG(L7G3iSbmArj_TCqHNumDWNsT{|gu4xOQ+9`Pqk%V$NEhuin#Du(uN`$Q+7_Jj_Y zi4skTth1lvcPV{Ml)u`ezw&Qln4hnQ$2oAU9zax9HXpSe1i1ehZhs&I08L1tPxZh4 zuc>xJXv8pD9ngTJ!`yAFL)Y;HPhMe+ZO2xwT*eNTrL_zWy$}4U6O>HY@Z!}xMO+~p zXu~8ofos|uBA`LNg@6^n2p3mXT`Y3%F8c{#AW!gC1!m*zT{JGSBeMC$5$(X)yJ=ul zC7`TcFI(8y@Ej;C1#mPKj%N46<3$~!9-Ho~1^^$kmQgI{_fYwNI<<S>TKhoG=P{>^ zoc%@2>fWM_cT+`MxX25h2nWoQ`k$XsV(V}Mpf6b1ibHGy0=;&Xkgn^Z)U(+1o&uPD z6u&Dl5|A7X0p)aCu^F*xp%w_h=^=2=Xea^@DO$P<VnLWe;&Qz2ARw{x(p@NdhMv<M zF9lpQ0NOtR7vG6mtidwNI@BvY`oHwl3Y7lG)-WQ?)oXnI25y@i?JOwdrN<R=COe8; zm+LC&edE*>x#Ds=SX^*{d1+>Ah_BSGs=$>t<>4(p%NGm=hct;_4ikYvBcx(cyZJ(u z6~-3K7NW@vG>2O0H(?;j7Gojpz+5()T?rH^hXEPwL*r!C($KN+R-?Un6?i;brwTEQ zWa269q#lICe~!1*;)OSRxz`|<rU)_9v0=mbFQlW0%R@RTs%u8WF2sjgRU<CZ981Q) zfem_%q{2#bgD|&vi;HMBB;0@SAe_ao_MdujWL$1BQFrl*?pl{2__4|dPi=uJdpZ)( zu&}9Y88w?n05&fIaC`XH_VK?7f{qjoZcCKZV)=>PL21Gby@b2*-}~q+=es8{VmI32 zIO$01IHQphO`66@HgZ*QuT__MN;8Qd$e8wMkcA{yhqATY3aSEg2Ad>w7tTwLAByEq zB|?aY7jMjUX911~>APn{Rf?5&tXr%tkSwJvA$M;yY|dzKgc``$*)0E-KeyzS-n35W z6URZqK=XCU!2m40GrK_01)h<Toda=D31RjRnSXX8+vXPcMWem`X-LW+EJfYTr6zC~ zBR%{GyShLbLEr*uQZWwX(h<pLRtboWgvN&X2mv4zZI7jTwg>>Z4vI{Sne?0_JOt9E zkZ-$X2EU1dyo912LA{_W3B(<eJp4Z$QV$v1#{KdK-z~&erx_<R%0k=QbNmo`Wc_rX zZOcOgRbxochDyTI>KF<GM@plFuK@?829k(e1Vl}%+_jN7<YaIHIyAIuJf)nZ(}803 z2aXR8T6vt@t6npGX!uc*iPyKMyK|hyXh42Zn-SD=dthuVGk^5*f0jaN#Ochz#V42` z>nid)oCs^z{M-5cvO(iXq?cK}E7Qvn`uRzk>?Blc*m4jD&_fTQMmq$FoPUiJ-N*T3 zT)hfth7O+WhuibmyOP?nNZ`V=RG}&5y;nIx?dWDY%3j~MRUxzjvb{l8T$v+fcnZaH zi4s3dhp^Wo0s3Pow1IE$D|Kw||Fq|`YftPj)wUVc&U<eZxZC7@%Gl!kd<iRZn;!z? zp8W7-ctOdc9k(q>nQyi!yjwFPx569lj{$IHvlLMD4jwd;p9t1c%6ht$Z0kc)f~WNG zn?PH?Cg1?=uYs6bWdSOE#d$Vt2WF_komiyWSqSOs__gmp?m3^WD7@y6-4WwAi{KPD za*R`k0J;2Tw%<mL)S|AguAnElcB@`?XOQi6n?#kzo_izTnL&f+I@9J-%6b<z=+Ov3 zAr3Jb%#7g|WM3ojhi1+GM*unI=>Lz*s6@vkP>e+i_KEMCp^HzOhcXQR&q4kC_p&Ft zZ=~i8_mamnVC`VIk98#Z>ftZ@gt)0G=0B0LOZk6n>i=sXFfaXo-hLuH;B3#NOeAHe zeioL6&i*%U&L`QtKC-xv1AJtd_`hahk1)1rYr$vr|C@-mx1=N_NC4sRz=YzpEI?oF z-Tm>#7VLV~f78^9K{p!8lU1z`ZU3=L8$cP?vXDq*gaKi3(dU1SaQ?7hY-h|)p-BK( z`Ttr^@&DZxXf*xyonp#s1M?Nei^Zev&*`~wYq$Z@ec>XU_Yxwz`?vn8yW?`*{Nj#= z4_9zf<4Jm-hqHb1gpl}`;99k4SJl&<o3&$H^Foc!H~jTe+;^VoSJnDmJr08iF=?k^ zt<Ra-Q01JCdMx}KSW~Cr&4Mw3C!AqShz!vx(fp^}&bg$ASt?s88g6GW4)zKfHpy=c z#&iYu;MrzNhkz0yzo~FU|7;Zt_?2){$>=c2rH}Gie{dr7?Z=$#Zx6E8Y`#oAA$GkV zq2H0)iHz@Ujd`)lD`LCp_#Ycrx?1^v5rvn&1AqX#l-W&Kg{3<j8pt|L)r;0<YY|FH zty>xRcmIji-Ys;qz|Q|jVOFENK5oxJtyd*L|0oAK2)i!7B?Kogg^M!#+&=s4+~slW zUgyi;h7r?@5iba_h>AI%OT{2PlQJ$6n{R^cT{YA^s}d$(MAy4?8zBzgw6(P@0y>v~ zedq{?vVhL2nJQ0D&mth9fjt(K^ys^}yDy_ZqCcSzv#@r>+}(2joiER=J!7n@@IYV2 zh$T65TUi#883Mwx`|7YtQ?hr)k`gpDdZ{p<V@ubfgD1Vc7C72BH%FdzTcoQ+dY6HG z)4IK4<KaFs;L7ircGUx4WW_9dA62TJ#i`Ls7@77iu?hALG7z|{%D}9bcNs>Bk|Z(1 zB_9{4_FUz#-KWQTEfiQ9Z@m&j>>LH)(=(MIoV1T*a0yAjbqMe2O)Yb_d>eItcVA4* z9?6n(CMG6|>oOYfg&YEbP_e~ZW2f?ml$XmE^v_i3CEJg|GQ<xym@=`zC6+u2jgODd z5q$mt;#drlV&)lW*AzC}%C2!`>pM%c4j!R9=2EW?IQ&|*k+VvkQH?GWrhcX@)SBoN z&%RV>YLG+PUc9@-Fx|3%2AC^h%fI)Av632$_V9P<@So|~PC9&Va{iH}+&1CeHmi>L zNHR?`a|(oU!pIRRh+!gk)y-GUQ*AIOv2T#oqE=eV@ypg@?qa3^!Ld<LE0Qrvnc>)P zuJhJl%43#itS7=_pFO1krAY6Y_P0O*)<r=<0e;xDiRsrsB#tr8^|jzi(-%<GSG;BY z=a7_YQ_C7}ufm0pz7q{Vhlk|SGDeJlX97_L!@-&S+fN`~t{=*9kb3UAV6BP}CSX73 zdRvCb3B1d3Gr-wuiuX%w&mFJQ|2GY@K=&E5ge;eI)~%c?$Gb04{`@ue46#tiy5$jk z@-3=1P*LK(f!RFG`tq9yCyXAK{Y+0Huj!N?7l?FF)Yit_RP5#UL73$bO?r;{+BEvL zK`Je<4N`+AHlSNQKr+}?SfZdG+BbAnvfrkls^-kk0@D=uhv=I-8s6?R9~~VXpi-%x zkm%O6nt9EhCC?&h{i^CHkvyFtI3iI+DkM1gZRX{Ot#e56Cas^g!?1_;<t`?;52@mu z<%{fTmFh3|9-=3wppoo!u~vb?F!C;TZ=O%(JwtX7BC(Yb)yf_;1C1lcA3S(K%vwur zB>q@TS-_Yp>_#zd36g*QVC;)`piZ5yj}-L#zp^jpXGigo+YZ~`6H{!lBP&Z*uLK8f zw0_ZV^7|PhY}2)lLfzMvOl`{|om|HkE<dI&{rIH4-4pkEX4J*I)6&hI<3B;KCNq4^ z*UHz4K+d9Gx9BLWRxvAweJX(p?9dKT`G=p35*Lp|Y5%P)?^eA8bRo`tn-Xj)70>a2 z&WneD_{D3pYfpj4d@16kwO2VT|KF3Nksl)|C;6c!P*N&tvoVZ#pRhVqr&1>t@;#$~ znZH4wgEhj=g!@*LW8SIY>U%IihY#wX<yOr^llK>!fnvC1+GXEN(NW)sDY?oH^}6-B zN`NXrcF$oy&h+M*l>d9eXb3=^zk-Rpe%ugHbZ7Ut5&&)Ckg)nStf=MjM%Xx!gB)rR z0#Hf)^$!sJ`)lw^hY?^76+X9hXYVHc8)dnIcr$jvKlkD0N{0sj!WAIt@?Eeld3YV? zWGgN=g#EI*P)<gM1I2M;@UM>(OExf^axR&klLB8EV`qP4B?6EV;>^7#KR;Eb#6R2R zxAk7rm515eYC9M!tF}BDr@`C1lOREWGL@Ne!tSm(pI9`OVry@2KSZ%nr03<4g!Q>$ zc&XzJciRb^z6ycmW%w+U3+VIJ(c0&Hi5o67T_AkCx>0R(qxS*j$PqaNs{d$uNUhdL zM4Xm=C_vE7XbdcUy;1-csM>0WJas=njG02s1(ZJXYE+nFmZy2U$RHw0M*$)rr1=PJ zP>2t+_#<-*K%)`!^6|AJ1LYk+2c4zlzXg^>=fDHwNdM}8qFWmix2>#l8z7q#lFZLZ zrobO4I*dTZOJv>p#7wj1u}g^SB+H7~g(0jh^VNl-%BjvGPEwlef`(+(5JN@F3bFyk zUC2j|7w)Nh7=RDXIjg_X5OhaS;eI3V#99bY<{SLo0AcZZR3=ex<)27(F&!~KVR6qM z#l!>T0)-0j1#?d}zZ4Xg0ZTNtwZ(0)4L($sYntIfu?vjX;4={09=1L;IikEspe=~F z3FK*9?<`?12DDG{FDi%vEYEudpwPJ$k#yPwN%o{#(eD+1`GSO=QE<B__2Ab6G%Q|h z&f}NaLpx$bjihZPKmri{eMCyXnlp8sZ^6I41JRmKKeym9Dz)V4;Sm8Q#Jn@erGFur zb?@B`I20EKD#XpR4?KeGrqf`@G-MWo)4@O+4N*<&pS<pCt#7x8K!U4S!Pddwy+JP8 zb41NTfoV~+-6H3^j#h)^$wY@SEwn1<*<Zfh`G)8SvRz9@DiZXI3dlym{Zb!pitdgC zu$O8h_?(UYct%uP`iv~2h?WH%dQnhZf{&H=0rM3dRml1j`e|roX7hek*n9<EET#Fw z*{POM2U~CaTkc&K0nl{BIi3gV<8|Xeb7J!J;C{bQcGq)*$4`5bp!zfd(qXV7*>iN2 zq)V;@G8)w8a;pF{-%XhkwpHR}kb9a|%!~-H#H^9}(NSGpuf*TkYytI=@E`v){S@|= z$X#%Z8ke|k>TrFB)r6Mf7Cb=_JoDrx3hAS>O-L?u>!3al)utXzsT_`kdvmsnFAPtt zs1HxR(B_Y^#X0RO_~y!_bTyk^pA(CD(1F`otyvmbExf0ay)40|kQ@}|_cT1H$uj~- zE`Ae8kw;5~b?m0F$XQYbV+WkC7cyY&N(CC+1n~H)VlRZn4rbc;W^SZDl~PvPS6Aeu zmaZrz+Pn3FuJXavFenmdlzlJTp3&UVpC)g5!)*QjJlQ<YQbD2o<D6=h+Px3`%a`9w zz;|3(z=lBzac&AsWi(9G0Fa+UUb_6iki_U7)&DfuUX0v|NW1XARrlr5Q1}1aDwRT1 zq$rbgw^4FuXADVNh?1x*;VxuPvW%H&v6UE=O2UwA*|RS*Q`REJK4qJ%gJH%thFQ$> z{;22o?R(C%ob#OD@0{QB*L^!<^jY7p>vdh%>v}t$t}2t7R$A|)8e1ztFLoC#6kDj$ zx=@_Q1Sa%~Jwz!yg1H#R-veG^At6?V+wxHPr#kCy9`~}V#+b7!VsgK0xp&b^*;cb4 z(XTA4H!IOFb-G&bWQ5&<t?DMkq@)0JKFG3eF&d;cqUYaIzLN=ys$w+u=Ujon#>45~ z)q33=!GuBrpEtlFPz~Zn!K;;{#BunD3TfPaLF02xN}z!$oOv1J27c>kjyfQ97JRQs z@0Pg2w1!3&@$vV1Tx8W2q$M3Xd%3AfsIR!|7*%5%JX&9^FYMF1=nwfHk|#C`(NbJC zqg6|O3|Obia_)Yr$#Cj*qn+=WLgcD)>{7m|nXFw&KP@?hIZ(={NG9A{fHSW!Ds=)9 zZ2A{p^v1cP4N4mVV2;nk%%@(8u{cwOSaqG+ME{{py$%sagU)>Xhh*AK&;+{1IobsN zR+w5upkZ;IY~XnEr3Ae}Tb%yR$=xM6vMVGor<&^3Wfw~~wKDC!ctcqKGD#{7++1Da z<m4pUC`NGen3n9xnu|%S9WA|A?spdK4xB5zd{D=9yd1ov%nFI9ruE+=lgX)!6v9E7 z9)WF)^d<Pq?O~j3aXQoTW5bJ+Wzq{p*y@in{$()i?Jv4%UU{J}TRF0?6!H~XX&P;u zR(I5^s~_I-f<S#;3%#GYtv1rPDTJA$*N+crxK`0*X+guHS@21xlDUEgt}^kIZ6LhF zfpljZoe}SR-LtqE8MsGs65O{FjJD3>-xKcje2oZocKwna2v?2a7vgx?Vq%ug=4UR+ ze}bBDu>)-TT%RwJQ<91X49a>b>z_22rBd`ySGcOQGdw5dJ{x@HTiAS7=`{myMg{E{ z1`Z8Ecn*USUPuZWJ8|#pU$6be+goWsho_KsiRoV+Tp4*`y4d@}ESdHG_-mW)*NG#8 zC{NEKKk}izgZA(rJ_uRz4L)u1Snt&2Lw6sG7F|${_!QOkz3d}}{Hg;^NSj`_^D^y8 zoe5J6d_&2P_<wj+IKAXuqBYjbbr&UeNlzrrPpV#%LtZF68FPAf1{KhIQ?8a}WX`lw zA1M*ui--U;O(4AxpYd*kbOI44>L+tP&q&S$=e_$h*|Iu-wK-yQiq;Byn{CR0!H$Ad zS=&8@(hjn$Z8TLpSgjTpI!rk$7xgStEbawA4o*ZeGiVy!D`su(M`>ApfsW(lOj)MZ z5bt>FJKlSg&9VH3Y9M)#7Vurj&4v^de1|S(6X#UQt-IE@klY%;ROkJrds9v)jgeW6 z3i@VYnVt@0DTS)60y9wscFXONu#z_@fWBAP<Lj?)CAKWr&BRgOICVKPR9!pVe)M-Q zEp?RKXk55^i&fRaqVpX6tIK8wWU_7TMPHD`Tujo^WqnOfr{`zD_?vq+w?9}L7f3W9 z`6ta+OZG`#0D_jstlq9ro`RPPeyV)t-KWg?O3B(z@g(uAd1j$XdGE;A7jO~hk2)qg zucym9#O-s`J^D0=dHFI3)7=|}ILaX$&w)0Fd75NPWp+WU`$nusKK3vD6%6)o&Nqwo zy(5z&4AonFOE`->=0;M`a<es<72)k?1(^>Lk~?bf*x2!dePN+uCJ$d9?cuYHRi5kP z%oXY7q{dLByL>Q5G4f%nCg-+s>!R<6U|mmUj~$Tq@oRfS8#gGgzYtQ=Di3c>oN&WG z2<Dhcob#1_v^MQYU`E$)ylA*qXpsrtDdgPx3#vONVnux=`nm*?lHMkKH!*BFIRo1a z#*#YkKcM5vf=@?32u0#cr#PE1#iSxcqiB<*{MGSt#`!)UTxuwMT0JtUO*xtGE)<E< zx>9qmt1yq+&R5GI$dV7?+#Z209BPgXJMJ@rww=6#)~wpExp?S{YyINLRxqhydxmFr zY_Z2lzNdC}dzF#(;6?a6JIj6n1RVsqY^xHdOJ=W2D9ye(iF)1IkvX`qIR%<dq>zWD zFTv1#uJC?KP$ra;x@8dPDjY7)cG*qLSIz3f#w+jz>1tV7(lJX$=|2ZMn>G;k66~Tv zM`3r65zS|-@$XI>eZ+{BJ4U*ruC}OIX280h33963UkP%Wb6b9-=e6{z=XsPaH}5$c zN;)`5Xh7?f)YTB^c`~o;bo*$<t_zQ(HHz|z?21gYva(RPn_;6)qH2BoX-`a{iQ13% zcXxv>WMbQ9-saezdc9D8mQk<JcD(x;XHonjm_5!wDMz<T50tJP*?YUpFILC&MNwUE zD{8&5yIr!y19id0<BE0<{tl*koqIqyh=LYIUUu7|z@xK-oz87&>G7w_(p^bE<57f} zfzHYSvL@@1D68k5^YKlVC(H~UN;_7&Z2!SXm%h88RZVNY;4dT~ATCb7*jAzA|3<8t z)jCcL>&WWOB9@B>P6@MLgmPwHT!pis7!Nq0aAgnK0l3E!p>|<iYz|C=X}ZHl!2run z@(gOzXH)yjaAq>u=D}rsWs$4hC3pFuG9ELW!G_9*4_h|kG`!#87(^gqziRo6#f;E4 z5(3|-#^_XvhA4{4f#{TZKm((6KI-{OZfi7=y%Hs>Nhch5`!Qd>-{~ttO1IzPy6wO} zxCNi-`9&h%Hoy7#eg0$D?jC;C5vPVI*TU1P`TKG8AM1fNd{OmEN<_b_uY2u0UUwrt zbO3-kVUvvX8<OTJ4PGHgc-~^d+E-EQUQPwHvx7Fu&<*Xc8f4X+@|L;Nf?rDr4Ct!t zWjI~o8Z&pj7ET0Yhis>$hyi{{qZQqGXv6f0w%IJ-#^#n>*72B{Im6yYdb;T0Yeu3r zv|dwvp(by~uz#GIu;7*heG%oUy6uc1v&QKePh^;tTrZrH6{_@mReD?T+G2rYNi0OR zi)Z2{bvF}tPQl*?WLQfbZlGwkgatMfUOX@4GpT>Y6R^Pp*8`0WLRBC1gRF&aS{N&M z)5IA8QJQ23(&V1ht>W&$$v3(~;qrkYhRpA-8Wjg-I`Unbf95sK-RuX*9Nj`hPq}`? z1M^hAWo%dW^6d<vNb%9o(JaD&#g5UHg=-sz+TZxzYcoF|0Uqfw^?N@aly>*>%ineA z-g)`M$SAXcaDz{6jGxxIonw-B4mmM8Q2KT{8~N({HDZ?7=NG71bAL~(ErYt+*U{fi z<1l&*PmOAn236PAjuz@Ax$$S@*1!Sv{hdw`YX|j09bIvm-e>TiW?iqeUd9$wzb{GE z6qRr&Tu4+kMp(aq2XpRhpA<DJBfFZDkldAx*EUq(_Jewqxy2smLKLwip<>OHbjLnk zHo{>`<Oh9S61<jA{=Ten`zlxFKaI=jDw4XdT3$AXFWsT;@naw7`j>DOc}rxkY4JFN zJ<J~0L#3g2X&cKPmIjVuKzKvU!@>jAoRNcw396^-NyRo*av?2KUk}f_X8QTmXX7>2 z_)h78JOS_J(bt?QUd5KmjAZ@DHE}a0qMO8YX6~DwN_VXdGc(Vn+V+x1`=J?OSg4LT zBlntXSX5>~X`IAI$@`ntN(sGajv0O$X@H+b`BqM!_|SDBuJty_!cWRCsO8#=x5NtM zOOwQuq+GGnSYJs*(p^|6e$QfNt`8Ks@ft6YICi2{b7tKev%GkXKBrP1l!0?lMMUm) z*?6JF4Rg<FcIa5xhWlWZSX21nc7MimrmEU_?3Hk`ce-z}spKc$DrfYDkgLo)3bhJ- zlgc5tySl2@#i{QTyvMVM?W8>x^(`YKFWu-qEFztmPvA)~6!!4JE5K_xA1!&S33jH8 zME40nPFJp+z8fRVvPa>GUSBKobt+N3F2Bn(*DZpo;*%#jUEBNi-rgB5a}yvgfTEqz z9;K2b>aq1GhU~FT-k0ja#-uQMrg3*)qd=;~?59y?WAI<=kF2M17(@yq4EB?KF}F2W zFV8D?tH9(lOGmw=vtLh|A=u+7@Yso<o;$R|{|HJy&wfL%Nu61cR@EjZp3ouQnjmW~ z_JjtqyELLj331+hfH;);#TZA82PBmk5wdufYbgn;0R=g2wZXET!f8wRkMK?Q?)@cY zIsI|-Y{3Qp7Kt^UNRO91CcUov{WA&OsFQyMb5z8aot_7X##LP?TnVdxHs$4?keg&K zbyEK9qAxCB?2Yc{8#?o4!GS&MS_y;7Ht^&!9i24uU7bIb`vz?#PWl=jJ|3zU$CHsd zN_I-~-O#gFK3PsKo|Geybv#oR<*r`kH|=`V-0E_|@!7=Fg~3|M7xid$MWoI%s+R|K zTkkOwS|`@=L`ft%LiK`k!qhBY7u=2&c2h!P(oA+k^<j}84PCAP&>rgx(+U(z9^9`e zh7D10`zLQET5@ty<D#SSlJ$b-M9kyk2f<>mw_{ND<x#uc5ACY(x!M{&+K&C$h5gRH z*~|fbro^OCAa~vMg%mr)T;XRej=T-xqohWc`L$e2i{5T57y;ezU@Fkw+4CNpXQ9z? zoaZKHQxf%xcInn;^z6-_)uT&|_%VNNUgJT1Le>pT(2dLl=FdCV``)q4`i4_c@oL#; z%u9ddbXfLyms<2z*B2$?#0N=IErq7(o%8&^^9<y!!1D$RzpQj|I&>AtH6K{J)><jL z*?qRd`EoVSEe24;0&_Mev$-F)kJZ^*U<|PM0c1H#DuVKMpme}4_9a|Vtf6Y$bLXBU zUNrpG<;#{$jnlZ99}DU_D1#94&I8dM=u2kDq~>b=?h@sw3~U5)k;g0xfu;-=%&2Ee zHFXPf4j^?gRi;h&`laHmTxt7-fxA;8cQ1o(aA`)aFXiKC#2Z^;$h?c&LhQva#`&)g zPl!?P25<{2`oyNQHB@4<a5>u%KwXL!758q9o>FUq%aXqyi-0Lu<|)PHn{m8-pC3GZ z;p)w>{)$EqB>H7@u6t?Mp3N&~HRw|%hFRKf?Nb{#Ki<Dwe2skF^DZs1=pcgP9vHXa zu--mB%!|TWp8CP@&Ui{&OwX%8!5L-|IQhOSRu(l;=VC9LG+nNqaaE-Q{|xK)`(0q( zY$fX1)bMD@TN_*Y?BFYu?zGtSqkLSa0&MZc;`!Kr%zW=6Y%xhgENM@90_8Pf(ehs9 zsI1sf1KCnaKw$5xl_qW-N$1pvO2&ZghpVnqh$}Z6qU;<IyE|?nBVCGl4JtooOVz(G zvyK)UQPr+TIBl^>)q{T$j3ykqk#+D2^&f?*57euMrK)b%@#6+R<ZUxM=W`MRre93% zuMOk9@3lv~d^-(9tDiuF16CVN*kz@VA@RoxrUuV@U9b6E>F;qre+}u@)$=e6V=*He zkYkh!JH8&ZzLRhaIAbMQX|9xiSRH!ET1adVfy9j%g$=$^7jjtl^Y|4njI>QUcBR1= zzCK#d?9O8zcrauk^z7oX;CdG4+M>N`G-@lZ0(|qAuu^KAJ2$Yj{|ie(Vp&xijpfq{ z&M_sbRa|WKsXu7(bYI##&vl#f)@9D?$4tK=9aAVpG#&*QcIh~9EsS3;NY}+DU#;jm zk>}d&`mw6IVt{K#TDJqA0hYi|oJeqbo||WX*qSTc3K(Ud47{i#+Ne~#<{yQ>4?(kO z{uD@UI-IausbjmH&{ag_@<hm-#H_)$gRPKQ#or8RO`D(L->Xa!tllXy<mb<a3@)$! z=~agdc(ebjtzLW#lEph{X~PiXnwAj*3<Ec&mbPkJYn{6&C>Yba|MCN+cjDrLf?LJ) z4b24CY&{i7l%DX~^q0ipuc0byC*W`0aSQ@tP^7Tt!sM<mUx$}RW^diP@b(SQzA(>J zTXNN!qF1*n$eMXWLae~$_*E0zf9^*rUH$zwAc8N~n%Nt3>D=Me&UUF7VAqP1R=s`s zwySHCsza?%D)fnkgD6Z_CsGz(F>89<Y9DYpTn=XcD0E71X=$-GWZ<DM$6R9rG5d<N z=AD0raX0c$0gF+l5NmpRIx{^z-5b0_=UwQ1<<;<1;0#C`g1rrxA5-<%Adn<j4ZpdK zZh!GqgYQM0?p^fao$|kc^`+=SFh>l*&G$Z`xOGr=haqAR9U!&{j!wXN&tT%;n^^f7 z(%bOhs(fk}ryqXdC8o0attc<kH^E3N>wb7<dg+idb3u`;@KqQ{+c}Q<@W%apHA9mZ z<{L(g%IsR8>zgCrXMO<udCQtU&gdKP*IKoH9gf@+MO>DDd)LcbSpI(B#g&uvEYCTt z90$yDej}Da|A|)tWK?}~6HuxJl6-@a&>w%e5IUbbkguzqc#i~o2K#|`>RD28Y<-hS zd-)m>G4HJxM@AYOF);JZiK^Pug(TexKxOmpp0@*Zp@$a0te22TBzjNen!4R9L(308 zXyjH_Y9s0q;(%yA6G%<))Aft2cZ_fs{`(SiA$AE*UWAT*|D5MPi*)~<mlcRz{cpb? zOjmKb6L+sYDaID1o!S!B$(s!xu%;}#G%`d<xWxgZJRab0UO+Kjoi+<6(&O)(>jCyt zPB3RhC3N9*-Qunjx8AQ=x8c1)ZrP9zXA(H;xgn4f@S0Isx^XpJQBROP{)`kc?C1Ml z`L%6aeL{do+#T8;7ka_Eju^y>Ze;n?oXVY6%}i8hM&FiJO@6InXrCvLWhT-QJePh8 zgb%Pvr9l9E2fe1qrK26>VLhXRY{UhCQ>e+DWZn0WHGjer!?_*^eziU3u=(7gKOn?6 zb^vqR^C-m1(gGM6=v-uykBhIt*n<_}e)rbZ$3VFC4d-V{FF}38k90o49rpgLn9lRG zcwclJp6}t({%N>9cp!<g(&Ku#m}H!prR~cMlAb}5;#GZaZDBpyC`LyPnkE2y&&2(8 zTQWj8mUbvrNKSIWGrP~rcvg8|16^MS5N4i(oXeLizy@hUCMuUlqH1S=qYBmIoDw-V zt1N;UZ%uZ|$|-52)~*~a?fZKpSNt;}B}LxG>+|{vAn!DhT|_v%KQHPT*(l1}ALd4k zj^$_Y=J?nHHZw0&Xhr7j*$)oBS8;QGqCt5^?KP6uGj(s_WxpwG2O3gzl+N529jO%% zZ}_3BMhp?ZMQc21q1h9CV&nMuD8-Y=Ywy19nE+fY%PIkLBYoS6^a@%UAkQ`JJikQC zxum|la?X!}@}svw3c`H;inGr6<YZ%{z}88nit%?UDE7kc@d$Ak85?>ZIK!3gkQX6C z<^Oz_9xjXxjhkZ!mbmXyPDJuYRbBetIHe}ezUb(bLBBY?MGM~i_V|HYBSumI?1iU6 zf!`ibe91OGdK9<9=JvF=9zE&Z);`UBCtwC6c0sdsMfK9I@3k3K^Mx#iWW;O^afR(N zRQq@WShY+Qvhz=}K@N`H^_z%l<ZRGnXJ$YPPYFF6!9L#^I*J8LQ@2(&RaW3<(_g<{ z>Amd9`ELs?JL4%b6zz)k_efcj`GFufYn){q|NKBd`^Myw|2cXN4)<Dqj3ma|T2Ts& zW;)yz-~+n=(jrWT>m!?(Am=X?#F?m(%EiD1vSas<39kkMX*t{qAqtCv!3^lSeb4W+ zI_}(>q_cpII9hUM-Nr4(pgr-VCyTYo!wlwu@%&?tDqDDVN9Q_$rMXS4n6qVJ>z}ml zHkhVv<n0q{5a-e9-`f)_kQJ9K8S{y;uVEX5dU|2h=6FqcQaQv1L<lc>_qe2wYO>@) zCqVFK;{+Jl`I;9ovqzYkQ#SOZxVJYX_AS4X!aKI--gkSKmljvf0z+58fUNMiVVRPx z)F4551X=^_bbqa!dc2K4NhK}B2^()(CHNny(&~sr&aJFb@SBB&C&F01-B%CV1dP5! zMLk|#RK}v)-=CcTefN1KBKHoCr;LN17E;7WT|QT15hMy_PGiOGvY*2E_dD|l#Qgh8 z(E1&<o_Po?%SVe2vC6TA3qw*!#c(No-Ld`#)TCn@-s*>L;Cx=i<cFXj#rINhCSZN- z6I1v=3V~DDbP!wnjcO!LaY;{@bAC|v(pE)CVhA3kF%+)TfCyzNK?dXBi>`riT|5UI zoVL;vGEN9|Olbe<EB?w(D}6qs=F+l=o}l?=pM0zxS1yp6S3VY3<!t+{9NPeVZ3>Yv z1mRxu&H)&F*;~7ceSNS__1$ZJFJ<MP$6YH4P<ZudLaX;{#}l(X`dVmjmb##B=oh1P zdc4+UafM-{{3!dy5cYfu74<Dv8P{vKdwZmScceoy-ocKS&ozWBoJGGXQqtkoBUa2X z0_ExV534m}oyi|{$obsA>YJYV>H%1pVL`F`{ln_fY>eCXueG=}=3hnYL0V5w&+S11 zsJHfjSvha8x>|!$&G}ub{{lf~xw>6t82iy6piM2e_z~t4DBwqnm-CL4?5l;hvqt^= z{AkAZpmOV(r<{&#T!R6VJImhQ3M&O4^6GiQ3jgsv1{eI8btD0XaRk6Xi@C7Sx%m}1 z8WqW-UknXtcX+P9pu>etix8*)l*E%&r+3oOs*O8CW7VN`<idZOkK!h$rm`)JjErz( z2+myk5I;FF@pV18i~tb<R3okIa4HuBwf>2Sq*Xucpr_n83*Diubl^mMTTxm05`sgQ zzp4U^umHwnHnU<*f<N)Z3*k9XRo@II$oFbp+}CHY>pvcZeSHm->t-7UW&aoV|JMVU zTEaaR1o_Z^KTcNn!>3X2kOj$vOO~F#JCx?K=-jD7cZ**b=+~PkoS*M3%h8^5^nB0w z%EyLPr4*_Uu@o0JH>v&W?Wx(vwhlv~r@rDBW_Oab=J|-;>%M<H`G&1Kr)V`OdJ+Hb zb-z=*#N6GpDN@AAKMU@h%ac4YX1SAY{XoNU?!aE07E+$~^l)a%bVBC|zkBHZ4!BY= zE2ulnZv3m`A|elr4Neg1B*}+q*CJ%-!>Hj(2_TKf4FGOV#i2Hwi?!q_N8)@MV-7>B ze<om#OYkeRAVAT?AXMZmnE%nAoO;R>8RPd&VsQX*1~TxhJ7Bdeyyx)-VJC3^<F8jH ze=lzAGy4Y4z~Qn@c*1he`H4p-_;!=KwP!mV<-J<Ol9>Ar0Y|Vd3W&24V9{?O9W+hk zmLIRo4#&9dQ13JHy?ggPg*&G1^6CB>my}4gb24uE`aPgrb_gp~nQ7+|w*Jh+@LYR< z1URSMk#3r|XZsLuqnK=bHwfV?`g-8)doXpUl;A(~xLhu2rOZe+U_WH+Z~<=YZ;~X( z>$7iO72}Qy-2a7Gqbqb`4Uk(F4{zio4hZzB4%G}$8mC?8y?Lov^xX^RV5Y`4CvK&c z51&qNq34=fHuJv$IP%QEO|T0b1x+*K^bPo6@b-2v2p}D08`NeF4F;wU)`Y3kuk8cZ zSs1b!bTlgD#kYW(qH=e<bpd=&0ZL9<t~{-TwujbufT@gW*@YJdpjtS}Fk?(+<y~;i zE;wBQGNyg7+?>*ZI6KIwP`u$GP#8|wIsW|gU;+#@kbG;m8og(d?GU0eYKkyu(xyrJ zSFza}8F1Xzui0)FhJA2*N3i(?6BrJuA9ttU!lh9Rd*KDf&w@P?)6xF^^CR;(wba3p zm`5IhY;cK>1ADgP1c<Ue16&g(?0R*=Gh~kZ)Un8=2D!km04B85+gx?TE>|m_EyJ=j zCNomnbvaY!GP<yLWHj)-m;zfb#kF@|egid9cJchN^8HZ!whJ)k7W0%x&{+85nS%*; zFS%b2uaDNa2fWqGOcV9~7?}-|7&NG|=eBUcY^^2w=pW}2ywAUc$U?_?F;FfoEKKy+ zG~OxBoBhM3`h{s)KnlVb?)$l923)kUfe~m*m9!Wp8+a(^W8;wtAP{7_%bd7n%m(%4 zl}FWVecyclz<_P9ltDWVJR>^q5hv#XQhW}<i`}nMlJ^D{J7Tt?4T2ZIbnih3k_LFN z-&sBPf`R#gs-hpa-lhU?IJpGkv|YL^ESvF@Axi<^s%S3<Y^6uoFUv{q8$w3z(JnF7 zz<NQHDS2$R!Ev@q98ozw$S3kSMD8`P_`Xuz(U}6F`n3A!@3S~^d*_3O^dC-%FAp$7 zIVvvP^ajI2^xpHbaMo6OO1hQ=eq4D!2E;10;Fsj8R{)BOqee;9EP-BaW&tFgjqpIM zmbGj*tk*$<v)Jp2^C%k(Edq}Z)p5A*JIIz}kTAn4n1XVl+P0cKk!vFyylYU(rSNWv zCE%06QD_f^k9{#<3?r=p{s_=Td%NKyln6^cg9O{z!ay);-O=NkXT!PL6%qQ-c|2T` z4Mt>5*rQ6At1|G`B{TpzYQLU4iLndp{i29re(GZ~UoQ14EZzGN$<$G4#qeAqH8oKp z`6J(p4=Kq%R%U9%sEHgfx2$dwdtA=FeDoEB{=W?B1X5Cr5P`|^hr-5rwqO#k1B7$G zL=qhn1B1Vhk4Bw-2pJs8(}~^|Y^z$&zB2C!9UaWsYE<~M^<Z4(&X&QpC2<3Wqdi_| zfZ5QUcNaE@2GfD#+vze0r>BD9j^O$b(K2fs?&{5=+giPW#{orm0^3snIUj0i&nNrL zji}5faxPJWziQT#b}a|SaX<0!gM<^LCeO<vP1wZIopF3H96csGF7&=FOICjcTwqg$ zoT5waH<znH0Bzi(>8T%u^MvB=YYOnCpN{~d>#eOT-Zv7uuTw3wx1QV#y*-~~g?sC$ z;f$T7?<2Nuw6yj%yyjlqb=zD_8eveF$Qg=_HHB>TW3tQat(%xbc(9?<3mK_g;OgL_ znFwKl`!^r|TE&jwA1Kp(DI5)iR(<q5z0Zka7xUB$<}>7Y2DQ*)#JICi)F8g-fM$cG z0w>iUA-fo;%+lQv9+AWao$x5NE@<v#@W8knALQd->h1o{v2nW|lV4djs9P)XXekOp zwYcf6RgND%fkB&ICuH)~GBM@Uy*nl%Har6PZ#gCSCE3}+BRe`22$njh9nYw!C{D80 z3oPxsx(cK6B`VCx+-I!*dDxv=#zf0!0#Tn~2m<1c92-kD5|7Hah3PnsvaBo!&UHr@ z4aG1b>R54^L0xG9TlDg1Pk>xCN@a({AVH|OPSxQbJ>KmF;X<%ugY;pCockT72s~+V zcDR8`+7U4rQlH;%SB7<Th*|-e*Ds~Uv&0se4X5s7D@AKFLQitz-znc{P0}wO77%y^ zrbZwJ<nV|We}bQ)WiH5B<};M~8sa(Q#n|4Tsz(CJe9-z(ms!mD4#$juU~+62%w9co zw4pj+>l_WBaG`ExD&eB_aJ0deudKIro%f00iUm@Kk+rv%y>T3&CGSe&PH9+aeMH-a zx`egTHH#$lVqp;o@JAi%Yw%jh1Cg=Il?~$|RvO1otDgcsM*h7=1$y?z=HUZ8tJ1xp zE3mt*`sH#rLDN|5x<)|p{4c)aQh1pLX0R&i3|6y~D)M8GJ+V;DifGn{gzsoo=w#&@ z845v4g%2qx`xuPnf*6Z+oYUbt5CXGb!GtGOLpcu01e<$5{(`JtbRUH(s~ZfkL^rL` z82haBq)wDo=NHam1GV_AWfRt7&XN5Y0;~(b*w`KAx&T~sT98Q&rF&gPVz+ng)__Em zARm+{EzzCF_mV-=-b;nm0Et{j-MW@j*T43i@*tR3Y2i#70d%aW@aq($#+%hC-#%;8 zuTyaQ?$>`<^v+`o)hX|Wx0HjW)Rp5X2&J{h4EPU6_5{=soCUrE4{67h>+Ua+b2LLz zptoz8VL{m-;o{T3!zVVj)eLAbh!=xOhSUO>4%dT1S3W4`H>kdQ;5hZYfM+W#aO0}O zFCI!NW4!B_#~SiZkmzD~C@Kj?T%utgCs|_>*eJP&o+6%kVx5tU;zO_0K>cZrUwyrn z)=I9aRIZhJGR>P-I*H;D02jn#N@Hzy%fJ4+k4$7qrOrC71<S{_)#bx3ss6@*F-p(< zN~AQ4<@aq!`s&FtC0e246E<u4-N1GM2)BZEbYtAL9?(VT`TQyb|K3vkf%N`l*!~aw zOyo}GeIVXI0pO>RXc+c4mX6c(N%JywfmlIh$NG``l<w|V$k~*k^55Ly6JlX~)Slj@ zgF7L<&-p`ox)B7z&lQ&?iTu}5pnzKaf9F(%yE-~L$~FlIScM9)KAl|c<F;d5myr>v z0Ee42zg1VV1ntCaPfwDCoB8T>IBz%W_sYu@g8rGn2b>1*SvrUy;aabr>q|@d(@)QU zwrkteVL)Z8NG9tB(jvP5`PFgQHYaGSM^1?@%h}cd&U2MS-Fa+-fZp=HJ`C8hBJ!>M zW2kNW7kd9cbc(CDHPg;a?A5D(r%wNOy=mgjYo?~Axq-k$Uj76X*)>&l#U+Sg*l)RB zJ_N9DuL_c6!6J4wtt)JZO$Dq&iMp(mWJAz1X@pVA`swRe{?+Azzl6FGm9HDPFs|Y~ zRI3XgGDLxC#fcQG?uQVz5@?1vQM*nYz@)7hgK8WpqwbOX8FTdycK4MFGua<(KH&mt z=@}_&ug}z|O%RgP0uzMhPEH^fxcQ`S;dF!}$Tx8z+xVFPPdIYRT*y$5Q-bdmEf6{} zuS920Tl~?UA4w5nA(p?IO8eb}Ea6(9QX-`2GF>Dx!;}}z4|z-~0#5Gtl2@$cKwbgj zgH5Rh|LKXAGeD%p9PMKrj5^xA)foiV7A7&oClTkpt+{SmT3R~-J?!5@{rTU&-mI4e z`CbUGpPzQq<*RmtZrKwDW!1k2FkTtI!lngWN9ChHa7qUQ&8oZ$e8j1c6VCJ}ian9u zab5`@lfJeOSfL?AoH4C%io^q%C9eRzhc5!LB<T>m4?ub+oFM6(*yHtS4XT>wnumYo zL0BH+5+Fzh9EKm(bHUju;sLknvNSU|0d1^M0i5UUVE>-^6=)NU2`B@mg1^G)SeWSG zRGC&0z;t3eR2~+<C&g+eNo5|+o}Q)<y3v}g-9Asc^NSH&<<S!xtvbEz7W(V}RC3`l z$)?Du0;8S)YJ$%aVK7wY_Jbv06*~(x7(I8Ij&^_*`Yl8N0ymaaSM`h-dgc*Sl13Ak zBh`8i@xZ1sIe1HZ0L)#$WTfdTMGkd1x8AyUQ>E@M^pV3j;1tz}REW(6KG5`{?rW~2 zEXB3xpq8CuM35gn!jQ&IfTa0vj6Jv$B{>B4<OGPeF$F;{E!0!P22ZzyZwQ5WO%zC^ z`9ekmf_)CTBXU=p_$=6@NCDa&q5SiWe?P$(FU%LYu#vsmV9SRhVBtxFIu%BQEe#sT z)XX<J1i3t4KrLWjq3+Gbn5t>u&nJD>44g6uW?Edi`WGt+1gB?GqGcXvN(&q#EDcrV z4**|vJSAl(T-<;u@83WJ2??ptLoflRftx6QtwpKmow^SL^n)%M+(}~@k23oek+w75 z;CRz4ENxWP&A^22D9LN|rR5lj2|y*)=iM5)md6(b+Kz9Pmv|?)H|=n(>ZH+;TE9rf zwn?MIDo}&=n@Rw0)8`_hmmQI)+y_kiW94M+&;cX=JjB7ZoZDGBuOQ^36AV8RSdpTi zG@gu&mi=6{b5ko$h}GtU@Spj~Wz#De7l2gYAX^W6qRDD2GlQkck2g%NfR@0Ej>q1R zeMemZWj$+;R2IL1RR;EQaqV^Zps!-g1tq+Z{J3o`lv1;W4#RN0<8%V<c({dM6fU@g z!AxR2gnyA9tBi)}&06s#Ar?4mTeOW}C)>*op~wekORAwbYM@1Yu>!V5Pfr79cX$KS z;X7&ydt=W7#M%H2fI8YQ8tr+B3tOr7ax4RUb;kwmqZ?`CSNR}CDINmh+z9O!5V70f z!$4J8iX?zz9$W#57|qm%5~0Zu=l9{ZOR*_-JJsB*dTu-tZ3ljBM&DbQ=r(1Cy##|< zn|JzqLnkmmo>-2rKTcVy*!3@hrSO}=N$22ivF5VyNhaq>59l&{ymG~IluNmwTQYua zedlbVIuT&k(K;%STb}Ix1OtpjACeCyFuG-pfXG0K^n$_pOh!kBa$lIxh;kU>^w!$e zr7}s|;FX=nVDr<C1TF{{curw}7pkddj#k41z`uujZ7bdJ;-`~}U!(@n0JjAk(F@9R z7WW4a$=ure7iZx^JZaC*QU-G=e#GzH6u%FU?D+ecIFc-stSqKG_F77TBIWScvV(q= zcrpuWVVjl23hobB66RhmfKG$zg>OHnF#6LjTwtZuKx}ko_hb!fTuDeh6!Z+B0X~A= z8Q!)A^uW#oJF>n*)OEm`s*}cI;iQ5jFJjk~>s_JCVN3J^XWJlZY!fVt2?Lq-#k@fP z;u^Ci$)-l(ROKgo#~9bm!~n5>5F+*y&ploq+e$C}?hw((k@e|wL<a<e&_GyewD4>h zAYDcVxL{^mfeaqX#7FMm&SIB2Z7H%;-jEdWi@_2WVvtV}tjv@iqMiyKT9Bd-YpvTL zGG6!`?QI>D3k4}(*tqAene8~e%hImdXB4Z;9uJDBbPf-fV=7Dj1cA9<si&}fG0aj; zPq9M_YWMciIfYYYSek_B_BLm6Q9<R9y{FgKlKxu6fvM=?8?v~=W4wl#2hMvl#d!br zFpt(o&yQzDwaTmk*SR5x<G@_nXWg*R7Zf$CE#KPY(ZC-+qB$8d-j7{o79gZI><c#X z^!JX8?Ztp}C33FR8ocsPqcc$(?t@9EW5i>j6-IS4d<KevbODWp=H7;qchBSolosn~ zWfry~nPP39#La~^7qr?faE;_o%k5Z+0P}se{&K`9k|g<Y=u-$do7#lCO5o?2xXcU( zPIWCp4Z;$xs}yAVr6<T%qvMfsG;iT@D_=tE&Km{`xuiEI(n-q7f<!bXTg#4!_#iZ2 z=ZLW{o8>(jjv(!lCMkJDSXSjy>@f6qZdpVR#r-=K#*D;JcsA*~mGFsQD&}gxe)(LX z-Zj`2slTe!w9~FGxd-9*))hoPsCrY+at#_N%Q55YHZQ6sQvUs0|1Tu@D)jjUS01GO z32!C&-@#6NDyyP2(5-(<)qqoP|Mup@JVNIelI@GrMFp-Pg&V=>wMirZD*Q*=k2e1P z3_`JyGOzjcU(_)~=L;-tll*L3=Hvn?X99N5**BE>3RS?rD{x=w?AA%ZhRXPTc7T*X zf&aeLc$~VYZJf4W?kZTneX;I0UHu^^=O`H{F0o)gzsyw&!MSWOCO<+fgg|@iWo`=C z=4+sAm%#mPr${I+e*H}dw?6TrK)@N$2C4g3wL0e`D+S78A_7UOe@Y_T2M6MjjbQ!% zzbGWX81m6G*|%Ykp`mdzYZU?iW`TDfu0~xve;(Y3|LGgpeK>Hs=?^ab)%n?oIcUHV z5O1aJz~B1@7A6KuELCFc`)P;aF(*KEcIyM%g#3rdOuFOpJ>Py+^94Jb+`a~Q!j3rC z+&2Jz<SanQfg#MSAxCIV@+_SDD3lThB!)cA_|BfL3t;BaNG?GG6k1@|?mK7LVCseJ zblthCyZWgFB<j>Z3<M3CQ~4#qZV*2JNAYNOrk1t=H>I`iItPNxy>@^rUV>%5(i)64 zdT7j_U=CKkS%1{Zl8FCNEM4P2yb>6}wq<UC$T$$;l;rJWQaCUD2lgJl1ZbEt43u`@ z2CX9<(yrOhJOJax)j}uh0$=k4$gevCK(kFCaCgox?&H=E14#KI7btai0jZh}U|6o{ z@k9-82M?7c(6%Q+oByR=OgTL|okw8bt^n~Nt{nnH@f%@5$KfETuGk02Aa6*K6YK23 zc-nHIH8_psc_=dm^^gbY{-Gkfo`awlJooAlI~k9M+iB|>h}6Ll=pcGAU_l^--4Y|Z z<xj1=DRsOYx-&lGqK46X0H@jmaIudS)(jf7N-rkcYV$~Zu4xb0T%%o!mi@v5i1$63 zTZ<g6_+TP58v8i(0hEFgz%TP2o?8U{zYfGBtjhHy$0$sdr|~9#NDnXAe!%$5TlbQy zXe`*ri|VdaHFNSBh?DVoWFW|Sux{fR8F(75_kc{q`FRKig6zQ2VXW3<hRTgk_lv+R zAGHB=4T_MEU~URmC6XZ~fz%5?>o4&h*cgIr<p>PGWxdTa4+{O$WYLtmuTOokj{?|+ zRhb?bYxM%b?u9;wu+(HA(n6sdE&vUFBRb1hc^0*u*8CYZZitnght&Ozqt1fiW_#>) zYt8sVq_#&eJhd&{3jn7v6rg?iZ)G+)sC<UngHkBItXU2oI0Mitf=Xh7%`uhjv`cs( zg|dmvry}@ouu9c@Fw>dH3Ioj!0yXVw*97Mk-fC`?#QB9tUO96x(ceKgO<Yt63Tm4V z;sWqG>Ml&fOF_?b!|&($^0#uBinAFT(0b3q25}(GMe_y*NQs#tz2bOETgoaMP?HkI z14sY07)+F;8HmAE;6VI#0ZP9wBYG~HEoo`3%$s{nG=?M~kKKn(IqQOnt9Bp}zp{hu z0|7C5Zk3=FnlBmGS6aISCdsCCHt*Fv4=EeVh4CQOrFeLl%U)(XB?jEGHAq@1G@QYb zfY~Nl_Y)~rIi=f`n12KI=UWbz4nS1lseo_ykxi4uQsaFtBp!r0&;tagfjA-W4sQQ) zth0DHwapa<8PkJoMf$PgC@|C4720ED7Pa9~r22q{y7Uz2BqqQJKnC-JkrL+V+VElU z>f!E!43iO7L>>KrX<|Hu3Zb`#dSpY!1G8^o*eCW}@Uis(0HPcUAB}Syx&|Qw*$P-* z#LrbS_M%`&{d(?>qBC|-F5Pc6ywLgx;047Og~)A%durNgb!JOD$7FrRQ=D{nltdU# zywm>)_1SyO3qFAjoCOJIPw8KlGU#{21T$mJi2zBAfemIv8ZaQfZmy3t{uOJ>7N^!0 zJB$aZh}0_4t%?z2bw(-rQxSEuC%?T=^02WCrZ3%ui3%vQ_tvgBMro#zl(%wI29vDH zluor`12}+PbrzX39R5_j>KysiCyt)mY6TRE0(MZ!Q0&fj0$4OyKcpV`0|UhuJf~m| zr6M2!<b|;gXs5rgqH7A`cwjFMOTR^Kv~11NF#O#`xzp>XK;mG42S%hE>)!Sj)=L06 zcVo-ULGC<>goCD#b8Qs5g{=UOJ%<bhy+RpivFEF}R)$1zpM{jRq2TQoGTapi^WO^` zrTk?+o&KX}C|W)dmx<`k0d9eEaupiMo41-eR_&u0?bl(VJ}Sr9nlIniFu4fy5I=Zm zJ&4R{o&bQ*KvoxKFyJ_jQp{j=<)Kws*$rII=SLgU0r#GzmaZF*W=~8IS7^jJ>y?u# zM`}yng&`ohCLoaunRJd3xpP(LR=`sdiyVz`5iHm_00y3~Y9BmhhP}9^V1@!R1fL%R zt{m>J;Yz8Rxd?`gy!g8UxwKuzZ~jhQ`TLJ5nK*hWI~WEZ_r|i#L=5usmTpSJDRu5M z`{EmhkXw@?>{$k3TbfxBSbMs+wW5a<o+5YBQ?auY^!?OicH4FscwWK?LY+V&v!XX+ zptcf|Z;M5&_z&zTtro5;s0kHqD$R=^Z6il8*GwXR49^>mE43URYiqd8+dAS{hIuNq z1Xhw~U@y>z*M{}Ic}rCYkXY+8d~#SK<kp|BSgH`cxkNI#Y$Y}}#TMZNSFt@9N>a}a zwaZghR8OS1U3cc{c;~Q59sai7LBsn3ylpXLPaPtf^SfZ4{^fD_<%0On;V=JHE&o?~ zd{Jp>I;eJCwk%+Hm=37}owNzqTOt+e*)@H}-UF)z)#w*tcflk<OO=n8-1l9Wr3j*t zoo@q$C?LaX;b%k2Dv&x-T91X<2`^T|A(H`w6#swmO8j?lbI|$g_&14t!5wd60I(J~ NYk1*Q?#UYu{|Agtq~HJm literal 0 HcmV?d00001 diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index 9c2d1168..da085de9 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -44,6 +44,8 @@ DBM Version for `1.17.0` is development! --- - Refactoring software homepage <br /> +- Add clickhouse datasource docs <br /> +- Add presto & trino datasource docs <br /> #### Bug diff --git a/docs/docs/reference/management/datasource/presto_trino.md b/docs/docs/reference/management/datasource/presto_trino.md new file mode 100644 index 00000000..9751da34 --- /dev/null +++ b/docs/docs/reference/management/datasource/presto_trino.md @@ -0,0 +1,58 @@ +--- +template: overrides/main.html +--- + +!!! note "Presto & Trino" + + It is mainly used to describe how the software builds the Presto & Trino data source for subsequent operations. + +!!! warning "System requirements" + + \>= `1.17.0` + +### Supported Versions + +--- + +| Version | Tested? | +|-----------|---------------------------------------------| +| `Presto` | :material-checkbox-marked-circle:{.success} | +| `Trino` | :material-checkbox-marked-circle:{.success} | + +!!! note "Supported versions" + + Most versions have been tested, please submit issues for non-adapted versions. + +### Created a Source + +--- + +After entering the data source management page, click the Add data source button. + +![img.png](../../../assets/images/others/management/datasource/datasource_type.png) + +Select the ClickHouse icon in the `Basic` type (Presto is the second, Trino is the third). + +After selecting the type, click the `Next` button at the bottom to configure the relevant information. + +![img.png](../../../assets/images/others/management/datasource/presto_trino/img.png) + +!!! note "Supported protocols" + + - [x] `HTTP` + +#### HTTP Protocol + +--- + +!!! note "HTTP Protocol" + + Use the HTTP interface provided by Presto & Trino to connect to the service. + +| Parameter | Description | Required | Unique | Default | +|-------------|-----------------------------------------------------------------------------------------------------|----------|--------|---------| +| `Alias` | The alias of the data source, which will be displayed later in the selected data source on the page | Yes | Yes | | +| `Host` | The host of the Presto & Trino server | Yes | Yes | | +| `Port` | The port of the Presto & Trino server | Yes | Yes | | +| `User Name` | The user name of the Presto & Trino server | Yes | No | | +| `Password` | The password of the Presto & Trino server | Yes | No | | diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index c10d91af..f55de961 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -156,6 +156,8 @@ nav: - Management: - Datasource: - ClickHouse: reference/management/datasource/clickhouse.md + - Presto: reference/management/datasource/presto_trino.md + - Trino: reference/management/datasource/presto_trino.md - Monitor: - Processor: reference/monitor/monitor-processor.md - Connection: reference/monitor/monitor_connection.md diff --git a/electron-builder.yml b/electron-builder.yml index a53473e3..ff22e529 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -20,6 +20,8 @@ releaseInfo: --- - Refactoring software homepage + - Add clickhouse datasource docs + - Add presto & trino datasource docs #### Optimize From 55dd26492417ca53ab88eb3c8f4598fd2ab74491 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Fri, 27 May 2022 11:24:17 +0800 Subject: [PATCH 15/17] [Enhancement] Support trino and presto for monitor --> slow query #158 --- .../development/version/1.17.0-development.md | 1 + electron-builder.yml | 5 ++- .../monitor/query/monitor.query.component.ts | 8 +--- src/renderer/config/base.config.ts | 1 + src/renderer/config/clickhouse.config.ts | 15 +++++++ src/renderer/config/presto.config.ts | 12 ++++++ .../services/monitor/monitor.service.ts | 42 +++++-------------- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index da085de9..dfa2d479 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -21,6 +21,7 @@ DBM Version for `1.17.0` is development! ![img_3.png](../../assets/images/versions/1.17.0/img_3.png) <br /> - Support trino and presto for monitor --> processors <br /> - Support trino and presto for monitor --> connection <br /> +- Support trino and presto for monitor --> slow query <br /> #### UI diff --git a/electron-builder.yml b/electron-builder.yml index ff22e529..1f94bacc 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -12,8 +12,9 @@ releaseInfo: - Support metadata management to filter the table - Support trino and presto for query - - Support trino and presto for monitor --> processors <br /> - - Support trino and presto for monitor --> connection <br /> + - Support trino and presto for monitor --> processors + - Support trino and presto for monitor --> connection + - Support trino and presto for monitor --> slow query #### Docs diff --git a/src/renderer/app/pages/monitor/query/monitor.query.component.ts b/src/renderer/app/pages/monitor/query/monitor.query.component.ts index fe92c685..2d7a74ff 100644 --- a/src/renderer/app/pages/monitor/query/monitor.query.component.ts +++ b/src/renderer/app/pages/monitor/query/monitor.query.component.ts @@ -7,7 +7,6 @@ import { ResponseDataModel } from '@renderer/model/response.model'; import { DatasourceService } from '@renderer/services/management/datasource.service'; import { MonitorService } from '@renderer/services/monitor/monitor.service'; import { NzMessageService } from 'ng-zorro-antd/message'; -import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-query', @@ -28,12 +27,7 @@ export class MonitorQueryComponent extends BaseComponent { private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response.map(item => { - if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { - item.status = false; - } - return item; - }); + this.dataSources = response; }); } diff --git a/src/renderer/config/base.config.ts b/src/renderer/config/base.config.ts index 4505e617..2cb99609 100644 --- a/src/renderer/config/base.config.ts +++ b/src/renderer/config/base.config.ts @@ -2,6 +2,7 @@ export interface BaseConfig { version: string; processesFetchAll: string; connectionFetchAll: string; + slowQueryFetchAll: string; diskUsedRatio: string; databaseDiskUsedRatio: string; tableDiskUsedRatio: string; diff --git a/src/renderer/config/clickhouse.config.ts b/src/renderer/config/clickhouse.config.ts index dab46830..dee2912f 100644 --- a/src/renderer/config/clickhouse.config.ts +++ b/src/renderer/config/clickhouse.config.ts @@ -21,6 +21,21 @@ FROM system.processes WHERE round(elapsed, 1) > 0 + `; + slowQueryFetchAll = ` +SELECT + user, client_hostname AS host, + client_name AS hash, query AS query, + query_start_time AS time, query_duration_ms AS elapsed, + round(memory_usage / 1048576) AS memoryUsage, + result_rows AS rows, result_bytes / 1048576 AS bytes, + read_rows AS readRows, round(read_bytes / 1048576) AS bytesRead, + written_rows AS writtenRows, round(written_bytes / 1048576) AS bytesWritten +FROM system.query_log +WHERE type = 2 +AND query_duration_ms >= {0} +ORDER BY query_duration_ms DESC +LIMIT 100 `; connectionFetchAll = ` SELECT diff --git a/src/renderer/config/presto.config.ts b/src/renderer/config/presto.config.ts index 84926de6..9d108a95 100644 --- a/src/renderer/config/presto.config.ts +++ b/src/renderer/config/presto.config.ts @@ -33,6 +33,18 @@ WHERE state = 'RUNNING' GROUP BY source ORDER BY source DESC `; + slowQueryFetchAll = ` +SELECT + query_id AS id, now() AS time, query AS query, '0' AS rows, + (analysis_time_ms + planning_time_ms + queued_time_ms) AS elapsed, + '0' AS bytes, '0' AS memoryUsage, + '0' AS bytesRead, '0' AS bytesWritten, + '' AS hash, '' AS host +FROM system.runtime.queries +WHERE (analysis_time_ms + planning_time_ms + queued_time_ms) >= {0} +ORDER BY (analysis_time_ms + planning_time_ms + queued_time_ms) DESC +LIMIT 100 + `; columnDiskUsedRatio: string; columnItems: string; databaseDiskUsedRatio: string; diff --git a/src/renderer/services/monitor/monitor.service.ts b/src/renderer/services/monitor/monitor.service.ts index d64d4399..43badfbc 100644 --- a/src/renderer/services/monitor/monitor.service.ts +++ b/src/renderer/services/monitor/monitor.service.ts @@ -1,13 +1,13 @@ -import {BaseService} from '@renderer/services/base.service'; -import {RequestModel} from '@renderer/model/request.model'; -import {ResponseModel} from '@renderer/model/response.model'; -import {Injectable} from '@angular/core'; -import {HttpService} from '@renderer/services/http.service'; -import {StringUtils} from '@renderer/utils/string.utils'; -import {SshService} from '@renderer/services/ssh.service'; -import {BasicService} from '@renderer/services/system/basic.service'; -import {ForwardService} from '@renderer/services/forward.service'; -import {FactoryService} from "@renderer/services/factory.service"; +import { BaseService } from '@renderer/services/base.service'; +import { RequestModel } from '@renderer/model/request.model'; +import { ResponseModel } from '@renderer/model/response.model'; +import { Injectable } from '@angular/core'; +import { HttpService } from '@renderer/services/http.service'; +import { StringUtils } from '@renderer/utils/string.utils'; +import { SshService } from '@renderer/services/ssh.service'; +import { BasicService } from '@renderer/services/system/basic.service'; +import { ForwardService } from '@renderer/services/forward.service'; +import { FactoryService } from "@renderer/services/factory.service"; import { PrestoService } from "@renderer/services/presto.service"; @Injectable() @@ -30,27 +30,7 @@ export class MonitorService extends ForwardService implements BaseService { } getSlowQuery(request: RequestModel, threshold: number): Promise<ResponseModel> { - const sql = StringUtils.format(` - SELECT - user, - client_hostname AS host, - client_name AS hash, - query AS query, - query_start_time AS time, - query_duration_ms AS elapsed, - round(memory_usage / 1048576) AS memoryUsage, - result_rows AS rows, - result_bytes / 1048576 AS bytes, - read_rows AS readRows, - round(read_bytes / 1048576) AS bytesRead, - written_rows AS writtenRows, - round(written_bytes / 1048576) AS bytesWritten - FROM system.query_log - WHERE type = 2 - AND query_duration_ms >= {0} - ORDER BY query_duration_ms DESC - LIMIT 100 - `, [threshold]); + const sql = StringUtils.format(this.factoryService.forward(request.config.type).slowQueryFetchAll, [threshold]); return this.getResponse(request, sql); } From 6c704c7b5ff6434c1569555fb6e035c59750feb7 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Fri, 27 May 2022 14:28:24 +0800 Subject: [PATCH 16/17] [Bug] Fix the exception that the data source is not selected in the track, the Track list can be selected --- docs/docs/development/version/1.17.0-development.md | 2 ++ electron-builder.yml | 2 ++ src/renderer/app/pages/tools/track/track.component.html | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index dfa2d479..ca257b7a 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -52,6 +52,8 @@ DBM Version for `1.17.0` is development! --- +- Fix the exception that the data source is not selected in the track, the Track list can be selected <br /> + #### Contributors (In no particular order) --- diff --git a/electron-builder.yml b/electron-builder.yml index 1f94bacc..f32eb3a9 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -35,6 +35,8 @@ releaseInfo: --- + - Fix the exception that the data source is not selected in the track, the Track list can be selected + #### UI --- diff --git a/src/renderer/app/pages/tools/track/track.component.html b/src/renderer/app/pages/tools/track/track.component.html index f1b0a931..b1c1b4c5 100644 --- a/src/renderer/app/pages/tools/track/track.component.html +++ b/src/renderer/app/pages/tools/track/track.component.html @@ -52,7 +52,7 @@ nzValue="{{detail.alias}}" nzLabel="{{detail.alias}}"></nz-option> </nz-select> {{'common.track'|translate}}&nbsp; - <nz-select [(ngModel)]="trackId" nzAllowClear nzShowSearch nzServerSearch nzSize="small" + <nz-select [(ngModel)]="trackId" [disabled]="!datasource" nzAllowClear nzShowSearch nzServerSearch nzSize="small" style="width: 300px;" (nzOnSearch)="handlerSearch($event)"> <ng-container *ngFor="let o of tracks"> <nz-option *ngIf="!loading.button" [nzValue]="o.value" [nzLabel]="o.value"></nz-option> From 2cf37026a338b6fa88d9d4bc5c97cbf9827dc6d5 Mon Sep 17 00:00:00 2001 From: qianmoQ <shicheng@ttxit.com> Date: Sat, 28 May 2022 21:33:06 +0800 Subject: [PATCH 17/17] [Release] Release 1.17.0 --- .../development/version/1.17.0-development.md | 26 -------- docs/docs/release/1.17.0-20220529.md | 59 +++++++++++++++++++ docs/mkdocs.yml | 3 +- package.json | 2 +- 4 files changed, 62 insertions(+), 28 deletions(-) create mode 100644 docs/docs/release/1.17.0-20220529.md diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index ca257b7a..0982565f 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -13,48 +13,22 @@ DBM Version for `1.17.0` is development! --- -- Support metadata management to filter the table <br /> -![img.png](../../assets/images/versions/1.17.0/img.png) <br /> -![img_1.png](../../assets/images/versions/1.17.0/img_1.png) <br /> -![img_2.png](../../assets/images/versions/1.17.0/img_2.png) <br /> -- Support trino and presto for query <br /> -![img_3.png](../../assets/images/versions/1.17.0/img_3.png) <br /> -- Support trino and presto for monitor --> processors <br /> -- Support trino and presto for monitor --> connection <br /> -- Support trino and presto for monitor --> slow query <br /> - #### UI --- -- Add multiple editor themes <br /> -- Query the list of data sources on the page, support the display of logo <br /> -![img_6.png](../../assets/images/versions/1.17.0/img_6.png) <br /> - #### Optimize ---- -- Optimize project description and introduction <br /> -- Optimize the homepage is not available & does not support data source charts <br /> -![img_4.png](../../assets/images/versions/1.17.0/img_4.png) <br /> -![img_5.png](../../assets/images/versions/1.17.0/img_5.png) <br /> - #### Docs --- -- Refactoring software homepage <br /> -- Add clickhouse datasource docs <br /> -- Add presto & trino datasource docs <br /> - #### Bug --- -- Fix the exception that the data source is not selected in the track, the Track list can be selected <br /> - -#### Contributors (In no particular order) --- diff --git a/docs/docs/release/1.17.0-20220529.md b/docs/docs/release/1.17.0-20220529.md new file mode 100644 index 00000000..43baeed4 --- /dev/null +++ b/docs/docs/release/1.17.0-20220529.md @@ -0,0 +1,59 @@ +--- +template: overrides/main.html +icon: material/gesture-tap-button +--- + +DBM Version for `1.17.0` is released! + +Release Time: `2022-05-29` + +#### Enhancement + +--- + +- Support metadata management to filter the table <br /> +![img.png](../assets/images/versions/1.17.0/img.png) <br /> +![img_1.png](../assets/images/versions/1.17.0/img_1.png) <br /> +![img_2.png](../assets/images/versions/1.17.0/img_2.png) <br /> +- Support trino and presto for query <br /> +![img_3.png](../assets/images/versions/1.17.0/img_3.png) <br /> +- Support trino and presto for monitor --> processors <br /> +- Support trino and presto for monitor --> connection <br /> +- Support trino and presto for monitor --> slow query <br /> + +#### UI + +--- + +- Add multiple editor themes <br /> +- Query the list of data sources on the page, support the display of logo <br /> +![img_6.png](../assets/images/versions/1.17.0/img_6.png) <br /> + +#### Optimize + +---- + +- Optimize project description and introduction <br /> +- Optimize the homepage is not available & does not support data source charts <br /> +![img_4.png](../assets/images/versions/1.17.0/img_4.png) <br /> +![img_5.png](../assets/images/versions/1.17.0/img_5.png) <br /> + +#### Docs + +--- + +- Refactoring software homepage <br /> +- Add clickhouse datasource docs <br /> +- Add presto & trino datasource docs <br /> + +#### Bug + +--- + +- Fix the exception that the data source is not selected in the track, the Track list can be selected <br /> + +#### Contributors (In no particular order) + +--- + +- @qianmoQ diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index f55de961..c72d1797 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -164,7 +164,8 @@ nav: - Mutations: reference/monitor/monitor_mutations.md - Query: reference/monitor/monitor_query.md - Release Note: - - 1.16.0 (latest): release/1.16.0-20220513.md + - 1.17.0 (latest): release/1.17.0-20220529.md + - 1.16.0: release/1.16.0-20220513.md - 1.15.0: release/1.15.0-20220425.md - 1.14.0: release/1.14.0-20220410.md - 1.13.0: release/1.13.0-20220329.md diff --git a/package.json b/package.json index 716cb631..3006ea58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dbm", - "version": "1.17.0-SNAPSHOT", + "version": "1.17.0", "author": "qianmoQ <shicheng@ttxit.com>", "description": "ClickHouse DataBase GUI", "github": "https://github.com/EdurtIO/dbm.git",