diff --git a/.dockerignore b/.dockerignore index bdaff1a0ffd..b93d3959abb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.editorconfig b/.editorconfig index 84c3600b4ca..fa036d15fd9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.eslintignore b/.eslintignore index 2a886f97425..349853159c2 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c2819d311ce..432544f21ad 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.github/assets/sponsors/sponsor-centara.png b/.github/assets/sponsors/sponsor-centara.png new file mode 100644 index 00000000000..309f9c946c5 Binary files /dev/null and b/.github/assets/sponsors/sponsor-centara.png differ diff --git a/.github/assets/sponsors/sponsor-intercomestibles.png b/.github/assets/sponsors/sponsor-intercomestibles.png new file mode 100644 index 00000000000..02c5c9b70fc Binary files /dev/null and b/.github/assets/sponsors/sponsor-intercomestibles.png differ diff --git a/.github/assets/sponsors/sponsor-logfire.png b/.github/assets/sponsors/sponsor-logfire.png new file mode 100644 index 00000000000..dee0faba1ca Binary files /dev/null and b/.github/assets/sponsors/sponsor-logfire.png differ diff --git a/.github/assets/sponsors/sponsor-octoperf.png b/.github/assets/sponsors/sponsor-octoperf.png new file mode 100644 index 00000000000..89b9eeaf4be Binary files /dev/null and b/.github/assets/sponsors/sponsor-octoperf.png differ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fe7664bdfc0..7b92675474a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -25,7 +25,7 @@ updates: directory: "/" labels: [] schedule: - interval: weekly + interval: monthly time: "04:00" - package-ecosystem: pip # We only want to bump versions of packages in case of security updates, as @@ -34,12 +34,12 @@ updates: directory: "/" labels: [] schedule: - interval: weekly + interval: monthly time: "04:00" - package-ecosystem: github-actions open-pull-requests-limit: 10 directory: "/" labels: [] schedule: - interval: weekly + interval: monthly time: "04:00" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 483881602e9..0afde75715e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index bd712aadbf7..447d72b040c 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.gitignore b/.gitignore index 04f3c0ecc76..14b86c7845d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/.stylelintignore b/.stylelintignore index 2ddc9dae475..dfbfbf3413e 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/CHANGELOG b/CHANGELOG index 3d9cfcc081e..d2b61439ec6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,147 @@ +mkdocs-material-9.6.15 (2025-07-01) + + * Updated Mongolian translations + * Improved semantic markup of "edit this page" button + * Improved info plugin virtual environment resolution + * Fixed #8291: Large font size setting throws of breakpoints in JavaScript + +mkdocs-material-9.6.14 (2025-05-13) + + * Fixed #8215: Social plugin crashes when CairoSVG is updated to 2.8 + +mkdocs-material-9.6.13 (2025-05-10) + + * Fixed #8204: Annotations showing list markers in print view + * Fixed #8153: Improve style of cardinality symbols in Mermaid.js ER diagrams + +mkdocs-material-9.6.12 (2025-04-17) + + * Fixed #8158: Flip footnote back reference icon for right-to-left languages + +mkdocs-material-9.6.11 (2025-04-01) + + * Updated Docker image to latest Alpine Linux + * Bump required Jinja version to 3.1 + * Fixed #8133: Jinja filter `items` not available (9.6.10 regression) + * Fixed #8128: Search plugin not entirely disabled via enabled setting + +mkdocs-material-9.6.10 (2025-03-30) + + This version is a pure refactoring release, and does not contain new features + or bug fixes. It strives to improve the compatibility of our templates with + alternative Jinja-like template engines that we're currently exploring, + including minijinja. + + Additionally, it replaces several instances of Python function invocations + with idiomatic use of template filters. All instances where variables have + been mutated inside templates have been replaced. Most changes have been made + in partials, and only a few in blocks, and all of them are fully backward + compatible, so no changes to overrides are necessary. + + Note that this release does not replace the Jinja template engine with + minijinja. However, our templates are now 99% compatible with minijinja, + which means we can explore alternative Jinja-compatible implementations. + Additionally, immutability and removal of almost all Python function + invocations means much more idiomatic templating. + +mkdocs-material-9.6.9 (2025-03-17) + + * Updated Serbo-Croatian translations + * Fixed #8086: Custom SVG icons containing hashes break rendering + * Fixed #8067: Drawer has gap on right side in Firefox on some OSs + +mkdocs-material-9.6.8+insiders-4.53.16 (2025-03-13) + + * Fixed #8019: Tooltips have precedence over instant previews + +mkdocs-material-9.6.8 (2025-03-13) + + * Added Welsh translations + * Fixed #8076: Privacy plugin crashes if HTTP download fails + +mkdocs-material-9.6.7 (2025-03-03) + + * Fixed #8056: Error in backrefs implementation (9.6.6 regression) + * Fixed #8054: Unescaped quotes in ARIA labels of table of contents + +mkdocs-material-9.6.6 (2025-03-01) + + * Fixed #8040: Privacy plugin not replacing exteral assets (9.6.5 regression) + * Fixed #8031: Replace unmaintained regex package in search plugin + +mkdocs-material-9.6.5 (2025-02-20) + + * Fixed #8016: Tags listing not showing when when file name has spaces + * Fixed #8012: Privacy plugin crashes if HTTP download fails + +mkdocs-material-9.6.4 (2025-02-12) + + * Fixed #7985: Blog content sometimes not stretching to full width + * Fixed #7978: Navigation rendering bug in Safari 18.3 + +mkdocs-material-9.6.3 (2025-02-07) + + * Fixed rendering of arrow heads in Mermaid.js class diagrams + * Fixed #7960: Tags plugin crashes on numeric metadata titles + +mkdocs-material-9.6.2 (2025-02-03) + + * Fixed #7955: Excessively long words don't break on narrow screens + * Fixed #7947: Scope setting interferes with outdated version banner + +mkdocs-material-9.6.1 (2025-01-31) + + * Fixed #7943: Tags plugin crashing due to merge error + +mkdocs-material-9.6.0 (2025-01-31) + + * Added meta plugin + * Rewrite of the tags plugin + * Added support for allow lists in tags plugin + * Added support for and custom sorting in tags plugin + * Added support for related links in blog plugin + * Added support for custom index pages in blog plugin + * Added support for navigation subtitles + * Fixed #7924: Anchors might require two clicks when using instant navigation + +mkdocs-material-9.5.50 (2025-01-18) + + * Fixed #7913: Social plugin renders attribute lists in page title + +mkdocs-material-9.5.49+insiders-4.53.15 (2025-01-15) + + * Fixed #7896: Scoped tags listings not rendering in subsections + +mkdocs-material-9.5.49 (2024-12-16) + + * Adjusted title color in dark mode for all supported Mermaid.js diagrams + * Fixed #7803: Privacy plugin crashes on generated files + * Fixed #7781: Mermaid.js flow chart title not visible in dark mode + +mkdocs-material-9.5.48 (2024-12-08) + + * Fixed #7774: Disabling social cards doesn't work + +mkdocs-material-9.5.47 (2024-12-01) + + * Fixed #7750: Numeric tags break search + * Fixed #7748: Blog plugin breaks when using future drafts (9.5.45 regression) + +mkdocs-material-9.5.46 (2024-11-25) + + * Added support for removing preload hints in privacy plugin + * Fixed #7734: Code blocks in h5 headlines are uppercased + * Fixed #7725: Blog plugin crashing on missing timezone (9.5.45 regression) + +mkdocs-material-9.5.45 (2024-11-20) + + * Reduced size of Docker image through multi-stage build + * Fixed #7708: Blog plugin crashing on YAML dates with timezones + +mkdocs-material-9.5.44 (2024-11-05) + + * Fixed #7672: Font CSS 404's when using privacy plugin (9.5.43 regression) + mkdocs-material-9.5.43 (2024-10-31) * Added support for external images in SVGs in privacy plugin diff --git a/Dockerfile b/Dockerfile index b042e3802db..f0d0fb451c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -18,7 +18,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -FROM python:3.11-alpine3.19 +FROM python:3.11-alpine3.21 AS build # Build-time flags ARG WITH_PLUGINS=true @@ -91,6 +91,12 @@ RUN \ && \ git config --system --add safe.directory /site +# From empty image +FROM scratch + +# Copy all from build +COPY --from=build / / + # Set working directory WORKDIR /docs diff --git a/LICENSE b/LICENSE index fb988d094a1..6b9d8b7ff84 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2024 Martin Donath +Copyright (c) 2016-2025 Martin Donath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/README.md b/README.md index e880dbbca10..b7335636bed 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@

Build - - - - @@ -192,6 +180,18 @@ + + + +

 

@@ -221,17 +221,17 @@ Don't let your users wait – get incredible value with a small footprint by usi one of the fastest themes available with excellent performance, yielding optimal search engine rankings and happy users that return. -### Built for everyone +### Maintain ownership -Make accessibility a priority – users can navigate your documentation with touch -devices, keyboards, and screen readers. Semantic markup ensures that your -documentation works for everyone. +Own your documentation's complete sources and outputs, guaranteeing both +integrity and security – no need to entrust the backbone of your product +knowledge to third-party platforms. Retain full control. ### Open Source -Trust 20,000+ users – choose a mature and actively maintained solution built -with state-of-the-art Open Source technologies. Keep ownership of your content -without fear of vendor lock-in. Licensed under MIT. +You're in good company – choose a mature and actively maintained solution built +with state-of-the-art Open Source technologies, trusted by more than 50,000 +individuals and organizations. Licensed under MIT. ## Quick start @@ -262,7 +262,6 @@ For detailed installation instructions, configuration options, and a demo, visit [AWS](https://aws.github.io/copilot-cli/), [Bloomberg](https://bloomberg.github.io/selekt/), [CERN](http://abpcomputing.web.cern.ch/), -[CloudFlare](https://cloudflare.github.io/itty-router-openapi/), [Datadog](https://datadoghq.dev/integrations-core/), [Google](https://google.github.io/accompanist/), [Harvard](https://informatics.fas.harvard.edu/), @@ -275,6 +274,7 @@ For detailed installation instructions, configuration options, and a demo, visit [Microsoft](https://microsoft.github.io/code-with-engineering-playbook/), [Mozilla](https://mozillafoundation.github.io/engineering-handbook/), [Netflix](https://netflix.github.io/titus/), +[OpenAI](https://openai.github.io/openai-agents-python/), [Red Hat](https://ansible.readthedocs.io/projects/lint/), [Roboflow](https://inference.roboflow.com/), [Salesforce](https://policy-sentry.readthedocs.io/), @@ -287,38 +287,54 @@ For detailed installation instructions, configuration options, and a demo, visit ### ... and successful Open Source projects [Amp](https://amp.rs/docs/), +[Apache Iceberg](https://iceberg.apache.org/), [Arduino](https://arduino.github.io/arduino-cli/), +[Asahi Linux](https://asahilinux.org/docs/), [Auto-GPT](https://docs.agpt.co/), [AutoKeras](https://autokeras.com/), [BFE](https://www.bfe-networks.net/), [CentOS](https://docs.infra.centos.org/), [Crystal](https://crystal-lang.org/reference/), [eBPF](https://ebpf-go.dev/), +[ejabberd](https://docs.ejabberd.im/), [Electron](https://www.electron.build/), [FastAPI](https://fastapi.tiangolo.com/), +[FlatBuffers](https://flatbuffers.dev/), +[{fmt}](https://fmt.dev/), [Freqtrade](https://www.freqtrade.io/en/stable/), [GoReleaser](https://goreleaser.com/), +[GraphRAG](https://microsoft.github.io/graphrag/), +[Headscale](https://headscale.net/), [HedgeDoc](https://docs.hedgedoc.org/), [Hummingbot](https://hummingbot.org/), [Knative](https://knative.dev/docs/), [Kubernetes](https://kops.sigs.k8s.io/), [kSQL](https://docs.ksqldb.io/), +[LeakCanary](https://square.github.io/leakcanary/), +[LlamaIndex](https://docs.llamaindex.ai/), [NetBox](https://netboxlabs.com/docs/netbox/en/stable/), [Nokogiri](https://nokogiri.org/), +[OpenAI](https://openai.github.io/openai-agents-python/), [OpenFaaS](https://docs.openfaas.com/), +[OpenSSL](https://docs.openssl.org/), [Orchard Core](https://docs.orchardcore.net/en/latest/), [Percona](https://docs.percona.com/percona-monitoring-and-management/), [Pi-Hole](https://docs.pi-hole.net/), +[Polars](https://docs.pola.rs/), [Pydantic](https://pydantic-docs.helpmanual.io/), [PyPI](https://docs.pypi.org/), +[Quivr](https://core.quivr.com/), [Renovate](https://docs.renovatebot.com/), [RetroPie](https://retropie.org.uk/docs/), +[Ruff](https://docs.astral.sh/ruff/), [Supervision](https://supervision.roboflow.com/latest/), +[Textual](https://textual.textualize.io/), [Traefik](https://docs.traefik.io/), [Trivy](https://aquasecurity.github.io/trivy/), [Typer](https://typer.tiangolo.com/), [tinygrad](https://docs.tinygrad.org/), [Ultralytics](https://docs.ultralytics.com/), +[UV](https://docs.astral.sh/uv/), [Vapor](https://docs.vapor.codes/), [WebKit](https://docs.webkit.org/), [WTF](https://wtfutil.com/), @@ -328,7 +344,7 @@ For detailed installation instructions, configuration options, and a demo, visit **MIT License** -Copyright (c) 2016-2024 Martin Donath +Copyright (c) 2016-2025 Martin Donath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/docs/blog/posts/transforming-material-for-mkdocs.md b/docs/blog/posts/transforming-material-for-mkdocs.md index d1df1935b65..3ce9a995d95 100644 --- a/docs/blog/posts/transforming-material-for-mkdocs.md +++ b/docs/blog/posts/transforming-material-for-mkdocs.md @@ -186,7 +186,7 @@ While we navigate the challenges and explore the opportunities of this project, Thanks to the generous support from our sponsors, we're fortunate to be assembling a team capable of dedicating significant time and expertise to this endeavor. This newfound capacity allows us to delve deeper into core development while also engaging more comprehensively with our user community. A special mention goes to @kamilkrzyskow, one of our invaluable [community experts], who has been essential in supporting users and fostering discussions on our platform. - [community experts]: http://localhost:3000/mkdocs-material/insiders/community-experts-program/ + [community experts]: ../../insiders/community-experts-program/index.md With the team's support, @squidfunk can concentrate on the heart of development, while we have begun investing in user research. This effort is helping us understand how organizations and individuals interact with our tools, guiding the project's future direction based on real feedback from numerous conversations with users and companies. diff --git a/docs/changelog/index.md b/docs/changelog/index.md index 29e712cef48..16824cad2e2 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -2,6 +2,144 @@ ## Material for MkDocs +### 9.6.15 July 1, 2025 { id="9.6.15" } + +- Updated Mongolian translations +- Improved semantic markup of "edit this page" button +- Improved info plugin virtual environment resolution +- Fixed #8291: Large font size setting throws of breakpoints in JavaScript + +### 9.6.14 May 13, 2025 { id="9.6.14" } + +- Fixed #8215: Social plugin crashes when CairoSVG is updated to 2.8 + +### 9.6.13 May 10, 2025 { id="9.6.13" } + +- Fixed #8204: Annotations showing list markers in print view +- Fixed #8153: Improve style of cardinality symbols in Mermaid.js ER diagrams + +### 9.6.12 April 17, 2025 { id="9.6.12" } + +- Fixed #8158: Flip footnote back reference icon for right-to-left languages + +### 9.6.11 April 1, 2025 { id="9.6.11" } + +- Updated Docker image to latest Alpine Linux +- Bump required Jinja version to 3.1 +- Fixed #8133: Jinja filter `items` not available (9.6.10 regression) +- Fixed #8128: Search plugin not entirely disabled via enabled setting + +### 9.6.10 March 30, 2025 { id="9.6.10" } + +This version is a pure refactoring release, and does not contain new features +or bug fixes. It strives to improve the compatibility of our templates with +alternative Jinja-like template engines that we're currently exploring, +including [minijinja]. + +Additionally, it replaces several instances of Python function invocations +with idiomatic use of template filters. All instances where variables have +been mutated inside templates have been replaced. Most changes have been made +in partials, and only a few in blocks, and all of them are fully backward +compatible, so no changes to overrides are necessary. + +Note that this release does not replace the Jinja template engine with +minijinja. However, our templates are now 99% compatible with minijinja, +which means we can explore alternative Jinja-compatible implementations. +Additionally, immutability and removal of almost all Python function +invocations means much more idiomatic templating. + + [minijinja]: https://github.com/mitsuhiko/minijinja + +### 9.6.9 March 17, 2025 { id="9.6.9" } + +- Updated Serbo-Croatian translations +- Fixed #8086: Custom SVG icons containing hashes break rendering +- Fixed #8067: Drawer has gap on right side in Firefox on some OSs + +### 9.6.8 March 13, 2025 { id="9.6.8" } + +- Added Welsh translations +- Fixed #8076: Privacy plugin crashes if HTTP download fails + +### 9.6.7 March 3, 2025 { id="9.6.7" } + +- Fixed #8056: Error in backrefs implementation (9.6.6 regression) +- Fixed #8054: Unescaped quotes in ARIA labels of table of contents + +### 9.6.6 March 1, 2025 { id="9.6.6" } + +- Fixed #8040: Privacy plugin not replacing exteral assets (9.6.5 regression) +- Fixed #8031: Replace unmaintained `regex` package in search plugin + +### 9.6.5 February 20, 2025 { id="9.6.5" } + +- Fixed #8016: Tags listing not showing when when file name has spaces +- Fixed #8012: Privacy plugin crashes if HTTP download fails + +### 9.6.4 February 12, 2025 { id="9.6.4" } + +- Fixed #7985: Blog content sometimes not stretching to full width +- Fixed #7978: Navigation rendering bug in Safari 18.3 + +### 9.6.3 February 7, 2025 { id="9.6.3" } + +- Fixed rendering of arrow heads in Mermaid.js class diagrams +- Fixed #7960: Tags plugin crashes on numeric metadata titles + +### 9.6.2 February 3, 2025 { id="9.6.2" } + +- Fixed #7955: Excessively long words don't break on narrow screens +- Fixed #7947: Scope setting interferes with outdated version banner + +### 9.6.1 January 31, 2025 { id="9.6.1" } + +- Fixed #7943: Tags plugin crashing due to merge error + +### 9.6.0 January 31, 2025 { id="9.6.0" } + +- Added meta plugin +- Rewrite of the tags plugin +- Added support for allow lists in tags plugin +- Added support for and custom sorting in tags plugin +- Added support for related links in blog plugin +- Added support for custom index pages in blog plugin +- Added support for navigation subtitles +- Fixed #7924: Anchors might require two clicks when using instant navigation + +### 9.5.50 January 18, 2025 { id="9.5.50" } + +- Fixed #7913: Social plugin renders attribute lists in page title + +### 9.5.49 December 16, 2024 { id="9.5.49" } + +- Adjusted title color in dark mode for all supported Mermaid.js diagrams +- Fixed #7803: Privacy plugin crashes on generated files +- Fixed #7781: Mermaid.js flow chart title not visible in dark mode + +### 9.5.48 December 8, 2024 { id="9.5.48" } + +- Fixed #7774: Disabling social cards doesn't work + +### 9.5.47 December 1, 2024 { id="9.5.47" } + +- Fixed #7750: Numeric tags break search +- Fixed #7748: Blog plugin breaks when using future drafts (9.5.45 regression) + +### 9.5.46 November 25, 2024 { id="9.5.46" } + +- Added support for removing `preload` hints in privacy plugin +- Fixed #7734: Code blocks in h5 headlines are uppercased +- Fixed #7725: Blog plugin crashing on missing timezone (9.5.45 regression) + +### 9.5.45 November 20, 2024 { id="9.5.45" } + +- Reduced size of Docker image through multi-stage build +- Fixed #7708: Blog plugin crashing on YAML dates with timezones + +### 9.5.44 November 5, 2024 { id="9.5.44" } + +- Fixed #7672: Font CSS 404's when using privacy plugin (9.5.43 regression) + ### 9.5.43 October 31, 2024 { id="9.5.43" } - Added support for external images in SVGs in privacy plugin diff --git a/docs/contributing/adding-translations.md b/docs/contributing/adding-translations.md index dbbc4edc76f..29d15b23c5e 100644 --- a/docs/contributing/adding-translations.md +++ b/docs/contributing/adding-translations.md @@ -98,7 +98,7 @@ adding the shortcode for the country flag to this field. Go to our translations for a subdivision, please choose the most appropriate available flag. - [Twemoji]: https://twemoji.twitter.com/ + [Twemoji]: https://github.com/jdecked/twemoji [emoji search]: ../reference/icons-emojis.md#search > __Why this might be helpful__: adding a country flag next to the country name diff --git a/docs/contributing/making-a-pull-request.md b/docs/contributing/making-a-pull-request.md index d1be831ddb6..c276007fd95 100644 --- a/docs/contributing/making-a-pull-request.md +++ b/docs/contributing/making-a-pull-request.md @@ -193,7 +193,7 @@ sequenceDiagram more focused on the specific issue or feature that you worked on. Please keep the discussion respectful at all times. - It is important to note that not all pull requests get incorporated int the + It is important to note that not all pull requests get incorporated into the codebase. The reasons can vary. The work may bring to light other issues that block integration of the pull request. Sometimes it helps uncover better ways of doing things or shows that a more general approach is needed. All of this is @@ -258,7 +258,7 @@ Please respect the [terms of the Insiders program] and the spirit of the Sponsorware approach used to maintain and develop Material for MkDocs. [the Insiders repository]: https://github.com/squidfunk/mkdocs-material-insiders/ -[terms of the Insiders program]: http://localhost:8000/mkdocs-material/insiders/faq/sponsoring/#licensing +[terms of the Insiders program]: https://squidfunk.github.io/mkdocs-material/insiders/license/#fair-use-policy ### Setting up a development environment @@ -296,7 +296,7 @@ will work against that branch in your fork by default. ### Merging concurrent changes If the work you do takes some time then the chances increase that changes will -be made to the main repository while you work.It is probably a good idea to set +be made to the main repository while you work. It is probably a good idea to set up the original Material for MkDocs repository as an `upstream` repository for your local clone. diff --git a/docs/contributing/requesting-a-change.md b/docs/contributing/requesting-a-change.md index a708ae50d57..3c58cb39a6e 100644 --- a/docs/contributing/requesting-a-change.md +++ b/docs/contributing/requesting-a-change.md @@ -20,6 +20,14 @@ implementation. [issue tracker]: https://github.com/squidfunk/mkdocs-material/issues +!!! warning "[How we manage change requests]" + + Before submitting a new idea, please take a moment to read how we manage + change requests + + + [How we manage change requests]: #how-we-manage-change-requests + ## Before creating an issue Before you invest your time to fill out and submit a change request, we kindly @@ -210,6 +218,39 @@ __We'll take it from here.__ --- +## How we manage change requests + +Change requests are submitted as issues on our public [issue tracker]. Since +they often propose new features or enhancements, we review and manage them +differently than bug reports. + +To maintain clarity and ensure that our roadmap remains focused and achievable, +we've introduced a structured process and use a dedicated [backlog] to +track and organize change requests, and how they fit into our roadmap. + + [backlog]: https://github.com/users/squidfunk/projects/4/views/1 + +Here’s how we handle new change requests: + +1. We read and review the request to understand the idea. +2. We may leave comments to clarify intent or suggest alternatives. +3. If the idea is out of scope, we will close the request and explain why. +4. If the idea aligns with the project's vision, we'll categorize it as a change +request, and add it to our [backlog]. +5. In either case, we close the request to keep the issue tracker clean and +focused on open bugs. + +> Note: While the issue may be closed, that doesn't mean it's forgotten – +> change requests added to the project board remain part of our long-term +> planning. + +__Benefits of this approach:__ +- Users get a clearer and quicker overview of known issues and bugs, as change +requests are managed separately, giving a better idea how actively this project +is maintained. +- Related ideas are grouped in the backlog, allowing us to track progress more +effectively, and to more easily see which change requests are related. + ## Rejected requests __Your change request got rejected? We're sorry for that.__ We understand it can diff --git a/docs/conventions.md b/docs/conventions.md index 0363412ab0a..a9da90ed1f7 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -91,3 +91,4 @@ Besides plugins, there are some utilities that build on top of MkDocs in order to provide extended functionality, like for example support for versioning. [Insiders]: insiders/index.md + diff --git a/docs/getting-started.md b/docs/getting-started.md index 9706e7eb744..b5e0b3dd04d 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -122,6 +122,13 @@ The following plugins are bundled with the Docker image: [mkdocs-minify-plugin]: https://github.com/byrnereese/mkdocs-minify-plugin [mkdocs-redirects]: https://github.com/datarobot/mkdocs-redirects +???+ warning + + The Docker container is intended for local previewing purposes only and + is not suitable for deployment. This is because the web server used by + MkDocs for live previews is not designed for production use and may have + security vulnerabilities. + ??? question "How to add plugins to the Docker image?" Material for MkDocs only bundles selected plugins in order to keep the size diff --git a/docs/insiders/benefits.md b/docs/insiders/benefits.md index f960160856d..eabbb95e427 100644 --- a/docs/insiders/benefits.md +++ b/docs/insiders/benefits.md @@ -7,15 +7,15 @@ for you to __start using now__. ## Features -Our sponsors currently enjoy access to the following 26 additional features. New +Our sponsors currently enjoy access to the following 20 additional features. New features are added regularly, so be sure to check back regularly to stay updated.
-- [x] [Blog plugin: pinned posts] :material-alert-decagram:{ .mdx-pulse title="Added on February 24, 2024" } -- [x] [Instant previews] :material-alert-decagram:{ .mdx-pulse title="Added on January 28, 2024" } -- [x] [Footnote tooltips] :material-alert-decagram:{ .mdx-pulse title="Added on January 24, 2024" } +- [x] [Blog plugin: pinned posts] +- [x] [Instant previews] +- [x] [Footnote tooltips] - [x] [Tags plugin: advanced settings] - [x] [Tags plugin: nested tags] - [x] [Tags plugin: shadow tags] @@ -33,12 +33,6 @@ updated. - [x] [Navigation path] (Breadcrumbs) - [x] [Typeset plugin] - [x] [Privacy plugin: external links] -- [x] [Navigation subtitles] -- [x] [Tags plugin: allow list] + [custom sorting] -- [x] [Blog plugin: custom index pages] -- [x] [Blog plugin: related links] -- [x] [Meta plugin] -- [x] [Tags plugin: configurable listings]
@@ -100,23 +94,6 @@ planned, but not yet implemented. This means that each funding goal unlocks new features for general availability in the community edition, after sponsors have used them for a while. -#### $ 16,000 – Chipotle - -- [x] [Meta plugin] -- [x] [Blog plugin: related links] -- [x] [Blog plugin: custom index pages] -- [x] [Tags plugin: configurable listings] -- [x] [Tags plugin: allow list] + [custom sorting] -- [x] [Navigation subtitles] - - [Meta plugin]: ../plugins/meta.md - [Blog plugin: related links]: ../setup/setting-up-a-blog.md#adding-related-links - [Blog plugin: custom index pages]: ../setup/setting-up-a-blog.md#custom-index-pages - [Tags plugin: configurable listings]: ../setup/setting-up-tags.md#configurable-listings - [Tags plugin: allow list]: ../plugins/tags.md#config.tags_allowed - [custom sorting]: ../plugins/tags.md#config.tags_sort_by - [Navigation subtitles]: ../reference/index.md#setting-the-page-subtitle - #### $ 18,000 – Lemon Drop - [x] [Optimize plugin] @@ -184,6 +161,23 @@ sponsors. Those features were once part of Material for MkDocs Insiders, and therefore only available to our sponsors, and are now generally available to be used by all users. +#### $ 16,000 – Chipotle + +- [x] [Meta plugin] +- [x] [Blog plugin: related links] +- [x] [Blog plugin: custom index pages] +- [x] [Tags plugin: configurable listings] +- [x] [Tags plugin: allow list] + [custom sorting] +- [x] [Navigation subtitles] + + [Meta plugin]: ../plugins/meta.md + [Blog plugin: related links]: ../setup/setting-up-a-blog.md#adding-related-links + [Blog plugin: custom index pages]: ../setup/setting-up-a-blog.md#custom-index-pages + [Tags plugin: configurable listings]: ../setup/setting-up-tags.md#configurable-listings + [Tags plugin: allow list]: ../plugins/tags.md#config.tags_allowed + [custom sorting]: ../plugins/tags.md#config.tags_sort_by + [Navigation subtitles]: ../reference/index.md#setting-the-page-subtitle + #### $ 14,000 – Goat's Horn - [x] [Privacy plugin] diff --git a/docs/insiders/changelog/index.md b/docs/insiders/changelog/index.md index 0e3aca78003..05c0dec7bce 100644 --- a/docs/insiders/changelog/index.md +++ b/docs/insiders/changelog/index.md @@ -2,6 +2,14 @@ ## Material for MkDocs Insiders +### 4.53.16 March 13, 2025 { id="4.53.16" } + +- Fixed #8019: Tooltips have precedence over instant previews + +### 4.53.15 January 15, 2025 { id="4.53.15" } + +- Fixed #7896: Scoped tags listings not rendering in subsections + ### 4.53.14 September 29, 2024 { id="4.53.14" } - Fixed #7567: Empty headlines when using typeset plugin with anchorlinks diff --git a/docs/insiders/community-experts-program/index.md b/docs/insiders/community-experts-program/index.md index 54c6276960d..1883ed77776 100644 --- a/docs/insiders/community-experts-program/index.md +++ b/docs/insiders/community-experts-program/index.md @@ -1,6 +1,5 @@ --- title: Community Experts Program -status: new --- # Calling for Community Experts diff --git a/docs/insiders/getting-started.md b/docs/insiders/getting-started.md index f0c7862cfac..8181eafbf18 100644 --- a/docs/insiders/getting-started.md +++ b/docs/insiders/getting-started.md @@ -83,10 +83,10 @@ comfortable self-hosting: 5. [Create a new release] to build and publish the Docker image 6. Install [Pull App] on your fork to stay in-sync with upstream -The [`publish`][publish] workflow[^5] is automatically run when a new tag +The [`build`][build] workflow is automatically run when a new tag (release) is created. When a new Insiders version is released on the upstream repository, the [Pull App] will create a pull request with the changes and -pull in the new tag, which is picked up by the [`publish`][publish] workflow +pull in the new tag, which is picked up by the [`build`][build] workflow that builds and publishes the Docker image automatically to your private registry. @@ -116,12 +116,6 @@ outlined in the [Getting Started guide](../getting-started.md#with-docker). token created to access the Insiders repository, it's safer to create a dedicated token which you'll only use for publishing the Docker image. - [^5]: - The Insiders repository contains two GitHub Actions workflows: - - - `build.yml` – Build and lint the project (disabled on forks) - - `publish.yml` – Build and publish the Docker image - ### with git Of course, you can use Material for MkDocs Insiders directly from `git`: @@ -145,7 +139,7 @@ pip install -e mkdocs-material [GitHub Actions secret]: https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository [Create a new release]: https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository#creating-a-release [Pull App]: https://github.com/apps/pull - [publish]: https://github.com/squidfunk/mkdocs-material-insiders/blob/master/.github/workflows/publish.yml + [build]: https://github.com/squidfunk/mkdocs-material-insiders/blob/master/.github/workflows/build.yml ## Built-in plugins @@ -159,14 +153,14 @@ plugins: - search - social - # CI=1 mkdocs build + # CI=true mkdocs build - group: enabled: !ENV CI plugins: - git-revision-date-localized - git-committers - # INSIDERS=1 mkdocs build + # INSIDERS=true mkdocs build - group: enabled: !ENV INSIDERS plugins: @@ -176,8 +170,8 @@ plugins: Of course, you can also enable both groups with: -``` -CI=1 INSIDERS=1 mkdocs build +``` shell +CI=true INSIDERS=true mkdocs build ``` [built-in group plugin]: ../plugins/group.md diff --git a/docs/insiders/index.md b/docs/insiders/index.md index ee6af1f346e..46b405de083 100644 --- a/docs/insiders/index.md +++ b/docs/insiders/index.md @@ -40,7 +40,7 @@ you should sponsor us, what's in it for you, and who is sponsoring us. --- - [:octicons-arrow-right-24: More infomation][What's in it for you] + [:octicons-arrow-right-24: More information][What's in it for you] - :fontawesome-solid-people-group:   __Who is sponsoring__ @@ -51,7 +51,7 @@ you should sponsor us, what's in it for you, and who is sponsoring us. --- - [:octicons-arrow-right-24: More infomation][Who is sponsoring] + [:octicons-arrow-right-24: More information][Who is sponsoring] @@ -104,7 +104,7 @@ access management, and more, here is everything you need to know: --- - [:octicons-arrow-right-24: More infomation][Payment and billing] + [:octicons-arrow-right-24: More information][Payment and billing] - :material-key-variant:   __Access management__ @@ -116,7 +116,7 @@ access management, and more, here is everything you need to know: --- - [:octicons-arrow-right-24: More infomation][Access management] + [:octicons-arrow-right-24: More information][Access management] - :material-clock-time-three:   __Runtime and cancellation__ @@ -139,7 +139,7 @@ access management, and more, here is everything you need to know: --- - [:octicons-arrow-right-24: More infomation][Privacy] + [:octicons-arrow-right-24: More information][Privacy] - :material-briefcase:   __License__ @@ -150,7 +150,7 @@ access management, and more, here is everything you need to know: --- - [:octicons-arrow-right-24: More infomation][License] + [:octicons-arrow-right-24: More information][License] - :material-email:   __Support__ @@ -193,7 +193,7 @@ get all the information you need to get started: --- - [:octicons-arrow-right-24: More infomation][Changelog] + [:octicons-arrow-right-24: More information][Changelog] - :material-update:  __Upgrade__ @@ -205,7 +205,7 @@ get all the information you need to get started: --- - [:octicons-arrow-right-24: More infomation][Upgrade] + [:octicons-arrow-right-24: More information][Upgrade] diff --git a/docs/insiders/our-sponsors.md b/docs/insiders/our-sponsors.md index d096dcedf5e..6861e99ce04 100644 --- a/docs/insiders/our-sponsors.md +++ b/docs/insiders/our-sponsors.md @@ -46,13 +46,10 @@ _Be our first gold sponsor!_ [![Neptune]](https://neptune.ai/){ target=_blank title="Neptune" } [![RackN]](https://rackn.com/){ target=_blank title="RackN" } [![CivicActions]](https://civicactions.com/){ target=_blank title="CivicActions" } -[![bitcrowd]](https://bitcrowd.net/){ target=_blank title="bitcrowd" } [![GetScreen.me]](https://getscreen.me/){ target=_blank title="GetScreen.me" } [![BotCity]](https://botcity.dev/){ target=_blank title="BotCity" } -[![Springer Nature Technology]](https://www.springernature.com/gp){ target=_blank title="Springer Nature Technology" } [![Kolena]](https://kolena.io/){ target=_blank title="Kolena" } [![Evergiving]](https://www.evergiving.com/){ target=_blank title="Evergiving" } -[![Koor]](https://koor.tech/){ target=_blank title="Koor" } [![Astral]](https://astral.sh/){ target=_blank title="Astral" } [![Oikolab]](https://oikolab.com/){ target=_blank title="Oikolab" } [![Bühler Group]](https://www.buhlergroup.com/){ target=_blank title="Bühler Group" } @@ -64,6 +61,10 @@ _Be our first gold sponsor!_ [![Maxar]](https://maxar.com/){ target=_blank title="Maxar" } [![EquipmentShare]](https://www.equipmentshare.com/){ target=_blank title="EquipmentShare" } [![Hummingbot]](https://hummingbot.org/){ target=_blank title="Hummingbot" } +[![OctoPerf]](https://octoperf.com/){ target=_blank title="OctoPerf" } +[![Inter Comestibles]](https://intercomestibles.ch/){ target=_blank title="Inter Comestibles" } +[![Centara]](https://www.centara.com/){ target=_blank title="Centara" } +[![Pydantic Logfire]](https://pydantic.dev/logfire/){ target=_blank title="Pydantic Logfire" } @@ -89,13 +90,10 @@ _Be our first gold sponsor!_ [Cash App]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-cashapp.png [RackN]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-rackn.png [CivicActions]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-civic-actions.png - [bitcrowd]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-bitcrowd.png [GetScreen.me]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-getscreenme.png [BotCity]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-botcity.png - [Springer Nature Technology]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-sn-technology.png [Kolena]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-kolena.png [Evergiving]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-evergiving.png - [Koor]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-koor.png [Astral]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-astral.png [Oikolab]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-oikolab.png [Bühler Group]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-buhler.png @@ -110,6 +108,10 @@ _Be our first gold sponsor!_ [Hummingbot]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-hummingbot.png [Future]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-future.svg [SIEMENS]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-siemens.png + [OctoPerf]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-octoperf.png + [Inter Comestibles]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-intercomestibles.png + [Centara]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-centara.png + [Pydantic Logfire]: https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/.github/assets/sponsors/sponsor-logfire.png
diff --git a/docs/license.md b/docs/license.md index 83fba873993..5783e40eeed 100644 --- a/docs/license.md +++ b/docs/license.md @@ -2,7 +2,7 @@ **MIT License** -Copyright (c) 2016-2024 Martin Donath +Copyright (c) 2016-2025 Martin Donath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/docs/philosophy.md b/docs/philosophy.md index 11b4d99bb40..35efcb16fbb 100644 --- a/docs/philosophy.md +++ b/docs/philosophy.md @@ -9,27 +9,16 @@ discusses the [conventions] used in this documentation. ## Design principles -- __It's just Markdown__: Focus on the content of your documentation and create - a professional static site in minutes. No need to know HTML,CSS or JavaScript - – let Material for MkDocs do the heavy lifting for you. +- **It's just Markdown**: Focus on the content of your documentation and create a professional static site in minutes. No need to know HTML, CSS or JavaScript – let Material for MkDocs do the heavy lifting for you. -- __Works on all devices__: Serve your documentation with confidence – the - underlying layout automatically adapts to perfectly fit the available screen - estate, no matter the type or size of the viewing device. +- **Works on all devices**: Serve your documentation with confidence – Material for MkDocs automatically adapts to perfectly fit the available screen estate, no matter the type or size of the viewing device. Desktop. Tablet. Mobile. All great. -- __Made to measure__: Change the colors, fonts, language, icons, logo and much - more with a few lines of configuration. Material for MkDocs can be easily - extended and provides tons of options to alter appearance and behavior. +- **Made to measure**: Make it yours – change the colors, fonts, language, icons, logo, and more with a few lines of configuration. Material for MkDocs can be easily extended and provides many options to alter appearance and behavior. -- __Fast and lightweight__: Don't let your users wait – get incredible value - with a small footprint, by using one of the fastest themes around with - excellent performance, yielding great search engine rankings and happy - users that return. +- **Fast and lightweight**: Don't let your users wait – get incredible value with a small footprint by using one of the fastest themes available with excellent performance, yielding optimal search engine rankings and happy users that return. -- __Accessible__: Make accessibility a priority – users can navigate your +- **Maintain ownership**: Make accessibility a priority – users can navigate your documentation with touch devices, keyboard, and screen readers. Semantic markup ensures that your documentation works for everyone. -- __Open Source__: Trust 45,000+ users – choose a mature and well-funded - solution built with state-of-the-art Open Source technologies. Keep ownership - of your content without fear of vendor lock-in. Licensed under MIT. +- **Open Source**: You're in good company – choose a mature and actively maintained solution built with state-of-the-art Open Source technologies, trusted by more than 50.000 individuals and organizations. Licensed under MIT. diff --git a/docs/plugins/blog.md b/docs/plugins/blog.md index e1e41270cfe..a76db4b7d1a 100644 --- a/docs/plugins/blog.md +++ b/docs/plugins/blog.md @@ -599,6 +599,14 @@ plugins: post_readtime: false ``` +!!! warning "Chinese, Japanese and Korean characters" + + Reading time computation currently does not take segmentation of Chinese, + Japanese and Korean characters into account. This means that the reading + time for posts in these languages may be inaccurate. We're planning on + adding support in the future. In the meantime, please use the `readtime` + front matter property to set the reading time. + --- #### diff --git a/docs/plugins/meta.md b/docs/plugins/meta.md index 5ab849602a7..4ef92ffde5b 100644 --- a/docs/plugins/meta.md +++ b/docs/plugins/meta.md @@ -10,13 +10,6 @@ pages in a folder, i.e., a subsection of your project, which is particularly useful to ensure that a certain subset of pages features specific tags, uses a custom template, or is attributed to an author. ---- - - __Sponsors only__ – this plugin is currently reserved to -[our awesome sponsors]. - - [our awesome sponsors]: ../insiders/index.md - ## Objective ### How it works @@ -132,8 +125,7 @@ of the meta plugin and other built-in plugins are: ## Configuration - - + @@ -160,8 +152,7 @@ The following settings are available: #### - - + Use this setting to enable or disable the plugin when [building your project]. @@ -184,8 +175,7 @@ The following settings are available for meta files: #### - - + Use this setting to change the meta file name the plugin will look for when diff --git a/docs/plugins/offline.md b/docs/plugins/offline.md index 760c01b90d7..243954d4c14 100644 --- a/docs/plugins/offline.md +++ b/docs/plugins/offline.md @@ -6,10 +6,11 @@ icon: material/connection # Built-in offline plugin -[MkDocs][mkdocs] is one of the few frameworks that allow to build offline-capable -documentation that can be directly viewed by the user – no server needed. With -the offline plugin, you can distribute the [`site` directory][mkdocs.site_dir] -as a downloadable `.zip` file while retaining most interactive functionality. +[MkDocs][mkdocs] is one of the few frameworks that supports building +offline-capable documentation that can be directly viewed by the user – no +server needed. With the offline plugin, you can distribute the +[`site` directory][mkdocs.site_dir] as a downloadable `.zip` file while +retaining most interactive functionality. ## Objective diff --git a/docs/plugins/social.md b/docs/plugins/social.md index 7ad60addff3..123d2dc09fe 100644 --- a/docs/plugins/social.md +++ b/docs/plugins/social.md @@ -669,6 +669,9 @@ Setting an option to `#!yaml null` resets the option. ### Layouts + + + While it is possible and simple to build [custom layouts], the plugin ships several predefined layouts, all of which are prefixed with `default`. The following layouts are included: diff --git a/docs/plugins/tags.md b/docs/plugins/tags.md index 87a26890c6f..bd1262e31c6 100644 --- a/docs/plugins/tags.md +++ b/docs/plugins/tags.md @@ -134,12 +134,14 @@ is enabled. -!!! info "This setting is not needed in [Insiders]" +!!! warning "This setting is deprecated" - Insiders ships a __ground up rewrite of the tags plugin__ which is infinitely - more powerful than the current version in the community edition. It allows - for an arbitrary number of tags indexes (listings), [scoped listings], - [shadow tags], [nested tags], and much more. + As of version , this setting is deprecated, as this + version ships a __ground up rewrite of the tags plugin__ which is much more + powerful than the previous version. Tags [listings] can be used on any page + now. + +
Use this setting to specify the location of the tags index, which is the page used to render a list of all tags and their associated pages. If this setting is @@ -158,17 +160,15 @@ if you want to have a tags index. The provided path is resolved from the [`docs` directory][mkdocs.docs_dir]. - [Insiders]: ../insiders/index.md - [scoped listings]: ../setup/setting-up-tags.md#scoped-listings - [shadow tags]: ../setup/setting-up-tags.md#shadow-tags - [nested tags]: ../setup/setting-up-tags.md#nested-tags +
+ + [listings]: ../setup/setting-up-tags.md#adding-a-tags-index --- #### - - + Use this setting to change the function for generating URL-compatible slugs @@ -194,8 +194,7 @@ more granular control. #### - - + Use this setting to change the separator that is passed to the slugification @@ -212,8 +211,7 @@ plugins: #### - - + Use this setting to change the format string that is used when generating tag @@ -272,8 +270,7 @@ plugins: #### - - + Use this setting to specify a custom function for comparing tags. By default, @@ -294,8 +291,7 @@ or number representing the tag, that is used for sorting, and reference it in #### - - + Use this setting to reverse the order in which tags are sorted when comparing @@ -312,8 +308,7 @@ plugins: #### - - + Use this setting to change the name of the front matter property that is used by @@ -330,8 +325,7 @@ plugins: #### - - + Use this setting to change the name of the template variable that is used by @@ -348,8 +342,7 @@ plugins: #### - - + The plugin allows to check tags against a predefined list, in order to catch @@ -377,8 +370,7 @@ The following settings are available for listings: #### - - + Use this setting to enable or disable listings. It is normally not necessary to @@ -400,8 +392,7 @@ is enabled. #### - - + Use this define listing configurations that you can then reference in listings @@ -431,8 +422,7 @@ See the [listings section] for a list of all available settings. #### - - + Use this setting to specify a custom function for comparing listing items. By @@ -463,8 +453,7 @@ or number representing the item, that is used for sorting, and reference it in #### - - + Use this setting to reverse the order in which items are sorted when comparing @@ -481,8 +470,7 @@ plugins: #### - - + Use this setting to specify a custom function for comparing tags in listings. By @@ -503,8 +491,7 @@ or number representing the tag, that is used for sorting, and reference it in #### - - + Use this setting to reverse the order in which tags are sorted when comparing @@ -521,8 +508,7 @@ plugins: #### - - + Use this setting to change the name of the directive the plugin will look for @@ -777,8 +763,7 @@ The following settings are available: #### - - + This setting specifies whether the listing should only consider pages that are @@ -879,8 +864,7 @@ setting on a per-listing basis: #### - - + Use this setting to specify which tags should be included in the listing. Each @@ -917,8 +901,7 @@ If this setting is left empty, all tags and pages are included. #### - - + Use this setting to specify which tags should be excluded from the listing. Each @@ -950,3 +933,9 @@ listing entirely: ``` If this setting is left empty, no tags or pages are excluded. + +## Limitations + +The implementation of the tags plugin is tricky due to MkDocs architecture. +Notably, tag listing markers cannot appear within code blocks. For technical +details, refer to #8114. diff --git a/docs/publishing-your-site.md b/docs/publishing-your-site.md index 4019a3f80ad..eebc287ac4c 100644 --- a/docs/publishing-your-site.md +++ b/docs/publishing-your-site.md @@ -46,10 +46,10 @@ contents: - uses: actions/cache@v4 with: key: mkdocs-material-${{ env.cache_id }} - path: .cache + path: .cache # (4)! restore-keys: | mkdocs-material- - - run: pip install mkdocs-material # (4)! + - run: pip install mkdocs-material # (5)! - run: mkdocs gh-deploy --force ``` @@ -67,7 +67,10 @@ contents: You can read the [manual page] to learn more about the formatting options of the `date` command. - 4. This is the place to install further [MkDocs plugins] or Markdown + 4. Some Material for MkDocs plugins use [caching] to speed up repeated + builds, and store the results in the `.cache` directory. + + 5. This is the place to install further [MkDocs plugins] or Markdown extensions with `pip` to be used during the build: ``` sh @@ -105,20 +108,23 @@ contents: - uses: actions/cache@v4 with: key: mkdocs-material-${{ env.cache_id }} - path: .cache + path: .cache # (1)! restore-keys: | mkdocs-material- - - run: apt-get install pngquant # (1)! + - run: apt-get install pngquant # (2)! - run: pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git - run: mkdocs gh-deploy --force env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} # (2)! + GH_TOKEN: ${{ secrets.GH_TOKEN }} # (3)! ``` - 1. This step is only necessary if you want to use the + 1. Some Material for MkDocs plugins use [caching] to speed up repeated + builds, and store the results in the `.cache` directory. + + 2. This step is only necessary if you want to use the [built-in optimize plugin] to automatically compress images. - 2. Remember to set the `GH_TOKEN` repository secret to the value of your + 3. Remember to set the `GH_TOKEN` repository secret to the value of your [personal access token] when deploying [Insiders], which can be done using [GitHub secrets]. @@ -132,6 +138,8 @@ Page is set to `gh-pages`. Your documentation should shortly appear at `.github.io/`. +To publish your site on a custom domain, please refer to the [MkDocs documentation]. + [GitHub Actions]: https://github.com/features/actions [MkDocs plugins]: https://github.com/mkdocs/mkdocs/wiki/MkDocs-Plugins [personal access token]: https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token @@ -140,6 +148,8 @@ Your documentation should shortly appear at `.github.io/`. [GitHub secrets]: https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets [publishing source branch]: https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site [manual page]: https://man7.org/linux/man-pages/man1/date.1.html + [caching]: plugins/requirements/caching.md + [MkDocs documentation]: https://www.mkdocs.org/user-guide/deploying-your-docs/#custom-domains ### with MkDocs @@ -174,13 +184,21 @@ contents: script: - pip install mkdocs-material - mkdocs build --site-dir public + cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - .cache/ # (1)! artifacts: paths: - public rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + ``` + 1. Some Material for MkDocs plugins use [caching] to speed up repeated + builds, and store the results in the `.cache` directory. + === "Insiders" ``` yaml @@ -190,6 +208,10 @@ contents: script: # (1)! - pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git - mkdocs build --site-dir public + cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - .cache/ # (2)! artifacts: paths: - public @@ -201,11 +223,30 @@ contents: [personal access token] when deploying [Insiders], which can be done using [masked custom variables]. + 2. Some Material for MkDocs plugins use [caching] to speed up repeated + builds, and store the results in the `.cache` directory. + Now, when a new commit is pushed to the [default branch] (typically `master` or `main`), the static site is automatically built and deployed. Commit and push the file to your repository to see the workflow in action. -Your documentation should shortly appear at `.gitlab.io/`. +Your documentation is not published under `.gitlab.io/` +by default since **GitLab 17.4** [^1]. However, if you prefer a cleaner URL +structure, such as `.gitlab.io/`, you need to adjust +your configuration. + +To switch from a unique domain to the traditional URL structure, follow +these steps: + +1. Locate Your Repository +2. Go to **Settings › Pages** in the repository menu. +3. In the **Unique domain settings** section, **uncheck** the box labeled +4. **Use unique domain**. +5. Click **Save changes** to apply the update. + +Now you can reach your documentation under `.gitlab.io/`. + +[^1]: [Release notes for Gitlab 17.4](https://about.gitlab.com/releases/2024/09/19/gitlab-17-4-released/) ## Other @@ -215,27 +256,19 @@ other providers:
-- [:material-microsoft-azure-devops: Azure][Azure] - [:simple-cloudflarepages: Cloudflare Pages][Cloudflare Pages] -- [:simple-digitalocean: DigitalOcean][DigitalOcean] - [:material-airballoon-outline: Fly.io][Flyio] - [:simple-netlify: Netlify][Netlify] -- [:simple-vercel: Vercel][Vercel] -- [:simple-codeberg: Codeberg Pages][Codeberg Pages] - [:simple-scaleway: Scaleway][Scaleway]
[GitLab Pages]: https://gitlab.com/pages [GitLab CI]: https://docs.gitlab.com/ee/ci/ - [masked custom variables]: https://docs.gitlab.com/ee/ci/variables/#create-a-custom-variable-in-the-ui + [masked custom variables]: https://docs.gitlab.com/ee/ci/variables/#mask-a-cicd-variable [default branch]: https://docs.gitlab.com/ee/user/project/repository/branches/default.html - [Azure]: https://bawmedical.co.uk/t/publishing-a-material-for-mkdocs-site-to-azure-with-automatic-branch-pr-preview-deployments/763 - [Cloudflare Pages]: https://deborahwrites.com/guides/deploy-mkdocs-material-cloudflare/ - [DigitalOcean]: https://deborahwrites.com/guides/deploy-mkdocs-material-digitalocean-app-platform/ + [Cloudflare Pages]: https://deborahwrites.com/guides/deploy-host-mkdocs/deploy-mkdocs-material-cloudflare/ [Flyio]: https://documentation.breadnet.co.uk/cloud/fly/mkdocs-on-fly/ - [Netlify]: https://deborahwrites.com/projects/deploy-host-docs/deploy-mkdocs-material-netlify/ - [Vercel]: https://deborahwrites.com/guides/deploy-mkdocs-material-vercel/ - [Codeberg Pages]: https://andre601.ch/blog/2023/11-05-using-codeberg-pages/ + [Netlify]: https://deborahwrites.com/guides/deploy-host-mkdocs/deploy-mkdocs-material-netlify/ [Scaleway]: https://www.scaleway.com/en/docs/tutorials/using-bucket-website-with-mkdocs/ diff --git a/docs/reference/admonitions.md b/docs/reference/admonitions.md index 02f9fe2c27a..d8b6568185b 100644 --- a/docs/reference/admonitions.md +++ b/docs/reference/admonitions.md @@ -155,6 +155,40 @@ links, formatting, ...) after the type qualifier: +### Nested admonitions + +You can also include nested admonitions in your documentation. To do this, you +can use your existing admonitions and indent the desired ones: + +``` markdown title="Nested Admonition" +!!! note "Outer Note" + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + + !!! note "Inner Note" + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +
+ +!!! note "Outer Note" + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + + !!! note "Inner Note" + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +
+ ### Removing the title Similar to [changing the title], the icon and title can be omitted entirely by @@ -185,7 +219,7 @@ not work for [collapsible blocks]: ### Collapsible blocks When [Details] is enabled and an admonition block is started with `???` instead -of `!!!`, the admonition is rendered as a collapsible block with a small toggle +of `!!!`, the admonition is rendered as an expandable block with a small toggle on the right side: ``` markdown title="Admonition, collapsible" diff --git a/docs/reference/footnotes.md b/docs/reference/footnotes.md index 1a2ec5ca386..ad1c1b8bd31 100644 --- a/docs/reference/footnotes.md +++ b/docs/reference/footnotes.md @@ -26,7 +26,7 @@ See additional configuration options: [Footnotes]: ../setup/extensions/python-markdown.md#footnotes -### Footnote tooltips :material-alert-decagram:{ .mdx-pulse title="Added on January 24, 2024" } +### Footnote tooltips diff --git a/docs/reference/icons-emojis.md b/docs/reference/icons-emojis.md index e9f5d6c3086..5ac5325b8cf 100644 --- a/docs/reference/icons-emojis.md +++ b/docs/reference/icons-emojis.md @@ -66,7 +66,7 @@ See additional configuration options: - [Emoji] - [Emoji with custom icons] - [Material Design]: https://materialdesignicons.com/ + [Material Design]: https://pictogrammers.com/library/mdi/ [FontAwesome]: https://fontawesome.com/search?m=free [Octicons]: https://octicons.github.com/ [Simple Icons]: https://simpleicons.org/ @@ -91,7 +91,7 @@ the shortcodes at [Emojipedia]: :smile: - [Twemoji]: https://github.com/twitter/twemoji + [Twemoji]: https://github.com/jdecked/twemoji [Emojipedia]: https://emojipedia.org/twitter/ ### Using icons diff --git a/docs/reference/index.md b/docs/reference/index.md index 741511c10ca..d13590c2f27 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -144,8 +144,7 @@ page status] to get you started. ### Setting the page `subtitle` - - + Each page can define a subtitle, which is then rendered below the title as part diff --git a/docs/schema.json b/docs/schema.json index f4b349c8d2d..24bef893ed6 100644 --- a/docs/schema.json +++ b/docs/schema.json @@ -166,6 +166,11 @@ "markdownDescription": "https://www.mkdocs.org/user-guide/configuration/#exclude_docs", "type": "string" }, + "draft_docs": { + "title": "Pattern to declare draft documents", + "markdownDescription": "https://www.mkdocs.org/user-guide/configuration/#draft_docs", + "type": "string" + }, "not_in_nav": { "title": "Pattern to declare pages that do not appear in the navigation", "markdownDescription": "https://www.mkdocs.org/user-guide/configuration/#not_in_nav", diff --git a/docs/schema/assets/icons.json b/docs/schema/assets/icons.json index 82399c35b0d..b371f983788 100644 --- a/docs/schema/assets/icons.json +++ b/docs/schema/assets/icons.json @@ -100,6 +100,7 @@ "fontawesome/brands/creative-commons-zero", "fontawesome/brands/creative-commons", "fontawesome/brands/critical-role", + "fontawesome/brands/css", "fontawesome/brands/css3-alt", "fontawesome/brands/css3", "fontawesome/brands/cuttlefish", @@ -149,6 +150,7 @@ "fontawesome/brands/fedex", "fontawesome/brands/fedora", "fontawesome/brands/figma", + "fontawesome/brands/files-pinwheel", "fontawesome/brands/firefox-browser", "fontawesome/brands/firefox", "fontawesome/brands/first-order-alt", @@ -371,6 +373,7 @@ "fontawesome/brands/speaker-deck", "fontawesome/brands/spotify", "fontawesome/brands/square-behance", + "fontawesome/brands/square-bluesky", "fontawesome/brands/square-dribbble", "fontawesome/brands/square-facebook", "fontawesome/brands/square-font-awesome-stroke", @@ -917,6 +920,7 @@ "fontawesome/solid/chart-area", "fontawesome/solid/chart-bar", "fontawesome/solid/chart-column", + "fontawesome/solid/chart-diagram", "fontawesome/solid/chart-gantt", "fontawesome/solid/chart-line", "fontawesome/solid/chart-pie", @@ -1010,6 +1014,7 @@ "fontawesome/solid/comment-dollar", "fontawesome/solid/comment-dots", "fontawesome/solid/comment-medical", + "fontawesome/solid/comment-nodes", "fontawesome/solid/comment-slash", "fontawesome/solid/comment-sms", "fontawesome/solid/comment", @@ -1172,6 +1177,8 @@ "fontawesome/solid/file-csv", "fontawesome/solid/file-excel", "fontawesome/solid/file-export", + "fontawesome/solid/file-fragment", + "fontawesome/solid/file-half-dashed", "fontawesome/solid/file-image", "fontawesome/solid/file-import", "fontawesome/solid/file-invoice-dollar", @@ -1323,6 +1330,8 @@ "fontawesome/solid/helicopter", "fontawesome/solid/helmet-safety", "fontawesome/solid/helmet-un", + "fontawesome/solid/hexagon-nodes-bolt", + "fontawesome/solid/hexagon-nodes", "fontawesome/solid/highlighter", "fontawesome/solid/hill-avalanche", "fontawesome/solid/hill-rockslide", @@ -1787,6 +1796,7 @@ "fontawesome/solid/spray-can-sparkles", "fontawesome/solid/spray-can", "fontawesome/solid/square-arrow-up-right", + "fontawesome/solid/square-binary", "fontawesome/solid/square-caret-down", "fontawesome/solid/square-caret-left", "fontawesome/solid/square-caret-right", @@ -9923,6 +9933,8 @@ "octicons/passkey-fill-24", "octicons/paste-16", "octicons/paste-24", + "octicons/pause-16", + "octicons/pause-24", "octicons/pencil-16", "octicons/pencil-24", "octicons/people-16", @@ -10039,12 +10051,18 @@ "octicons/sort-asc-24", "octicons/sort-desc-16", "octicons/sort-desc-24", + "octicons/sparkle-16", + "octicons/sparkle-24", "octicons/sparkle-fill-16", "octicons/sparkle-fill-24", + "octicons/sparkles-fill-16", + "octicons/sparkles-fill-24", "octicons/sponsor-tiers-16", "octicons/sponsor-tiers-24", "octicons/square-16", "octicons/square-24", + "octicons/square-circle-16", + "octicons/square-circle-24", "octicons/square-fill-16", "octicons/square-fill-24", "octicons/squirrel-16", @@ -10147,6 +10165,7 @@ "octicons/zoom-out-16", "octicons/zoom-out-24", "simple/1001tracklists", + "simple/1and1", "simple/1dot1dot1dot1", "simple/1panel", "simple/1password", @@ -10162,43 +10181,35 @@ "simple/7zip", "simple/99designs", "simple/9gag", + "simple/abb", "simple/abbott", - "simple/abbrobotstudio", "simple/abbvie", + "simple/abdownloadmanager", "simple/aboutdotme", "simple/abstract", "simple/abusedotch", "simple/academia", "simple/accenture", "simple/accusoft", + "simple/accuweather", "simple/acer", "simple/acm", "simple/actigraph", + "simple/activeloop", "simple/activision", "simple/activitypub", "simple/actix", "simple/actualbudget", "simple/acura", + "simple/ada", "simple/adafruit", + "simple/adaway", "simple/adblock", "simple/adblockplus", + "simple/addydotio", "simple/adguard", "simple/adidas", "simple/adminer", - "simple/adobe", - "simple/adobeacrobatreader", - "simple/adobeaftereffects", - "simple/adobeaudition", - "simple/adobecreativecloud", - "simple/adobedreamweaver", - "simple/adobefonts", - "simple/adobeillustrator", - "simple/adobeindesign", - "simple/adobelightroom", - "simple/adobelightroomclassic", - "simple/adobephotoshop", - "simple/adobepremierepro", - "simple/adobexd", "simple/adonisjs", "simple/adp", "simple/adroll", @@ -10210,6 +10221,7 @@ "simple/aeromexico", "simple/aerospike", "simple/aew", + "simple/afdian", "simple/affine", "simple/affinity", "simple/affinitydesigner", @@ -10217,6 +10229,7 @@ "simple/affinitypublisher", "simple/aframe", "simple/afterpay", + "simple/aftership", "simple/agora", "simple/aib", "simple/aidungeon", @@ -10234,11 +10247,13 @@ "simple/airindia", "simple/airplayaudio", "simple/airplayvideo", + "simple/airserbia", "simple/airtable", "simple/airtel", "simple/airtransat", "simple/ajv", "simple/akamai", + "simple/akasaair", "simple/akaunting", "simple/akiflow", "simple/alacritty", @@ -10257,6 +10272,7 @@ "simple/alienware", "simple/aliexpress", "simple/alipay", + "simple/alist", "simple/allegro", "simple/alliedmodders", "simple/allocine", @@ -10269,32 +10285,6 @@ "simple/altiumdesigner", "simple/alwaysdata", "simple/alx", - "simple/amazon", - "simple/amazonalexa", - "simple/amazonapigateway", - "simple/amazoncloudwatch", - "simple/amazoncognito", - "simple/amazondocumentdb", - "simple/amazondynamodb", - "simple/amazonec2", - "simple/amazonecs", - "simple/amazoneks", - "simple/amazonelasticache", - "simple/amazonfiretv", - "simple/amazongames", - "simple/amazoniam", - "simple/amazonlumberyard", - "simple/amazonluna", - "simple/amazonmusic", - "simple/amazonpay", - "simple/amazonprime", - "simple/amazonrds", - "simple/amazonredshift", - "simple/amazonroute53", - "simple/amazons3", - "simple/amazonsimpleemailservice", - "simple/amazonsqs", - "simple/amazonwebservices", "simple/amd", "simple/ameba", "simple/americanairlines", @@ -10320,11 +10310,12 @@ "simple/anta", "simple/antdesign", "simple/antena3", + "simple/antennapod", "simple/anthropic", + "simple/antv", "simple/anycubic", "simple/anydesk", "simple/anytype", - "simple/aol", "simple/apache", "simple/apacheairflow", "simple/apacheant", @@ -10333,6 +10324,7 @@ "simple/apachecordova", "simple/apachecouchdb", "simple/apachedolphinscheduler", + "simple/apachedoris", "simple/apachedruid", "simple/apacheecharts", "simple/apacheflink", @@ -10345,6 +10337,7 @@ "simple/apachejmeter", "simple/apachekafka", "simple/apachekylin", + "simple/apachelucene", "simple/apachemaven", "simple/apachenetbeanside", "simple/apachenifi", @@ -10362,6 +10355,7 @@ "simple/apmterminals", "simple/apollographql", "simple/apostrophe", + "simple/appgallery", "simple/appian", "simple/appium", "simple/apple", @@ -10404,7 +10398,6 @@ "simple/asciinema", "simple/asda", "simple/aseprite", - "simple/askfm", "simple/assemblyscript", "simple/asterisk", "simple/astonmartin", @@ -10443,23 +10436,21 @@ "simple/avast", "simple/avianca", "simple/avira", + "simple/avm", "simple/awesomelists", "simple/awesomewm", - "simple/awsamplify", - "simple/awselasticloadbalancing", - "simple/awsfargate", - "simple/awslambda", - "simple/awsorganizations", - "simple/awssecretsmanager", "simple/awwwards", "simple/axios", + "simple/axisbank", "simple/babel", "simple/babelio", "simple/babylondotjs", "simple/backblaze", + "simple/backbone", "simple/backbonedotjs", "simple/backendless", "simple/backstage", + "simple/backstage_casting", "simple/badoo", "simple/baidu", "simple/bakalari", @@ -10495,6 +10486,8 @@ "simple/bentoml", "simple/bereal", "simple/betfair", + "simple/betterauth", + "simple/betterdiscord", "simple/betterstack", "simple/bevy", "simple/bigbasket", @@ -10525,6 +10518,7 @@ "simple/blazemeter", "simple/blazor", "simple/blender", + "simple/blibli", "simple/blockbench", "simple/blockchaindotcom", "simple/blogger", @@ -10540,9 +10534,11 @@ "simple/boat", "simple/boehringeringelheim", "simple/boeing", + "simple/bohemiainteractive", "simple/bombardier", "simple/bookalope", "simple/bookbub", + "simple/bookingdotcom", "simple/bookmeter", "simple/bookmyshow", "simple/bookstack", @@ -10559,6 +10555,8 @@ "simple/box", "simple/boxysvg", "simple/braintree", + "simple/braintrust", + "simple/brandfetch", "simple/brandfolder", "simple/brave", "simple/breaker", @@ -10578,7 +10576,6 @@ "simple/buffer", "simple/bugatti", "simple/bugcrowd", - "simple/bugsnag", "simple/buhl", "simple/buildkite", "simple/builtbybit", @@ -10586,6 +10583,7 @@ "simple/bulma", "simple/bun", "simple/bungie", + "simple/bunnydotnet", "simple/bunq", "simple/burgerking", "simple/burpsuite", @@ -10601,9 +10599,9 @@ "simple/caddy", "simple/cadillac", "simple/cafepress", - "simple/caffeine", "simple/cairographics", "simple/cairometro", + "simple/caixabank", "simple/cakephp", "simple/caldotcom", "simple/calendly", @@ -10628,8 +10626,10 @@ "simple/caterpillar", "simple/cbc", "simple/cbs", + "simple/ccc", "simple/ccleaner", "simple/cdprojekt", + "simple/ce", "simple/celery", "simple/celestron", "simple/centos", @@ -10639,6 +10639,7 @@ "simple/chainguard", "simple/chainlink", "simple/chakraui", + "simple/changedetection", "simple/channel4", "simple/charles", "simple/chartdotjs", @@ -10660,7 +10661,6 @@ "simple/chinasouthernairlines", "simple/chocolatey", "simple/chromatic", - "simple/chromecast", "simple/chromewebstore", "simple/chrysler", "simple/chupachups", @@ -10676,16 +10676,15 @@ "simple/citroen", "simple/civicrm", "simple/civo", - "simple/ckeditor4", "simple/clarifai", "simple/claris", "simple/clarivate", + "simple/claude", "simple/clerk", "simple/clevercloud", "simple/clickhouse", "simple/clickup", "simple/clion", - "simple/cliqz", "simple/clockify", "simple/clojure", "simple/cloud66", @@ -10697,6 +10696,7 @@ "simple/cloudflareworkers", "simple/cloudfoundry", "simple/cloudinary", + "simple/cloudnativebuild", "simple/cloudron", "simple/cloudsmith", "simple/cloudways", @@ -10705,8 +10705,10 @@ "simple/clyp", "simple/cmake", "simple/cncf", + "simple/cnes", "simple/cnet", "simple/cnn", + "simple/cobalt", "simple/cocacola", "simple/cockpit", "simple/cockroachlabs", @@ -10726,7 +10728,6 @@ "simple/codeforces", "simple/codefresh", "simple/codeigniter", - "simple/codeium", "simple/codemagic", "simple/codementor", "simple/codemirror", @@ -10734,6 +10735,7 @@ "simple/codepen", "simple/codeproject", "simple/coder", + "simple/coderabbit", "simple/codersrank", "simple/coderwall", "simple/codesandbox", @@ -10747,14 +10749,15 @@ "simple/coffeescript", "simple/coggle", "simple/cognizant", - "simple/coil", "simple/coinbase", "simple/coinmarketcap", + "simple/collaboraonline", "simple/comicfury", "simple/comma", "simple/commerzbank", "simple/commitlint", "simple/commodore", + "simple/commonlisp", "simple/commonworkflowlanguage", "simple/compilerexplorer", "simple/composer", @@ -10773,6 +10776,7 @@ "simple/contao", "simple/contentful", "simple/contentstack", + "simple/continente", "simple/contributorcovenant", "simple/conventionalcommits", "simple/convertio", @@ -10805,6 +10809,7 @@ "simple/creativetechnology", "simple/credly", "simple/crehana", + "simple/crewai", "simple/crewunited", "simple/criticalrole", "simple/crowdin", @@ -10812,10 +10817,11 @@ "simple/crunchbase", "simple/crunchyroll", "simple/cryengine", + "simple/cryptomator", "simple/cryptpad", "simple/crystal", "simple/csdn", - "simple/css3", + "simple/css", "simple/cssdesignawards", "simple/cssmodules", "simple/csswizardry", @@ -10830,7 +10836,7 @@ "simple/cypress", "simple/cytoscapedotjs", "simple/d", - "simple/d3dotjs", + "simple/d3", "simple/dacia", "simple/daf", "simple/dailydotdev", @@ -10873,7 +10879,6 @@ "simple/deepin", "simple/deepl", "simple/deepnote", - "simple/delicious", "simple/deliveroo", "simple/dell", "simple/delonghi", @@ -10889,7 +10894,9 @@ "simple/deutschebahn", "simple/deutschebank", "simple/deutschepost", + "simple/deutschetelekom", "simple/deutschewelle", + "simple/devbox", "simple/devdotto", "simple/devexpress", "simple/deviantart", @@ -10909,16 +10916,19 @@ "simple/directus", "simple/discogs", "simple/discord", + "simple/discorddotjs", "simple/discourse", "simple/discover", "simple/disqus", "simple/disroot", + "simple/distrobox", "simple/distrokid", "simple/django", "simple/dji", "simple/dlib", "simple/dlna", "simple/dm", + "simple/dmm", "simple/docker", "simple/docsdotrs", "simple/docsify", @@ -10927,6 +10937,8 @@ "simple/dogecoin", "simple/doi", "simple/dolby", + "simple/dolibarr", + "simple/dolphin", "simple/doordash", "simple/dota2", "simple/dotenv", @@ -10965,6 +10977,7 @@ "simple/e", "simple/e3", "simple/ea", + "simple/eac", "simple/eagle", "simple/easyeda", "simple/easyjet", @@ -11001,11 +11014,10 @@ "simple/element", "simple/elementary", "simple/elementor", + "simple/elevenlabs", "simple/eleventy", "simple/elgato", "simple/elixir", - "simple/eljueves", - "simple/ello", "simple/elm", "simple/elsevier", "simple/embarcadero", @@ -11014,10 +11026,10 @@ "simple/emby", "simple/emirates", "simple/emlakjet", - "simple/empirekred", "simple/endeavouros", - "simple/engadget", "simple/enpass", + "simple/ens", + "simple/ente", "simple/enterprisedb", "simple/envato", "simple/envoyproxy", @@ -11043,9 +11055,10 @@ "simple/ethiopianairlines", "simple/etihadairways", "simple/etsy", - "simple/eventbrite", + "simple/europeanunion", "simple/eventstore", "simple/evernote", + "simple/everydotorg", "simple/excalidraw", "simple/exercism", "simple/exordo", @@ -11055,6 +11068,7 @@ "simple/expertsexchange", "simple/expo", "simple/express", + "simple/expressdotcom", "simple/expressvpn", "simple/eyeem", "simple/f1", @@ -11082,8 +11096,8 @@ "simple/fathom", "simple/fauna", "simple/favro", + "simple/fcc", "simple/fdroid", - "simple/feathub", "simple/fedex", "simple/fedora", "simple/feedly", @@ -11099,7 +11113,9 @@ "simple/figma", "simple/figshare", "simple/fila", + "simple/filament", "simple/filedotio", + "simple/filen", "simple/files", "simple/filezilla", "simple/fineco", @@ -11128,12 +11144,12 @@ "simple/flipkart", "simple/floatplane", "simple/flood", + "simple/floorp", "simple/fluentbit", "simple/fluentd", "simple/fluke", "simple/flutter", "simple/flux", - "simple/fluxus", "simple/flydotio", "simple/flyway", "simple/fmod", @@ -11147,16 +11163,17 @@ "simple/foodpanda", "simple/ford", "simple/forgejo", + "simple/formbricks", "simple/formik", "simple/formspree", "simple/formstack", "simple/fortinet", + "simple/fortnite", "simple/fortran", "simple/fossa", "simple/fossilscm", "simple/foundryvirtualtabletop", "simple/foursquare", - "simple/foursquarecityguide", "simple/fox", "simple/foxtel", "simple/fozzy", @@ -11173,38 +11190,41 @@ "simple/freelancer", "simple/freelancermap", "simple/freenas", + "simple/freenet", "simple/freepik", + "simple/freetube", "simple/fresh", + "simple/frigate", + "simple/fritz", "simple/frontendmentor", "simple/frontify", - "simple/fsecure", "simple/fsharp", "simple/fubo", "simple/fueler", "simple/fugacloud", "simple/fujifilm", "simple/fujitsu", - "simple/funimation", "simple/furaffinity", "simple/furrynetwork", "simple/fusionauth", "simple/futurelearn", + "simple/fyle", "simple/g2", "simple/g2a", "simple/g2g", "simple/galaxus", - "simple/gameandwatch", "simple/gamebanana", "simple/gamedeveloper", "simple/gamejolt", "simple/gameloft", "simple/gamemaker", + "simple/gamescience", + "simple/gandi", "simple/garmin", "simple/gatling", "simple/gatsby", "simple/gcore", "simple/gdal", - "simple/geant", "simple/geeksforgeeks", "simple/generalelectric", "simple/generalmotors", @@ -11239,12 +11259,15 @@ "simple/gitpod", "simple/gitter", "simple/glassdoor", + "simple/gldotinet", + "simple/gleam", "simple/glide", "simple/glitch", "simple/globus", "simple/glovo", "simple/gltf", "simple/gmail", + "simple/gmx", "simple/gnome", "simple/gnometerminal", "simple/gnu", @@ -11261,7 +11284,6 @@ "simple/gogdotcom", "simple/gojek", "simple/goland", - "simple/goldenline", "simple/goldmansachs", "simple/goodreads", "simple/google", @@ -11277,6 +11299,7 @@ "simple/googlecalendar", "simple/googlecampaignmanager360", "simple/googlecardboard", + "simple/googlecast", "simple/googlechat", "simple/googlechrome", "simple/googlechronicle", @@ -11289,7 +11312,6 @@ "simple/googlecontaineroptimizedos", "simple/googledataflow", "simple/googledataproc", - "simple/googledatastudio", "simple/googledisplayandvideo360", "simple/googledocs", "simple/googledrive", @@ -11317,11 +11339,15 @@ "simple/googlesheets", "simple/googleslides", "simple/googlestreetview", + "simple/googlesummerofcode", "simple/googletagmanager", "simple/googletasks", "simple/googletranslate", + "simple/googletv", "simple/gotomeeting", + "simple/gplv3", "simple/grab", + "simple/gradio", "simple/gradle", "simple/gradleplaypublisher", "simple/grafana", @@ -11339,11 +11365,12 @@ "simple/greensock", "simple/griddotai", "simple/gridsome", + "simple/grocy", "simple/groupme", "simple/groupon", - "simple/grubhub", "simple/grunt", "simple/gsk", + "simple/gsma", "simple/gsmarenadotcom", "simple/gstreamer", "simple/gtk", @@ -11357,6 +11384,7 @@ "simple/gurobi", "simple/gusto", "simple/gutenberg", + "simple/h2database", "simple/h3", "simple/habr", "simple/hackaday", @@ -11381,8 +11409,11 @@ "simple/hasura", "simple/hatenabookmark", "simple/haveibeenpwned", + "simple/havells", "simple/haxe", + "simple/haystack", "simple/hbo", + "simple/hbomax", "simple/hcl", "simple/hdfcbank", "simple/headlessui", @@ -11391,6 +11422,7 @@ "simple/hearth", "simple/hearthisdotat", "simple/hedera", + "simple/hedgedoc", "simple/helium", "simple/helix", "simple/hellofresh", @@ -11401,7 +11433,9 @@ "simple/hepsiemlak", "simple/here", "simple/hermes", + "simple/heroicgameslauncher", "simple/heroku", + "simple/heroui", "simple/hetzner", "simple/hevy", "simple/hexlet", @@ -11425,6 +11459,8 @@ "simple/homify", "simple/honda", "simple/honey", + "simple/honeybadger", + "simple/honeygain", "simple/hono", "simple/honor", "simple/hootsuite", @@ -11437,6 +11473,8 @@ "simple/houzz", "simple/hp", "simple/hsbc", + "simple/htc", + "simple/htcvive", "simple/html5", "simple/htmlacademy", "simple/htmx", @@ -11482,6 +11520,7 @@ "simple/iheartradio", "simple/ikea", "simple/iledefrancemobilites", + "simple/ilovepdf", "simple/imagedotsc", "simple/imagej", "simple/imdb", @@ -11498,6 +11537,7 @@ "simple/inductiveautomation", "simple/inertia", "simple/infiniti", + "simple/infinityfree", "simple/influxdb", "simple/infomaniak", "simple/infoq", @@ -11508,6 +11548,7 @@ "simple/inkdrop", "simple/inkscape", "simple/inoreader", + "simple/inquirer", "simple/insomnia", "simple/inspire", "simple/insta360", @@ -11528,6 +11569,7 @@ "simple/internetcomputer", "simple/intigriti", "simple/intuit", + "simple/invidious", "simple/invision", "simple/invoiceninja", "simple/iobroker", @@ -11539,6 +11581,7 @@ "simple/iris", "simple/irobot", "simple/isc2", + "simple/isro", "simple/issuu", "simple/istio", "simple/itchdotio", @@ -11549,7 +11592,6 @@ "simple/jabber", "simple/jaeger", "simple/jaguar", - "simple/jamboard", "simple/jameson", "simple/jamstack", "simple/japanairlines", @@ -11557,6 +11599,7 @@ "simple/javascript", "simple/jbl", "simple/jcb", + "simple/jdoodle", "simple/jeep", "simple/jekyll", "simple/jellyfin", @@ -11570,6 +11613,7 @@ "simple/jfrogpipelines", "simple/jhipster", "simple/jinja", + "simple/jio", "simple/jira", "simple/jirasoftware", "simple/jitpack", @@ -11613,17 +11657,19 @@ "simple/kasasmart", "simple/kashflow", "simple/kaspersky", - "simple/katacoda", "simple/katana", "simple/kaufland", "simple/kde", + "simple/kdeneon", "simple/kdenlive", "simple/kdeplasma", "simple/kedro", "simple/keenetic", "simple/keepachangelog", "simple/keepassxc", + "simple/keeper", "simple/keeweb", + "simple/kenmei", "simple/kentico", "simple/keras", "simple/keybase", @@ -11645,7 +11691,9 @@ "simple/kirby", "simple/kit", "simple/kitsu", + "simple/kiwix", "simple/klarna", + "simple/kleinanzeigen", "simple/klm", "simple/klook", "simple/knative", @@ -11666,15 +11714,19 @@ "simple/kong", "simple/kongregate", "simple/konva", + "simple/koreader", "simple/kotlin", "simple/koyeb", + "simple/kred", "simple/krita", "simple/ktm", "simple/ktor", "simple/kuaishou", "simple/kubernetes", + "simple/kubespray", "simple/kubuntu", "simple/kucoin", + "simple/kueski", "simple/kuma", "simple/kununu", "simple/kuula", @@ -11685,6 +11737,8 @@ "simple/lamborghini", "simple/landrover", "simple/langchain", + "simple/langflow", + "simple/langgraph", "simple/languagetool", "simple/lapce", "simple/laragon", @@ -11746,11 +11800,11 @@ "simple/lineageos", "simple/linear", "simple/lining", - "simple/linkedin", "simple/linkerd", "simple/linkfire", "simple/linksys", "simple/linktree", + "simple/linphone", "simple/lintcode", "simple/linux", "simple/linuxcontainers", @@ -11785,8 +11839,10 @@ "simple/lootcrate", "simple/lospec", "simple/lotpolishairlines", + "simple/lottiefiles", "simple/ltspice", "simple/lua", + "simple/luau", "simple/lubuntu", "simple/lucia", "simple/lucid", @@ -11796,14 +11852,15 @@ "simple/lumen", "simple/lunacy", "simple/lutris", + "simple/lvgl", "simple/lydia", "simple/lyft", "simple/maas", "simple/macos", "simple/macpaw", + "simple/macports", "simple/macys", "simple/magasinsu", - "simple/magento", "simple/magic", "simple/magisk", "simple/mahindra", @@ -11823,14 +11880,16 @@ "simple/mamp", "simple/man", "simple/manageiq", + "simple/mangaupdates", "simple/manjaro", "simple/mantine", "simple/mapbox", + "simple/mapillary", "simple/maplibre", + "simple/maptiler", "simple/mariadb", "simple/mariadbfoundation", "simple/markdown", - "simple/marketo", "simple/marko", "simple/marriott", "simple/marvelapp", @@ -11852,12 +11911,14 @@ "simple/maxplanckgesellschaft", "simple/maytag", "simple/mazda", + "simple/maze", "simple/mcafee", "simple/mcdonalds", "simple/mclaren", "simple/mdbook", "simple/mdnwebdocs", "simple/mdx", + "simple/mealie", "simple/mediafire", "simple/mediamarkt", "simple/mediapipe", @@ -11873,7 +11934,6 @@ "simple/mendeley", "simple/mentorcruise", "simple/mercadopago", - "simple/mercedes", "simple/merck", "simple/mercurial", "simple/mermaid", @@ -11882,6 +11942,7 @@ "simple/metabase", "simple/metacritic", "simple/metafilter", + "simple/metager", "simple/metasploit", "simple/meteor", "simple/metro", @@ -11889,16 +11950,17 @@ "simple/metrodemadrid", "simple/metrodeparis", "simple/mewe", + "simple/mezmo", "simple/mg", "simple/microbit", "simple/microdotblog", "simple/microeditor", - "simple/microgenetics", "simple/micropython", "simple/microstation", "simple/microstrategy", "simple/midi", "simple/migadu", + "simple/mihon", "simple/mihoyo", "simple/mikrotik", "simple/milanote", @@ -11913,6 +11975,7 @@ "simple/miraheze", "simple/miro", "simple/misskey", + "simple/mistralai", "simple/mitsubishi", "simple/mix", "simple/mixcloud", @@ -11927,6 +11990,7 @@ "simple/modin", "simple/modrinth", "simple/modx", + "simple/mojeek", "simple/moleculer", "simple/momenteo", "simple/monero", @@ -11949,6 +12013,7 @@ "simple/morrisons", "simple/moscowmetro", "simple/motorola", + "simple/movistar", "simple/mozilla", "simple/mpv", "simple/mqtt", @@ -11960,6 +12025,7 @@ "simple/mui", "simple/mulesoft", "simple/muller", + "simple/mullvad", "simple/multisim", "simple/mumble", "simple/muo", @@ -11970,6 +12036,7 @@ "simple/myanimelist", "simple/myget", "simple/myob", + "simple/myshows", "simple/myspace", "simple/mysql", "simple/n26", @@ -11981,6 +12048,7 @@ "simple/namuwiki", "simple/nano", "simple/nanostores", + "simple/napster", "simple/nasa", "simple/nationalgrid", "simple/nationalrail", @@ -11994,6 +12062,7 @@ "simple/near", "simple/nebula", "simple/nec", + "simple/nederlandsespoorwegen", "simple/neo4j", "simple/neovim", "simple/neptune", @@ -12005,6 +12074,7 @@ "simple/neteasecloudmusic", "simple/netflix", "simple/netgear", + "simple/netim", "simple/netlify", "simple/nette", "simple/netto", @@ -12012,34 +12082,36 @@ "simple/newbalance", "simple/newegg", "simple/newjapanprowrestling", + "simple/newpipe", "simple/newrelic", "simple/newyorktimes", "simple/nexon", + "simple/nextbike", "simple/nextbilliondotai", "simple/nextcloud", "simple/nextdns", "simple/nextdoor", "simple/nextdotjs", + "simple/nextflow", "simple/nextra", - "simple/nextui", "simple/nexusmods", "simple/nfc", + "simple/nfcore", "simple/nginx", "simple/nginxproxymanager", "simple/ngrok", "simple/ngrx", "simple/nhl", + "simple/nhost", "simple/nicehash", "simple/niconico", "simple/nike", "simple/nikon", "simple/nim", - "simple/nintendo", - "simple/nintendo3ds", - "simple/nintendogamecube", - "simple/nintendoswitch", "simple/nissan", "simple/nixos", + "simple/nobaralinux", + "simple/nodebb", "simple/nodedotjs", "simple/nodemon", "simple/nodered", @@ -12051,6 +12123,7 @@ "simple/normalizedotcss", "simple/norton", "simple/norwegian", + "simple/notebooklm", "simple/notepadplusplus", "simple/notion", "simple/notist", @@ -12070,17 +12143,20 @@ "simple/nunjucks", "simple/nushell", "simple/nutanix", - "simple/nuxtdotjs", + "simple/nuxt", "simple/nvidia", "simple/nvm", "simple/nx", "simple/nxp", "simple/nzxt", "simple/o2", + "simple/obb", "simple/observable", "simple/obsidian", "simple/obsstudio", + "simple/obtainium", "simple/ocaml", + "simple/oclc", "simple/oclif", "simple/octanerender", "simple/octave", @@ -12088,6 +12164,7 @@ "simple/octoprint", "simple/octopusdeploy", "simple/oculus", + "simple/odin", "simple/odnoklassniki", "simple/odoo", "simple/odysee", @@ -12096,12 +12173,15 @@ "simple/okta", "simple/okx", "simple/ollama", + "simple/omadacloud", "simple/oneplus", + "simple/onestream", "simple/onlyfans", "simple/onlyoffice", "simple/onnx", "simple/onstar", "simple/opel", + "simple/open3d", "simple/openaccess", "simple/openai", "simple/openaigym", @@ -12111,6 +12191,7 @@ "simple/openbugbounty", "simple/opencollective", "simple/opencontainersinitiative", + "simple/opencritic", "simple/opencv", "simple/openfaas", "simple/opengl", @@ -12147,7 +12228,6 @@ "simple/opsgenie", "simple/opslevel", "simple/optimism", - "simple/oracle", "simple/orange", "simple/orcid", "simple/oreilly", @@ -12158,6 +12238,7 @@ "simple/osf", "simple/osgeo", "simple/oshkosh", + "simple/osmand", "simple/osmc", "simple/osu", "simple/otto", @@ -12176,6 +12257,7 @@ "simple/paddle", "simple/paddlepaddle", "simple/paddypower", + "simple/padlet", "simple/pagekit", "simple/pagerduty", "simple/pagespeedinsights", @@ -12190,6 +12272,7 @@ "simple/paperlessngx", "simple/paperspace", "simple/paperswithcode", + "simple/paradoxinteractive", "simple/paramountplus", "simple/paritysubstrate", "simple/parrotsecurity", @@ -12202,6 +12285,7 @@ "simple/payloadcms", "simple/payoneer", "simple/paypal", + "simple/paysafe", "simple/paytm", "simple/pcgamingwiki", "simple/pdm", @@ -12235,6 +12319,7 @@ "simple/photon", "simple/photopea", "simple/php", + "simple/phpbb", "simple/phpmyadmin", "simple/phpstorm", "simple/piaggiogroup", @@ -12244,6 +12329,7 @@ "simple/picnic", "simple/picpay", "simple/picrew", + "simple/picsart", "simple/picxy", "simple/pihole", "simple/pimcore", @@ -12288,7 +12374,6 @@ "simple/plume", "simple/pluralsight", "simple/plurk", - "simple/pluscodes", "simple/pm2", "simple/pnpm", "simple/pocket", @@ -12299,8 +12384,6 @@ "simple/podman", "simple/poe", "simple/poetry", - "simple/pointy", - "simple/pokemon", "simple/polars", "simple/polestar", "simple/polkadot", @@ -12312,6 +12395,7 @@ "simple/popos", "simple/porkbun", "simple/porsche", + "simple/portableappsdotcom", "simple/portainer", "simple/portswigger", "simple/posit", @@ -12325,6 +12409,7 @@ "simple/preact", "simple/precommit", "simple/prefect", + "simple/premid", "simple/premierleague", "simple/prepbytes", "simple/prestashop", @@ -12333,11 +12418,9 @@ "simple/pretzel", "simple/prevention", "simple/prezi", - "simple/prime", "simple/primefaces", "simple/primeng", "simple/primereact", - "simple/primevideo", "simple/primevue", "simple/printables", "simple/prisma", @@ -12406,7 +12489,10 @@ "simple/qlik", "simple/qmk", "simple/qnap", + "simple/qodo", + "simple/qq", "simple/qt", + "simple/quad9", "simple/qualcomm", "simple/qualtrics", "simple/qualys", @@ -12434,12 +12520,13 @@ "simple/racket", "simple/radar", "simple/radarr", - "simple/radiopublic", + "simple/radiofrance", "simple/radixui", "simple/radstudio", "simple/railway", "simple/rainmeter", "simple/rakuten", + "simple/rakutenkobo", "simple/ram", "simple/rancher", "simple/rapid", @@ -12465,7 +12552,6 @@ "simple/readdotcv", "simple/readme", "simple/readthedocs", - "simple/realm", "simple/reason", "simple/reasonstudios", "simple/recoil", @@ -12487,6 +12573,7 @@ "simple/redwoodjs", "simple/reebok", "simple/refine", + "simple/refinedgithub", "simple/relay", "simple/relianceindustrieslimited", "simple/remark", @@ -12498,6 +12585,7 @@ "simple/renovate", "simple/renpy", "simple/renren", + "simple/replicate", "simple/replit", "simple/republicofgamers", "simple/rescript", @@ -12511,10 +12599,10 @@ "simple/retropie", "simple/revanced", "simple/revealdotjs", + "simple/revenuecat", "simple/reverbnation", "simple/revoltdotchat", "simple/revolut", - "simple/revue", "simple/rewe", "simple/rezgo", "simple/rhinoceros", @@ -12546,6 +12634,7 @@ "simple/roll20", "simple/rollsroyce", "simple/rollupdotjs", + "simple/rook", "simple/roon", "simple/rootme", "simple/roots", @@ -12585,6 +12674,7 @@ "simple/sabanci", "simple/safari", "simple/sage", + "simple/sagemath", "simple/sahibinden", "simple/sailfishos", "simple/sailsdotjs", @@ -12594,7 +12684,6 @@ "simple/samsclub", "simple/samsung", "simple/samsungpay", - "simple/sandisk", "simple/sanfranciscomunicipalrailway", "simple/sanic", "simple/sanity", @@ -12608,6 +12697,7 @@ "simple/saucelabs", "simple/saudia", "simple/scala", + "simple/scalar", "simple/scaleway", "simple/scania", "simple/schneiderelectric", @@ -12626,6 +12716,7 @@ "simple/scrumalliance", "simple/scrutinizerci", "simple/scylladb", + "simple/seafile", "simple/seagate", "simple/searxng", "simple/seat", @@ -12680,12 +12771,15 @@ "simple/siemens", "simple/sifive", "simple/signal", + "simple/silverairways", "simple/similarweb", "simple/simkl", "simple/simpleanalytics", "simple/simpleicons", + "simple/simplelocalize", "simple/simplelogin", "simple/simplenote", + "simple/simplex", "simple/sinaweibo", "simple/singaporeairlines", "simple/singlestore", @@ -12700,7 +12794,6 @@ "simple/skoda", "simple/sky", "simple/skypack", - "simple/skyrock", "simple/slack", "simple/slackware", "simple/slashdot", @@ -12710,12 +12803,12 @@ "simple/slint", "simple/smart", "simple/smartthings", - "simple/smashdotgg", "simple/smashingmagazine", "simple/smrt", "simple/smugmug", "simple/snapchat", "simple/snapcraft", + "simple/snapdragon", "simple/sncf", "simple/snort", "simple/snowflake", @@ -12723,7 +12816,9 @@ "simple/snyk", "simple/socialblade", "simple/society6", + "simple/socket", "simple/socketdotio", + "simple/softcatala", "simple/softpedia", "simple/sogou", "simple/solana", @@ -12732,9 +12827,9 @@ "simple/sololearn", "simple/solus", "simple/sonar", - "simple/sonarcloud", - "simple/sonarlint", - "simple/sonarqube", + "simple/sonarqubecloud", + "simple/sonarqubeforide", + "simple/sonarqubeserver", "simple/sonarr", "simple/sonatype", "simple/songkick", @@ -12767,7 +12862,6 @@ "simple/spigotmc", "simple/spine", "simple/spinnaker", - "simple/spinrilla", "simple/splunk", "simple/spoj", "simple/spond", @@ -12794,7 +12888,6 @@ "simple/stackexchange", "simple/stackhawk", "simple/stackoverflow", - "simple/stackpath", "simple/stackshare", "simple/stadia", "simple/staffbase", @@ -12805,6 +12898,8 @@ "simple/stardock", "simple/starlingbank", "simple/starship", + "simple/startdotgg", + "simple/startpage", "simple/startrek", "simple/starz", "simple/statamic", @@ -12823,7 +12918,6 @@ "simple/stencil", "simple/stencyl", "simple/stimulus", - "simple/stitcher", "simple/stmicroelectronics", "simple/stockx", "simple/stopstalk", @@ -12834,12 +12928,12 @@ "simple/streamlabs", "simple/streamlit", "simple/streamrunners", + "simple/stremio", "simple/stripe", "simple/strongswan", "simple/stryker", "simple/stubhub", "simple/studio3t", - "simple/studyverse", "simple/styledcomponents", "simple/stylelint", "simple/styleshare", @@ -12858,6 +12952,7 @@ "simple/supercrease", "simple/supermicro", "simple/superuser", + "simple/surfshark", "simple/surrealdb", "simple/surveymonkey", "simple/suse", @@ -12874,6 +12969,7 @@ "simple/swift", "simple/swiggy", "simple/swiper", + "simple/swisscows", "simple/swr", "simple/symantec", "simple/symbolab", @@ -12884,7 +12980,6 @@ "simple/synology", "simple/system76", "simple/tabelog", - "simple/tableau", "simple/tablecheck", "simple/tacobell", "simple/tado", @@ -12920,11 +13015,12 @@ "simple/teespring", "simple/tekton", "simple/tele5", + "simple/telefonica", "simple/telegram", "simple/telegraph", + "simple/telenor", "simple/telequebec", "simple/temporal", - "simple/tencentqq", "simple/tensorflow", "simple/teradata", "simple/teratail", @@ -12952,9 +13048,11 @@ "simple/themoviedatabase", "simple/thenorthface", "simple/theodinproject", + "simple/theplanetarysociety", "simple/theregister", "simple/thesoundsresource", "simple/thespritersresource", + "simple/thestorygraph", "simple/thewashingtonpost", "simple/theweatherchannel", "simple/thingiverse", @@ -12988,7 +13086,6 @@ "simple/tinyletter", "simple/tistory", "simple/tldraw", - "simple/tmobile", "simple/tmux", "simple/todoist", "simple/toggl", @@ -12997,11 +13094,13 @@ "simple/toll", "simple/toml", "simple/tomorrowland", + "simple/tomtom", "simple/ton", "simple/topcoder", "simple/topdotgg", "simple/toptal", "simple/torbrowser", + "simple/torizon", "simple/torproject", "simple/toshiba", "simple/totvs", @@ -13025,11 +13124,13 @@ "simple/treehouse", "simple/trello", "simple/trendmicro", + "simple/tresorit", "simple/treyarch", "simple/tricentis", "simple/trilium", "simple/triller", "simple/trillertv", + "simple/trimble", "simple/trino", "simple/tripadvisor", "simple/tripdotcom", @@ -13054,9 +13155,11 @@ "simple/turbosquid", "simple/turkishairlines", "simple/turso", - "simple/tutanota", + "simple/tuta", + "simple/tuxedocomputers", "simple/tv4play", "simple/tvtime", + "simple/twenty", "simple/twilio", "simple/twinkly", "simple/twinmotion", @@ -13076,12 +13179,16 @@ "simple/ubuntumate", "simple/udacity", "simple/udemy", + "simple/udotsdotnews", "simple/ufc", "simple/uikit", "simple/uipath", + "simple/ukca", + "simple/ultralytics", "simple/ulule", "simple/umami", "simple/umbraco", + "simple/umbrel", "simple/uml", "simple/unacademy", "simple/underarmour", @@ -13109,12 +13216,13 @@ "simple/ups", "simple/upstash", "simple/uptimekuma", - "simple/uptobox", "simple/upwork", + "simple/uservoice", "simple/usps", "simple/utorrent", "simple/uv", "simple/v", + "simple/v0", "simple/v2ex", "simple/v8", "simple/vaadin", @@ -13122,6 +13230,7 @@ "simple/vala", "simple/valorant", "simple/valve", + "simple/vanillaextract", "simple/vapor", "simple/vault", "simple/vaultwarden", @@ -13135,7 +13244,9 @@ "simple/veepee", "simple/vega", "simple/vegas", + "simple/velocity", "simple/velog", + "simple/vencord", "simple/venmo", "simple/vercel", "simple/verdaccio", @@ -13151,9 +13262,11 @@ "simple/viblo", "simple/victoriametrics", "simple/victronenergy", + "simple/vikunja", "simple/vim", "simple/vimeo", "simple/vimeolivestream", + "simple/vinted", "simple/virgin", "simple/virginatlantic", "simple/virginmedia", @@ -13174,6 +13287,7 @@ "simple/vlcmediaplayer", "simple/vmware", "simple/vodafone", + "simple/voelkner", "simple/voidlinux", "simple/voipdotms", "simple/volkswagen", @@ -13219,6 +13333,7 @@ "simple/webassembly", "simple/webauthn", "simple/webcomponentsdotorg", + "simple/webdotde", "simple/webdriverio", "simple/webex", "simple/webflow", @@ -13244,10 +13359,10 @@ "simple/wetransfer", "simple/wezterm", "simple/wgpu", + "simple/what3words", "simple/whatsapp", "simple/wheniwork", - "simple/wii", - "simple/wiiu", + "simple/wikibooks", "simple/wikidata", "simple/wikidotgg", "simple/wikidotjs", @@ -13255,8 +13370,12 @@ "simple/wikimediafoundation", "simple/wikipedia", "simple/wikiquote", + "simple/wikisource", + "simple/wikiversity", "simple/wikivoyage", "simple/winamp", + "simple/windsurf", + "simple/wine", "simple/wipro", "simple/wire", "simple/wireguard", @@ -13282,6 +13401,7 @@ "simple/writedotas", "simple/wwe", "simple/wwise", + "simple/wxt", "simple/wykop", "simple/wyze", "simple/x", @@ -13302,6 +13422,8 @@ "simple/xsplit", "simple/xstate", "simple/xubuntu", + "simple/xyflow", + "simple/yaak", "simple/yabai", "simple/yale", "simple/yamahacorporation", @@ -13314,6 +13436,8 @@ "simple/yeti", "simple/yii", "simple/yoast", + "simple/yolo", + "simple/youhodler", "simple/youtube", "simple/youtubegaming", "simple/youtubekids", @@ -13339,6 +13463,7 @@ "simple/zebratechnologies", "simple/zedindustries", "simple/zelle", + "simple/zenbrowser", "simple/zend", "simple/zendesk", "simple/zenn", @@ -13346,7 +13471,6 @@ "simple/zensar", "simple/zerodha", "simple/zerotier", - "simple/zerply", "simple/zettlr", "simple/zhihu", "simple/zig", diff --git a/docs/schema/extensions/pymdownx.json b/docs/schema/extensions/pymdownx.json index 9da8895fcd4..137bb304f48 100644 --- a/docs/schema/extensions/pymdownx.json +++ b/docs/schema/extensions/pymdownx.json @@ -65,6 +65,73 @@ } ] }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "pymdownx.blocks.caption": { + "title": "Caption – Python Markdown Extensions", + "markdownDescription": "https://squidfunk.github.io/mkdocs-material/setup/extensions/python-markdown-extensions/#caption", + "type": "object", + "properties": { + "types": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#global-options", + "type": "array", + "items": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#configuring-figure-types", + "oneOf": [ + { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#configuring-figure-types", + "type":"string" + }, + { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#configuring-figure-types", + "type": "object", + "properties": { + "name": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#configuring-figure-types", + "type": "string" + }, + "prefix": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#configuring-figure-types", + "type": "string" + } + } + } + ] + }, + "uniqueItems": true, + "minItems": 1 + }, + "prepend": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#global-options", + "type": "boolean", + "default": false + }, + "auto": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#global-options", + "type": "boolean", + "default": true + }, + "auto_leval": { + "markdownDescription": "https://facelessuser.github.io/pymdown-extensions/extensions/blocks/plugins/caption/#global-options", + "type": "integer", + "default": 0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "title": "Caption – Python Markdown Extensions", + "markdownDescription": "https://squidfunk.github.io/mkdocs-material/setup/extensions/python-markdown-extensions/#caption", + "const": "pymdownx.blocks.caption" + } + ] + }, { "oneOf": [ { diff --git a/docs/schema/plugins.json b/docs/schema/plugins.json index e1c1ef94147..5c436205b2e 100644 --- a/docs/schema/plugins.json +++ b/docs/schema/plugins.json @@ -114,16 +114,16 @@ "$ref": "https://raw.githubusercontent.com/prcr/mkdocs-meta-descriptions-plugin/main/schema.json" }, { - "$ref": "https://raw.githubusercontent.com/mkdocstrings/mkdocstrings/master/docs/schema.json" + "$ref": "https://raw.githubusercontent.com/mkdocstrings/mkdocstrings/main/docs/schema.json" }, { - "$ref": "https://raw.githubusercontent.com/pawamoy/mkdocs-coverage/master/docs/schema.json" + "$ref": "https://raw.githubusercontent.com/pawamoy/mkdocs-coverage/main/docs/schema.json" }, { - "$ref": "https://raw.githubusercontent.com/pawamoy/mkdocs-spellcheck/master/docs/schema.json" + "$ref": "https://raw.githubusercontent.com/pawamoy/mkdocs-spellcheck/main/docs/schema.json" }, { - "$ref": "https://raw.githubusercontent.com/pawamoy/markdown-exec/master/docs/schema.json" + "$ref": "https://raw.githubusercontent.com/pawamoy/markdown-exec/main/docs/schema.json" }, { "$ref": "https://raw.githubusercontent.com/timvink/mkdocs-table-reader-plugin/master/docs/schema.json" diff --git a/docs/schema/validation.json b/docs/schema/validation.json index 94c0c3a69b3..dd61f65a16f 100644 --- a/docs/schema/validation.json +++ b/docs/schema/validation.json @@ -43,7 +43,10 @@ }, "absolute_links": { "title": "warning level when absolute links are used", - "$ref": "#/$defs/warning_levels" + "oneOf": [ + { "$ref": "#/$defs/warning_levels" }, + { "enum": ["relative_to_docs"] } + ] }, "unrecognized_links": { "title": "warning level when a relative link cannot be resolved to a document", diff --git a/docs/setup/building-for-offline-usage.md b/docs/setup/building-for-offline-usage.md index 5c13b574269..9ceacf071c2 100644 --- a/docs/setup/building-for-offline-usage.md +++ b/docs/setup/building-for-offline-usage.md @@ -1,7 +1,7 @@ # Building for offline usage If you want to ship your documentation together with your product, MkDocs has -you covered – with support from themes, [MkDocs] allows for building +you covered – with support from themes, [MkDocs] supports building offline-capable documentation. Notably, Material for MkDocs offers offline support for many of its features. diff --git a/docs/setup/changing-the-colors.md b/docs/setup/changing-the-colors.md index 25d93ce1f44..c306c4b63d8 100644 --- a/docs/setup/changing-the-colors.md +++ b/docs/setup/changing-the-colors.md @@ -340,7 +340,7 @@ add: === ":octicons-file-code-16: `docs/stylesheets/extra.css`" ``` css - :root { + :root > * { --md-primary-fg-color: #EE0F0F; --md-primary-fg-color--light: #ECB7B7; --md-primary-fg-color--dark: #90030C; diff --git a/docs/setup/changing-the-logo-and-icons.md b/docs/setup/changing-the-logo-and-icons.md index c8cdd05ff74..c26529cfcd5 100644 --- a/docs/setup/changing-the-logo-and-icons.md +++ b/docs/setup/changing-the-logo-and-icons.md @@ -68,7 +68,7 @@ theme: favicon: images/favicon.png ``` - [Favicon default]: https://github.com/squidfunk/mkdocs-material/blob/master/material/assets/images/favicon.png + [Favicon default]: https://github.com/squidfunk/mkdocs-material/blob/master/material/templates/assets/images/favicon.png ### Site icons diff --git a/docs/setup/setting-up-a-blog.md b/docs/setup/setting-up-a-blog.md index 35dd9d66552..baabf57c654 100644 --- a/docs/setup/setting-up-a-blog.md +++ b/docs/setup/setting-up-a-blog.md @@ -22,6 +22,7 @@ __Check out our [blog], which is created with the new [built-in blog plugin]!__ + The built-in blog plugin adds support for building a blog from a folder of posts, which are annotated with dates and other structured data. First, add the @@ -447,8 +448,7 @@ slug: hello-world #### Adding related links - - + Related links offer the perfect way to prominently add a _further reading_ @@ -519,7 +519,7 @@ when the site is being built. Of course, you can also reference assets from posts outside of the `posts` directory. The [built-in blog plugin] ensures that all links are correct. -#### Pinning a post :material-alert-decagram:{ .mdx-pulse title="Added on February 24, 2024" } +#### Pinning a post @@ -544,10 +544,10 @@ descending order. #### Setting the reading time -When [enabled], the [readtime] package is used to compute the expected reading -time of each post, which is rendered as part of the post and post excerpt. -Nowadays, many blogs show reading times, which is why the [built-in blog plugin] -offers this capability as well. +When [enabled], the reading the expected reading time of each post is computed, +which is rendered as part of the post and post excerpt. Nowadays, many blogs +show reading times, which is why the [built-in blog plugin] offers this +capability as well. Sometimes, however, the computed reading time might not feel accurate, or result in odd and unpleasant numbers. For this reason, reading time can be @@ -566,13 +566,19 @@ readtime: 15 This will disable automatic reading time computation. - [readtime]: https://pypi.org/project/readtime/ +!!! warning "Chinese, Japanese and Korean characters" + + Reading time computation currently does not take segmentation of Chinese, + Japanese and Korean characters into account. This means that the reading + time for posts in these languages may be inaccurate. We're planning on + adding support in the future. In the meantime, please use the `readtime` + front matter property to set the reading time. + [enabled]: ../plugins/blog.md#config.post_readtime #### Setting defaults - - + @@ -638,8 +644,7 @@ nav: ### Custom index pages - - + If you want to add custom content to automatically generated [archive] and diff --git a/docs/setup/setting-up-navigation.md b/docs/setup/setting-up-navigation.md index 3aa3b765ed1..c9a61bab07c 100644 --- a/docs/setup/setting-up-navigation.md +++ b/docs/setup/setting-up-navigation.md @@ -91,7 +91,7 @@ The progress indicator will only show if the page hasn't finished loading after 400ms, so that fast connections will never show it for a better instant experience. -### Instant previews :material-alert-decagram:{ .mdx-pulse title="Added on January 28, 2024" } +### Instant previews @@ -137,12 +137,13 @@ instant previews on a per-page or per-section level for your documentation: ``` yaml markdown_extensions: - material.extensions.preview: - targets: - include: - - changelog/index.md - - customization.md - - insiders/changelog/* - - setup/extensions/* + configurations: + - targets: + include: + - changelog/index.md + - customization.md + - insiders/changelog/* + - setup/extensions/* ``` The above configuration is what we use for our documentation. We've enabled @@ -154,16 +155,17 @@ as well as for all Markdown extensions that we support. ``` yaml markdown_extensions: - material.extensions.preview: - sources: # (1)! - include: - - ... - exclude: - - ... - targets: # (2)! - include: - - ... - exclude: - - ... + configurations: + - sources: # (1)! + include: + - ... + exclude: + - ... + targets: # (2)! + include: + - ... + exclude: + - ... ``` 1. Sources specify the pages _on_ which instant previews should be enabled. @@ -172,6 +174,10 @@ as well as for all Markdown extensions that we support. evaluated on top of inclusion, so if a page is matched by both, it will be excluded. + Note that you can define multiple items under the `configurations` + setting, which allows to precisely control where instant previews are + shown. + 2. Targets specify the pages _to_ which instant previews should be enabled. This is the recommended way to enable instant previews. --- diff --git a/docs/setup/setting-up-site-analytics.md b/docs/setup/setting-up-site-analytics.md index d1dc0865658..5a8c523036a 100644 --- a/docs/setup/setting-up-site-analytics.md +++ b/docs/setup/setting-up-site-analytics.md @@ -98,8 +98,8 @@ integrated with the [cookie consent] feature[^2]. 1. Go to your Google Analytics __dashboard__ - 2. Go to the __configure__ page on the left hand menu, then select - __custom definitions__ + 2. Go to the __Admin__ page on the left hand menu (at the bottom), then select + __custom definitions__ on the __Data display__ card 3. Click the __custom metrics__ tab and then __create custom metrics__, enter the following values: @@ -273,25 +273,29 @@ generated by users interacting with the feedback widget with the help of some === ":octicons-file-code-16: `docs/javascripts/feedback.js`" ``` js - var feedback = document.forms.feedback - feedback.hidden = false // (1)! - - feedback.addEventListener("submit", function(ev) { - ev.preventDefault() - - var page = document.location.pathname // (2)! - var data = ev.submitter.getAttribute("data-md-value") - - console.log(page, data) // (3)! - - feedback.firstElementChild.disabled = true // (4)! - - var note = feedback.querySelector( - ".md-feedback__note [data-md-value='" + data + "']" - ) - if (note) - note.hidden = false // (5)! - }) + document$.subscribe(function() { + var feedback = document.forms.feedback + if (typeof feedback === "undefined") return + + feedback.hidden = false // (1)! + + feedback.addEventListener("submit", function(ev) { + ev.preventDefault() + + var page = document.location.pathname // (2)! + var data = ev.submitter.getAttribute("data-md-value") + + console.log(page, data) // (3)! + + feedback.firstElementChild.disabled = true // (4)! + + var note = feedback.querySelector( + ".md-feedback__note [data-md-value='" + data + "']" + ) + if (note) + note.hidden = false // (5)! + }) + } ``` 1. The feedback widget is hidden by default so that it does not appear when diff --git a/docs/setup/setting-up-social-cards.md b/docs/setup/setting-up-social-cards.md index 0603cb08cad..53fc620f0ca 100644 --- a/docs/setup/setting-up-social-cards.md +++ b/docs/setup/setting-up-social-cards.md @@ -37,6 +37,7 @@ Social card of our [formatting] reference + The built-in social plugin automatically generate a custom preview image for each page. Install all [dependencies for image processing] and add the diff --git a/docs/setup/setting-up-tags.md b/docs/setup/setting-up-tags.md index 644ea45e667..af4877a6e43 100644 --- a/docs/setup/setting-up-tags.md +++ b/docs/setup/setting-up-tags.md @@ -190,25 +190,12 @@ Following is a list of relevant tags: ``` -Then in your `mkdocs.yml` file, add the following. - -``` yaml -plugins: - - tags: - tags_file: tags.md # (1)! -``` - -1. This setting is not necessary when using [Insiders]. - -Note that the path to `tags.md` is relative to the `docs/` directory. - The tags marker specifies the position of the tags index, i.e. it is replaced with the actual tags index when the page is rendered. You can include arbitrary content before and after the marker: [![Tags index][tags index enabled]][tags index enabled] - [tags.tags_file]: #tags-file [tags index enabled]: ../assets/screenshots/tags-index.png ### Advanced features @@ -224,8 +211,7 @@ for an arbitrary number of tags indexes (listings), [scoped listings], #### Configurable listings - - + Listings can be configured in `mkdocs.yml` or directly at the location of the diff --git a/docs/setup/setting-up-versioning.md b/docs/setup/setting-up-versioning.md index cc90634fa47..7d62a3bf505 100644 --- a/docs/setup/setting-up-versioning.md +++ b/docs/setup/setting-up-versioning.md @@ -13,6 +13,7 @@ documentation remain untouched. + [mike] makes it easy to deploy multiple versions of your project documentation. It integrates natively with Material for MkDocs and can be enabled via diff --git a/docs/tutorials/blogs/basic.md b/docs/tutorials/blogs/basic.md index 5d193aba65e..f02548c4675 100644 --- a/docs/tutorials/blogs/basic.md +++ b/docs/tutorials/blogs/basic.md @@ -53,7 +53,7 @@ in the `mkdocs.yml`. !!! example "Set up a blog" If you have not done so already, create a project for your blog, - then edit the `mkdocs.yml` file to make sure if has the following content: + then edit the `mkdocs.yml` file to make sure it has the following content: ```yaml site_name: Blog Tutorial @@ -143,7 +143,7 @@ header to indicate that a post is still in draft form. Create a second blog post in `docs/blogs/posts/draft.md` with the following contents: - ```hl_lines="3" + ```hl_lines="4" --- date: created: 2024-01-01 @@ -240,7 +240,7 @@ attribute in the page header: Add the `pin` attribute to your first blog post: - ```hl_lines="5" + ```hl_lines="6" --- date: created: 2023-12-31 @@ -254,13 +254,12 @@ attribute in the page header: its publication date is prior to other posts. A small pin icon shows that the post has been pinned. -### Related links +### Related links When your blog is part of a wider site such as technical documentation, you will want to provide links from blog posts into your other content. One way you -can do this is to have a related links section. In the [Insiders Edition], the -blog plugin can create one for you if you provide link targets in your page -header: +can do this is to have a related links section. The blog plugin can create one +for you if you provide link targets in your page header: !!! example "Add a related links section " @@ -306,16 +305,15 @@ The plugin renders related links in the left sidebar on screens that are wide enough and at the bottom of the post on narrow screens. Change the size of your browser window to see this in action. -## Meta plugin +## Meta plugin -The Meta plugin is available in the [Insiders Edition]. -It helps simplify the management of metadata that is common to a group of -files in the same subdirectory. Instead of having to repeat the -same metadata in the page headers of a number of files, you can add a -`.meta.yml` file in the directory and the Meta plugin will merge its contents -into the headers of all the pages contained. -Settings from the page header take precedence, so you can always override -settings by adding them to a post's header. +The Meta plugin helps simplify the management of metadata that is common to a +group of files in the same subdirectory. Instead of having to repeat the same +metadata in the page headers of a number of files, you can add a `.meta.yml` +file in the directory and the Meta plugin will merge its contents into the +headers of all the pages contained. Settings from the page header take +precedence, so you can always override settings by adding them to a post's +header. For example, you may want to manage drafts by keeping them in a directory together so that they are not only flagged as drafts but also easier to find. @@ -342,7 +340,9 @@ output to the files to figure out which posts are drafts.) ``` === "Windows" - TODO + ```powershell + $ mkdir docs\blog\posts\drafts + ``` Now, within this folder, crate a file `.meta.yml` that contains: @@ -355,6 +355,7 @@ output to the files to figure out which posts are drafts.) while in the version built for publication it does not appear. To move a post from draft status to published, simply move it outside `drafts/`. +[meta]: ../../plugins/meta.md [Insiders Edition]: ../../insiders/index.md ## What's next? diff --git a/docs/tutorials/blogs/engage.md b/docs/tutorials/blogs/engage.md index 31505a48dd8..2fa60bf673a 100644 --- a/docs/tutorials/blogs/engage.md +++ b/docs/tutorials/blogs/engage.md @@ -4,7 +4,7 @@ You can foster reader engagement and improve the dissemination of content on your blog by providing an RSS feed that people can subscribe to and by integrating a discussion system. To learn more about who is or is not reading your posts, you may want to integrate an analytics system. You may also want -to post on social media when you public a new blog post. This tutorial gives +to post on social media when you publish a new blog post. This tutorial gives you a leg up on all of these topics. __Time required:__ typically 30 minutes diff --git a/docs/tutorials/blogs/navigation.md b/docs/tutorials/blogs/navigation.md index f0b0c5c5230..762f99ebea8 100644 --- a/docs/tutorials/blogs/navigation.md +++ b/docs/tutorials/blogs/navigation.md @@ -79,7 +79,7 @@ listings by month, you can configure the date format for the archive. archive_date_format: MMMM yyyy ``` - If you do not want the full month name, you can make the the date + If you do not want the full month name, you can make the date configuration `MM/yyyy`, for example. If you want to add the day, you can add a placeholder for them. @@ -230,7 +230,7 @@ indexes, scoped listings, shadow tags, nested tags, and much more. - Usage: usage.md - Blog: - blog/index.md - Tags: blog/tags.md + - Tags: blog/tags.md ``` The tag index will be appended to the configured page, which you should diff --git a/docs/tutorials/social/basic.md b/docs/tutorials/social/basic.md index aaea6c7f6bd..62e476e7360 100644 --- a/docs/tutorials/social/basic.md +++ b/docs/tutorials/social/basic.md @@ -106,7 +106,9 @@ so this is where you should make the `layouts` directory and place the background image. The default site of the social cards included with the plugin is 1200x630 pixels, so choose an image that size or one that scales well to it. -## Additional layouts and styles +## Additional layouts and styles + + The Insiders Edition provides additional layouts as well as the option to configure different styles for different (kinds of) pages. @@ -165,7 +167,9 @@ page. If that is not what you want then you will need to modify the social card template to gets its icons from another source. You can learn how to do this in the [custom social cards tutorial](custom.md). -## Per-page settings +## Per-page settings + + With the Insiders Edition, you can customize the card layout for each page by adding settings to the page header. You have effectively done this diff --git a/material/__init__.py b/material/__init__.py index c0ef38c8efc..847d25ccee5 100644 --- a/material/__init__.py +++ b/material/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -18,4 +18,4 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -__version__ = "9.5.43" +__version__ = "9.6.15" diff --git a/material/extensions/__init__.py b/material/extensions/__init__.py index 9c58b37928d..cf4e7db9044 100644 --- a/material/extensions/__init__.py +++ b/material/extensions/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/material/extensions/emoji.py b/material/extensions/emoji.py index df886f6b046..0a5e14315bf 100644 --- a/material/extensions/emoji.py +++ b/material/extensions/emoji.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2024 Martin Donath +# Copyright (c) 2016-2025 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to diff --git a/material/overrides/assets/javascripts/custom.4e50d00f.min.js.map b/material/overrides/assets/javascripts/custom.4e50d00f.min.js.map deleted file mode 100644 index 3b48135fbfb..00000000000 --- a/material/overrides/assets/javascripts/custom.4e50d00f.min.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["node_modules/fuzzaldrin-plus/lib/scorer.js", "node_modules/fuzzaldrin-plus/lib/pathScorer.js", "node_modules/fuzzaldrin-plus/lib/query.js", "node_modules/fuzzaldrin-plus/lib/filter.js", "node_modules/fuzzaldrin-plus/lib/matcher.js", "node_modules/fuzzaldrin-plus/lib/fuzzaldrin.js", "node_modules/tslib/tslib.es6.mjs", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/overrides/assets/javascripts/components/_/index.ts", "src/overrides/assets/javascripts/components/iconsearch/query/index.ts", "src/overrides/assets/javascripts/components/iconsearch/result/index.ts", "src/overrides/assets/javascripts/templates/iconsearch/index.tsx", "src/overrides/assets/javascripts/templates/sponsorship/index.tsx", "src/overrides/assets/javascripts/components/iconsearch/_/index.ts", "src/overrides/assets/javascripts/components/sponsorship/index.ts", "src/overrides/assets/javascripts/integrations/analytics/index.ts", "src/overrides/assets/javascripts/custom.ts"], - "sourcesContent": ["(function() {\n var AcronymResult, computeScore, emptyAcronymResult, isAcronymFullWord, isMatch, isSeparator, isWordEnd, isWordStart, miss_coeff, pos_bonus, scoreAcronyms, scoreCharacter, scoreConsecutives, scoreExact, scoreExactMatch, scorePattern, scorePosition, scoreSize, tau_size, wm;\n\n wm = 150;\n\n pos_bonus = 20;\n\n tau_size = 150;\n\n miss_coeff = 0.75;\n\n exports.score = function(string, query, options) {\n var allowErrors, preparedQuery, score, string_lw;\n preparedQuery = options.preparedQuery, allowErrors = options.allowErrors;\n if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) {\n return 0;\n }\n string_lw = string.toLowerCase();\n score = computeScore(string, string_lw, preparedQuery);\n return Math.ceil(score);\n };\n\n exports.isMatch = isMatch = function(subject, query_lw, query_up) {\n var i, j, m, n, qj_lw, qj_up, si;\n m = subject.length;\n n = query_lw.length;\n if (!m || n > m) {\n return false;\n }\n i = -1;\n j = -1;\n while (++j < n) {\n qj_lw = query_lw.charCodeAt(j);\n qj_up = query_up.charCodeAt(j);\n while (++i < m) {\n si = subject.charCodeAt(i);\n if (si === qj_lw || si === qj_up) {\n break;\n }\n }\n if (i === m) {\n return false;\n }\n }\n return true;\n };\n\n exports.computeScore = computeScore = function(subject, subject_lw, preparedQuery) {\n var acro, acro_score, align, csc_diag, csc_row, csc_score, csc_should_rebuild, i, j, m, miss_budget, miss_left, n, pos, query, query_lw, record_miss, score, score_diag, score_row, score_up, si_lw, start, sz;\n query = preparedQuery.query;\n query_lw = preparedQuery.query_lw;\n m = subject.length;\n n = query.length;\n acro = scoreAcronyms(subject, subject_lw, query, query_lw);\n acro_score = acro.score;\n if (acro.count === n) {\n return scoreExact(n, m, acro_score, acro.pos);\n }\n pos = subject_lw.indexOf(query_lw);\n if (pos > -1) {\n return scoreExactMatch(subject, subject_lw, query, query_lw, pos, n, m);\n }\n score_row = new Array(n);\n csc_row = new Array(n);\n sz = scoreSize(n, m);\n miss_budget = Math.ceil(miss_coeff * n) + 5;\n miss_left = miss_budget;\n csc_should_rebuild = true;\n j = -1;\n while (++j < n) {\n score_row[j] = 0;\n csc_row[j] = 0;\n }\n i = -1;\n while (++i < m) {\n si_lw = subject_lw[i];\n if (!si_lw.charCodeAt(0) in preparedQuery.charCodes) {\n if (csc_should_rebuild) {\n j = -1;\n while (++j < n) {\n csc_row[j] = 0;\n }\n csc_should_rebuild = false;\n }\n continue;\n }\n score = 0;\n score_diag = 0;\n csc_diag = 0;\n record_miss = true;\n csc_should_rebuild = true;\n j = -1;\n while (++j < n) {\n score_up = score_row[j];\n if (score_up > score) {\n score = score_up;\n }\n csc_score = 0;\n if (query_lw[j] === si_lw) {\n start = isWordStart(i, subject, subject_lw);\n csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);\n align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score);\n if (align > score) {\n score = align;\n miss_left = miss_budget;\n } else {\n if (record_miss && --miss_left <= 0) {\n return Math.max(score, score_row[n - 1]) * sz;\n }\n record_miss = false;\n }\n }\n score_diag = score_up;\n csc_diag = csc_row[j];\n csc_row[j] = csc_score;\n score_row[j] = score;\n }\n }\n score = score_row[n - 1];\n return score * sz;\n };\n\n exports.isWordStart = isWordStart = function(pos, subject, subject_lw) {\n var curr_s, prev_s;\n if (pos === 0) {\n return true;\n }\n curr_s = subject[pos];\n prev_s = subject[pos - 1];\n return isSeparator(prev_s) || (curr_s !== subject_lw[pos] && prev_s === subject_lw[pos - 1]);\n };\n\n exports.isWordEnd = isWordEnd = function(pos, subject, subject_lw, len) {\n var curr_s, next_s;\n if (pos === len - 1) {\n return true;\n }\n curr_s = subject[pos];\n next_s = subject[pos + 1];\n return isSeparator(next_s) || (curr_s === subject_lw[pos] && next_s !== subject_lw[pos + 1]);\n };\n\n isSeparator = function(c) {\n return c === ' ' || c === '.' || c === '-' || c === '_' || c === '/' || c === '\\\\';\n };\n\n scorePosition = function(pos) {\n var sc;\n if (pos < pos_bonus) {\n sc = pos_bonus - pos;\n return 100 + sc * sc;\n } else {\n return Math.max(100 + pos_bonus - pos, 0);\n }\n };\n\n exports.scoreSize = scoreSize = function(n, m) {\n return tau_size / (tau_size + Math.abs(m - n));\n };\n\n scoreExact = function(n, m, quality, pos) {\n return 2 * n * (wm * quality + scorePosition(pos)) * scoreSize(n, m);\n };\n\n exports.scorePattern = scorePattern = function(count, len, sameCase, start, end) {\n var bonus, sz;\n sz = count;\n bonus = 6;\n if (sameCase === count) {\n bonus += 2;\n }\n if (start) {\n bonus += 3;\n }\n if (end) {\n bonus += 1;\n }\n if (count === len) {\n if (start) {\n if (sameCase === len) {\n sz += 2;\n } else {\n sz += 1;\n }\n }\n if (end) {\n bonus += 1;\n }\n }\n return sameCase + sz * (sz + bonus);\n };\n\n exports.scoreCharacter = scoreCharacter = function(i, j, start, acro_score, csc_score) {\n var posBonus;\n posBonus = scorePosition(i);\n if (start) {\n return posBonus + wm * ((acro_score > csc_score ? acro_score : csc_score) + 10);\n }\n return posBonus + wm * csc_score;\n };\n\n exports.scoreConsecutives = scoreConsecutives = function(subject, subject_lw, query, query_lw, i, j, startOfWord) {\n var k, m, mi, n, nj, sameCase, sz;\n m = subject.length;\n n = query.length;\n mi = m - i;\n nj = n - j;\n k = mi < nj ? mi : nj;\n sameCase = 0;\n sz = 0;\n if (query[j] === subject[i]) {\n sameCase++;\n }\n while (++sz < k && query_lw[++j] === subject_lw[++i]) {\n if (query[j] === subject[i]) {\n sameCase++;\n }\n }\n if (sz < k) {\n i--;\n }\n if (sz === 1) {\n return 1 + 2 * sameCase;\n }\n return scorePattern(sz, n, sameCase, startOfWord, isWordEnd(i, subject, subject_lw, m));\n };\n\n exports.scoreExactMatch = scoreExactMatch = function(subject, subject_lw, query, query_lw, pos, n, m) {\n var end, i, pos2, sameCase, start;\n start = isWordStart(pos, subject, subject_lw);\n if (!start) {\n pos2 = subject_lw.indexOf(query_lw, pos + 1);\n if (pos2 > -1) {\n start = isWordStart(pos2, subject, subject_lw);\n if (start) {\n pos = pos2;\n }\n }\n }\n i = -1;\n sameCase = 0;\n while (++i < n) {\n if (query[pos + i] === subject[i]) {\n sameCase++;\n }\n }\n end = isWordEnd(pos + n - 1, subject, subject_lw, m);\n return scoreExact(n, m, scorePattern(n, n, sameCase, start, end), pos);\n };\n\n AcronymResult = (function() {\n function AcronymResult(score, pos, count) {\n this.score = score;\n this.pos = pos;\n this.count = count;\n }\n\n return AcronymResult;\n\n })();\n\n emptyAcronymResult = new AcronymResult(0, 0.1, 0);\n\n exports.scoreAcronyms = scoreAcronyms = function(subject, subject_lw, query, query_lw) {\n var count, fullWord, i, j, m, n, qj_lw, sameCase, score, sepCount, sumPos;\n m = subject.length;\n n = query.length;\n if (!(m > 1 && n > 1)) {\n return emptyAcronymResult;\n }\n count = 0;\n sepCount = 0;\n sumPos = 0;\n sameCase = 0;\n i = -1;\n j = -1;\n while (++j < n) {\n qj_lw = query_lw[j];\n if (isSeparator(qj_lw)) {\n i = subject_lw.indexOf(qj_lw, i + 1);\n if (i > -1) {\n sepCount++;\n continue;\n } else {\n break;\n }\n }\n while (++i < m) {\n if (qj_lw === subject_lw[i] && isWordStart(i, subject, subject_lw)) {\n if (query[j] === subject[i]) {\n sameCase++;\n }\n sumPos += i;\n count++;\n break;\n }\n }\n if (i === m) {\n break;\n }\n }\n if (count < 2) {\n return emptyAcronymResult;\n }\n fullWord = count === n ? isAcronymFullWord(subject, subject_lw, query, count) : false;\n score = scorePattern(count, n, sameCase, true, fullWord);\n return new AcronymResult(score, sumPos / count, count + sepCount);\n };\n\n isAcronymFullWord = function(subject, subject_lw, query, nbAcronymInQuery) {\n var count, i, m, n;\n m = subject.length;\n n = query.length;\n count = 0;\n if (m > 12 * n) {\n return false;\n }\n i = -1;\n while (++i < m) {\n if (isWordStart(i, subject, subject_lw) && ++count > nbAcronymInQuery) {\n return false;\n }\n }\n return true;\n };\n\n}).call(this);\n", "(function() {\n var computeScore, countDir, file_coeff, getExtension, getExtensionScore, isMatch, scorePath, scoreSize, tau_depth, _ref;\n\n _ref = require('./scorer'), isMatch = _ref.isMatch, computeScore = _ref.computeScore, scoreSize = _ref.scoreSize;\n\n tau_depth = 20;\n\n file_coeff = 2.5;\n\n exports.score = function(string, query, options) {\n var allowErrors, preparedQuery, score, string_lw;\n preparedQuery = options.preparedQuery, allowErrors = options.allowErrors;\n if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) {\n return 0;\n }\n string_lw = string.toLowerCase();\n score = computeScore(string, string_lw, preparedQuery);\n score = scorePath(string, string_lw, score, options);\n return Math.ceil(score);\n };\n\n scorePath = function(subject, subject_lw, fullPathScore, options) {\n var alpha, basePathScore, basePos, depth, end, extAdjust, fileLength, pathSeparator, preparedQuery, useExtensionBonus;\n if (fullPathScore === 0) {\n return 0;\n }\n preparedQuery = options.preparedQuery, useExtensionBonus = options.useExtensionBonus, pathSeparator = options.pathSeparator;\n end = subject.length - 1;\n while (subject[end] === pathSeparator) {\n end--;\n }\n basePos = subject.lastIndexOf(pathSeparator, end);\n fileLength = end - basePos;\n extAdjust = 1.0;\n if (useExtensionBonus) {\n extAdjust += getExtensionScore(subject_lw, preparedQuery.ext, basePos, end, 2);\n fullPathScore *= extAdjust;\n }\n if (basePos === -1) {\n return fullPathScore;\n }\n depth = preparedQuery.depth;\n while (basePos > -1 && depth-- > 0) {\n basePos = subject.lastIndexOf(pathSeparator, basePos - 1);\n }\n basePathScore = basePos === -1 ? fullPathScore : extAdjust * computeScore(subject.slice(basePos + 1, end + 1), subject_lw.slice(basePos + 1, end + 1), preparedQuery);\n alpha = 0.5 * tau_depth / (tau_depth + countDir(subject, end + 1, pathSeparator));\n return alpha * basePathScore + (1 - alpha) * fullPathScore * scoreSize(0, file_coeff * fileLength);\n };\n\n exports.countDir = countDir = function(path, end, pathSeparator) {\n var count, i;\n if (end < 1) {\n return 0;\n }\n count = 0;\n i = -1;\n while (++i < end && path[i] === pathSeparator) {\n continue;\n }\n while (++i < end) {\n if (path[i] === pathSeparator) {\n count++;\n while (++i < end && path[i] === pathSeparator) {\n continue;\n }\n }\n }\n return count;\n };\n\n exports.getExtension = getExtension = function(str) {\n var pos;\n pos = str.lastIndexOf(\".\");\n if (pos < 0) {\n return \"\";\n } else {\n return str.substr(pos + 1);\n }\n };\n\n getExtensionScore = function(candidate, ext, startPos, endPos, maxDepth) {\n var m, matched, n, pos;\n if (!ext.length) {\n return 0;\n }\n pos = candidate.lastIndexOf(\".\", endPos);\n if (!(pos > startPos)) {\n return 0;\n }\n n = ext.length;\n m = endPos - pos;\n if (m < n) {\n n = m;\n m = ext.length;\n }\n pos++;\n matched = -1;\n while (++matched < n) {\n if (candidate[pos + matched] !== ext[matched]) {\n break;\n }\n }\n if (matched === 0 && maxDepth > 0) {\n return 0.9 * getExtensionScore(candidate, ext, startPos, pos - 2, maxDepth - 1);\n }\n return matched / m;\n };\n\n}).call(this);\n", "(function() {\n var Query, coreChars, countDir, getCharCodes, getExtension, opt_char_re, truncatedUpperCase, _ref;\n\n _ref = require(\"./pathScorer\"), countDir = _ref.countDir, getExtension = _ref.getExtension;\n\n module.exports = Query = (function() {\n function Query(query, _arg) {\n var optCharRegEx, pathSeparator, _ref1;\n _ref1 = _arg != null ? _arg : {}, optCharRegEx = _ref1.optCharRegEx, pathSeparator = _ref1.pathSeparator;\n if (!(query && query.length)) {\n return null;\n }\n this.query = query;\n this.query_lw = query.toLowerCase();\n this.core = coreChars(query, optCharRegEx);\n this.core_lw = this.core.toLowerCase();\n this.core_up = truncatedUpperCase(this.core);\n this.depth = countDir(query, query.length, pathSeparator);\n this.ext = getExtension(this.query_lw);\n this.charCodes = getCharCodes(this.query_lw);\n }\n\n return Query;\n\n })();\n\n opt_char_re = /[ _\\-:\\/\\\\]/g;\n\n coreChars = function(query, optCharRegEx) {\n if (optCharRegEx == null) {\n optCharRegEx = opt_char_re;\n }\n return query.replace(optCharRegEx, '');\n };\n\n truncatedUpperCase = function(str) {\n var char, upper, _i, _len;\n upper = \"\";\n for (_i = 0, _len = str.length; _i < _len; _i++) {\n char = str[_i];\n upper += char.toUpperCase()[0];\n }\n return upper;\n };\n\n getCharCodes = function(str) {\n var charCodes, i, len;\n len = str.length;\n i = -1;\n charCodes = [];\n while (++i < len) {\n charCodes[str.charCodeAt(i)] = true;\n }\n return charCodes;\n };\n\n}).call(this);\n", "(function() {\n var Query, pathScorer, pluckCandidates, scorer, sortCandidates;\n\n scorer = require('./scorer');\n\n pathScorer = require('./pathScorer');\n\n Query = require('./query');\n\n pluckCandidates = function(a) {\n return a.candidate;\n };\n\n sortCandidates = function(a, b) {\n return b.score - a.score;\n };\n\n module.exports = function(candidates, query, options) {\n var bKey, candidate, key, maxInners, maxResults, score, scoreProvider, scoredCandidates, spotLeft, string, usePathScoring, _i, _len;\n scoredCandidates = [];\n key = options.key, maxResults = options.maxResults, maxInners = options.maxInners, usePathScoring = options.usePathScoring;\n spotLeft = (maxInners != null) && maxInners > 0 ? maxInners : candidates.length + 1;\n bKey = key != null;\n scoreProvider = usePathScoring ? pathScorer : scorer;\n for (_i = 0, _len = candidates.length; _i < _len; _i++) {\n candidate = candidates[_i];\n string = bKey ? candidate[key] : candidate;\n if (!string) {\n continue;\n }\n score = scoreProvider.score(string, query, options);\n if (score > 0) {\n scoredCandidates.push({\n candidate: candidate,\n score: score\n });\n if (!--spotLeft) {\n break;\n }\n }\n }\n scoredCandidates.sort(sortCandidates);\n candidates = scoredCandidates.map(pluckCandidates);\n if (maxResults != null) {\n candidates = candidates.slice(0, maxResults);\n }\n return candidates;\n };\n\n}).call(this);\n", "(function() {\n var basenameMatch, computeMatch, isMatch, isWordStart, match, mergeMatches, scoreAcronyms, scoreCharacter, scoreConsecutives, _ref;\n\n _ref = require('./scorer'), isMatch = _ref.isMatch, isWordStart = _ref.isWordStart, scoreConsecutives = _ref.scoreConsecutives, scoreCharacter = _ref.scoreCharacter, scoreAcronyms = _ref.scoreAcronyms;\n\n exports.match = match = function(string, query, options) {\n var allowErrors, baseMatches, matches, pathSeparator, preparedQuery, string_lw;\n allowErrors = options.allowErrors, preparedQuery = options.preparedQuery, pathSeparator = options.pathSeparator;\n if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) {\n return [];\n }\n string_lw = string.toLowerCase();\n matches = computeMatch(string, string_lw, preparedQuery);\n if (matches.length === 0) {\n return matches;\n }\n if (string.indexOf(pathSeparator) > -1) {\n baseMatches = basenameMatch(string, string_lw, preparedQuery, pathSeparator);\n matches = mergeMatches(matches, baseMatches);\n }\n return matches;\n };\n\n exports.wrap = function(string, query, options) {\n var matchIndex, matchPos, matchPositions, output, strPos, tagClass, tagClose, tagOpen, _ref1;\n if ((options.wrap != null)) {\n _ref1 = options.wrap, tagClass = _ref1.tagClass, tagOpen = _ref1.tagOpen, tagClose = _ref1.tagClose;\n }\n if (tagClass == null) {\n tagClass = 'highlight';\n }\n if (tagOpen == null) {\n tagOpen = '';\n }\n if (tagClose == null) {\n tagClose = '';\n }\n if (string === query) {\n return tagOpen + string + tagClose;\n }\n matchPositions = match(string, query, options);\n if (matchPositions.length === 0) {\n return string;\n }\n output = '';\n matchIndex = -1;\n strPos = 0;\n while (++matchIndex < matchPositions.length) {\n matchPos = matchPositions[matchIndex];\n if (matchPos > strPos) {\n output += string.substring(strPos, matchPos);\n strPos = matchPos;\n }\n while (++matchIndex < matchPositions.length) {\n if (matchPositions[matchIndex] === matchPos + 1) {\n matchPos++;\n } else {\n matchIndex--;\n break;\n }\n }\n matchPos++;\n if (matchPos > strPos) {\n output += tagOpen;\n output += string.substring(strPos, matchPos);\n output += tagClose;\n strPos = matchPos;\n }\n }\n if (strPos <= string.length - 1) {\n output += string.substring(strPos);\n }\n return output;\n };\n\n basenameMatch = function(subject, subject_lw, preparedQuery, pathSeparator) {\n var basePos, depth, end;\n end = subject.length - 1;\n while (subject[end] === pathSeparator) {\n end--;\n }\n basePos = subject.lastIndexOf(pathSeparator, end);\n if (basePos === -1) {\n return [];\n }\n depth = preparedQuery.depth;\n while (depth-- > 0) {\n basePos = subject.lastIndexOf(pathSeparator, basePos - 1);\n if (basePos === -1) {\n return [];\n }\n }\n basePos++;\n end++;\n return computeMatch(subject.slice(basePos, end), subject_lw.slice(basePos, end), preparedQuery, basePos);\n };\n\n mergeMatches = function(a, b) {\n var ai, bj, i, j, m, n, out;\n m = a.length;\n n = b.length;\n if (n === 0) {\n return a.slice();\n }\n if (m === 0) {\n return b.slice();\n }\n i = -1;\n j = 0;\n bj = b[j];\n out = [];\n while (++i < m) {\n ai = a[i];\n while (bj <= ai && ++j < n) {\n if (bj < ai) {\n out.push(bj);\n }\n bj = b[j];\n }\n out.push(ai);\n }\n while (j < n) {\n out.push(b[j++]);\n }\n return out;\n };\n\n computeMatch = function(subject, subject_lw, preparedQuery, offset) {\n var DIAGONAL, LEFT, STOP, UP, acro_score, align, backtrack, csc_diag, csc_row, csc_score, i, j, m, matches, move, n, pos, query, query_lw, score, score_diag, score_row, score_up, si_lw, start, trace;\n if (offset == null) {\n offset = 0;\n }\n query = preparedQuery.query;\n query_lw = preparedQuery.query_lw;\n m = subject.length;\n n = query.length;\n acro_score = scoreAcronyms(subject, subject_lw, query, query_lw).score;\n score_row = new Array(n);\n csc_row = new Array(n);\n STOP = 0;\n UP = 1;\n LEFT = 2;\n DIAGONAL = 3;\n trace = new Array(m * n);\n pos = -1;\n j = -1;\n while (++j < n) {\n score_row[j] = 0;\n csc_row[j] = 0;\n }\n i = -1;\n while (++i < m) {\n score = 0;\n score_up = 0;\n csc_diag = 0;\n si_lw = subject_lw[i];\n j = -1;\n while (++j < n) {\n csc_score = 0;\n align = 0;\n score_diag = score_up;\n if (query_lw[j] === si_lw) {\n start = isWordStart(i, subject, subject_lw);\n csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);\n align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score);\n }\n score_up = score_row[j];\n csc_diag = csc_row[j];\n if (score > score_up) {\n move = LEFT;\n } else {\n score = score_up;\n move = UP;\n }\n if (align > score) {\n score = align;\n move = DIAGONAL;\n } else {\n csc_score = 0;\n }\n score_row[j] = score;\n csc_row[j] = csc_score;\n trace[++pos] = score > 0 ? move : STOP;\n }\n }\n i = m - 1;\n j = n - 1;\n pos = i * n + j;\n backtrack = true;\n matches = [];\n while (backtrack && i >= 0 && j >= 0) {\n switch (trace[pos]) {\n case UP:\n i--;\n pos -= n;\n break;\n case LEFT:\n j--;\n pos--;\n break;\n case DIAGONAL:\n matches.push(i + offset);\n j--;\n i--;\n pos -= n + 1;\n break;\n default:\n backtrack = false;\n }\n }\n matches.reverse();\n return matches;\n };\n\n}).call(this);\n", "(function() {\n var Query, defaultPathSeparator, filter, matcher, parseOptions, pathScorer, preparedQueryCache, scorer;\n\n filter = require('./filter');\n\n matcher = require('./matcher');\n\n scorer = require('./scorer');\n\n pathScorer = require('./pathScorer');\n\n Query = require('./query');\n\n preparedQueryCache = null;\n\n defaultPathSeparator = (typeof process !== \"undefined\" && process !== null ? process.platform : void 0) === \"win32\" ? '\\\\' : '/';\n\n module.exports = {\n filter: function(candidates, query, options) {\n if (options == null) {\n options = {};\n }\n if (!((query != null ? query.length : void 0) && (candidates != null ? candidates.length : void 0))) {\n return [];\n }\n options = parseOptions(options, query);\n return filter(candidates, query, options);\n },\n score: function(string, query, options) {\n if (options == null) {\n options = {};\n }\n if (!((string != null ? string.length : void 0) && (query != null ? query.length : void 0))) {\n return 0;\n }\n options = parseOptions(options, query);\n if (options.usePathScoring) {\n return pathScorer.score(string, query, options);\n } else {\n return scorer.score(string, query, options);\n }\n },\n match: function(string, query, options) {\n var _i, _ref, _results;\n if (options == null) {\n options = {};\n }\n if (!string) {\n return [];\n }\n if (!query) {\n return [];\n }\n if (string === query) {\n return (function() {\n _results = [];\n for (var _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }\n return _results;\n }).apply(this);\n }\n options = parseOptions(options, query);\n return matcher.match(string, query, options);\n },\n wrap: function(string, query, options) {\n if (options == null) {\n options = {};\n }\n if (!string) {\n return [];\n }\n if (!query) {\n return [];\n }\n options = parseOptions(options, query);\n return matcher.wrap(string, query, options);\n },\n prepareQuery: function(query, options) {\n if (options == null) {\n options = {};\n }\n options = parseOptions(options, query);\n return options.preparedQuery;\n }\n };\n\n parseOptions = function(options, query) {\n if (options.allowErrors == null) {\n options.allowErrors = false;\n }\n if (options.usePathScoring == null) {\n options.usePathScoring = true;\n }\n if (options.useExtensionBonus == null) {\n options.useExtensionBonus = false;\n }\n if (options.pathSeparator == null) {\n options.pathSeparator = defaultPathSeparator;\n }\n if (options.optCharRegEx == null) {\n options.optCharRegEx = null;\n }\n if (options.wrap == null) {\n options.wrap = null;\n }\n if (options.preparedQuery == null) {\n options.preparedQuery = preparedQueryCache && preparedQueryCache.query === query ? preparedQueryCache : (preparedQueryCache = new Query(query, options));\n }\n return options;\n };\n\n}).call(this);\n", "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an