pax_global_header00006660000000000000000000000064146102334250014512gustar00rootroot0000000000000052 comment=934c5367f15ff9971a52cd30962fd3542b6a1e86 thinc-9.0.0/000077500000000000000000000000001461023342500126255ustar00rootroot00000000000000thinc-9.0.0/.github/000077500000000000000000000000001461023342500141655ustar00rootroot00000000000000thinc-9.0.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001461023342500163505ustar00rootroot00000000000000thinc-9.0.0/.github/ISSUE_TEMPLATE/01_bugs.md000066400000000000000000000007301461023342500201320ustar00rootroot00000000000000--- name: "\U0001F6A8 Submit a Bug Report" about: Use this template if you came across a bug or unexpected behaviour differing from the docs. --- ## How to reproduce the behaviour ## Your Environment - Operating System: - Python Version Used: - Thinc Version Used: - Environment Information: thinc-9.0.0/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000017371461023342500177760ustar00rootroot00000000000000 ## Description ### Types of change ## Checklist - [ ] I confirm that I have the right to submit this contribution under the project's MIT license. - [ ] I ran the tests, and all new and existing tests passed. - [ ] My changes don't require a change to the documentation, or if they do, I've added all required information. thinc-9.0.0/.github/workflows/000077500000000000000000000000001461023342500162225ustar00rootroot00000000000000thinc-9.0.0/.github/workflows/explosionbot.yml000066400000000000000000000014141461023342500214720ustar00rootroot00000000000000name: Explosion Bot on: issue_comment: types: - created - edited jobs: explosion-bot: runs-on: ubuntu-latest steps: - name: Dump GitHub context env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v3 - uses: actions/setup-python@v4 - name: Install and run explosion-bot run: | pip install git+https://${{ secrets.EXPLOSIONBOT_TOKEN }}@github.com/explosion/explosion-bot python -m explosionbot env: INPUT_TOKEN: ${{ secrets.EXPLOSIONBOT_TOKEN }} INPUT_BK_TOKEN: ${{ secrets.BUILDKITE_SECRET }} ENABLED_COMMANDS: "test_gpu,test_slow,test_slow_gpu" ALLOWED_TEAMS: "spacy-maintainers" thinc-9.0.0/.github/workflows/issue-manager.yml000066400000000000000000000012421461023342500215040ustar00rootroot00000000000000name: Issue Manager on: schedule: - cron: "0 0 * * *" issue_comment: types: - created - edited issues: types: - labeled jobs: issue-manager: runs-on: ubuntu-latest steps: - uses: tiangolo/issue-manager@0.4.0 with: token: ${{ secrets.GITHUB_TOKEN }} config: > { "resolved": { "delay": "P7D", "message": "This issue has been automatically closed because it was answered and there was no follow-up discussion.", "remove_label_on_comment": true, "remove_label_on_close": true } } thinc-9.0.0/.github/workflows/tests.yml000066400000000000000000000114301461023342500201060ustar00rootroot00000000000000name: tests on: push: paths-ignore: - "website/**" - "*.md" pull_request: types: [opened, synchronize, reopened, edited] paths-ignore: - "website/**" - "*.md" jobs: validate: name: Validate if: github.repository_owner == 'explosion' runs-on: ubuntu-latest steps: - name: Check out repo uses: actions/checkout@v3 - name: Configure Python version uses: actions/setup-python@v4 with: python-version: "3.9" architecture: x64 - name: black run: | python -m pip install black -c requirements.txt python -m black thinc --check - name: isort run: | python -m pip install isort -c requirements.txt python -m isort thinc --check - name: flake8 run: | python -m pip install flake8==5.0.4 python -m flake8 thinc --count --select=E901,E999,F821,F822,F823,W605 --show-source --statistics tests: name: Test needs: Validate if: github.repository_owner == 'explosion' strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python_version: ["3.12"] include: - os: windows-latest python_version: "3.9" - os: macos-latest python_version: "3.10" - os: ubuntu-latest python_version: "3.11" runs-on: ${{ matrix.os }} env: NOTEBOOK_KERNEL: "thinc-notebook-tests" steps: - name: Check out repo uses: actions/checkout@v3 - name: Configure Python version uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} architecture: x64 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel pip install -r requirements.txt - name: Build sdist run: | python setup.py build_ext --inplace python setup.py sdist --formats=gztar - name: Run mypy run: python -m mypy thinc --no-implicit-reexport - name: Delete source directory run: rm -rf thinc shell: bash - name: Uninstall all packages run: | python -m pip freeze pip freeze --exclude pywin32 > installed.txt pip uninstall -y -r installed.txt - name: Install from sdist run: | SDIST=$(python -c "import os;print(os.listdir('./dist')[-1])" 2>&1) PIP_CONSTRAINT="build-constraints.txt" pip install dist/$SDIST shell: bash - name: Test import run: python -c "import thinc" - name: Install test requirements run: | pip install -r requirements.txt - name: Install notebook test requirements run: | pip install ipykernel pydot graphviz python -m ipykernel install --name thinc-notebook-tests --user if: matrix.python_version != '3.12' - name: Run tests without extras run: | python -m pytest --pyargs thinc -Werror --cov=thinc --cov-report=term # Notes on numpy requirements hacks: # 1. torch does not have a direct numpy requirement but is compiled # against a newer version than the oldest supported numpy for windows and # python 3.10; this version of numpy would not work with # tensorflow~=2.5.0 as specified above, but there is no release for # python 3.10 anyway # 2. restrict to numpy<1.24.0 due to mxnet incompatibility # 3. forbid torch!=1.13.0 due to segfaults with numpy<1.24.0 # Note: some of these pip install commands are known to fail for some platforms. # To continue despite errors as in azure pipelines, remove -e from the default # bash flags. - name: Install extras for testing run: | pip install "protobuf~=3.20.0" "tensorflow~=2.5.0" pip install "mxnet; sys_platform != 'win32' and python_version < '3.12'" pip install "torch!=1.13.0; sys_platform!='darwin'" --extra-index-url https://download.pytorch.org/whl/cpu # there is a bug related to MPS devices in github macos runners that # will be fixed in torch v2.1.1 # https://github.com/pytorch/pytorch/pull/111576 pip install "torch>=2.1.1; sys_platform=='darwin'" --extra-index-url https://download.pytorch.org/whl/cpu pip install "numpy~=1.23.0; python_version=='3.10' and sys_platform=='win32'" pip install "numpy<1.24.0" pip install -r requirements.txt pip uninstall -y mypy shell: bash --noprofile --norc -o pipefail {0} - name: Run tests with extras run: python -m pytest --pyargs thinc --cov=thinc --cov-report=term -p thinc.tests.enable_tensorflow -p thinc.tests.enable_mxnet thinc-9.0.0/.gitignore000066400000000000000000000024171461023342500146210ustar00rootroot00000000000000# File extensions *.pdf *.aux *.orig *.pyo *.pickle *.dvi *.o *.sqlite .*.s* *.dat # Varia _paths.py .mypy_cache .hypothesis/ version.cc version.pl # Tests tests/model/* tests/model/ # Website website/.cache/ website/public/ website/node_modules website/.npm website/logs *.log npm-debug.log* website/www/ website/_deploy.sh *.html # Cython / C extensions cythonize.json *.cpp *.so *.so.1 # Vim / VSCode / editors *.swp *.swo *.sw* Profile.prof .vscode .sass-cache # Python .Python .python-version __pycache__/ .pytest_cache *.py[cod] .env/ .env* .~env/ .venv env3.*/ venv/ .dev .denv .pypyenv .pytest_cache/ # Distribution / packaging env/ build/ develop-eggs/ dist/ eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ pip-wheel-metadata/ Pipfile.lock .installed.cfg *.egg .eggs MANIFEST # Temporary files *.~* tmp/ predict train # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .cache nosetests.xml coverage.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # Rope .ropeproject # Django stuff: *.log *.pot # Windows *.bat Thumbs.db Desktop.ini # Mac OS X *.DS_Store # Komodo project files *.komodoproject # Other *.tgz # Pycharm project files *.idea # IPython .ipynb_checkpoints/ thinc-9.0.0/CITATION.cff000066400000000000000000000011271461023342500145200ustar00rootroot00000000000000cff-version: 1.2.0 message: If you use Thinc in research, please use this as a citation. title: Thinc abstract: "๐Ÿ”ฎ A refreshing functional take on deep learning, compatible with your favorite libraries" authors: - family-names: "Honnibal" given-names: "Matthew" - family-names: "Montani" given-names: "Ines" - family-names: "Van Landeghem" given-names: "Sofie" - family-names: "Boyd" given-names: "Adriane" - family-names: "DuJardin" given-names: "Justin" version: 8.0.0 date-released: "2021-01-21" license: MIT repository-code: "https://github.com/explosion/thinc" thinc-9.0.0/LICENSE000066400000000000000000000021431461023342500136320ustar00rootroot00000000000000The MIT License (MIT) Copyright (C) 2016 ExplosionAI GmbH, 2016 spaCy GmbH, 2015 Matthew Honnibal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. thinc-9.0.0/MANIFEST.in000066400000000000000000000003361461023342500143650ustar00rootroot00000000000000recursive-include thinc *.cu *.pyx *.pxd *.hh include LICENSE include README.md prune tmp/ include thinc/tests/mypy/configs/*.ini include thinc/tests/mypy/outputs/*.txt include thinc/py.typed recursive-exclude thinc *.cpp thinc-9.0.0/README.md000066400000000000000000000263521461023342500141140ustar00rootroot00000000000000 # Thinc: A refreshing functional take on deep learning, compatible with your favorite libraries ### From the makers of [spaCy](https://spacy.io) and [Prodigy](https://prodi.gy) [Thinc](https://thinc.ai) is a **lightweight deep learning library** that offers an elegant, type-checked, functional-programming API for **composing models**, with support for layers defined in other frameworks such as **PyTorch, TensorFlow and MXNet**. You can use Thinc as an interface layer, a standalone toolkit or a flexible way to develop new models. Previous versions of Thinc have been running quietly in production in thousands of companies, via both [spaCy](https://spacy.io) and [Prodigy](https://prodi.gy). We wrote the new version to let users **compose, configure and deploy custom models** built with their favorite framework. [![tests](https://github.com/explosion/thinc/actions/workflows/tests.yml/badge.svg)](https://github.com/explosion/thinc/actions/workflows/tests.yml) [![Current Release Version](https://img.shields.io/github/v/release/explosion/thinc.svg?include_prereleases&sort=semver&style=flat-square&logo=github)](https://github.com/explosion/thinc/releases) [![PyPi Version](https://img.shields.io/pypi/v/thinc.svg?include_prereleases&sort=semver&style=flat-square&logo=pypi&logoColor=white)](https://pypi.python.org/pypi/thinc) [![conda Version](https://img.shields.io/conda/vn/conda-forge/thinc.svg?style=flat-square&logo=conda-forge&logoColor=white)](https://anaconda.org/conda-forge/thinc) [![Python wheels](https://img.shields.io/badge/wheels-%E2%9C%93-4c1.svg?longCache=true&style=flat-square&logo=python&logoColor=white)](https://github.com/explosion/wheelwright/releases) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/ambv/black) [![Open demo in Colab][colab]][intro_to_thinc_colab] ## ๐Ÿ”ฅ Features - **Type-check** your model definitions with custom types and [`mypy`](https://mypy.readthedocs.io/en/latest/) plugin. - Wrap **PyTorch**, **TensorFlow** and **MXNet** models for use in your network. - Concise **functional-programming** approach to model definition, using composition rather than inheritance. - Optional custom infix notation via **operator overloading**. - Integrated **config system** to describe trees of objects and hyperparameters. - Choice of **extensible backends**. - **[Read more →](https://thinc.ai/docs)** ## ๐Ÿš€ Quickstart Thinc is compatible with **Python 3.6+** and runs on **Linux**, **macOS** and **Windows**. The latest releases with binary wheels are available from [pip](https://pypi.python.org/pypi/thinc). Before you install Thinc and its dependencies, make sure that your `pip`, `setuptools` and `wheel` are up to date. For the most recent releases, pip 19.3 or newer is recommended. ```bash pip install -U pip setuptools wheel pip install thinc ``` See the [extended installation docs](https://thinc.ai/docs/install#extended) for details on optional dependencies for different backends and GPU. You might also want to [set up static type checking](https://thinc.ai/docs/install#type-checking) to take advantage of Thinc's type system. > โš ๏ธ If you have installed PyTorch and you are using Python 3.7+, uninstall the > package `dataclasses` with `pip uninstall dataclasses`, since it may have been > installed by PyTorch and is incompatible with Python 3.7+. ### ๐Ÿ““ Selected examples and notebooks Also see the [`/examples`](examples) directory and [usage documentation](https://thinc.ai/docs) for more examples. Most examples are Jupyter notebooks โ€“ to launch them on [Google Colab](https://colab.research.google.com) (with GPU support!) click on the button next to the notebook name. | Notebook | Description | | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`intro_to_thinc`][intro_to_thinc]
[![Open in Colab][colab]][intro_to_thinc_colab] | Everything you need to know to get started. Composing and training a model on the MNIST data, using config files, registering custom functions and wrapping PyTorch, TensorFlow and MXNet models. | | [`transformers_tagger_bert`][transformers_tagger_bert]
[![Open in Colab][colab]][transformers_tagger_bert_colab] | How to use Thinc, `transformers` and PyTorch to train a part-of-speech tagger. From model definition and config to the training loop. | | [`pos_tagger_basic_cnn`][pos_tagger_basic_cnn]
[![Open in Colab][colab]][pos_tagger_basic_cnn_colab] | Implementing and training a basic CNN for part-of-speech tagging model without external dependencies and using different levels of Thinc's config system. | | [`parallel_training_ray`][parallel_training_ray]
[![Open in Colab][colab]][parallel_training_ray_colab] | How to set up synchronous and asynchronous parameter server training with Thinc and [Ray](https://ray.readthedocs.io/en/latest/). | **[View more →](examples)** [colab]: https://gistcdn.githack.com/ines/dcf354aa71a7665ae19871d7fd14a4e0/raw/461fc1f61a7bc5860f943cd4b6bcfabb8c8906e7/colab-badge.svg [intro_to_thinc]: examples/00_intro_to_thinc.ipynb [intro_to_thinc_colab]: https://colab.research.google.com/github/explosion/thinc/blob/master/examples/00_intro_to_thinc.ipynb [transformers_tagger_bert]: examples/02_transformers_tagger_bert.ipynb [transformers_tagger_bert_colab]: https://colab.research.google.com/github/explosion/thinc/blob/master/examples/02_transformers_tagger_bert.ipynb [pos_tagger_basic_cnn]: examples/03_pos_tagger_basic_cnn.ipynb [pos_tagger_basic_cnn_colab]: https://colab.research.google.com/github/explosion/thinc/blob/master/examples/03_pos_tagger_basic_cnn.ipynb [parallel_training_ray]: examples/04_parallel_training_ray.ipynb [parallel_training_ray_colab]: https://colab.research.google.com/github/explosion/thinc/blob/master/examples/04_parallel_training_ray.ipynb ### ๐Ÿ“– Documentation & usage guides | Documentation | Description | | --------------------------------------------------------------------------------- | ----------------------------------------------------- | | [Introduction](https://thinc.ai/docs) | Everything you need to know. | | [Concept & Design](https://thinc.ai/docs/concept) | Thinc's conceptual model and how it works. | | [Defining and using models](https://thinc.ai/docs/usage-models) | How to compose models and update state. | | [Configuration system](https://thinc.ai/docs/usage-config) | Thinc's config system and function registry. | | [Integrating PyTorch, TensorFlow & MXNet](https://thinc.ai/docs/usage-frameworks) | Interoperability with machine learning frameworks | | [Layers API](https://thinc.ai/docs/api-layers) | Weights layers, transforms, combinators and wrappers. | | [Type Checking](https://thinc.ai/docs/usage-type-checking) | Type-check your model definitions and more. | ## ๐Ÿ—บ What's where | Module | Description | | ----------------------------------------- | --------------------------------------------------------------------------------- | | [`thinc.api`](thinc/api.py) | **User-facing API.** All classes and functions should be imported from here. | | [`thinc.types`](thinc/types.py) | Custom [types and dataclasses](https://thinc.ai/docs/api-types). | | [`thinc.model`](thinc/model.py) | The `Model` class. All Thinc models are an instance (not a subclass) of `Model`. | | [`thinc.layers`](thinc/layers) | The layers. Each layer is implemented in its own module. | | [`thinc.shims`](thinc/shims) | Interface for external models implemented in PyTorch, TensorFlow etc. | | [`thinc.loss`](thinc/loss.py) | Functions to calculate losses. | | [`thinc.optimizers`](thinc/optimizers.py) | Functions to create optimizers. Currently supports "vanilla" SGD, Adam and RAdam. | | [`thinc.schedules`](thinc/schedules.py) | Generators for different rates, schedules, decays or series. | | [`thinc.backends`](thinc/backends) | Backends for `numpy` and `cupy`. | | [`thinc.config`](thinc/config.py) | Config parsing and validation and function registry system. | | [`thinc.util`](thinc/util.py) | Utilities and helper functions. | ## ๐Ÿ Development notes Thinc uses [`black`](https://github.com/psf/black) for auto-formatting, [`flake8`](http://flake8.pycqa.org/en/latest/) for linting and [`mypy`](https://mypy.readthedocs.io/en/latest/) for type checking. All code is written compatible with **Python 3.6+**, with type hints wherever possible. See the [type reference](https://thinc.ai/docs/api-types) for more details on Thinc's custom types. ### ๐Ÿ‘ทโ€โ™€๏ธ Building Thinc from source Building Thinc from source requires the full dependencies listed in [`requirements.txt`](requirements.txt) to be installed. You'll also need a compiler to build the C extensions. ```bash git clone https://github.com/explosion/thinc cd thinc python -m venv .env source .env/bin/activate pip install -U pip setuptools wheel pip install -r requirements.txt pip install --no-build-isolation . ``` Alternatively, install in editable mode: ```bash pip install -r requirements.txt pip install --no-build-isolation --editable . ``` Or by setting `PYTHONPATH`: ```bash export PYTHONPATH=`pwd` pip install -r requirements.txt python setup.py build_ext --inplace ``` ### ๐Ÿšฆ Running tests Thinc comes with an [extensive test suite](thinc/tests). The following should all pass and not report any warnings or errors: ```bash python -m pytest thinc # test suite python -m mypy thinc # type checks python -m flake8 thinc # linting ``` To view test coverage, you can run `python -m pytest thinc --cov=thinc`. We aim for a 100% test coverage. This doesn't mean that we meticulously write tests for every single line โ€“ we ignore blocks that are not relevant or difficult to test and make sure that the tests execute all code paths. thinc-9.0.0/bin/000077500000000000000000000000001461023342500133755ustar00rootroot00000000000000thinc-9.0.0/bin/push-tag.sh000077500000000000000000000005541461023342500154700ustar00rootroot00000000000000#!/usr/bin/env bash set -e # Insist repository is clean git diff-index --quiet HEAD git checkout $1 git pull origin $1 git push origin $1 version=$(grep "__version__ = " thinc/about.py) version=${version/__version__ = } version=${version/\'/} version=${version/\'/} version=${version/\"/} version=${version/\"/} git tag "v$version" git push origin "v$version" thinc-9.0.0/build-constraints.txt000066400000000000000000000001471461023342500170340ustar00rootroot00000000000000# build version constraints for use with wheelwright + multibuild numpy>=1.25.0; python_version>='3.9' thinc-9.0.0/examples/000077500000000000000000000000001461023342500144435ustar00rootroot00000000000000thinc-9.0.0/examples/00_intro_to_thinc.ipynb000066400000000000000000014643621461023342500210470ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "4q-j8ckEGcit" }, "source": [ "# Intro to Thinc for beginners: defining a simple model and config & wrapping PyTorch, TensorFlow and MXNet\n", "\n", "This example shows how to get started with Thinc, using the \"hello world\" of neural network models: recognizing handwritten digits from the [MNIST dataset](http://yann.lecun.com/exdb/mnist/). For comparison, here's the same model implemented in other frameworks: [PyTorch version](https://github.com/pytorch/examples/blob/master/mnist/main.py), [TensorFlow version](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist.py). In this notebook, we'll walk through **creating and training the model**, using **config files**, registering **custom functions** and **wrapping models** defined in PyTorch, TensorFlow and MXNet. This tutorial is aimed at beginners, but it assumes basic knowledge of machine learning concepts and terminology." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "FVWFT2nnGci4", "outputId": "ee32dc55-5d02-473e-dc5b-2422dc1e34db" }, "outputs": [], "source": [ "!pip install \"thinc>=8.2.0\" \"ml_datasets>=0.2.0\" \"tqdm>=4.41\"" ] }, { "cell_type": "markdown", "metadata": { "id": "vUsjn12zberE" }, "source": [ "There are also some optional extras to install, depending on whether you want to run this on GPU, and depending on which of the integrations you want to test." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "l310yc2IawXM", "scrolled": false }, "outputs": [], "source": [ "import thinc.util\n", "# If you want to run this notebook on GPU, you'll need to install cupy.\n", "if not thinc.util.has_cupy:\n", " !pip install \"cupy-cuda101\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "a23GlJVJa0T-", "scrolled": true }, "outputs": [], "source": [ "import thinc.util\n", "# If you want to try out the tensorflow integration, you'll need to install that.\n", "# You'll either need to do tensorflow or tensorflow-gpu, depending on your\n", "# requirements.\n", "if not thinc.util.has_tensorflow:\n", " !pip install \"tensorflow-gpu>=2\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "PpL4s7hEbHhJ" }, "outputs": [], "source": [ "import thinc.util\n", "# If you want to try out the PyTorch integration, you'll need to install it.\n", "if not thinc.util.has_torch:\n", " !pip install \"torch\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "LTOk4rfwbOSS" }, "outputs": [], "source": [ "import thinc.util\n", "# If you want to try out the MxNet integration, you'll need to install it.\n", "if not thinc.util.has_mxnet:\n", " !pip install \"mxnet>=1.5.1,<1.6.0\"" ] }, { "cell_type": "markdown", "metadata": { "id": "GhyglLtPGci7" }, "source": [ "If you're running the notebook on GPU, the first thing to do is use Thinc's `prefer_gpu` helper to make sure we're performing operations **on GPU if available**. The function should be called right after importing Thinc, and it returns a boolean indicating whether the GPU has been activated. If you want to test out an integration with another library, you should check that it can access the GPU too." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "2xkReqDJGci8", "outputId": "9492ddc7-6c34-4f39-b781-e5df6ed06709" }, "outputs": [], "source": [ "from thinc.api import prefer_gpu\n", "import thinc.util\n", "print(\"Thinc GPU?\", prefer_gpu())\n", "\n", "if thinc.util.has_tensorflow:\n", " import tensorflow as tf\n", " print(\"Tensorflow GPU?\", bool(tf.config.experimental.list_physical_devices('GPU')))" ] }, { "cell_type": "markdown", "metadata": { "id": "BZVtDmLCGci8" }, "source": [ "Weโ€™ve prepared a separate package [`ml-datasets`](https://github.com/explosion/ml-datasets) with loaders for some common datasets, including MNIST. So we can set up the data as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "qctw-vbZGci_", "outputId": "8f866627-0b2d-4392-eb61-7a7fc7c2e797" }, "outputs": [], "source": [ "import ml_datasets\n", "(train_X, train_Y), (dev_X, dev_Y) = ml_datasets.mnist()\n", "print(f\"Training size={len(train_X)}, dev size={len(dev_X)}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "p8jv7snxGcjB" }, "source": [ "Now letโ€™s define a model with two **Relu-activated hidden layers**, followed by a **softmax-activated output layer**. Weโ€™ll also add **dropout** after the two hidden layers, to help the model generalize better. The `chain` combinator is like `Sequential` in PyTorch or Keras: it combines a list of layers together with a feed-forward relationship." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "hrhydeJSGcjB" }, "outputs": [], "source": [ "from thinc.api import chain, Relu, Softmax\n", " \n", "n_hidden = 32\n", "dropout = 0.2\n", "\n", "model = chain(\n", " Relu(nO=n_hidden, dropout=dropout), \n", " Relu(nO=n_hidden, dropout=dropout), \n", " Softmax()\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "gmIH7Xr5GcjD" }, "source": [ "After creating the model, we can call the `Model.initialize` method, passing in a small batch of input data `X` and a small batch of output data `Y`. This allows Thinc to **infer the missing dimensions**: when we defined the model, we didnโ€™t tell it the input size `nI` or the output size `nO`. When passing in the data, make sure it is on the right device by calling `model.ops.asarray` which will e.g. transform the arrays to `cupy` when running on GPU." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ODzZCkuSGcjD", "outputId": "b1c178db-b297-4cf7-e135-596dae2a7a75" }, "outputs": [], "source": [ "# making sure the data is on the right device\n", "train_X = model.ops.asarray(train_X)\n", "train_Y = model.ops.asarray(train_Y)\n", "dev_X = model.ops.asarray(dev_X)\n", "dev_Y = model.ops.asarray(dev_Y)\n", "\n", "model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "nI = model.get_dim(\"nI\")\n", "nO = model.get_dim(\"nO\")\n", "print(f\"Initialized model with input dimension nI={nI} and output dimension nO={nO}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "th0djZu7GcjE" }, "source": [ "Next we need to create an **optimizer**, and make several passes over the data, randomly selecting paired batches of the inputs and labels each time. While some machine learning libraries provide a single `.fit()` method to train a model all at once, Thinc puts you in charge of **shuffling and batching your data**, with the help of a few handy utility methods. `model.ops.xp` is an instance of either `numpy` or `cupy`, depending on whether you run the code on CPU or GPU." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 219, "referenced_widgets": [ "d9ba3c88398d4e12a674eca10a8633ff", "2637352462d94fe795a409fbbbe70926", "d266fcfaaa9741b1a4be560f094ac1d2", "cd54b80e170c4a6c94fe419c2cf8bcd6", "db2b8e98efcd4a7599b7bbd57c55e70c", "71522233b5b64b3dbd29ec69e47788d8", "81a8b3ff6d644f2c83f04a835bef5333", "4c60aa21f05a4d678b2135d4d1f2c99a", "7f3517a0116846708d65a947e534de05", "2fa0fd59f8844a4e99eda19fc4151962", "ca4f1e1dbbbd46618b40291f94ef1102", "3ab377ee24544e2a95433448a8331ed1", "5fe58d7f655243c8b9d29f31a0eb7b53", "b1548f9f9f4642ef814e9d3565002501", "7fcc9f928ddd4f52a9d420862b9be6ef", "70898e759e6945a1a479dcb2d434b50d", "6ae1111eff4043f294a7bbafcb5de189", "0443d3d3c8564616a9cae2616c370a72", "f3abedf22ff649b4b90e85fc68f93c67", "d4f5f106a2ed488fbba2b626bbd72714", "d904c7aebabb477a99f41e95f1b0b9cf", "e82d78f382b343c384bb7895daa18c82", "b9862082c1cf47d1bb6057537571499d", "ebebf706cc9549d9803b796ea2ef2853", "b50ff7a73c0f4a6da93443ca019ba785", "0a9b4f19291b403dadeca3938004561e", "e2a09b4280db464f863a1ae66d58ea02", "7f60da0694d343fca576f9cfaf7352ac", "5ac87cfe946d483b8088df90b22490d8", "5d84a716b7ed4ad8927ee8ea8493e4db", "ea6cbc2071af4c018f96e5846f328a1f", "db3333497eba4ee1a63225b4c6bf468c", "e3ddfbf3678a41ab9926976cf1beee85", "a16d1171acfe48b5abfd3652d0cf119f", "7ae0b9e9e6964641a7d529b03d60b034", "4a9b8833512a4f07a4411b1e8c2ca0c8", "05de1b15d6244f82bcef782c8f73f8a8", "84fb3096f29f40bf9f4d20bca7608c05", "aa1f805540a74c7380bd2b333b9ecc88", "a0b0dd366b424f03adde1e0698b8b31f", "86c4306d45c04ce783d40f202c30c350", "2be93e1e76224f61afd058eea4583a05", "6f8967c159b1474ab706026b6becd9a1", "5c5c9d38d86c4d2486c547a3add4a04c", "6da928e744da4d0bb1cbb1df33c201ee", "017d16a6d32b4d6a9f868a57cd736568", "eb2cfbd11882434e9373f36d62d06258", "ceefe7af1738490d9414c6c690eb4681", "fc6d6eef364446c3b54b68c5c4c1cb1b", "662835d152984f4eb87fa7cef0c0e28d", "1de0cf05f59b49eb8f8d233b9a4e490e", "9bf763a02b58454ab1e4f9598939fd79", "af32974b6ed54e9da7b89fe35a749640", "aa7c50235a9f43fa96a7d9ef7be20861", "407a6771394a4e69a504ea5b67164a64", "e0077b7268614d85b4a08ad07183a2e4", "1a394e179354494487365d1a5242e2d3", "e567c933e82146758cb690a190f1199c", "35181a9eb7bc4967984c327a8b6f7f8f", "3cf4e5fcc4a64c13b100093fb12e2cd2", "b826f8a9468d4c23b35f6021791885b6", "016371ed2b1e43d29e7542dc20f9ef64", "70537ee37fd645c8ba0d3e88fc43fdb5", "6db4cb7968194992819296b341c378f1", "ad58dbfc6a294f3f9dc89c4a3f9658dc", "8f521dc0bd094a3da7cffd4da51ce7e0", "0eea906841464f978a262640badc0fae", "11daf0a19032495ab15cdda96b0030e7", "6565004456e24a88a2e1e04ebe7004df", "a63ede007e94496c884527478a9b0d17", "e6b70306bfea4bd09f17eac179387a96", "1e34b8465bc84f94b13a3d7a94d5f9ce", "c0db04b51d0c4e9e9081c0169cca1f4e", "cb35834c71e24301abd3574d82e017b9", "80016285573540f998aeec24132c0bb3", "f999eff152854b6da98defded43c8818", "ebfa4d5418d84b3ea8fad62dfabce7c1", "265c8c05122c406fa6b603070e2ca7bd", "85e62f6e0211431a9f6513285ef1aa0b", "92ae4ede68904e2f8b0b2322f099d32b" ] }, "id": "jnqyIuNgGcjF", "outputId": "5e4cecd4-8fd1-4608-ed8e-7ddfed1a7762" }, "outputs": [], "source": [ "from thinc.api import Adam, fix_random_seed\n", "from tqdm.notebook import tqdm\n", "\n", "fix_random_seed(0)\n", "optimizer = Adam(0.001)\n", "batch_size = 128\n", "print(\"Measuring performance across iterations:\")\n", "\n", "for i in range(10):\n", " batches = model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True)\n", " for X, Y in tqdm(batches, leave=False):\n", " Yh, backprop = model.begin_update(X)\n", " backprop(Yh - Y)\n", " model.finish_update(optimizer)\n", " # Evaluate and print progress\n", " correct = 0\n", " total = 0\n", " for X, Y in model.ops.multibatch(batch_size, dev_X, dev_Y):\n", " Yh = model.predict(X)\n", " correct += (Yh.argmax(axis=1) == Y.argmax(axis=1)).sum()\n", " total += Yh.shape[0]\n", " score = correct / total\n", " print(f\" {i} {float(score):.3f}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "FkcctgKzGcjG" }, "source": [ "Let's wrap the training code in a function, so we can reuse it later:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "6VRxmeipGcjH" }, "outputs": [], "source": [ "def train_model(data, model, optimizer, n_iter, batch_size):\n", " (train_X, train_Y), (dev_X, dev_Y) = data\n", " indices = model.ops.xp.arange(train_X.shape[0], dtype=\"i\")\n", " for i in range(n_iter):\n", " batches = model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True)\n", " for X, Y in tqdm(batches, leave=False):\n", " Yh, backprop = model.begin_update(X)\n", " backprop(Yh - Y)\n", " model.finish_update(optimizer)\n", " # Evaluate and print progress\n", " correct = 0\n", " total = 0\n", " for X, Y in model.ops.multibatch(batch_size, dev_X, dev_Y):\n", " Yh = model.predict(X)\n", " correct += (Yh.argmax(axis=1) == Y.argmax(axis=1)).sum()\n", " total += Yh.shape[0]\n", " score = correct / total\n", " print(f\" {i} {float(score):.3f}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "X6tmwMlsGcjH" }, "source": [ "### Operator overloading for more concise model definitions\n", "\n", "Thinc allows you to **overload operators** and bind arbitrary functions to Python operators like `+`, `*`, but also `>>` or `@`. The `Model.define_operators` contextmanager takes a dict of operators mapped to functions โ€“ typically combinators like `chain`. The operators are only valid for the `with` block. This lets us define the model like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "eZlHX5j5GcjH" }, "outputs": [], "source": [ "from thinc.api import Model, chain, Relu, Softmax\n", " \n", "n_hidden = 32\n", "dropout = 0.2\n", "\n", "with Model.define_operators({\">>\": chain}):\n", " model = Relu(nO=n_hidden, dropout=dropout) >> Relu(nO=n_hidden, dropout=dropout) >> Softmax()" ] }, { "cell_type": "markdown", "metadata": { "id": "liNMnvKzGcjH" }, "source": [ "If your model definitions are very complex, mapping combinators to operators can help you keep the code readable and concise. You can find more examples of model definitions with overloaded operators [in the docs](https://thinc.ai/docs). (Also note that you don't _have to_ use this syntax!)" ] }, { "cell_type": "markdown", "metadata": { "id": "HTFBXZxXGcjI" }, "source": [ "---\n", "\n", "## Using config files\n", "\n", "Configuration is a huge problem for machine learning code, because you may want to expose almost any detail of any function as a hyperparameter. The setting you want to expose might be arbitrarily far down in your call stack. Default values also become hard to change without breaking backwards compatibility.\n", "\n", "To solve this problem, Thinc provides a config system that lets you easily describe **arbitrary trees of objects**. The objects can be created via function calls you register using a simple decorator syntax. The config can include values like hyperparameters or training settings (whatever you need), or references to functions and the values of their arguments. Thinc will then construct the config **bottom-up** โ€“ so you can define one function with its arguments, and then pass the return value into another function.\n", "\n", "> ๐Ÿ’ก You can keep the config as a string in your Python script, or save it to a file like `config.cfg`. To load a config from a string, you can use `Config.from_str`. To load from a file, you can use `Config.from_disk`. The following examples all use strings so we can include them in the notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "BEvOL8kWGcjI", "outputId": "b6d12471-0128-497c-e67a-1b10f2d1e43b" }, "outputs": [], "source": [ "from thinc.api import Config, registry\n", "\n", "EXAMPLE_CONFIG1 = \"\"\"\n", "[hyper_params]\n", "learn_rate = 0.001\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = ${hyper_params:learn_rate}\n", "\"\"\"\n", "\n", "config1 = Config().from_str(EXAMPLE_CONFIG1)\n", "config1" ] }, { "cell_type": "markdown", "metadata": { "id": "olHiDguEGcjJ" }, "source": [ "When you open the config with `Config.from_str`, Thinc will parse it as a dict and fill in the references to values defined in other sections. For example, `${hyper_params:learn_rate}` is substituted with `0.001`. \n", "\n", "Keys starting with `@` are references to **registered functions**. For example, `@optimizers = \"Adam.v1\"` refers to the function registered under the name `\"Adam.v1\"`, a function creating an Adam optimizer. The function takes one argument, the `learn_rate`. Calling `registry.resolve` will resolve the config and create the functions it defines." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "61kSjIhqGcjJ", "outputId": "f5a28ea7-174f-465b-9847-e0286a07e910" }, "outputs": [], "source": [ "loaded_config1 = registry.resolve(config1)\n", "loaded_config1" ] }, { "cell_type": "markdown", "metadata": { "id": "U7_Pfg62GcjJ" }, "source": [ "If function arguments are missing or have incompatible types, Thinc will raise an error and tell you what's wrong. Configs can also define **nested blocks** using the `.` notation. In this example, `optimizer.learn_rate` defines the `learn_rate` argument of the `optimizer` block. Instead of a float, the learning rate can also be a generator โ€“ for instance, a linear warm-up rate:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "XqEL3yoVGcjJ", "outputId": "007060a7-c387-4eab-e8be-0573069257fc" }, "outputs": [], "source": [ "EXAMPLE_CONFIG2 = \"\"\"\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "\n", "[optimizer.learn_rate]\n", "@schedules = \"warmup_linear.v1\"\n", "initial_rate = 2e-5\n", "warmup_steps = 1000\n", "total_steps = 10000\n", "\"\"\"\n", "\n", "config2 = Config().from_str(EXAMPLE_CONFIG2)\n", "config2" ] }, { "cell_type": "markdown", "metadata": { "id": "_q6MvvG9GcjK" }, "source": [ "Calling `registry.resolve` will now construct the objects bottom-up: first, it will create the schedule with the given arguments. Next, it will create the optimizer and pass in the schedule as the `learn_rate` argument." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "u9wjWVwLGcjK", "outputId": "4bdbd58d-44e1-417a-9ee6-b6dc1925d5ef" }, "outputs": [], "source": [ "loaded_config2 = registry.resolve(config2)\n", "loaded_config2" ] }, { "cell_type": "markdown", "metadata": { "id": "WRw-cbKVGcjL" }, "source": [ "This gives you a loaded optimizer using the settings defined in the config, which you can then use in your script. How you set up your config and what you do with the result is **entirely up to you**. Thinc just gives you a dictionary of objects back and makes no assumptions about what they _\"mean\"_. This means that you can also choose the names of the config sections โ€“ the only thing that needs to stay consistent are the names of the function arguments." ] }, { "cell_type": "markdown", "metadata": { "id": "oKno-aCHGcjM" }, "source": [ "### Configuring the MNIST model\n", "\n", "Here's a config describing the model we defined above. The values in the `hyper_params` section can be referenced in other sections to keep them consistent. The `*` is used for **positional arguments** โ€“ in this case, the arguments to the `chain` function, two Relu layers and one softmax layer." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Gm762LNgGcjM", "outputId": "dc6bc047-3b1f-4f82-edd5-ba6cc7fc7c26" }, "outputs": [], "source": [ "CONFIG = \"\"\"\n", "[hyper_params]\n", "n_hidden = 32\n", "dropout = 0.2\n", "learn_rate = 0.001\n", "\n", "[model]\n", "@layers = \"chain.v1\"\n", "\n", "[model.*.relu1]\n", "@layers = \"Relu.v1\"\n", "nO = ${hyper_params:n_hidden}\n", "dropout = ${hyper_params:dropout}\n", "\n", "[model.*.relu2]\n", "@layers = \"Relu.v1\"\n", "nO = ${hyper_params:n_hidden}\n", "dropout = ${hyper_params:dropout}\n", "\n", "[model.*.softmax]\n", "@layers = \"Softmax.v1\"\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = ${hyper_params:learn_rate}\n", "\n", "[training]\n", "n_iter = 10\n", "batch_size = 128\n", "\"\"\"\n", "\n", "config = Config().from_str(CONFIG)\n", "config" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "z1KGVcQQGcjM", "outputId": "960ee075-0ecc-4289-929b-61eb5ea93b38" }, "outputs": [], "source": [ "loaded_config = registry.resolve(config)\n", "loaded_config" ] }, { "cell_type": "markdown", "metadata": { "id": "irXmLRk4GcjN" }, "source": [ "When you call `registry.resolve`, Thinc will first create the three layers using the specified arguments populated by the hyperparameters. It will then pass the return values (the layer objects) to `chain`. It will also create an optimizer. All other values, like the training config, will be passed through as a regular dict. Your training code can now look like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 201, "referenced_widgets": [ "a5ac2b15a8ae40ce92160a960414279c", "b52a071acc34438d849dbc7adcc91631", "43b0d557889248f287edd4edf50e3a9b", "99c3aedf530c44d69f3c145efc7da6da", "773cbd3194e142c694f73fd52ee6aa8c", "7aebabcd7cd546e989eb0c148ebb1348", "199cccb400aa4fc59a1f95317db0ae2b", "9024d8c79164492e80170ca565f2e367", "14717f9c7a3f4bbc97978023bad0d876", "d7d3d6ec8a144738b61b59e8e1d37f1e", "4f27062765bd41f589215a61e2d0840a", "f5f4c5a71a9c41f88fafc9abea500f14", "95f5d01ae2524dd2bcfab4945816b6a4", "3edb84e7ef724a1887df6dcf31f75448", "c918030a689a4842b727d9b7ecbe39ae", "eac2608b4c0e4ad9ac81838ad7d68657", "21f9b00564ea47ffa4523dd9a8eec4e9", "6f2523ef7d0243b38975e5b657b43dd9", "34c8794ff06d4875aec3ecaacb7f11bd", "05eaa0a6003243bab5378655193332c0", "31ef257d727346478de228f6cbd27021", "4a97428d8e9944d5b2a00466e6a80c53", "2e0751da78e14c88bfaf8b45f30fcd05", "4b433703db1a41baa3e7e9f45d72aa57", "b668e892e9cb4571b173390e78d8d786", "7e569ac0f5974f4aaed7cf2e953bc316", "79574d891d35493da77efbbad6fff11f", "583d96a84b3642f4b864c7ae7ab6f598", "3563f3d4033b4ac7b43279cf13d8bdd2", "989fb7b65c504a1aad8ec0f53e2e43c3", "ee11cbb4ec3d4042b6c62536a477c10a", "5978e50fc32f4fe1ab99fbfc42e87c89", "3bbd206a74794ed4a5500b7bafe546ea", "d6f5cf60a40c4825bfca5a960056d078", "3161c8b70d9748c5a1400c0fe543d442", "421fbeb9dd4c422999932f7dcd210da7", "7326a18ab885419691c5bfc3666154bc", "3a1091487eac40cdac4046173caaaaf3", "0ed86bd7b55f49bcb9927be28a279a49", "d64df8ba0ab04aad9e1c2c4551a0b7d9", "565b64b2df2f4342bdb56ad34b468de2", "08b6e41233db46a6911d22fe531832f5", "6699fda35d5b495da6052e53f4e24a01", "649359bad86d415094308180006a0e11", "f82fd9ccee6b423c8bdbc830ba0f8a93", "afe82cf54da249cb815dc3ece7bac260", "c1a8a841a5124a6eb364863a2fc11447", "a13d290a9ddf41deb2f258c617dfd2e3", "110b5a48694c48059985490cae348dc6", "4c61f8b9314c4bec8a0c3a5ecab3356d", "c99185c8dfbe47aab9e29a90b92c63a0", "4553ca36932d4a20b898d7fa7b23bcc3", "0829771aa327491e8b7d05ef2b084175", "1687134f713c4c039365c0a66d1aab82", "27a1f038ed8a41dfb4d18175f80aab7a", "b32999bf8b8148e98bbbb6ba1acb4548", "000b5ea0ab444688bf195d6c810a9ee4", "5c9d8559f7134842ab00b99d28bfd644", "630b657a06384d7abd3b63bcf02c3a3e", "ac609c059aac45bba0ea7ee76e057977", "88a24010610d4a19a3fb81eddfcfaf52", "f7dd4ce672014ce6ba3d7d50ff090c9e", "fdd43b573d18496a9eec5f61632b33ed", "318b1b7bb5064c5aabd39540bf2d7bf2", "53065cc4a41d4652bfb986ae1d28ce9b", "5cc3f44e4660481d920e9120fd0d254a", "b7740ddd81034150bca1bf841f43af31", "c330191809e44832a89abcc6c4a6fd5d", "9e2a1ec730be42d38a3f04b967ed0b88", "583c6058061240838ad63f2a8ddf9a00", "e731309213c94e92be1a389d13a190f5", "110f5508e00e4ec6b5c84877abc9c265", "80538e2ccd7f490987a79d4c70c9571b", "50b4abff394846eabd6f6fdcac8a7762", "d17516de5c52450abfd79af7db04a282", "584cadfb0a6c480f94aad4b9842c4d25", "22a455a7b3f841a9b01bc83dee7717cc", "3c80e2934eda4d19825a76c6400a3823", "a991cedbd4b24c139430a06369ad527f", "490a7c3043e24e378892816de13970eb" ] }, "id": "1kjJ79orGcjN", "outputId": "c62b4795-f5a3-4257-d695-871fa4af1d08" }, "outputs": [], "source": [ "model = loaded_config[\"model\"]\n", "optimizer = loaded_config[\"optimizer\"]\n", "n_iter = loaded_config[\"training\"][\"n_iter\"]\n", "batch_size = loaded_config[\"training\"][\"batch_size\"]\n", "\n", "model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "train_model(((train_X, train_Y), (dev_X, dev_Y)), model, optimizer, n_iter, batch_size)" ] }, { "cell_type": "markdown", "metadata": { "id": "vcH1GbRnGcjN" }, "source": [ "If you want to change a hyperparamter or experiment with a different optimizer, all you need to change is the config. For each experiment you run, you can save a config and you'll be able to reproduce it later." ] }, { "cell_type": "markdown", "metadata": { "id": "ml9jX5SNGcjO" }, "source": [ "---\n", "\n", "## Programming via config vs. registering custom functions\n", "\n", "The config system is very powerful and lets you define complex relationships, including model definitions with levels of nested layers. However, it's not always a good idea to program entirely in your config โ€“ this just replaces one problem (messy and hard to maintain code) with another one (messy and hard to maintain configs). So ultimately, it's about finding the **best possible trade-off**.\n", "\n", "If you've written a layer or model definition you're happy with, you can use Thinc's function registry to register it and assign it a string name. Your function can take any arguments that can later be defined in the config. Adding **type hints** ensures that config settings will be **parsed and validated** before they're passed into the function, so you don't end up with incompatible settings and confusing failures later on. Here's the MNIST model, defined as a custom layer:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "xgWuX6ceGcjO" }, "outputs": [], "source": [ "import thinc\n", "\n", "@thinc.registry.layers(\"MNIST.v1\")\n", "def create_mnist(nO: int, dropout: float):\n", " return chain(\n", " Relu(nO, dropout=dropout), \n", " Relu(nO, dropout=dropout), \n", " Softmax()\n", " )" ] }, { "cell_type": "markdown", "metadata": { "id": "o5hWEjL8GcjQ" }, "source": [ "In the config, we can now refer to it by name and set its arguments. This makes the config maintainable and compact, while still allowing you to change and record the hyperparameters." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "LsWrE-lyGcjR", "outputId": "28a9411c-0cc0-401d-9c3a-a5fae0410bde" }, "outputs": [], "source": [ "CONFIG2 = \"\"\"\n", "[model]\n", "@layers = \"MNIST.v1\"\n", "nO = 32\n", "dropout = 0.2\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = 0.001\n", "\n", "[training]\n", "n_iter = 10\n", "batch_size = 128\n", "\"\"\"\n", "\n", "config = Config().from_str(CONFIG2)\n", "config" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "jqQLLw-gGcjS", "outputId": "8d30cbed-1a3e-4a6a-8893-cf353d15fa3c" }, "outputs": [], "source": [ "loaded_config = registry.resolve(config)\n", "loaded_config" ] }, { "cell_type": "markdown", "metadata": { "id": "kqYF8mP8GcjS" }, "source": [ "If you don't want to hard-code the dataset being used, you can also wrap it in a registry function. This lets you refer to it by name in the config, and makes it easy to swap it out. In your config, you can then load the data in its own section, or as a subsection of `training`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "vz3IxOetGcjS" }, "outputs": [], "source": [ "@thinc.registry.datasets(\"mnist_data.v1\")\n", "def mnist():\n", " return ml_datasets.mnist()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "suiQ2psrGcjT", "outputId": "4e72a0dc-b33b-4c5e-90f1-1dfa8f311b65", "scrolled": true }, "outputs": [], "source": [ "CONFIG3 = \"\"\"\n", "[model]\n", "@layers = \"MNIST.v1\"\n", "nO = 32\n", "dropout = 0.2\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = 0.001\n", "\n", "[training]\n", "n_iter = 10\n", "batch_size = 128\n", "\n", "[training.data]\n", "@datasets = \"mnist_data.v1\"\n", "\"\"\"\n", "\n", "config = Config().from_str(CONFIG3)\n", "loaded_config = registry.resolve(config)\n", "loaded_config" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 201, "referenced_widgets": [ "f160728d6cfc4cd380fafce5b253d2c7", "b9db25806c4a410db0004f77a1acaee5", "0b2d03b2d0f6447293576ff8e9ed9ea3", "f839ef53446f4fa9834edc8da44f1327", "cc7f3e43ff504effb6fcbd63bac5546f", "dc4f419827134de0b96b9b020fa8a788", "68b365d2d435430aae5af88ecdae39a5", "0459c93679e54f9db4e7009420b8a612", "99fd455414304cb5a2a08077c2182452", "65729f9c7457426eb006da855388182b", "449ba373a94641f2ac9078d8f98c3f1a", "fa591816c3414db3a7dc1478649ac230", "3b06657d55a44d2486a3d65af18286d6", "14cf79b923404000b5eb2762d161ec78", "d673cd4b0e384aee988f565ab73cb022", "829ad0cbf2bb49d9bde04dcff1f9cb3c", "47a3f9dad5e2486b98ddd34b7bcf1201", "9bc1cd208dfd4a55bd52a4d0f399117c", "a27c932db2c84a86a75a92af92a07f0b", "8d73c0c46c944eb89e95a9efb0a891a6", "a183401dedf140979852bfc28122d689", "8b2e77ece9f14c37ad8efab38442acbb", "cf424d3cddcb4e469f4c88d1df70dedb", "2c303e0697ec4cca9e949207f89d7695", "b3664609744546988f30152c49d02ac8", "3e395e497d8f4f10812b2af65ccac13b", "247a4869ae564aefa501053956083a6a", "5ac7bb8fbf0048c492fc4f6c8b69d828", "099e1066f01c4b1780cf20a0700414a5", "2cdf06e67ced403795e3ba594fbf3c55", "2c6a4ebe2c914b028062eb3651de99e3", "fdd481739b6a4d64ac739965c621d3b8", "97e1cf826ec54af79646bee305e23601", "c8de4a1a7be449e68787a4dcdc94801d", "1c2657c607454a0eb329ae8663665e82", "1c4cfdd4f52a4db182cd08357b3d3abe", "db4cab1a1150482c861e22d6e7b2be09", "eaa7c96f7ee849948f10033289dfbd05", "d23105e4cc4141b5937063dc03e9d565", "ef3638ddf37547fe8359b8f4333dc2e8", "6b3e7a3ba015416cada97bb79d4c8fb1", "a780eb0b79ff40e9966a72a3c5a81eca", "0a9276f6ae784e63a6daaecdd2bc7e64", "0046f7bffaa6438d8cf31a0d558c4b46", "fce1dcea8fd749569b29e353a086ad45", "34d176a20c5e429a8852cb3e2d3bb507", "0a3730284d6a4110bf5247d537a24262", "efb84c9861764c61b09ad02f170d8530", "d98b018eb67447eca644cd5fa56f2723", "8ff0e222da2b47d99e8931080555cb7e", "a887772c5344437aa896b3ed1bd5208f", "734031c5bb6e4e7d9e30f1a15861924f", "e5caa26da44e411f891a71b85c46c87a", "e53b1041df93415c9852da6d8a05b7d3", "34237141f8854d33af9223e75e390ba5", "8a0e36efabb04f869ba2c080446525da", "e28f8422f22b4ef29ec9f6cffe959ecd", "03edea4af2724453bfbb6b8e2e74cda2", "dd43258264da429a9aeb315f1715b7db", "43d68f9905354442bad801fb61bfd02a", "861a02913c8346f2a2c7c7c049364acd", "4bccad99024f4d77a23b657d9dc7746d", "591e3bae35404f68b24f607ece97a9d3", "19b5d9601cb94873b3f550214d586577", "dba0b00af12d410cb8dfd4be838b173a", "b34c1730161e41c5bb901128ccb4ff65", "bce5275ceea044c3ba0f1635b0657ac4", "7048d397ed0647a19587c17deec944bb", "caff75ab1b874f9da109674579faadf3", "1017871f46b44c9cb3f976d1af607ffc", "32272e5a9e194bed9ffe5f16a3ae1d61", "a4823e3708aa4ccba43e3547a229095e", "ab99a2cf8919454bb780cc24088f2b85", "9c7baaf83e734b86b2234c735dca859d", "fddd7fb9ef3f4535a97775548abbabd1", "fa68877e48ab41a48a3c10dc3fe329d1", "32ff8a0bfbcb44ebb0c80363f6115e07", "3f0d72d9c4984f89a82862fcdd24643b", "96e832df4dec40d9a97bd129ef55effa", "3e448a3c76bc4fdfa57f82327411f2e2" ] }, "id": "TYYXzyYNGcjT", "outputId": "edaaf25e-5e9f-43a5-8a6a-04bd5b612317" }, "outputs": [], "source": [ "model = loaded_config[\"model\"]\n", "optimizer = loaded_config[\"optimizer\"]\n", "n_iter = loaded_config[\"training\"][\"n_iter\"]\n", "batch_size = loaded_config[\"training\"][\"batch_size\"]\n", "(train_X, train_Y), (dev_X, dev_Y) = loaded_config[\"training\"][\"data\"]\n", "\n", "# After loading the data from config, they might still need to be moved to the right device\n", "train_X = model.ops.asarray(train_X)\n", "train_Y = model.ops.asarray(train_Y)\n", "dev_X = model.ops.asarray(dev_X)\n", "dev_Y = model.ops.asarray(dev_Y)\n", "\n", "model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "train_model(((train_X, train_Y), (dev_X, dev_Y)), model, optimizer, n_iter, batch_size)" ] }, { "cell_type": "markdown", "metadata": { "id": "46MPK6-XGcjT" }, "source": [ "---\n", "\n", "## Wrapping TensorFlow, PyTorch and MXNet models\n", "\n", "The previous example showed how to define the model directly in Thinc, which is pretty straightforward. But you can also define your model using a **machine learning library of your choice** and wrap it as a Thinc model. This gives your layers a unified interface so you can easily mix and match them, and also lets you take advantage of the config system and type hints. Thinc currently ships with built-in wrappers for [PyTorch](https://pytorch.org), [TensorFlow](https://tensorflow.org) and [MXNet](https://mxnet.apache.org/)." ] }, { "cell_type": "markdown", "metadata": { "id": "S9fK_9mAGcjT" }, "source": [ "### Wrapping TensorFlow models\n", "\n", "Here's the same model definition in TensorFlow: a `Sequential` layer (equivalent of Thinc's `chain`) with two Relu layers and dropout, and an output layer with a softmax activation. Thinc's `TensorFlowWrapper` wraps the model and turns it into a regular Thinc `Model`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "IkgBI5wbGcjU", "outputId": "65179036-11ea-430e-e54a-3ee0d02dcdad" }, "outputs": [], "source": [ "from tensorflow.keras.layers import Dense, Dropout\n", "from tensorflow.keras.models import Sequential\n", "from thinc.api import enable_tensorflow, TensorFlowWrapper, Adam\n", "enable_tensorflow()\n", "\n", "width = 32\n", "nO = 10\n", "nI = 784\n", "dropout = 0.2\n", "\n", "tf_model = Sequential()\n", "tf_model.add(Dense(width, activation=\"relu\", input_shape=(nI,)))\n", "tf_model.add(Dropout(dropout))\n", "tf_model.add(Dense(width, activation=\"relu\", input_shape=(nI,)))\n", "tf_model.add(Dropout(dropout))\n", "tf_model.add(Dense(nO, activation=\"softmax\"))\n", "\n", "wrapped_tf_model = TensorFlowWrapper(tf_model)\n", "wrapped_tf_model" ] }, { "cell_type": "markdown", "metadata": { "id": "FVG18Ew_GcjU" }, "source": [ "You can now use the same training code to train the model:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 257, "referenced_widgets": [ "7ed4511c19b24c7fadf283d962a612a2", "7e44024663ce4bd4833c4dcdf2d63d14", "4b2f4fa05e7a465eacf809489243b2a8", "a3426fcb07904ca4be130a71b330c77a", "df732c32eb1340a890c181eed7358452", "e18cf1aef5834391ae7410dcb90f1c59", "759a4d04fe92425ab0d6d8681d3ed0c6", "8a25115e9fef433e90b70e1ff3bbe341", "8b296000cd0446e2952bff859b785260", "f6f53ccede894d5fa859543bcd5d07a1", "26fa7101f97f4aed98a774c83e802bc9", "3a4fc2bfed8549d980a4884715d9c650", "a21851e9b7b24098b3fbbe6d9f1f8e9c", "a73abf53972a4913bf2c50b0d341fc13", "6d23bd6b099746028b353af12380d226", "2233981c90214b7cae8d5bfc7410802b", "4faac8b7bdd748a7b908d46ed058aa3a", "995ac4803a534d0883a15702eae4fc50", "8584d1e513e7496192af75d2cf4f84c0", "943c772ee3fe43cea3d05cea3f7f12bb", "74632c71eef34180a7dba0c22fd9df80", "dbd113a86ad44f0b95261ed9f6e6c93c", "054a82c3f2dc4de9864b83dcd1a2abd8", "f4fd9c138d8c4192afdb4324afe46771", "0d95eef69a7d42418cc79e4cf4d8a3cd", "84ddb87806a94da8902e3da8a06aa7e5", "61540f7e300545eebbd697227a3b3d7d", "c9892de0df614a84b8ba7a6e259ffe09", "a08bba98a4994866949e19f6104e6991", "d74548d2826c45cba4e730b3a9638fd4", "fac6ce9bd41f43f9821f45741359f5f4", "86ea34c601f447f18eaaf30fd1711f77", "8c639957ced245318db4865da9e0c1df", "0cdbaa847609462aa3163c49db61a7cd", "7b5bf62263a64441b7424aab153415be", "370044cae56f42fd992e4c4ce3240f68", "7eb7725598674b13b049a370bb505ea7", "d1758fb53b404e3f9b8f317be75684b4", "8dde5fd1fe4347c7bea1c51c47b14e5e", "ca1968d9a9f7462e88c9a051cb7a6777", "db1b1bff50974cd0823dcccecd2ae1c4", "fad451dd3ae040a8aede364098400642", "e47127013eaa48979dc86657839ba227", "eb6a91e79a1b4998bc2751d3e572b05f", "0b62d25712a2403ab488914a7109ab47", "ff6267b3dd63479a8e260848a30709a8", "dd52397ee21b49f999121fb8a62ea4bf", "8404870254bf4dfa80ce1a11acaa5969", "e9228023d62243569a1e2e06a1cf94b5", "f08fd096dcb743faafc6dbc604b45989", "c808822cdef941a3879bf1cc2b32720a", "e4e73b9dcadd4bacb50d03152e7d81e8", "c8967d63161647d4a9e778765d3e7ac2", "570de138283348be9b7575b51df33eea", "6b89100361a443bd85a01f8e47374c96", "6485d6b9b194425f8eb28b779d7d6e9a", "5bd005f55b724af4893bb2d0718d9408", "2e5a7bb281d840e6a4522a4dc602fd80", "4005b0b6131a400e927343af9a20e154", "87a3fcd0fd8d4df1b885b1e106d085a8", "493826515d934872b80d127fbf8e6a85", "594aebcc9478429d9a5063327c9953bc", "7411b7336cab4e8f92347df274e93876", "7e91135b95964e35a11bd312983f31c3", "ab756a05d67241baabcb4ee84b35efe3", "9b16033c7b7a47568a0d078d708cf28d", "de806eb1cca0447c92917881ec18d49a", "00a9eda2268e47baaae96926bb7d8c51", "64cc1e2f91a44b218a7824aedd373b31", "e9c21ca7465449d3a8930234e9ed8dcf", "b775d1f8fbae434185d52dafd207b592", "0fc3d74e4d4a4ac8b057342c0a017394", "02a62e897a334ff88aa5282286de0bab", "2cbcffe4ddd8450db4b259d368516d9d", "880dce5bac5148988119a4c0f7296c83", "6790ba4beb8a4bae8f9a14f0cca3b5c9", "6cba2abf076d483ba8847ccbcf537c52", "c2fa2316330f4edc83a8e3e4de571cf3", "f55d98fcc3524d94ba73b3192ee19281", "21f755e5d9774eb3aab7604140054a6d" ] }, "id": "mu3vRO95GcjU", "outputId": "cfb89aaf-581a-4bc6-f13e-aa7d8990d81b" }, "outputs": [], "source": [ "data = ml_datasets.mnist()\n", "optimizer = Adam(0.001)\n", "wrapped_tf_model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "train_model(data, wrapped_tf_model, optimizer, n_iter=10, batch_size=128)" ] }, { "cell_type": "markdown", "metadata": { "id": "YxiSA-iwGcjV" }, "source": [ "### Wrapping PyTorch models\n", "\n", "Here's the PyTorch version. Thinc's `PyTorchWrapper` wraps the model and turns it into a regular Thinc `Model`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "rBiDnLGhGcjW", "outputId": "a208e5b6-8dc9-460a-f98a-b3d14186c4dc", "scrolled": true }, "outputs": [], "source": [ "import torch\n", "import torch.nn\n", "import torch.nn.functional as F\n", "from thinc.api import PyTorchWrapper, Adam\n", "\n", "\n", "width = 32\n", "nO = 10\n", "nI = 784\n", "dropout = 0.2\n", "\n", "\n", "class PyTorchModel(torch.nn.Module):\n", " def __init__(self, width, nO, nI, dropout):\n", " super(PyTorchModel, self).__init__()\n", " self.dropout1 = torch.nn.Dropout2d(dropout)\n", " self.dropout2 = torch.nn.Dropout2d(dropout)\n", " self.fc1 = torch.nn.Linear(nI, width)\n", " self.fc2 = torch.nn.Linear(width, nO)\n", "\n", " def forward(self, x):\n", " x = F.relu(x)\n", " x = self.dropout1(x)\n", " x = self.fc1(x)\n", " x = F.relu(x)\n", " x = self.dropout2(x)\n", " x = self.fc2(x)\n", " output = F.log_softmax(x, dim=1)\n", " return output\n", " \n", "wrapped_pt_model = PyTorchWrapper(PyTorchModel(width, nO, nI, dropout))\n", "wrapped_pt_model" ] }, { "cell_type": "markdown", "metadata": { "id": "9DHValebGcjX" }, "source": [ "You can now use the same training code to train the model:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 201, "referenced_widgets": [ "9bce5f414ec043509c06f10840cc2d0f", "47fd69df905945a09183f89126c665f0", "50ded217cb2440249cd86a4dcc0e1b7a", "e1229e07527b4a67bb7de71715ed10ca", "987b752181564435ab5a7f8d838651f5", "009991c634044a2c8dfb58aa7da342a6", "5ee467d84bd24e5db0507a994273ea28", "6bc78efbc98a4cb5ad04647f893e2f1a", "973c950b92d14614a5df848d2a8c024e", "a702297c0c7e40b08546a7669dfb6917", "637ac772584f4f169d59c0964be8acfd", "dd2ea7e5c59f4a3a807a7f8048eafb1e", "fe0223b47b9346e7ad056b86841f91d9", "e32b04ebb4454ca2848b799045c30320", "608cfc45e4ec4579b75999043e62ab19", "69f5f6ef84e44fc284dd9be06beaaf65", "4381199cd6fd46e98175bc65f3283a07", "f8c7cd8112274e26996a56ecae42ec3f", "ad1659c9381a4afca67aac81d1470776", "28f837093edd4e60bde32ec8d23b7497", "f0c3740bcfb04fa6a12e1f1025aff42f", "191e3c3e02b44eda9ebe4859325830e5", "b7341f8df10a4e1ab8c3cbb475de0d82", "de11572a1baa4efabaa5c1436af92f06", "8619ba70e84f4bda9d5c966863d0d4e3", "0c037dcc8bbb4f38977b3e516d3a2014", "977ab80b593849389b224d18aefb6814", "d62d3423df7f49d18b45bb87e9919ade", "473ece24383049f6964082046f5a8cef", "a859b046e9e84f518b8c4aa449fb75cc", "50d48e02aa744ad8adbccce94148b060", "b3f89680663b466f9dda719fa6843707", "faa57a96c1e7416fa9a9a41b5bc6e308", "b4979a909ae64f48888d2383285f4f68", "732824b0216e44f7a88da251febff435", "c5b2f89f03264317aa734883c164cabb", "40b7a89564684301ae357cae6c517be4", "b91537eaa9ba44f8952cb65696d236fe", "79c6ecc409764fc78294fcbd9319c3c0", "b31897c725c946e8a08a2ef0e80b6520", "cb24ce5968194d92bf77463a59eea46b", "5bfe581cc5db4002b38c89df6b245720", "aa86d75f3dba49a481c2c15167387b99", "e83ab25fcda94a90bdd58143c3624263", "82076a20084549719b917b071d1d1b91", "49bbc050955c4ddd931efc9a468faccb", "ae7ec72f5d064a6a80433613be03f849", "5eb4571729ea4b92857d3ba3c575721a", "1cea7c77162d42b2a464aeb98f86d36d", "66fc9d3aad8f478c8884e74990c9f2f9", "15062403d526469e910691b9b59f06bd", "aa3e1f1cf64a47af9aa0930b855c14bc", "b875c88f7ae74f8391ac58fc31a3aabc", "4c6f9216f6b14905bbfeffd81e14c973", "550caabed61042e1b89dd8a826897b77", "27ca20cabb94467492f29713fad334dd", "70bb47f183e24e7c805d8b5e89ce1b3e", "838598dc75fb4836b3f4d769d68de597", "c2b02e00355041919382a3c23c0d6850", "6e396b43955349b28a280ccb1d41c716", "9f6277814410407fae19e3aee971c997", "1480b195483d454c844c9e6a724b02b3", "501c6677916d40f9afaea8f48be244fe", "2e78f48b6298490885474f27bcbf2928", "df901f8348654af087a63b43ec822b9e", "dffdd7d2ddf24707a1b2fb0df00cf957", "3fb34090b5b34d6fa8f039440e839fbd", "46796020aa1145fc87c7f458ee41e14e", "3b153a8becf5411c871221d482680caa", "0701da5b35604eaebcecf87335ad324c", "76c193b0729b4a57b1664a94163bb38a", "877c9e4a3541425eac50c9250e5ff568", "4e2c73f549d94202a34b4a1046d011e5", "847aaa75aecc40f3bc9d67c37cf03362", "8c10956546bd46cc94c322044b217a1a", "cfa1762b9dd740f39d4dc3f198abdcc6", "5edf3c8cd0f64046ac298d48a93ef32e", "77325a33c7b6495e9301c771dbf935de", "ce87dfd22b554e0a83b264913f7156c6", "2eb23201ad354f3ba8a0720757d4d8bd" ] }, "id": "OCXFDVIHGcjX", "outputId": "8fad70f4-c323-46b0-de52-2d4b65aed7b1", "scrolled": true }, "outputs": [], "source": [ "data = ml_datasets.mnist()\n", "optimizer = Adam(0.001)\n", "wrapped_pt_model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "train_model(data, wrapped_pt_model, optimizer, n_iter=10, batch_size=128)" ] }, { "cell_type": "markdown", "metadata": { "id": "E91d8Wm3GcjX" }, "source": [ "### Wrapping MXNet models\n", "\n", "Here's the MXNet version. Thinc's `MXNetWrapper` wraps the model and turns it into a regular Thinc `Model`.\n", "\n", "MXNet doesn't provide a `Softmax` layer but a `.softmax()` operation/method for prediction and it integrates an internal softmax during training. So to be able to integrate it with the rest of the components, you combine it with a `Softmax()` Thinc layer using the `chain` combinator. Make sure you `initialize()` the MXNet model *and* the Thinc model." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "6KU34c-1GcjY", "outputId": "5c5db8b7-9a5d-4652-f1c9-4efac0d0e1a2" }, "outputs": [], "source": [ "from mxnet.gluon.nn import Dense, Sequential, Dropout\n", "from thinc.api import enable_mxnet, MXNetWrapper, chain, Softmax\n", "import thinc.util\n", "enable_mxnet()\n", "\n", "assert thinc.util.has_mxnet\n", "\n", "width = 32\n", "nO = 10\n", "nI = 784\n", "dropout = 0.2\n", "\n", "mx_model = Sequential()\n", "mx_model.add(Dense(width, activation=\"relu\"))\n", "mx_model.add(Dropout(dropout))\n", "mx_model.add(Dense(width, activation=\"relu\"))\n", "mx_model.add(Dropout(dropout))\n", "mx_model.add(Dense(nO))\n", "mx_model.initialize()\n", "wrapped_mx_model = chain(MXNetWrapper(mx_model), Softmax())\n", "wrapped_mx_model" ] }, { "cell_type": "markdown", "metadata": { "id": "V9ySHavEGcjY" }, "source": [ "And train it the same way:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 227 }, "id": "SeE6CPUKGcjY", "outputId": "9616cc90-2164-4da5-d3fd-928c7d47b726" }, "outputs": [], "source": [ "data = ml_datasets.mnist()\n", "optimizer = Adam(0.001)\n", "wrapped_mx_model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "train_model(data, wrapped_mx_model, optimizer, n_iter=10, batch_size=128)" ] }, { "cell_type": "markdown", "metadata": { "id": "v3uPO9ZYGcjY" }, "source": [ "---\n", "\n", "## Documentation and resources\n", "\n", "- USAGE [Configuration files](https://thinc.ai/docs/usage-config)\n", "- USAGE [Defining and using models](https://thinc.ai/docs/usage-models)\n", "- USAGE [Using Thinc with PyTorch, TensorFlow & MXNet](https://thinc.ai/docs/usage-frameworks)\n", "- API [Available layers and combinators](https://thinc.ai/docs/api-layers)\n", "- API [`Config` and `registry`](https://thinc.ai/docs/api-config)\n", "- API [`Model` class](https://thinc.ai/docs/api-model)" ] } ], "metadata": { "accelerator": "GPU", "colab": { "name": "00_intro_to_thinc.ipynb", "provenance": [] }, "file_extension": ".py", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "mimetype": "text/x-python", "name": "python", "npconvert_exporter": "python", "pygments_lexer": "ipython3", "version": 3, "widgets": { "application/vnd.jupyter.widget-state+json": { "000b5ea0ab444688bf195d6c810a9ee4": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_630b657a06384d7abd3b63bcf02c3a3e", "IPY_MODEL_ac609c059aac45bba0ea7ee76e057977" ], "layout": "IPY_MODEL_5c9d8559f7134842ab00b99d28bfd644" } }, "0046f7bffaa6438d8cf31a0d558c4b46": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_efb84c9861764c61b09ad02f170d8530", "placeholder": "โ€‹", "style": "IPY_MODEL_0a3730284d6a4110bf5247d537a24262", "value": " 422/422 [00:01<00:00, 307.85it/s]" } }, "009991c634044a2c8dfb58aa7da342a6": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "00a9eda2268e47baaae96926bb7d8c51": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_0fc3d74e4d4a4ac8b057342c0a017394", "placeholder": "โ€‹", "style": "IPY_MODEL_b775d1f8fbae434185d52dafd207b592", "value": " 422/422 [00:04<00:00, 106.76it/s]" } }, "016371ed2b1e43d29e7542dc20f9ef64": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "017d16a6d32b4d6a9f868a57cd736568": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "02a62e897a334ff88aa5282286de0bab": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_880dce5bac5148988119a4c0f7296c83", "IPY_MODEL_6790ba4beb8a4bae8f9a14f0cca3b5c9" ], "layout": "IPY_MODEL_2cbcffe4ddd8450db4b259d368516d9d" } }, "03edea4af2724453bfbb6b8e2e74cda2": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0443d3d3c8564616a9cae2616c370a72": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0459c93679e54f9db4e7009420b8a612": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "054a82c3f2dc4de9864b83dcd1a2abd8": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "05de1b15d6244f82bcef782c8f73f8a8": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "05eaa0a6003243bab5378655193332c0": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_4b433703db1a41baa3e7e9f45d72aa57", "placeholder": "โ€‹", "style": "IPY_MODEL_2e0751da78e14c88bfaf8b45f30fcd05", "value": " 422/422 [00:01<00:00, 303.55it/s]" } }, "0701da5b35604eaebcecf87335ad324c": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0829771aa327491e8b7d05ef2b084175": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "08b6e41233db46a6911d22fe531832f5": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "099e1066f01c4b1780cf20a0700414a5": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "0a3730284d6a4110bf5247d537a24262": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "0a9276f6ae784e63a6daaecdd2bc7e64": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_34d176a20c5e429a8852cb3e2d3bb507", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_fce1dcea8fd749569b29e353a086ad45", "value": 422 } }, "0a9b4f19291b403dadeca3938004561e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0b2d03b2d0f6447293576ff8e9ed9ea3": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_dc4f419827134de0b96b9b020fa8a788", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_cc7f3e43ff504effb6fcbd63bac5546f", "value": 422 } }, "0b62d25712a2403ab488914a7109ab47": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "0c037dcc8bbb4f38977b3e516d3a2014": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0cdbaa847609462aa3163c49db61a7cd": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0d95eef69a7d42418cc79e4cf4d8a3cd": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_61540f7e300545eebbd697227a3b3d7d", "IPY_MODEL_c9892de0df614a84b8ba7a6e259ffe09" ], "layout": "IPY_MODEL_84ddb87806a94da8902e3da8a06aa7e5" } }, "0ed86bd7b55f49bcb9927be28a279a49": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "0eea906841464f978a262640badc0fae": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_a63ede007e94496c884527478a9b0d17", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_6565004456e24a88a2e1e04ebe7004df", "value": 422 } }, "0fc3d74e4d4a4ac8b057342c0a017394": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "1017871f46b44c9cb3f976d1af607ffc": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "110b5a48694c48059985490cae348dc6": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_c99185c8dfbe47aab9e29a90b92c63a0", "IPY_MODEL_4553ca36932d4a20b898d7fa7b23bcc3" ], "layout": "IPY_MODEL_4c61f8b9314c4bec8a0c3a5ecab3356d" } }, "110f5508e00e4ec6b5c84877abc9c265": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "11daf0a19032495ab15cdda96b0030e7": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_1e34b8465bc84f94b13a3d7a94d5f9ce", "placeholder": "โ€‹", "style": "IPY_MODEL_e6b70306bfea4bd09f17eac179387a96", "value": " 422/422 [00:01<00:00, 311.51it/s]" } }, "14717f9c7a3f4bbc97978023bad0d876": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_4f27062765bd41f589215a61e2d0840a", "IPY_MODEL_f5f4c5a71a9c41f88fafc9abea500f14" ], "layout": "IPY_MODEL_d7d3d6ec8a144738b61b59e8e1d37f1e" } }, "1480b195483d454c844c9e6a724b02b3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "14cf79b923404000b5eb2762d161ec78": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "15062403d526469e910691b9b59f06bd": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_4c6f9216f6b14905bbfeffd81e14c973", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_b875c88f7ae74f8391ac58fc31a3aabc", "value": 422 } }, "1687134f713c4c039365c0a66d1aab82": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "191e3c3e02b44eda9ebe4859325830e5": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "199cccb400aa4fc59a1f95317db0ae2b": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "19b5d9601cb94873b3f550214d586577": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "1a394e179354494487365d1a5242e2d3": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_35181a9eb7bc4967984c327a8b6f7f8f", "IPY_MODEL_3cf4e5fcc4a64c13b100093fb12e2cd2" ], "layout": "IPY_MODEL_e567c933e82146758cb690a190f1199c" } }, "1c2657c607454a0eb329ae8663665e82": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_eaa7c96f7ee849948f10033289dfbd05", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_db4cab1a1150482c861e22d6e7b2be09", "value": 422 } }, "1c4cfdd4f52a4db182cd08357b3d3abe": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ef3638ddf37547fe8359b8f4333dc2e8", "placeholder": "โ€‹", "style": "IPY_MODEL_d23105e4cc4141b5937063dc03e9d565", "value": " 422/422 [00:01<00:00, 304.76it/s]" } }, "1cea7c77162d42b2a464aeb98f86d36d": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_15062403d526469e910691b9b59f06bd", "IPY_MODEL_aa3e1f1cf64a47af9aa0930b855c14bc" ], "layout": "IPY_MODEL_66fc9d3aad8f478c8884e74990c9f2f9" } }, "1de0cf05f59b49eb8f8d233b9a4e490e": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_aa7c50235a9f43fa96a7d9ef7be20861", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_af32974b6ed54e9da7b89fe35a749640", "value": 422 } }, "1e34b8465bc84f94b13a3d7a94d5f9ce": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "21f755e5d9774eb3aab7604140054a6d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "21f9b00564ea47ffa4523dd9a8eec4e9": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_34c8794ff06d4875aec3ecaacb7f11bd", "IPY_MODEL_05eaa0a6003243bab5378655193332c0" ], "layout": "IPY_MODEL_6f2523ef7d0243b38975e5b657b43dd9" } }, "2233981c90214b7cae8d5bfc7410802b": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "22a455a7b3f841a9b01bc83dee7717cc": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "247a4869ae564aefa501053956083a6a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_2cdf06e67ced403795e3ba594fbf3c55", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_099e1066f01c4b1780cf20a0700414a5", "value": 422 } }, "2637352462d94fe795a409fbbbe70926": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "265c8c05122c406fa6b603070e2ca7bd": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "26fa7101f97f4aed98a774c83e802bc9": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_a73abf53972a4913bf2c50b0d341fc13", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_a21851e9b7b24098b3fbbe6d9f1f8e9c", "value": 422 } }, "27a1f038ed8a41dfb4d18175f80aab7a": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "27ca20cabb94467492f29713fad334dd": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "28f837093edd4e60bde32ec8d23b7497": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_de11572a1baa4efabaa5c1436af92f06", "placeholder": "โ€‹", "style": "IPY_MODEL_b7341f8df10a4e1ab8c3cbb475de0d82", "value": " 422/422 [00:01<00:00, 300.55it/s]" } }, "2be93e1e76224f61afd058eea4583a05": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2c303e0697ec4cca9e949207f89d7695": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2c6a4ebe2c914b028062eb3651de99e3": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "2cbcffe4ddd8450db4b259d368516d9d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2cdf06e67ced403795e3ba594fbf3c55": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2e0751da78e14c88bfaf8b45f30fcd05": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "2e5a7bb281d840e6a4522a4dc602fd80": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2e78f48b6298490885474f27bcbf2928": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2eb23201ad354f3ba8a0720757d4d8bd": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2fa0fd59f8844a4e99eda19fc4151962": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3161c8b70d9748c5a1400c0fe543d442": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_3a1091487eac40cdac4046173caaaaf3", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_7326a18ab885419691c5bfc3666154bc", "value": 422 } }, "318b1b7bb5064c5aabd39540bf2d7bf2": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "31ef257d727346478de228f6cbd27021": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "32272e5a9e194bed9ffe5f16a3ae1d61": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "32ff8a0bfbcb44ebb0c80363f6115e07": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "34237141f8854d33af9223e75e390ba5": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "34c8794ff06d4875aec3ecaacb7f11bd": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_4a97428d8e9944d5b2a00466e6a80c53", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_31ef257d727346478de228f6cbd27021", "value": 422 } }, "34d176a20c5e429a8852cb3e2d3bb507": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "35181a9eb7bc4967984c327a8b6f7f8f": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_016371ed2b1e43d29e7542dc20f9ef64", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_b826f8a9468d4c23b35f6021791885b6", "value": 422 } }, "3563f3d4033b4ac7b43279cf13d8bdd2": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "370044cae56f42fd992e4c4ce3240f68": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ca1968d9a9f7462e88c9a051cb7a6777", "placeholder": "โ€‹", "style": "IPY_MODEL_8dde5fd1fe4347c7bea1c51c47b14e5e", "value": " 422/422 [00:04<00:00, 95.92it/s]" } }, "3a1091487eac40cdac4046173caaaaf3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3a4fc2bfed8549d980a4884715d9c650": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_2233981c90214b7cae8d5bfc7410802b", "placeholder": "โ€‹", "style": "IPY_MODEL_6d23bd6b099746028b353af12380d226", "value": " 422/422 [00:04<00:00, 101.43it/s]" } }, "3ab377ee24544e2a95433448a8331ed1": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_70898e759e6945a1a479dcb2d434b50d", "placeholder": "โ€‹", "style": "IPY_MODEL_7fcc9f928ddd4f52a9d420862b9be6ef", "value": " 422/422 [00:01<00:00, 305.51it/s]" } }, "3b06657d55a44d2486a3d65af18286d6": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "3b153a8becf5411c871221d482680caa": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "3bbd206a74794ed4a5500b7bafe546ea": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_3161c8b70d9748c5a1400c0fe543d442", "IPY_MODEL_421fbeb9dd4c422999932f7dcd210da7" ], "layout": "IPY_MODEL_d6f5cf60a40c4825bfca5a960056d078" } }, "3c80e2934eda4d19825a76c6400a3823": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3cf4e5fcc4a64c13b100093fb12e2cd2": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_6db4cb7968194992819296b341c378f1", "placeholder": "โ€‹", "style": "IPY_MODEL_70537ee37fd645c8ba0d3e88fc43fdb5", "value": " 422/422 [00:01<00:00, 310.58it/s]" } }, "3e395e497d8f4f10812b2af65ccac13b": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3e448a3c76bc4fdfa57f82327411f2e2": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3edb84e7ef724a1887df6dcf31f75448": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3f0d72d9c4984f89a82862fcdd24643b": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3fb34090b5b34d6fa8f039440e839fbd": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_0701da5b35604eaebcecf87335ad324c", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_3b153a8becf5411c871221d482680caa", "value": 422 } }, "4005b0b6131a400e927343af9a20e154": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_594aebcc9478429d9a5063327c9953bc", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_493826515d934872b80d127fbf8e6a85", "value": 422 } }, "407a6771394a4e69a504ea5b67164a64": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "40b7a89564684301ae357cae6c517be4": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "421fbeb9dd4c422999932f7dcd210da7": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_d64df8ba0ab04aad9e1c2c4551a0b7d9", "placeholder": "โ€‹", "style": "IPY_MODEL_0ed86bd7b55f49bcb9927be28a279a49", "value": " 422/422 [00:01<00:00, 301.60it/s]" } }, "4381199cd6fd46e98175bc65f3283a07": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_ad1659c9381a4afca67aac81d1470776", "IPY_MODEL_28f837093edd4e60bde32ec8d23b7497" ], "layout": "IPY_MODEL_f8c7cd8112274e26996a56ecae42ec3f" } }, "43b0d557889248f287edd4edf50e3a9b": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_7aebabcd7cd546e989eb0c148ebb1348", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_773cbd3194e142c694f73fd52ee6aa8c", "value": 422 } }, "43d68f9905354442bad801fb61bfd02a": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_19b5d9601cb94873b3f550214d586577", "placeholder": "โ€‹", "style": "IPY_MODEL_591e3bae35404f68b24f607ece97a9d3", "value": " 422/422 [00:01<00:00, 304.08it/s]" } }, "449ba373a94641f2ac9078d8f98c3f1a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_14cf79b923404000b5eb2762d161ec78", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_3b06657d55a44d2486a3d65af18286d6", "value": 422 } }, "4553ca36932d4a20b898d7fa7b23bcc3": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_b32999bf8b8148e98bbbb6ba1acb4548", "placeholder": "โ€‹", "style": "IPY_MODEL_27a1f038ed8a41dfb4d18175f80aab7a", "value": " 422/422 [00:01<00:00, 308.41it/s]" } }, "46796020aa1145fc87c7f458ee41e14e": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_877c9e4a3541425eac50c9250e5ff568", "placeholder": "โ€‹", "style": "IPY_MODEL_76c193b0729b4a57b1664a94163bb38a", "value": " 422/422 [00:01<00:00, 297.86it/s]" } }, "473ece24383049f6964082046f5a8cef": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "47a3f9dad5e2486b98ddd34b7bcf1201": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_a27c932db2c84a86a75a92af92a07f0b", "IPY_MODEL_8d73c0c46c944eb89e95a9efb0a891a6" ], "layout": "IPY_MODEL_9bc1cd208dfd4a55bd52a4d0f399117c" } }, "47fd69df905945a09183f89126c665f0": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "490a7c3043e24e378892816de13970eb": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "493826515d934872b80d127fbf8e6a85": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "49bbc050955c4ddd931efc9a468faccb": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4a97428d8e9944d5b2a00466e6a80c53": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4a9b8833512a4f07a4411b1e8c2ca0c8": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_a0b0dd366b424f03adde1e0698b8b31f", "placeholder": "โ€‹", "style": "IPY_MODEL_aa1f805540a74c7380bd2b333b9ecc88", "value": " 422/422 [00:01<00:00, 308.54it/s]" } }, "4b2f4fa05e7a465eacf809489243b2a8": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_e18cf1aef5834391ae7410dcb90f1c59", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_df732c32eb1340a890c181eed7358452", "value": 422 } }, "4b433703db1a41baa3e7e9f45d72aa57": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4bccad99024f4d77a23b657d9dc7746d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4c60aa21f05a4d678b2135d4d1f2c99a": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4c61f8b9314c4bec8a0c3a5ecab3356d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4c6f9216f6b14905bbfeffd81e14c973": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4e2c73f549d94202a34b4a1046d011e5": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_8c10956546bd46cc94c322044b217a1a", "IPY_MODEL_cfa1762b9dd740f39d4dc3f198abdcc6" ], "layout": "IPY_MODEL_847aaa75aecc40f3bc9d67c37cf03362" } }, "4f27062765bd41f589215a61e2d0840a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_3edb84e7ef724a1887df6dcf31f75448", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_95f5d01ae2524dd2bcfab4945816b6a4", "value": 422 } }, "4faac8b7bdd748a7b908d46ed058aa3a": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_8584d1e513e7496192af75d2cf4f84c0", "IPY_MODEL_943c772ee3fe43cea3d05cea3f7f12bb" ], "layout": "IPY_MODEL_995ac4803a534d0883a15702eae4fc50" } }, "501c6677916d40f9afaea8f48be244fe": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "50b4abff394846eabd6f6fdcac8a7762": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "50d48e02aa744ad8adbccce94148b060": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "50ded217cb2440249cd86a4dcc0e1b7a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_009991c634044a2c8dfb58aa7da342a6", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_987b752181564435ab5a7f8d838651f5", "value": 422 } }, "53065cc4a41d4652bfb986ae1d28ce9b": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_b7740ddd81034150bca1bf841f43af31", "IPY_MODEL_c330191809e44832a89abcc6c4a6fd5d" ], "layout": "IPY_MODEL_5cc3f44e4660481d920e9120fd0d254a" } }, "550caabed61042e1b89dd8a826897b77": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "565b64b2df2f4342bdb56ad34b468de2": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_6699fda35d5b495da6052e53f4e24a01", "IPY_MODEL_649359bad86d415094308180006a0e11" ], "layout": "IPY_MODEL_08b6e41233db46a6911d22fe531832f5" } }, "570de138283348be9b7575b51df33eea": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "583c6058061240838ad63f2a8ddf9a00": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "583d96a84b3642f4b864c7ae7ab6f598": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_5978e50fc32f4fe1ab99fbfc42e87c89", "placeholder": "โ€‹", "style": "IPY_MODEL_ee11cbb4ec3d4042b6c62536a477c10a", "value": " 422/422 [00:01<00:00, 314.30it/s]" } }, "584cadfb0a6c480f94aad4b9842c4d25": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_490a7c3043e24e378892816de13970eb", "placeholder": "โ€‹", "style": "IPY_MODEL_a991cedbd4b24c139430a06369ad527f", "value": " 422/422 [00:01<00:00, 310.32it/s]" } }, "591e3bae35404f68b24f607ece97a9d3": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "594aebcc9478429d9a5063327c9953bc": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5978e50fc32f4fe1ab99fbfc42e87c89": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5ac7bb8fbf0048c492fc4f6c8b69d828": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_fdd481739b6a4d64ac739965c621d3b8", "placeholder": "โ€‹", "style": "IPY_MODEL_2c6a4ebe2c914b028062eb3651de99e3", "value": " 422/422 [00:01<00:00, 311.10it/s]" } }, "5ac87cfe946d483b8088df90b22490d8": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "5bd005f55b724af4893bb2d0718d9408": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_4005b0b6131a400e927343af9a20e154", "IPY_MODEL_87a3fcd0fd8d4df1b885b1e106d085a8" ], "layout": "IPY_MODEL_2e5a7bb281d840e6a4522a4dc602fd80" } }, "5bfe581cc5db4002b38c89df6b245720": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5c5c9d38d86c4d2486c547a3add4a04c": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ceefe7af1738490d9414c6c690eb4681", "placeholder": "โ€‹", "style": "IPY_MODEL_eb2cfbd11882434e9373f36d62d06258", "value": " 422/422 [00:01<00:00, 307.38it/s]" } }, "5c9d8559f7134842ab00b99d28bfd644": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5cc3f44e4660481d920e9120fd0d254a": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5d84a716b7ed4ad8927ee8ea8493e4db": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5eb4571729ea4b92857d3ba3c575721a": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5edf3c8cd0f64046ac298d48a93ef32e": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "5ee467d84bd24e5db0507a994273ea28": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "5fe58d7f655243c8b9d29f31a0eb7b53": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "608cfc45e4ec4579b75999043e62ab19": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "61540f7e300545eebbd697227a3b3d7d": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_d74548d2826c45cba4e730b3a9638fd4", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_a08bba98a4994866949e19f6104e6991", "value": 422 } }, "630b657a06384d7abd3b63bcf02c3a3e": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_f7dd4ce672014ce6ba3d7d50ff090c9e", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_88a24010610d4a19a3fb81eddfcfaf52", "value": 422 } }, "637ac772584f4f169d59c0964be8acfd": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_e32b04ebb4454ca2848b799045c30320", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_fe0223b47b9346e7ad056b86841f91d9", "value": 422 } }, "6485d6b9b194425f8eb28b779d7d6e9a": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "649359bad86d415094308180006a0e11": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_a13d290a9ddf41deb2f258c617dfd2e3", "placeholder": "โ€‹", "style": "IPY_MODEL_c1a8a841a5124a6eb364863a2fc11447", "value": " 422/422 [00:01<00:00, 315.93it/s]" } }, "64cc1e2f91a44b218a7824aedd373b31": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "6565004456e24a88a2e1e04ebe7004df": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "65729f9c7457426eb006da855388182b": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "662835d152984f4eb87fa7cef0c0e28d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6699fda35d5b495da6052e53f4e24a01": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_afe82cf54da249cb815dc3ece7bac260", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_f82fd9ccee6b423c8bdbc830ba0f8a93", "value": 422 } }, "66fc9d3aad8f478c8884e74990c9f2f9": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6790ba4beb8a4bae8f9a14f0cca3b5c9": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_21f755e5d9774eb3aab7604140054a6d", "placeholder": "โ€‹", "style": "IPY_MODEL_f55d98fcc3524d94ba73b3192ee19281", "value": " 422/422 [00:04<00:00, 104.34it/s]" } }, "68b365d2d435430aae5af88ecdae39a5": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "69f5f6ef84e44fc284dd9be06beaaf65": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6ae1111eff4043f294a7bbafcb5de189": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_f3abedf22ff649b4b90e85fc68f93c67", "IPY_MODEL_d4f5f106a2ed488fbba2b626bbd72714" ], "layout": "IPY_MODEL_0443d3d3c8564616a9cae2616c370a72" } }, "6b3e7a3ba015416cada97bb79d4c8fb1": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_0a9276f6ae784e63a6daaecdd2bc7e64", "IPY_MODEL_0046f7bffaa6438d8cf31a0d558c4b46" ], "layout": "IPY_MODEL_a780eb0b79ff40e9966a72a3c5a81eca" } }, "6b89100361a443bd85a01f8e47374c96": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "6bc78efbc98a4cb5ad04647f893e2f1a": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6cba2abf076d483ba8847ccbcf537c52": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "6d23bd6b099746028b353af12380d226": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "6da928e744da4d0bb1cbb1df33c201ee": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "6db4cb7968194992819296b341c378f1": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6e396b43955349b28a280ccb1d41c716": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_2e78f48b6298490885474f27bcbf2928", "placeholder": "โ€‹", "style": "IPY_MODEL_501c6677916d40f9afaea8f48be244fe", "value": " 422/422 [00:01<00:00, 300.05it/s]" } }, "6f2523ef7d0243b38975e5b657b43dd9": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6f8967c159b1474ab706026b6becd9a1": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_017d16a6d32b4d6a9f868a57cd736568", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_6da928e744da4d0bb1cbb1df33c201ee", "value": 422 } }, "7048d397ed0647a19587c17deec944bb": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_a4823e3708aa4ccba43e3547a229095e", "placeholder": "โ€‹", "style": "IPY_MODEL_32272e5a9e194bed9ffe5f16a3ae1d61", "value": " 422/422 [00:01<00:00, 309.82it/s]" } }, "70537ee37fd645c8ba0d3e88fc43fdb5": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "70898e759e6945a1a479dcb2d434b50d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "70bb47f183e24e7c805d8b5e89ce1b3e": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_c2b02e00355041919382a3c23c0d6850", "IPY_MODEL_6e396b43955349b28a280ccb1d41c716" ], "layout": "IPY_MODEL_838598dc75fb4836b3f4d769d68de597" } }, "71522233b5b64b3dbd29ec69e47788d8": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7326a18ab885419691c5bfc3666154bc": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "732824b0216e44f7a88da251febff435": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_b91537eaa9ba44f8952cb65696d236fe", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_40b7a89564684301ae357cae6c517be4", "value": 422 } }, "734031c5bb6e4e7d9e30f1a15861924f": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_8a0e36efabb04f869ba2c080446525da", "placeholder": "โ€‹", "style": "IPY_MODEL_34237141f8854d33af9223e75e390ba5", "value": " 422/422 [00:01<00:00, 304.14it/s]" } }, "7411b7336cab4e8f92347df274e93876": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "74632c71eef34180a7dba0c22fd9df80": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "759a4d04fe92425ab0d6d8681d3ed0c6": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "76c193b0729b4a57b1664a94163bb38a": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "77325a33c7b6495e9301c771dbf935de": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "773cbd3194e142c694f73fd52ee6aa8c": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "79574d891d35493da77efbbad6fff11f": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_989fb7b65c504a1aad8ec0f53e2e43c3", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_3563f3d4033b4ac7b43279cf13d8bdd2", "value": 422 } }, "79c6ecc409764fc78294fcbd9319c3c0": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "7ae0b9e9e6964641a7d529b03d60b034": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_84fb3096f29f40bf9f4d20bca7608c05", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_05de1b15d6244f82bcef782c8f73f8a8", "value": 422 } }, "7aebabcd7cd546e989eb0c148ebb1348": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7b5bf62263a64441b7424aab153415be": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_d1758fb53b404e3f9b8f317be75684b4", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_7eb7725598674b13b049a370bb505ea7", "value": 422 } }, "7e44024663ce4bd4833c4dcdf2d63d14": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7e569ac0f5974f4aaed7cf2e953bc316": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7e91135b95964e35a11bd312983f31c3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7eb7725598674b13b049a370bb505ea7": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "7ed4511c19b24c7fadf283d962a612a2": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_4b2f4fa05e7a465eacf809489243b2a8", "IPY_MODEL_a3426fcb07904ca4be130a71b330c77a" ], "layout": "IPY_MODEL_7e44024663ce4bd4833c4dcdf2d63d14" } }, "7f3517a0116846708d65a947e534de05": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_ca4f1e1dbbbd46618b40291f94ef1102", "IPY_MODEL_3ab377ee24544e2a95433448a8331ed1" ], "layout": "IPY_MODEL_2fa0fd59f8844a4e99eda19fc4151962" } }, "7f60da0694d343fca576f9cfaf7352ac": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_db3333497eba4ee1a63225b4c6bf468c", "placeholder": "โ€‹", "style": "IPY_MODEL_ea6cbc2071af4c018f96e5846f328a1f", "value": " 422/422 [00:01<00:00, 308.78it/s]" } }, "7fcc9f928ddd4f52a9d420862b9be6ef": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "80016285573540f998aeec24132c0bb3": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_265c8c05122c406fa6b603070e2ca7bd", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_ebfa4d5418d84b3ea8fad62dfabce7c1", "value": 422 } }, "80538e2ccd7f490987a79d4c70c9571b": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_d17516de5c52450abfd79af7db04a282", "IPY_MODEL_584cadfb0a6c480f94aad4b9842c4d25" ], "layout": "IPY_MODEL_50b4abff394846eabd6f6fdcac8a7762" } }, "81a8b3ff6d644f2c83f04a835bef5333": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "82076a20084549719b917b071d1d1b91": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "829ad0cbf2bb49d9bde04dcff1f9cb3c": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "838598dc75fb4836b3f4d769d68de597": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8404870254bf4dfa80ce1a11acaa5969": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "847aaa75aecc40f3bc9d67c37cf03362": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "84ddb87806a94da8902e3da8a06aa7e5": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "84fb3096f29f40bf9f4d20bca7608c05": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8584d1e513e7496192af75d2cf4f84c0": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_dbd113a86ad44f0b95261ed9f6e6c93c", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_74632c71eef34180a7dba0c22fd9df80", "value": 422 } }, "85e62f6e0211431a9f6513285ef1aa0b": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "8619ba70e84f4bda9d5c966863d0d4e3": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_977ab80b593849389b224d18aefb6814", "IPY_MODEL_d62d3423df7f49d18b45bb87e9919ade" ], "layout": "IPY_MODEL_0c037dcc8bbb4f38977b3e516d3a2014" } }, "861a02913c8346f2a2c7c7c049364acd": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "86c4306d45c04ce783d40f202c30c350": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_6f8967c159b1474ab706026b6becd9a1", "IPY_MODEL_5c5c9d38d86c4d2486c547a3add4a04c" ], "layout": "IPY_MODEL_2be93e1e76224f61afd058eea4583a05" } }, "86ea34c601f447f18eaaf30fd1711f77": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "877c9e4a3541425eac50c9250e5ff568": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "87a3fcd0fd8d4df1b885b1e106d085a8": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_7e91135b95964e35a11bd312983f31c3", "placeholder": "โ€‹", "style": "IPY_MODEL_7411b7336cab4e8f92347df274e93876", "value": " 422/422 [00:04<00:00, 102.91it/s]" } }, "880dce5bac5148988119a4c0f7296c83": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_c2fa2316330f4edc83a8e3e4de571cf3", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_6cba2abf076d483ba8847ccbcf537c52", "value": 422 } }, "88a24010610d4a19a3fb81eddfcfaf52": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "8a0e36efabb04f869ba2c080446525da": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8a25115e9fef433e90b70e1ff3bbe341": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8b296000cd0446e2952bff859b785260": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_26fa7101f97f4aed98a774c83e802bc9", "IPY_MODEL_3a4fc2bfed8549d980a4884715d9c650" ], "layout": "IPY_MODEL_f6f53ccede894d5fa859543bcd5d07a1" } }, "8b2e77ece9f14c37ad8efab38442acbb": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8c10956546bd46cc94c322044b217a1a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_77325a33c7b6495e9301c771dbf935de", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_5edf3c8cd0f64046ac298d48a93ef32e", "value": 422 } }, "8c639957ced245318db4865da9e0c1df": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_7b5bf62263a64441b7424aab153415be", "IPY_MODEL_370044cae56f42fd992e4c4ce3240f68" ], "layout": "IPY_MODEL_0cdbaa847609462aa3163c49db61a7cd" } }, "8d73c0c46c944eb89e95a9efb0a891a6": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_2c303e0697ec4cca9e949207f89d7695", "placeholder": "โ€‹", "style": "IPY_MODEL_cf424d3cddcb4e469f4c88d1df70dedb", "value": " 422/422 [00:01<00:00, 311.63it/s]" } }, "8dde5fd1fe4347c7bea1c51c47b14e5e": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "8f521dc0bd094a3da7cffd4da51ce7e0": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8ff0e222da2b47d99e8931080555cb7e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9024d8c79164492e80170ca565f2e367": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "92ae4ede68904e2f8b0b2322f099d32b": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "943c772ee3fe43cea3d05cea3f7f12bb": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_f4fd9c138d8c4192afdb4324afe46771", "placeholder": "โ€‹", "style": "IPY_MODEL_054a82c3f2dc4de9864b83dcd1a2abd8", "value": " 422/422 [00:04<00:00, 101.82it/s]" } }, "95f5d01ae2524dd2bcfab4945816b6a4": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "96e832df4dec40d9a97bd129ef55effa": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "973c950b92d14614a5df848d2a8c024e": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_637ac772584f4f169d59c0964be8acfd", "IPY_MODEL_dd2ea7e5c59f4a3a807a7f8048eafb1e" ], "layout": "IPY_MODEL_a702297c0c7e40b08546a7669dfb6917" } }, "977ab80b593849389b224d18aefb6814": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_a859b046e9e84f518b8c4aa449fb75cc", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_473ece24383049f6964082046f5a8cef", "value": 422 } }, "97e1cf826ec54af79646bee305e23601": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_1c2657c607454a0eb329ae8663665e82", "IPY_MODEL_1c4cfdd4f52a4db182cd08357b3d3abe" ], "layout": "IPY_MODEL_c8de4a1a7be449e68787a4dcdc94801d" } }, "987b752181564435ab5a7f8d838651f5": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "989fb7b65c504a1aad8ec0f53e2e43c3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "995ac4803a534d0883a15702eae4fc50": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "99c3aedf530c44d69f3c145efc7da6da": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_9024d8c79164492e80170ca565f2e367", "placeholder": "โ€‹", "style": "IPY_MODEL_199cccb400aa4fc59a1f95317db0ae2b", "value": " 422/422 [00:01<00:00, 307.88it/s]" } }, "99fd455414304cb5a2a08077c2182452": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_449ba373a94641f2ac9078d8f98c3f1a", "IPY_MODEL_fa591816c3414db3a7dc1478649ac230" ], "layout": "IPY_MODEL_65729f9c7457426eb006da855388182b" } }, "9b16033c7b7a47568a0d078d708cf28d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9bc1cd208dfd4a55bd52a4d0f399117c": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9bce5f414ec043509c06f10840cc2d0f": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_50ded217cb2440249cd86a4dcc0e1b7a", "IPY_MODEL_e1229e07527b4a67bb7de71715ed10ca" ], "layout": "IPY_MODEL_47fd69df905945a09183f89126c665f0" } }, "9bf763a02b58454ab1e4f9598939fd79": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_e0077b7268614d85b4a08ad07183a2e4", "placeholder": "โ€‹", "style": "IPY_MODEL_407a6771394a4e69a504ea5b67164a64", "value": " 422/422 [00:01<00:00, 302.85it/s]" } }, "9c7baaf83e734b86b2234c735dca859d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9e2a1ec730be42d38a3f04b967ed0b88": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "9f6277814410407fae19e3aee971c997": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "a08bba98a4994866949e19f6104e6991": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "a0b0dd366b424f03adde1e0698b8b31f": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a13d290a9ddf41deb2f258c617dfd2e3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a16d1171acfe48b5abfd3652d0cf119f": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a183401dedf140979852bfc28122d689": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "a21851e9b7b24098b3fbbe6d9f1f8e9c": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "a27c932db2c84a86a75a92af92a07f0b": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_8b2e77ece9f14c37ad8efab38442acbb", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_a183401dedf140979852bfc28122d689", "value": 422 } }, "a3426fcb07904ca4be130a71b330c77a": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_8a25115e9fef433e90b70e1ff3bbe341", "placeholder": "โ€‹", "style": "IPY_MODEL_759a4d04fe92425ab0d6d8681d3ed0c6", "value": " 422/422 [00:04<00:00, 99.10it/s]" } }, "a4823e3708aa4ccba43e3547a229095e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a5ac2b15a8ae40ce92160a960414279c": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_43b0d557889248f287edd4edf50e3a9b", "IPY_MODEL_99c3aedf530c44d69f3c145efc7da6da" ], "layout": "IPY_MODEL_b52a071acc34438d849dbc7adcc91631" } }, "a63ede007e94496c884527478a9b0d17": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a702297c0c7e40b08546a7669dfb6917": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a73abf53972a4913bf2c50b0d341fc13": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a780eb0b79ff40e9966a72a3c5a81eca": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a859b046e9e84f518b8c4aa449fb75cc": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a887772c5344437aa896b3ed1bd5208f": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_e53b1041df93415c9852da6d8a05b7d3", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_e5caa26da44e411f891a71b85c46c87a", "value": 422 } }, "a991cedbd4b24c139430a06369ad527f": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "aa1f805540a74c7380bd2b333b9ecc88": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "aa3e1f1cf64a47af9aa0930b855c14bc": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_27ca20cabb94467492f29713fad334dd", "placeholder": "โ€‹", "style": "IPY_MODEL_550caabed61042e1b89dd8a826897b77", "value": " 422/422 [00:01<00:00, 304.47it/s]" } }, "aa7c50235a9f43fa96a7d9ef7be20861": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "aa86d75f3dba49a481c2c15167387b99": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_49bbc050955c4ddd931efc9a468faccb", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_82076a20084549719b917b071d1d1b91", "value": 422 } }, "ab756a05d67241baabcb4ee84b35efe3": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_de806eb1cca0447c92917881ec18d49a", "IPY_MODEL_00a9eda2268e47baaae96926bb7d8c51" ], "layout": "IPY_MODEL_9b16033c7b7a47568a0d078d708cf28d" } }, "ab99a2cf8919454bb780cc24088f2b85": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_fddd7fb9ef3f4535a97775548abbabd1", "IPY_MODEL_fa68877e48ab41a48a3c10dc3fe329d1" ], "layout": "IPY_MODEL_9c7baaf83e734b86b2234c735dca859d" } }, "ac609c059aac45bba0ea7ee76e057977": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_318b1b7bb5064c5aabd39540bf2d7bf2", "placeholder": "โ€‹", "style": "IPY_MODEL_fdd43b573d18496a9eec5f61632b33ed", "value": " 422/422 [00:01<00:00, 315.84it/s]" } }, "ad1659c9381a4afca67aac81d1470776": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_191e3c3e02b44eda9ebe4859325830e5", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_f0c3740bcfb04fa6a12e1f1025aff42f", "value": 422 } }, "ad58dbfc6a294f3f9dc89c4a3f9658dc": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_0eea906841464f978a262640badc0fae", "IPY_MODEL_11daf0a19032495ab15cdda96b0030e7" ], "layout": "IPY_MODEL_8f521dc0bd094a3da7cffd4da51ce7e0" } }, "ae7ec72f5d064a6a80433613be03f849": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "af32974b6ed54e9da7b89fe35a749640": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "afe82cf54da249cb815dc3ece7bac260": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b1548f9f9f4642ef814e9d3565002501": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b31897c725c946e8a08a2ef0e80b6520": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b32999bf8b8148e98bbbb6ba1acb4548": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b34c1730161e41c5bb901128ccb4ff65": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b3664609744546988f30152c49d02ac8": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_247a4869ae564aefa501053956083a6a", "IPY_MODEL_5ac7bb8fbf0048c492fc4f6c8b69d828" ], "layout": "IPY_MODEL_3e395e497d8f4f10812b2af65ccac13b" } }, "b3f89680663b466f9dda719fa6843707": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b4979a909ae64f48888d2383285f4f68": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b50ff7a73c0f4a6da93443ca019ba785": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_e2a09b4280db464f863a1ae66d58ea02", "IPY_MODEL_7f60da0694d343fca576f9cfaf7352ac" ], "layout": "IPY_MODEL_0a9b4f19291b403dadeca3938004561e" } }, "b52a071acc34438d849dbc7adcc91631": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b668e892e9cb4571b173390e78d8d786": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_79574d891d35493da77efbbad6fff11f", "IPY_MODEL_583d96a84b3642f4b864c7ae7ab6f598" ], "layout": "IPY_MODEL_7e569ac0f5974f4aaed7cf2e953bc316" } }, "b7341f8df10a4e1ab8c3cbb475de0d82": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "b7740ddd81034150bca1bf841f43af31": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_583c6058061240838ad63f2a8ddf9a00", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_9e2a1ec730be42d38a3f04b967ed0b88", "value": 422 } }, "b775d1f8fbae434185d52dafd207b592": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "b826f8a9468d4c23b35f6021791885b6": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "b875c88f7ae74f8391ac58fc31a3aabc": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "b91537eaa9ba44f8952cb65696d236fe": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b9862082c1cf47d1bb6057537571499d": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "b9db25806c4a410db0004f77a1acaee5": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "bce5275ceea044c3ba0f1635b0657ac4": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_1017871f46b44c9cb3f976d1af607ffc", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_caff75ab1b874f9da109674579faadf3", "value": 422 } }, "c0db04b51d0c4e9e9081c0169cca1f4e": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_80016285573540f998aeec24132c0bb3", "IPY_MODEL_f999eff152854b6da98defded43c8818" ], "layout": "IPY_MODEL_cb35834c71e24301abd3574d82e017b9" } }, "c1a8a841a5124a6eb364863a2fc11447": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "c2b02e00355041919382a3c23c0d6850": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_1480b195483d454c844c9e6a724b02b3", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_9f6277814410407fae19e3aee971c997", "value": 422 } }, "c2fa2316330f4edc83a8e3e4de571cf3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c330191809e44832a89abcc6c4a6fd5d": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_110f5508e00e4ec6b5c84877abc9c265", "placeholder": "โ€‹", "style": "IPY_MODEL_e731309213c94e92be1a389d13a190f5", "value": " 422/422 [00:01<00:00, 314.36it/s]" } }, "c5b2f89f03264317aa734883c164cabb": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_b31897c725c946e8a08a2ef0e80b6520", "placeholder": "โ€‹", "style": "IPY_MODEL_79c6ecc409764fc78294fcbd9319c3c0", "value": " 422/422 [00:01<00:00, 305.91it/s]" } }, "c808822cdef941a3879bf1cc2b32720a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_570de138283348be9b7575b51df33eea", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_c8967d63161647d4a9e778765d3e7ac2", "value": 422 } }, "c8967d63161647d4a9e778765d3e7ac2": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "c8de4a1a7be449e68787a4dcdc94801d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c918030a689a4842b727d9b7ecbe39ae": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "c9892de0df614a84b8ba7a6e259ffe09": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_86ea34c601f447f18eaaf30fd1711f77", "placeholder": "โ€‹", "style": "IPY_MODEL_fac6ce9bd41f43f9821f45741359f5f4", "value": " 422/422 [00:04<00:00, 101.74it/s]" } }, "c99185c8dfbe47aab9e29a90b92c63a0": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_1687134f713c4c039365c0a66d1aab82", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_0829771aa327491e8b7d05ef2b084175", "value": 422 } }, "ca1968d9a9f7462e88c9a051cb7a6777": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ca4f1e1dbbbd46618b40291f94ef1102": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_b1548f9f9f4642ef814e9d3565002501", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_5fe58d7f655243c8b9d29f31a0eb7b53", "value": 422 } }, "caff75ab1b874f9da109674579faadf3": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "cb24ce5968194d92bf77463a59eea46b": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_aa86d75f3dba49a481c2c15167387b99", "IPY_MODEL_e83ab25fcda94a90bdd58143c3624263" ], "layout": "IPY_MODEL_5bfe581cc5db4002b38c89df6b245720" } }, "cb35834c71e24301abd3574d82e017b9": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "cc7f3e43ff504effb6fcbd63bac5546f": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "cd54b80e170c4a6c94fe419c2cf8bcd6": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_4c60aa21f05a4d678b2135d4d1f2c99a", "placeholder": "โ€‹", "style": "IPY_MODEL_81a8b3ff6d644f2c83f04a835bef5333", "value": " 422/422 [00:04<00:00, 36.83it/s]" } }, "ce87dfd22b554e0a83b264913f7156c6": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "ceefe7af1738490d9414c6c690eb4681": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "cf424d3cddcb4e469f4c88d1df70dedb": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "cfa1762b9dd740f39d4dc3f198abdcc6": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_2eb23201ad354f3ba8a0720757d4d8bd", "placeholder": "โ€‹", "style": "IPY_MODEL_ce87dfd22b554e0a83b264913f7156c6", "value": " 422/422 [00:01<00:00, 303.83it/s]" } }, "d17516de5c52450abfd79af7db04a282": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_3c80e2934eda4d19825a76c6400a3823", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_22a455a7b3f841a9b01bc83dee7717cc", "value": 422 } }, "d1758fb53b404e3f9b8f317be75684b4": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d23105e4cc4141b5937063dc03e9d565": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "d266fcfaaa9741b1a4be560f094ac1d2": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_71522233b5b64b3dbd29ec69e47788d8", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_db2b8e98efcd4a7599b7bbd57c55e70c", "value": 422 } }, "d4f5f106a2ed488fbba2b626bbd72714": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ebebf706cc9549d9803b796ea2ef2853", "placeholder": "โ€‹", "style": "IPY_MODEL_b9862082c1cf47d1bb6057537571499d", "value": " 422/422 [00:01<00:00, 312.14it/s]" } }, "d62d3423df7f49d18b45bb87e9919ade": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_b3f89680663b466f9dda719fa6843707", "placeholder": "โ€‹", "style": "IPY_MODEL_50d48e02aa744ad8adbccce94148b060", "value": " 422/422 [00:01<00:00, 298.70it/s]" } }, "d64df8ba0ab04aad9e1c2c4551a0b7d9": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d673cd4b0e384aee988f565ab73cb022": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "d6f5cf60a40c4825bfca5a960056d078": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d74548d2826c45cba4e730b3a9638fd4": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d7d3d6ec8a144738b61b59e8e1d37f1e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d904c7aebabb477a99f41e95f1b0b9cf": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "d98b018eb67447eca644cd5fa56f2723": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_a887772c5344437aa896b3ed1bd5208f", "IPY_MODEL_734031c5bb6e4e7d9e30f1a15861924f" ], "layout": "IPY_MODEL_8ff0e222da2b47d99e8931080555cb7e" } }, "d9ba3c88398d4e12a674eca10a8633ff": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_d266fcfaaa9741b1a4be560f094ac1d2", "IPY_MODEL_cd54b80e170c4a6c94fe419c2cf8bcd6" ], "layout": "IPY_MODEL_2637352462d94fe795a409fbbbe70926" } }, "db1b1bff50974cd0823dcccecd2ae1c4": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_e47127013eaa48979dc86657839ba227", "IPY_MODEL_eb6a91e79a1b4998bc2751d3e572b05f" ], "layout": "IPY_MODEL_fad451dd3ae040a8aede364098400642" } }, "db2b8e98efcd4a7599b7bbd57c55e70c": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "db3333497eba4ee1a63225b4c6bf468c": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "db4cab1a1150482c861e22d6e7b2be09": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "dba0b00af12d410cb8dfd4be838b173a": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_bce5275ceea044c3ba0f1635b0657ac4", "IPY_MODEL_7048d397ed0647a19587c17deec944bb" ], "layout": "IPY_MODEL_b34c1730161e41c5bb901128ccb4ff65" } }, "dbd113a86ad44f0b95261ed9f6e6c93c": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "dc4f419827134de0b96b9b020fa8a788": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "dd2ea7e5c59f4a3a807a7f8048eafb1e": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_69f5f6ef84e44fc284dd9be06beaaf65", "placeholder": "โ€‹", "style": "IPY_MODEL_608cfc45e4ec4579b75999043e62ab19", "value": " 422/422 [00:01<00:00, 301.40it/s]" } }, "dd43258264da429a9aeb315f1715b7db": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_4bccad99024f4d77a23b657d9dc7746d", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_861a02913c8346f2a2c7c7c049364acd", "value": 422 } }, "dd52397ee21b49f999121fb8a62ea4bf": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "de11572a1baa4efabaa5c1436af92f06": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "de806eb1cca0447c92917881ec18d49a": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_e9c21ca7465449d3a8930234e9ed8dcf", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_64cc1e2f91a44b218a7824aedd373b31", "value": 422 } }, "df732c32eb1340a890c181eed7358452": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "df901f8348654af087a63b43ec822b9e": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_3fb34090b5b34d6fa8f039440e839fbd", "IPY_MODEL_46796020aa1145fc87c7f458ee41e14e" ], "layout": "IPY_MODEL_dffdd7d2ddf24707a1b2fb0df00cf957" } }, "dffdd7d2ddf24707a1b2fb0df00cf957": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e0077b7268614d85b4a08ad07183a2e4": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e1229e07527b4a67bb7de71715ed10ca": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_6bc78efbc98a4cb5ad04647f893e2f1a", "placeholder": "โ€‹", "style": "IPY_MODEL_5ee467d84bd24e5db0507a994273ea28", "value": " 422/422 [00:01<00:00, 213.42it/s]" } }, "e18cf1aef5834391ae7410dcb90f1c59": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e28f8422f22b4ef29ec9f6cffe959ecd": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_dd43258264da429a9aeb315f1715b7db", "IPY_MODEL_43d68f9905354442bad801fb61bfd02a" ], "layout": "IPY_MODEL_03edea4af2724453bfbb6b8e2e74cda2" } }, "e2a09b4280db464f863a1ae66d58ea02": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_5d84a716b7ed4ad8927ee8ea8493e4db", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_5ac87cfe946d483b8088df90b22490d8", "value": 422 } }, "e32b04ebb4454ca2848b799045c30320": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e3ddfbf3678a41ab9926976cf1beee85": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_7ae0b9e9e6964641a7d529b03d60b034", "IPY_MODEL_4a9b8833512a4f07a4411b1e8c2ca0c8" ], "layout": "IPY_MODEL_a16d1171acfe48b5abfd3652d0cf119f" } }, "e47127013eaa48979dc86657839ba227": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_ff6267b3dd63479a8e260848a30709a8", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_0b62d25712a2403ab488914a7109ab47", "value": 422 } }, "e4e73b9dcadd4bacb50d03152e7d81e8": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_6485d6b9b194425f8eb28b779d7d6e9a", "placeholder": "โ€‹", "style": "IPY_MODEL_6b89100361a443bd85a01f8e47374c96", "value": " 422/422 [00:04<00:00, 95.15it/s]" } }, "e53b1041df93415c9852da6d8a05b7d3": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e567c933e82146758cb690a190f1199c": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e5caa26da44e411f891a71b85c46c87a": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "e6b70306bfea4bd09f17eac179387a96": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "e731309213c94e92be1a389d13a190f5": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "e82d78f382b343c384bb7895daa18c82": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e83ab25fcda94a90bdd58143c3624263": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_5eb4571729ea4b92857d3ba3c575721a", "placeholder": "โ€‹", "style": "IPY_MODEL_ae7ec72f5d064a6a80433613be03f849", "value": " 422/422 [00:01<00:00, 294.05it/s]" } }, "e9228023d62243569a1e2e06a1cf94b5": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_c808822cdef941a3879bf1cc2b32720a", "IPY_MODEL_e4e73b9dcadd4bacb50d03152e7d81e8" ], "layout": "IPY_MODEL_f08fd096dcb743faafc6dbc604b45989" } }, "e9c21ca7465449d3a8930234e9ed8dcf": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ea6cbc2071af4c018f96e5846f328a1f": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "eaa7c96f7ee849948f10033289dfbd05": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "eac2608b4c0e4ad9ac81838ad7d68657": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "eb2cfbd11882434e9373f36d62d06258": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "eb6a91e79a1b4998bc2751d3e572b05f": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_8404870254bf4dfa80ce1a11acaa5969", "placeholder": "โ€‹", "style": "IPY_MODEL_dd52397ee21b49f999121fb8a62ea4bf", "value": " 422/422 [00:04<00:00, 98.38it/s]" } }, "ebebf706cc9549d9803b796ea2ef2853": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ebfa4d5418d84b3ea8fad62dfabce7c1": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "ee11cbb4ec3d4042b6c62536a477c10a": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "ef3638ddf37547fe8359b8f4333dc2e8": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "efb84c9861764c61b09ad02f170d8530": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f08fd096dcb743faafc6dbc604b45989": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f0c3740bcfb04fa6a12e1f1025aff42f": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "f160728d6cfc4cd380fafce5b253d2c7": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_0b2d03b2d0f6447293576ff8e9ed9ea3", "IPY_MODEL_f839ef53446f4fa9834edc8da44f1327" ], "layout": "IPY_MODEL_b9db25806c4a410db0004f77a1acaee5" } }, "f3abedf22ff649b4b90e85fc68f93c67": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_e82d78f382b343c384bb7895daa18c82", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_d904c7aebabb477a99f41e95f1b0b9cf", "value": 422 } }, "f4fd9c138d8c4192afdb4324afe46771": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f55d98fcc3524d94ba73b3192ee19281": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "f5f4c5a71a9c41f88fafc9abea500f14": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_eac2608b4c0e4ad9ac81838ad7d68657", "placeholder": "โ€‹", "style": "IPY_MODEL_c918030a689a4842b727d9b7ecbe39ae", "value": " 422/422 [00:01<00:00, 313.61it/s]" } }, "f6f53ccede894d5fa859543bcd5d07a1": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f7dd4ce672014ce6ba3d7d50ff090c9e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f82fd9ccee6b423c8bdbc830ba0f8a93": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "f839ef53446f4fa9834edc8da44f1327": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_0459c93679e54f9db4e7009420b8a612", "placeholder": "โ€‹", "style": "IPY_MODEL_68b365d2d435430aae5af88ecdae39a5", "value": " 422/422 [00:01<00:00, 292.61it/s]" } }, "f8c7cd8112274e26996a56ecae42ec3f": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f999eff152854b6da98defded43c8818": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_92ae4ede68904e2f8b0b2322f099d32b", "placeholder": "โ€‹", "style": "IPY_MODEL_85e62f6e0211431a9f6513285ef1aa0b", "value": " 422/422 [00:01<00:00, 309.42it/s]" } }, "fa591816c3414db3a7dc1478649ac230": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_829ad0cbf2bb49d9bde04dcff1f9cb3c", "placeholder": "โ€‹", "style": "IPY_MODEL_d673cd4b0e384aee988f565ab73cb022", "value": " 422/422 [00:01<00:00, 311.00it/s]" } }, "fa68877e48ab41a48a3c10dc3fe329d1": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_3e448a3c76bc4fdfa57f82327411f2e2", "placeholder": "โ€‹", "style": "IPY_MODEL_96e832df4dec40d9a97bd129ef55effa", "value": " 422/422 [00:01<00:00, 317.23it/s]" } }, "faa57a96c1e7416fa9a9a41b5bc6e308": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_732824b0216e44f7a88da251febff435", "IPY_MODEL_c5b2f89f03264317aa734883c164cabb" ], "layout": "IPY_MODEL_b4979a909ae64f48888d2383285f4f68" } }, "fac6ce9bd41f43f9821f45741359f5f4": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "fad451dd3ae040a8aede364098400642": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "fc6d6eef364446c3b54b68c5c4c1cb1b": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_1de0cf05f59b49eb8f8d233b9a4e490e", "IPY_MODEL_9bf763a02b58454ab1e4f9598939fd79" ], "layout": "IPY_MODEL_662835d152984f4eb87fa7cef0c0e28d" } }, "fce1dcea8fd749569b29e353a086ad45": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "fdd43b573d18496a9eec5f61632b33ed": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "fdd481739b6a4d64ac739965c621d3b8": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "fddd7fb9ef3f4535a97775548abbabd1": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_3f0d72d9c4984f89a82862fcdd24643b", "max": 422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_32ff8a0bfbcb44ebb0c80363f6115e07", "value": 422 } }, "fe0223b47b9346e7ad056b86841f91d9": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial" } }, "ff6267b3dd63479a8e260848a30709a8": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } } } } }, "nbformat": 4, "nbformat_minor": 1 } thinc-9.0.0/examples/01_intro_model_definition_methods.ipynb000066400000000000000000000314351461023342500242620ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Intro to Thinc's `Model` class, model definition and methods\n", "\n", "Thinc follows a functional-programming approach to model definition. Its approach is especially effective for **complicated network architectures**, and use cases where different data types need to be passed through the network to reach specific subcomponents. This notebook shows how to compose Thinc models and how to use the `Model` class and its methods." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Thinc provides a variety of [layers](https://thinc.ai/docs/api-layers), functions that create `Model` instances. Thinc tries to avoid inheritance, preferring function composition. The `Linear` function gives you a model that computes `Y = X @ W.T + b` (the function is defined in `thinc.layers.linear.forward`)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy\n", "from thinc.api import Linear, zero_init\n", "\n", "n_in = numpy.zeros((128, 16), dtype=\"f\")\n", "n_out = numpy.zeros((128, 10), dtype=\"f\")\n", "\n", "model = Linear(nI=n_in.shape[1], nO=n_out.shape[1], init_W=zero_init)\n", "nI = model.get_dim(\"nI\")\n", "nO = model.get_dim(\"nO\")\n", "print(f\"Initialized model with input dimension nI={nI} and output dimension nO={nO}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Models support **dimension inference from data**. You can defer some or all of the dimensions." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = Linear(init_W=zero_init)\n", "print(f\"Initialized model with no input/output dimensions.\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X = numpy.zeros((128, 16), dtype=\"f\")\n", "Y = numpy.zeros((128, 10), dtype=\"f\")\n", "model.initialize(X=X, Y=Y)\n", "nI = model.get_dim(\"nI\")\n", "nO = model.get_dim(\"nO\")\n", "print(f\"Initialized model with input dimension nI={nI} and output dimension nO={nO}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `chain` function wires two model instances together, with a feed-forward relationship. Dimension inference is especially helpful here." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import chain, glorot_uniform_init\n", "\n", "n_hidden = 128\n", "X = numpy.zeros((128, 16), dtype=\"f\")\n", "Y = numpy.zeros((128, 10), dtype=\"f\")\n", "\n", "model = chain(Linear(n_hidden, init_W=glorot_uniform_init), Linear(init_W=zero_init),)\n", "model.initialize(X=X, Y=Y)\n", "nI = model.get_dim(\"nI\")\n", "nO = model.get_dim(\"nO\")\n", "nO_hidden = model.layers[0].get_dim(\"nO\")\n", "print(f\"Initialized model with input dimension nI={nI} and output dimension nO={nO}.\")\n", "print(f\"The size of the hidden layer is {nO_hidden}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We call functions like `chain` [**combinators**](https://thinc.ai/docs/api-layers#combinators). Combinators take one or more models as arguments, and return another model instance, without introducing any new weight parameters. Another useful combinator is `concatenate`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import concatenate\n", "\n", "model = concatenate(Linear(n_hidden), Linear(n_hidden))\n", "model.initialize(X=X)\n", "nO = model.get_dim(\"nO\")\n", "print(f\"Initialized model with output dimension nO={nO}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `concatenate` function produces a layer that **runs the child layers separately**, and then **concatenates their outputs together**. This is often useful for combining features from different sources. For instance, we use this all the time to build [spaCy](https://spacy.io)'s embedding layers.\n", "\n", "Some combinators work on a layer and a numeric argument. For instance, the `clone` combinator creates a number of copies of a layer, and chains them together into a deep feed-forward network. The shape inference is especially handy here: we want the first and last layers to have different shapes, so we can avoid providing any dimensions into the layer we clone. We then just have to specify the first layer's output size, and we can let the rest of the dimensions be inferred from the data." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import clone\n", "\n", "model = clone(Linear(), 5)\n", "model.layers[0].set_dim(\"nO\", n_hidden)\n", "model.initialize(X=X, Y=Y)\n", "nI = model.get_dim(\"nI\")\n", "nO = model.get_dim(\"nO\")\n", "print(f\"Initialized model with input dimension nI={nI} and output dimension nO={nO}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can apply `clone` to model instances that have child layers, making it easy to define more complex architectures. For instance, we often want to attach an activation function and dropout to a linear layer, and then repeat that substructure a number of times. Of course, you can make whatever intermediate functions you find helpful." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Relu, Dropout\n", "\n", "def Hidden(dropout=0.2):\n", " return chain(Linear(), Relu(), Dropout(dropout))\n", "\n", "model = clone(Hidden(0.2), 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some combinators are unary functions: they take only one model. These are usually **input and output transformations**. For instance, the `with_array` combinator produces a model that flattens lists of arrays into a single array, and then calls the child layer to get the flattened output. It then reverses the transformation on the output." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import with_array\n", "\n", "model = with_array(Linear(4, 2))\n", "Xs = [model.ops.alloc2f(10, 2, dtype=\"f\")]\n", "model.initialize(X=Xs)\n", "Ys = model.predict(Xs)\n", "print(f\"Prediction shape: {Ys[0].shape}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The combinator system makes it easy to wire together complex models very concisely. A concise notation is a huge advantage, because it lets you read and review your model with less clutter โ€“ making it easy to spot mistakes, and easy to make changes. For the ultimate in concise notation, you can also take advantage of Thinc's **operator overloading**, which lets you use an infix notation. Operator overloading can lead to unexpected results, so you have to enable the overloading explicitly **in a contextmanager**. This also lets you control how the operators are bound, making it easy to use the feature with your own combinators. For instance, here is a definition for a text classification network:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import add, chain, concatenate, clone\n", "from thinc.api import with_array, reduce_max, reduce_mean, residual\n", "from thinc.api import Model, Embed, Maxout, Softmax\n", "\n", "nH = 5\n", "\n", "with Model.define_operators({\">>\": chain, \"|\": concatenate, \"+\": add, \"**\": clone}):\n", " model = (\n", " with_array(\n", " (Embed(128, column=0) + Embed(64, column=1))\n", " >> Maxout(nH, normalize=True, dropout=0.2)\n", " )\n", " >> (reduce_max() | reduce_mean())\n", " >> residual(Relu() >> Dropout(0.2)) ** 2\n", " >> Softmax()\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The network above will expect a list of arrays as input, where each array should have two columns with different numeric identifier features. The two features will be embedded using separate embedding tables, and the two vectors added and passed through a `Maxout` layer with layer normalization and dropout. The sequences then pass through two pooling functions, and the concatenated results are passed through 2 `Relu` layers with dropout and residual connections. Finally, the sequence vectors are passed through an output layer, which has a `Softmax` activation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Using a model\n", "\n", "Define the model:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Linear, Adam\n", "import numpy\n", "\n", "X = numpy.zeros((128, 10), dtype=\"f\")\n", "dY = numpy.zeros((128, 10), dtype=\"f\")\n", "\n", "model = Linear(10, 10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Initialize the model with a sample of the data:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model.initialize(X=X, Y=dY)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the model over some data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Y = model.predict(X)\n", "Y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get a callback to backpropagate:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Y, backprop = model.begin_update(X)\n", "Y, backprop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the callback to calculate the gradient with respect to the inputs. If the model has trainable parameters, gradients for the parameters are accumulated internally, as a side-effect." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dX = backprop(dY)\n", "dX" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `backprop()` callback only increments the parameter gradients, it doesn't actually change the weights. To increment the weights, call `model.finish_update()`, passing it an optimizer:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "optimizer = Adam()\n", "model.finish_update(optimizer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can get and set dimensions, parameters and attributes by name:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dim = model.get_dim(\"nO\")\n", "W = model.get_param(\"W\")\n", "model.attrs[\"hello\"] = \"world\"\n", "model.attrs.get(\"foo\", \"bar\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also retrieve parameter gradients, and increment them explicitly:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dW = model.get_grad(\"W\")\n", "model.inc_grad(\"W\", dW * 0.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, you can serialize models using the `model.to_bytes` and `model.to_disk` methods, and load them back with `from_bytes` and `from_disk`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model_bytes = model.to_bytes()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 } thinc-9.0.0/examples/02_transformers_tagger_bert.ipynb000066400000000000000000000521121461023342500231020ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Training a part-of-speech tagger with transformers (BERT)\n", "\n", "This example shows how to use Thinc and Hugging Face's [`transformers`](https://github.com/huggingface/transformers) library to implement and train a part-of-speech tagger on the Universal Dependencies [AnCora corpus](https://github.com/UniversalDependencies/UD_Spanish-AnCora). This notebook assumes familiarity with machine learning concepts, transformer models and Thinc's config system and `Model` API (see the \"Thinc for beginners\" notebook and the [documentation](https://thinc.ai/docs) for more info)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\" transformers torch \"ml_datasets>=0.2.0\" \"tqdm>=4.41\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, let's use Thinc's `prefer_gpu` helper to make sure we're performing operations **on GPU if available**. The function should be called right after importing Thinc, and it returns a boolean indicating whether the GPU has been activated. If we're on GPU, we can also call `use_pytorch_for_gpu_memory` to route `cupy`'s memory allocation via PyTorch, so both can play together nicely." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import prefer_gpu, use_pytorch_for_gpu_memory\n", "\n", "is_gpu = prefer_gpu()\n", "print(\"GPU:\", is_gpu)\n", "if is_gpu:\n", " use_pytorch_for_gpu_memory()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overview: the final config\n", "\n", "Here's the final config for the model we're building in this notebook. It references a custom `TransformersTagger` that takes the name of a starter (the pretrained model to use), an optimizer, a learning rate schedule with warm-up and the general training settings. You can keep the config string within your file or notebook, or save it to a `conig.cfg` file and load it in via `Config.from_disk`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "CONFIG = \"\"\"\n", "[model]\n", "@layers = \"TransformersTagger.v1\"\n", "starter = \"bert-base-multilingual-cased\"\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "\n", "[optimizer.learn_rate]\n", "@schedules = \"warmup_linear.v1\"\n", "initial_rate = 0.01\n", "warmup_steps = 3000\n", "total_steps = 6000\n", "\n", "[loss]\n", "@losses = \"SequenceCategoricalCrossentropy.v1\"\n", "\n", "[training]\n", "batch_size = 128\n", "words_per_subbatch = 2000\n", "n_epoch = 10\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Defining the model\n", "\n", "The Thinc model we want to define should consist of 3 components: the transformers **tokenizer**, the actual **transformer** implemented in PyTorch and a **softmax-activated output layer**.\n", "\n", "\n", "### 1. Wrapping the tokenizer\n", "\n", "To make it easier to keep track of the data that's passed around (and get type errors if something goes wrong), we first create a `TokensPlus` dataclass that holds the information we need from the `transformers` tokenizer. The most important work we'll do in this class is to build an _alignment map_. The transformer models are trained on input sequences that over-segment the sentence, so that they can work on smaller vocabularies. These over-segmentations are generally called \"word pieces\". The transformer will return a tensor with one vector per wordpiece. We need to map that to a tensor with one vector per POS-tagged token. We'll pass those token representations into a feed-forward network to predict the tag probabilities. During the backward pass, we'll then need to invert this mapping, so that we can calculate the gradients with respect to the wordpieces given the gradients with respect to the tokens. To keep things relatively simple, we'll store the alignment as a list of arrays, with each array mapping one token to one wordpiece vector (its first one). To make this work, we'll need to run the tokenizer with `is_split_into_words=True`, which should ensure that we get at least one wordpiece per token." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import Optional, List\n", "import numpy\n", "from thinc.types import Ints1d, Floats2d\n", "from dataclasses import dataclass\n", "import torch\n", "from transformers import BatchEncoding, TokenSpan\n", "\n", "\n", "@dataclass\n", "class TokensPlus:\n", " batch_size: int\n", " tok2wp: List[Ints1d]\n", " input_ids: torch.Tensor\n", " token_type_ids: torch.Tensor\n", " attention_mask: torch.Tensor\n", " \n", " def __init__(self, inputs: List[List[str]], wordpieces: BatchEncoding):\n", " self.input_ids = wordpieces[\"input_ids\"]\n", " self.attention_mask = wordpieces[\"attention_mask\"]\n", " self.token_type_ids = wordpieces[\"token_type_ids\"]\n", " self.batch_size = self.input_ids.shape[0]\n", " self.tok2wp = []\n", " for i in range(self.batch_size):\n", " spans = [wordpieces.word_to_tokens(i, j) for j in range(len(inputs[i]))]\n", " self.tok2wp.append(self.get_wp_starts(spans))\n", " \n", " def get_wp_starts(self, spans: List[Optional[TokenSpan]]) -> Ints1d:\n", " \"\"\"Calculate an alignment mapping each token index to its first wordpiece.\"\"\"\n", " alignment = numpy.zeros((len(spans)), dtype=\"i\")\n", " for i, span in enumerate(spans):\n", " if span is None:\n", " raise ValueError(\n", " \"Token did not align to any wordpieces. Was the tokenizer \"\n", " \"run with is_split_into_words=True?\"\n", " )\n", " else:\n", " alignment[i] = span.start\n", " return alignment\n", " \n", "\n", "def test_tokens_plus(name: str=\"bert-base-multilingual-cased\"):\n", " from transformers import AutoTokenizer\n", " inputs = [\n", " [\"Our\", \"band\", \"is\", \"called\", \"worlthatmustbedivided\", \"!\"],\n", " [\"We\", \"rock\", \"!\"]\n", " ]\n", " tokenizer = AutoTokenizer.from_pretrained(name)\n", " wordpieces = tokenizer(\n", " inputs,\n", " is_split_into_words=True,\n", " add_special_tokens=True,\n", " return_token_type_ids=True,\n", " return_attention_mask=True,\n", " return_length=True,\n", " return_tensors=\"pt\",\n", " padding=\"longest\"\n", " )\n", " tplus = TokensPlus(inputs, wordpieces)\n", " assert len(tplus.tok2wp) == len(inputs) == len(tplus.input_ids)\n", " for i, align in enumerate(tplus.tok2wp):\n", " assert len(align) == len(inputs[i])\n", " for j in align:\n", " assert j >= 0 and j < tplus.input_ids.shape[1]\n", " \n", "test_tokens_plus()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The wrapped tokenizer will take a list-of-lists as input (the texts) and will output a `TokensPlus` object containing the fully padded batch of tokens. The wrapped transformer will take a list of `TokensPlus` objects and will output a list of 2-dimensional arrays.\n", "\n", "1. **TransformersTokenizer**: `List[List[str]]` โ†’ `TokensPlus`\n", "2. **Transformer**: `TokensPlus` โ†’ `List[Array2d]`\n", "\n", "> ๐Ÿ’ก Since we're adding type hints everywhere (and Thinc is fully typed, too), you can run your code through [`mypy`](https://mypy.readthedocs.io/en/stable/) to find type errors and inconsistencies. If you're using an editor like Visual Studio Code, you can enable `mypy` linting and type errors will be highlighted in real time as you write code.\n", "\n", "To use the tokenizer as a layer in our network, we register a new function that returns a Thinc `Model`. The function takes the name of the pretrained weights (e.g. `\"bert-base-multilingual-cased\"`) as an argument that can later be provided via the config. After loading the `AutoTokenizer`, we can stash it in the attributes. This lets us access it at any point later on via `model.attrs[\"tokenizer\"]`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import thinc\n", "from thinc.api import Model\n", "from transformers import AutoTokenizer\n", "\n", "@thinc.registry.layers(\"transformers_tokenizer.v1\")\n", "def TransformersTokenizer(name: str) -> Model[List[List[str]], TokensPlus]:\n", " def forward(model, inputs: List[List[str]], is_train: bool):\n", " tokenizer = model.attrs[\"tokenizer\"]\n", " wordpieces = tokenizer(\n", " inputs,\n", " is_split_into_words=True,\n", " add_special_tokens=True,\n", " return_token_type_ids=True,\n", " return_attention_mask=True,\n", " return_length=True,\n", " return_tensors=\"pt\",\n", " padding=\"longest\"\n", " )\n", " return TokensPlus(inputs, wordpieces), lambda d_tokens: []\n", "\n", " return Model(\"tokenizer\", forward, attrs={\"tokenizer\": AutoTokenizer.from_pretrained(name)})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The forward pass takes the model and a list-of-lists of strings and outputs the `TokensPlus` dataclass. It also outputs a dummy callback function, to meet the API contract for Thinc models. Even though there's no way we can meaningfully \"backpropagate\" this layer, we need to make sure the function has the right signature, so that it can be used interchangeably with other layers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Wrapping the transformer\n", "\n", "To load and wrap the transformer, we can use `transformers.AutoModel` and Thinc's `PyTorchWrapper`. The forward method of the wrapped model can take arbitrary positional arguments and keyword arguments. Here's what the wrapped model is going to look like:\n", "\n", "```python\n", "@thinc.registry.layers(\"transformers_model.v1\")\n", "def Transformer(name) -> Model[TokensPlus, List[Floats2d]]:\n", " return PyTorchWrapper(\n", " AutoModel.from_pretrained(name),\n", " convert_inputs=convert_transformer_inputs,\n", " convert_outputs=convert_transformer_outputs,\n", " )\n", "```\n", "\n", "The `Transformer` layer takes our `TokensPlus` dataclass as input and outputs a list of 2-dimensional arrays. The convert functions are used to **map inputs and outputs to and from the PyTorch model**. Each function should return the converted output, and a callback to use during the backward pass. To make the arbitrary positional and keyword arguments easier to manage, Thinc uses an `ArgsKwargs` dataclass, essentially a named tuple with `args` and `kwargs` that can be spread into a function as `*ArgsKwargs.args` and `**ArgsKwargs.kwargs`. The `ArgsKwargs` objects will be passed straight into the model in the forward pass, and straight into `torch.autograd.backward` during the backward pass." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List, Tuple, Callable\n", "from thinc.api import ArgsKwargs, torch2xp, xp2torch\n", "from thinc.types import Floats2d\n", "\n", "def convert_transformer_inputs(model, tokens: TokensPlus, is_train):\n", " kwargs = {\n", " \"input_ids\": tokens.input_ids,\n", " \"attention_mask\": tokens.attention_mask,\n", " \"token_type_ids\": tokens.token_type_ids,\n", " }\n", " return ArgsKwargs(args=(), kwargs=kwargs), lambda dX: []\n", "\n", "\n", "def convert_transformer_outputs(\n", " model: Model,\n", " inputs_outputs: Tuple[TokensPlus, Tuple[torch.Tensor]],\n", " is_train: bool\n", ") -> Tuple[List[Floats2d], Callable]:\n", " tplus, trf_outputs = inputs_outputs\n", " wp_vectors = torch2xp(trf_outputs[0])\n", " tokvecs = [wp_vectors[i, idx] for i, idx in enumerate(tplus.tok2wp)]\n", "\n", " def backprop(d_tokvecs: List[Floats2d]) -> ArgsKwargs:\n", " # Restore entries for BOS and EOS markers\n", " d_wp_vectors = model.ops.alloc3f(*trf_outputs[0].shape, dtype=\"f\")\n", " for i, idx in enumerate(tplus.tok2wp):\n", " d_wp_vectors[i, idx] += d_tokvecs[i]\n", " return ArgsKwargs(\n", " args=(trf_outputs[0],),\n", " kwargs={\"grad_tensors\": xp2torch(d_wp_vectors)},\n", " )\n", "\n", " return tokvecs, backprop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The input and output transformation functions give you full control of how data is passed into and out of the underlying PyTorch model, so you can work with PyTorch layers that expect and return arbitrary objects. Putting it all together, we now have a nice layer that is configured with the name of a transformer model, that acts as a function mapping tokenized input into feature vectors." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import thinc\n", "from thinc.api import PyTorchWrapper\n", "from transformers import AutoModel\n", "\n", "@thinc.registry.layers(\"transformers_model.v1\")\n", "def Transformer(name: str) -> Model[TokensPlus, List[Floats2d]]:\n", " return PyTorchWrapper(\n", " AutoModel.from_pretrained(name),\n", " convert_inputs=convert_transformer_inputs,\n", " convert_outputs=convert_transformer_outputs,\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now combine the `TransformersTokenizer` and `Transformer` into a feed-forward network using the `chain` combinator. The `with_array` layer transforms a sequence of data into a contiguous 2d array on the way into and\n", "out of a model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import chain, with_array, Softmax\n", "\n", "@thinc.registry.layers(\"TransformersTagger.v1\")\n", "def TransformersTagger(starter: str, n_tags: int = 17) -> Model[List[List[str]], List[Floats2d]]:\n", " return chain(\n", " TransformersTokenizer(starter),\n", " Transformer(starter),\n", " with_array(Softmax(n_tags)),\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Training the model\n", "\n", "### Setting up model and data\n", "\n", "Since we've registered all layers via `@thinc.registry.layers`, we can construct the model, its settings and other functions we need from a config (see `CONFIG` above). The result is a config object with a model, an optimizer, a function to calculate the loss and the training settings." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Config, registry\n", "\n", "C = registry.resolve(Config().from_str(CONFIG))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = C[\"model\"]\n", "optimizer = C[\"optimizer\"]\n", "calculate_loss = C[\"loss\"]\n", "cfg = C[\"training\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Weโ€™ve prepared a separate package [`ml-datasets`](https://github.com/explosion/ml-datasets) with loaders for some common datasets, including the AnCora data. If we're using a GPU, calling `ops.asarray` on the outputs ensures that they're converted to `cupy` arrays (instead of `numpy` arrays). Calling `Model.initialize` with a batch of inputs and outputs allows Thinc to **infer the missing dimensions**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ml_datasets\n", "(train_X, train_Y), (dev_X, dev_Y) = ml_datasets.ud_ancora_pos_tags()\n", "\n", "train_Y = list(map(model.ops.asarray, train_Y)) # convert to cupy if needed\n", "dev_Y = list(map(model.ops.asarray, dev_Y)) # convert to cupy if needed\n", "\n", "model.initialize(X=train_X[:5], Y=train_Y[:5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Helper functions for training and evaluation\n", "\n", "Before we can train the model, we also need to set up the following helper functions for batching and evaluation:\n", "\n", "* **`minibatch_by_words`:** Group pairs of sequences into minibatches under `max_words` in size, considering padding. The size of a padded batch is the length of its longest sequence multiplied by the number of elements in the batch.\n", "* **`evaluate_sequences`:** Evaluate the model sequences of two-dimensional arrays and return the score." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def minibatch_by_words(pairs, max_words):\n", " pairs = list(zip(*pairs))\n", " pairs.sort(key=lambda xy: len(xy[0]), reverse=True)\n", " batch = []\n", " for X, Y in pairs:\n", " batch.append((X, Y))\n", " n_words = max(len(xy[0]) for xy in batch) * len(batch)\n", " if n_words >= max_words:\n", " yield batch[:-1]\n", " batch = [(X, Y)]\n", " if batch:\n", " yield batch\n", "\n", "def evaluate_sequences(model, Xs: List[Floats2d], Ys: List[Floats2d], batch_size: int) -> float:\n", " correct = 0.0\n", " total = 0.0\n", " for X, Y in model.ops.multibatch(batch_size, Xs, Ys):\n", " Yh = model.predict(X)\n", " for yh, y in zip(Yh, Y):\n", " correct += (y.argmax(axis=1) == yh.argmax(axis=1)).sum()\n", " total += y.shape[0]\n", " return float(correct / total)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The training loop\n", "\n", "Transformers often learn best with **large batch sizes** โ€“ larger than fits in GPU memory. But you don't have to backprop the whole batch at once. Here we consider the \"logical\" batch size (number of examples per update) separately from the physical batch size. For the physical batch size, what we care about is the **number of words** (considering padding too). We also want to sort by length, for efficiency. \n", "\n", "At the end of the batch, we **call the optimizer** with the accumulated gradients, and **advance the learning rate schedules**. You might want to evaluate more often than once per epoch โ€“ that's up to you." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from tqdm.notebook import tqdm\n", "from thinc.api import fix_random_seed\n", "\n", "fix_random_seed(0)\n", "\n", "for epoch in range(cfg[\"n_epoch\"]):\n", " batches = model.ops.multibatch(cfg[\"batch_size\"], train_X, train_Y, shuffle=True)\n", " for outer_batch in tqdm(batches, leave=False):\n", " for batch in minibatch_by_words(outer_batch, cfg[\"words_per_subbatch\"]):\n", " inputs, truths = zip(*batch)\n", " inputs = list(inputs)\n", " guesses, backprop = model(inputs, is_train=True)\n", " backprop(calculate_loss.get_grad(guesses, truths))\n", " model.finish_update(optimizer)\n", " optimizer.step_schedules()\n", " score = evaluate_sequences(model, dev_X, dev_Y, cfg[\"batch_size\"])\n", " print(epoch, f\"{score:.3f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you like, you can call `model.to_disk` or `model.to_bytes` to save the model weights to a directory or a bytestring." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 } thinc-9.0.0/examples/03_pos_tagger_basic_cnn.ipynb000066400000000000000000000324121461023342500221430ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Basic CNN part-of-speech tagger with Thinc\n", "\n", "This notebook shows how to implement a basic CNN for part-of-speech tagging model in Thinc (without external dependencies) and train the model on the Universal Dependencies [AnCora corpus](https://github.com/UniversalDependencies/UD_Spanish-AnCora). The tutorial shows three different workflows:\n", "\n", "1. Composing the model **in code** (basic usage)\n", "2. Composing the model **via a config file only** (mostly to demonstrate advanced usage of configs)\n", "3. Composing the model **in code and configuring it via config** (recommended)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\" \"ml_datasets>=0.2.0\" \"tqdm>=4.41\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We start by making sure the computation is performed on GPU if available. `prefer_gpu` should be called right after importing Thinc, and it returns a boolean indicating whether the GPU has been activated." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import prefer_gpu\n", "\n", "prefer_gpu()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also define the following helper functions for loading the data, and training and evaluating a given model. Don't forget to call `model.initialize` with a batch of input and output data to initialize the model and fill in any missing shapes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ml_datasets\n", "from tqdm.notebook import tqdm\n", "from thinc.api import fix_random_seed\n", "\n", "fix_random_seed(0)\n", "\n", "def train_model(model, optimizer, n_iter, batch_size):\n", " (train_X, train_y), (dev_X, dev_y) = ml_datasets.ud_ancora_pos_tags()\n", " model.initialize(X=train_X[:5], Y=train_y[:5])\n", " for n in range(n_iter):\n", " loss = 0.0\n", " batches = model.ops.multibatch(batch_size, train_X, train_y, shuffle=True)\n", " for X, Y in tqdm(batches, leave=False):\n", " Yh, backprop = model.begin_update(X)\n", " d_loss = []\n", " for i in range(len(Yh)):\n", " d_loss.append(Yh[i] - Y[i])\n", " loss += ((Yh[i] - Y[i]) ** 2).sum()\n", " backprop(d_loss)\n", " model.finish_update(optimizer)\n", " score = evaluate(model, dev_X, dev_y, batch_size)\n", " print(f\"{n}\\t{loss:.2f}\\t{score:.3f}\")\n", " \n", "def evaluate(model, dev_X, dev_Y, batch_size):\n", " correct = 0\n", " total = 0\n", " for X, Y in model.ops.multibatch(batch_size, dev_X, dev_Y):\n", " Yh = model.predict(X)\n", " for yh, y in zip(Yh, Y):\n", " correct += (y.argmax(axis=1) == yh.argmax(axis=1)).sum()\n", " total += y.shape[0]\n", " return float(correct / total)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## 1. Composing the model in code\n", "\n", "Here's the model definition, using the `>>` operator for the `chain` combinator. The `strings2arrays` transform converts a sequence of strings to a list of arrays. `with_array` transforms sequences (the sequences of arrays) into a contiguous 2-dimensional array on the way into and out of the model it wraps. This means our model has the following signature: `Model[Sequence[str], Sequence[Array2d]]`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Model, chain, strings2arrays, with_array, HashEmbed, expand_window, Relu, Softmax, Adam, warmup_linear\n", "\n", "width = 32\n", "vector_width = 16\n", "nr_classes = 17\n", "learn_rate = 0.001\n", "n_iter = 10\n", "batch_size = 128\n", "\n", "with Model.define_operators({\">>\": chain}):\n", " model = strings2arrays() >> with_array(\n", " HashEmbed(nO=width, nV=vector_width, column=0)\n", " >> expand_window(window_size=1)\n", " >> Relu(nO=width, nI=width * 3)\n", " >> Relu(nO=width, nI=width)\n", " >> Softmax(nO=nr_classes, nI=width)\n", " )\n", "optimizer = Adam(learn_rate)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "train_model(model, optimizer, n_iter, batch_size)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Composing the model via a config file\n", "\n", "Thinc's config system lets describe **arbitrary trees of objects**. The config can include values like hyperparameters or training settings, or references to functions and the values of their arguments. Thinc will then construct the config **bottom-up** โ€“ so you can define one function with its arguments, and then pass the return value into another function.\n", "\n", "If we want to rebuild the model defined above in a config file, we first need to break down its structure:\n", "\n", "* `chain` (any number of positional arguments)\n", " * `strings2arrays` (no arguments)\n", " * `with_array` (one argument **layer**)\n", " * **layer:** `chain` (any number of positional arguments)\n", " * `HashEmbed`\n", " * `expand_window`\n", " * `Relu`\n", " * `Relu`\n", " * `Softmax`\n", "\n", "`chain` takes a variable number of positional arguments (the layers to compose). In the config, positional arguments can be expressed using `*` in the dot notation. For example, `model.layer` could describe a function passed to `model` as the argument `layer`, while `model.*.relu` defines a positional argument passed to `model`. The name of the argument, e.g. `relu` โ€“ doesn't matter in this case. It just needs to be unique.\n", "\n", "> โš ๏ธ **Important note:** This example is mostly intended to show what's possible. We don't recommend \"programming via config files\" as shown here, since it doesn't really solve any problem and makes the model definition just as complicated. Instead, we recommend a hybrid approach: wrap the model definition in a registered function and configure it via the config." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "CONFIG = \"\"\"\n", "[hyper_params]\n", "width = 32\n", "vector_width = 16\n", "learn_rate = 0.001\n", "\n", "[training]\n", "n_iter = 10\n", "batch_size = 128\n", "\n", "[model]\n", "@layers = \"chain.v1\"\n", "\n", "[model.*.strings2arrays]\n", "@layers = \"strings2arrays.v1\"\n", "\n", "[model.*.with_array]\n", "@layers = \"with_array.v1\"\n", "\n", "[model.*.with_array.layer]\n", "@layers = \"chain.v1\"\n", "\n", "[model.*.with_array.layer.*.hashembed]\n", "@layers = \"HashEmbed.v1\"\n", "nO = ${hyper_params:width}\n", "nV = ${hyper_params:vector_width}\n", "column = 0\n", "\n", "[model.*.with_array.layer.*.expand_window]\n", "@layers = \"expand_window.v1\"\n", "window_size = 1\n", "\n", "[model.*.with_array.layer.*.relu1]\n", "@layers = \"Relu.v1\"\n", "nO = ${hyper_params:width}\n", "nI = 96\n", "\n", "[model.*.with_array.layer.*.relu2]\n", "@layers = \"Relu.v1\"\n", "nO = ${hyper_params:width}\n", "nI = ${hyper_params:width}\n", "\n", "[model.*.with_array.layer.*.softmax]\n", "@layers = \"Softmax.v1\"\n", "nO = 17\n", "nI = ${hyper_params:width}\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = ${hyper_params:learn_rate}\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When the config is loaded, it's first parsed as a dictionary and all references to values from other sections, e.g. `${hyper_params:width}` are replaced. The result is a nested dictionary describing the objects defined in the config." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import registry, Config\n", "\n", "config = Config().from_str(CONFIG)\n", "config" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`registry.resolve` then creates the objects and calls the functions **bottom-up**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "C = registry.resolve(config)\n", "C" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now have a model, optimizer and training settings, built from the config, and can use them to train the model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = C[\"model\"]\n", "optimizer = C[\"optimizer\"]\n", "n_iter = C[\"training\"][\"n_iter\"]\n", "batch_size = C[\"training\"][\"batch_size\"]\n", "train_model(model, optimizer, n_iter, batch_size)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Composing the model with code and config\n", "\n", "The `@thinc.registry` decorator lets you register your own layers and model definitions, which can then be referenced in config files. This approach gives you the most flexibility, while also keeping your config and model definitions concise.\n", "\n", "> ๐Ÿ’ก The function you register will be filled in by the config โ€“ e.g. the value of `width` defined in the config block will be passed in as the argument `width`. If arguments are missing, you'll see a validation error. If you're using **type hints** in the function, the values will be parsed to ensure they always have the right type. If they're invalid โ€“ e.g. if you're passing in a list as the value of `width` โ€“ you'll see an error. This makes it easier to prevent bugs caused by incorrect values lower down in the network." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import thinc\n", "from thinc.api import Model, chain, strings2arrays, with_array, HashEmbed, expand_window, Relu, Softmax, Adam, warmup_linear\n", "\n", "@thinc.registry.layers(\"cnn_tagger.v1\")\n", "def create_cnn_tagger(width: int, vector_width: int, nr_classes: int = 17):\n", " with Model.define_operators({\">>\": chain}):\n", " model = strings2arrays() >> with_array(\n", " HashEmbed(nO=width, nV=vector_width, column=0)\n", " >> expand_window(window_size=1)\n", " >> Relu(nO=width, nI=width * 3)\n", " >> Relu(nO=width, nI=width)\n", " >> Softmax(nO=nr_classes, nI=width)\n", " )\n", " return model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The config would then only need to define one model block with `@layers = \"cnn_tagger.v1\"` and the function arguments. Whether you move them out to a section like `[hyper_params]` or just hard-code them into the block is up to you. The advantage of a separate section is that the values are **preserved in the parsed config object** (and not just passed into the function), so you can always print and view them." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "CONFIG = \"\"\"\n", "[hyper_params]\n", "width = 32\n", "vector_width = 16\n", "learn_rate = 0.001\n", "\n", "[training]\n", "n_iter = 10\n", "batch_size = 128\n", "\n", "[model]\n", "@layers = \"cnn_tagger.v1\"\n", "width = ${hyper_params:width}\n", "vector_width = ${hyper_params:vector_width}\n", "nr_classes = 17\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = ${hyper_params:learn_rate}\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "C = registry.resolve(Config().from_str(CONFIG))\n", "C" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = C[\"model\"]\n", "optimizer = C[\"optimizer\"]\n", "n_iter = C[\"training\"][\"n_iter\"]\n", "batch_size = C[\"training\"][\"batch_size\"]\n", "train_model(model, optimizer, n_iter, batch_size)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 4 } thinc-9.0.0/examples/03_textcat_basic_neural_bow.ipynb000066400000000000000000000210421461023342500230410ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Basic neural bag-of-words text classifier with Thinc\n", "\n", "This notebook shows how to implement a simple neural text classification model in Thinc. Last tested with `thinc==8.0.13`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install thinc syntok \"ml_datasets>=0.2.0\" tqdm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For simple and standalone tokenization, we'll use the [`syntok`](https://github.com/fnl/syntok) package and the following function:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from syntok.tokenizer import Tokenizer\n", "\n", "def tokenize_texts(texts):\n", " tok = Tokenizer()\n", " return [[token.value for token in tok.tokenize(text)] for text in texts]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting up the data\n", "\n", "The `load_data` function loads the DBPedia Ontology dataset, converts and tokenizes the data and generates a simple vocabulary mapping. Instead of `ml_datasets.dbpedia` you can also try `ml_datasets.imdb` for the IMDB review dataset." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ml_datasets\n", "import numpy\n", "\n", "def load_data():\n", " train_data, dev_data = ml_datasets.dbpedia(train_limit=2000, dev_limit=2000)\n", " train_texts, train_cats = zip(*train_data)\n", " dev_texts, dev_cats = zip(*dev_data)\n", " unique_cats = list(numpy.unique(numpy.concatenate((train_cats, dev_cats))))\n", " nr_class = len(unique_cats)\n", " print(f\"{len(train_data)} training / {len(dev_data)} dev\\n{nr_class} classes\")\n", "\n", " train_y = numpy.zeros((len(train_cats), nr_class), dtype=\"f\")\n", " for i, cat in enumerate(train_cats):\n", " train_y[i][unique_cats.index(cat)] = 1\n", " dev_y = numpy.zeros((len(dev_cats), nr_class), dtype=\"f\")\n", " for i, cat in enumerate(dev_cats):\n", " dev_y[i][unique_cats.index(cat)] = 1\n", "\n", " train_tokenized = tokenize_texts(train_texts)\n", " dev_tokenized = tokenize_texts(dev_texts)\n", " # Generate simple vocab mapping, is 0\n", " vocab = {}\n", " count_id = 1\n", " for text in train_tokenized:\n", " for token in text:\n", " if token not in vocab:\n", " vocab[token] = count_id\n", " count_id += 1\n", " # Map texts using vocab\n", " train_X = []\n", " for text in train_tokenized:\n", " train_X.append(numpy.array([vocab.get(t, 0) for t in text]))\n", " dev_X = []\n", " for text in dev_tokenized:\n", " dev_X.append(numpy.array([vocab.get(t, 0) for t in text]))\n", " return (train_X, train_y), (dev_X, dev_y), vocab" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Defining the model and config\n", "\n", "The model takes a list of 2-dimensional arrays (the tokenized texts mapped to vocab IDs) and outputs a 2d array. Because the embed layer's `nV` dimension (the number of entries in the lookup table) depends on the vocab and the training data, it's passed in as an argument and registered as a **reference**. This makes it easy to retrieve it later on by calling `model.get_ref(\"embed\")`, so we can set its `nV` dimension." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List\n", "import thinc\n", "from thinc.api import Model, chain, list2ragged, with_array, reduce_mean, Softmax\n", "from thinc.types import Array2d\n", "\n", "@thinc.registry.layers(\"EmbedPoolTextcat.v1\")\n", "def EmbedPoolTextcat(embed: Model[Array2d, Array2d]) -> Model[List[Array2d], Array2d]:\n", " with Model.define_operators({\">>\": chain}):\n", " model = with_array(embed) >> list2ragged() >> reduce_mean() >> Softmax()\n", " model.set_ref(\"embed\", embed)\n", " return model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The config defines the top-level model using the registered `EmbedPoolTextcat` function, and the `embed` argument, referencing the `Embed` layer." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "CONFIG = \"\"\"\n", "[hyper_params]\n", "width = 64\n", "\n", "[model]\n", "@layers = \"EmbedPoolTextcat.v1\"\n", "\n", "[model.embed]\n", "@layers = \"Embed.v1\"\n", "nO = ${hyper_params:width}\n", "\n", "[optimizer]\n", "@optimizers = \"Adam.v1\"\n", "learn_rate = 0.001\n", "\n", "[training]\n", "batch_size = 8\n", "n_iter = 10\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Training setup\n", "\n", "When the config is loaded, it's first parsed as a dictionary and all references to values from other sections, e.g. `${hyper_params:width}` are replaced. The result is a nested dictionary describing the objects defined in the config. `registry.resolve` then creates the objects and calls the functions **bottom-up**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import registry, Config\n", "\n", "C = registry.resolve(Config().from_str(CONFIG))\n", "C" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once the data is loaded, we'll know the vocabulary size and can set the dimension on the embedding layer. `model.get_ref(\"embed\")` returns the layer defined as the ref `\"embed\"` and the `set_dim` method lets you set a value for a dimension. To fill in the other missing shapes, we can call `model.initialize` with some input and output data. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(train_X, train_y), (dev_X, dev_y), vocab = load_data()\n", "\n", "batch_size = C[\"training\"][\"batch_size\"]\n", "optimizer = C[\"optimizer\"]\n", "model = C[\"model\"]\n", "model.get_ref(\"embed\").set_dim(\"nV\", len(vocab) + 1)\n", "\n", "model.initialize(X=train_X, Y=train_y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def evaluate_model(model, dev_X, dev_Y, batch_size):\n", " correct = 0.0\n", " total = 0.0\n", " for X, Y in model.ops.multibatch(batch_size, dev_X, dev_Y):\n", " Yh = model.predict(X)\n", " for j in range(len(Yh)):\n", " correct += Yh[j].argmax(axis=0) == Y[j].argmax(axis=0)\n", " total += len(Y)\n", " return float(correct / total)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Training the model" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import fix_random_seed\n", "from tqdm.notebook import tqdm\n", "\n", "fix_random_seed(0)\n", "for n in range(C[\"training\"][\"n_iter\"]):\n", " loss = 0.0\n", " batches = model.ops.multibatch(batch_size, train_X, train_y, shuffle=True)\n", " for X, Y in tqdm(batches, leave=False):\n", " Yh, backprop = model.begin_update(X)\n", " d_loss = []\n", " for i in range(len(Yh)):\n", " d_loss.append(Yh[i] - Y[i])\n", " loss += ((Yh[i] - Y[i]) ** 2).sum()\n", " backprop(numpy.array(d_loss))\n", " model.finish_update(optimizer)\n", " score = evaluate_model(model, dev_X, dev_y, batch_size)\n", " print(f\"{n}\\t{loss:.2f}\\t{score:.3f}\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 } thinc-9.0.0/examples/04_configure_gpu_memory.ipynb000066400000000000000000000104571461023342500222440ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using a single memory pool for Cupy and PyTorch or TensorFlow\n", "\n", "Requesting memory from a GPU device directly is expensive, so most deep learning libraries will over-allocate, and maintain an internal pool of memory they will keep a hold of, instead of returning it back to the device. This means the libraries don't by default play well together: they all expect to be the single consumer of the GPU memory, so they hog it selfishly. If you use two frameworks together, you can get unexpected out-of-memory errors.\n", "\n", "Thinc's internal models use cupy for GPU operations, and cupy offers a nice solution for this problem. You can provide cupy with a custom memory allocation function, which allows us to route cupy's memory requests via another library. This avoids the memory problem when you use PyTorch and cupy together, or when you use cupy and Tensorflow together. We don't yet have a similar solution for using PyTorch and Tensorflow together, however.\n", "\n", "To start with, we call the `require_gpu()` function, which tells Thinc and PyTorch to allocate on GPU." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\" torch \"tensorflow>=2.0\" " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import require_gpu\n", "\n", "require_gpu()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We then call `use_pytorch_for_gpu_memory()` to set up the allocation strategy. Now when `cupy` tries to request GPU memory, it will do so by asking PyTorch, rather than asking the GPU directly." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import use_pytorch_for_gpu_memory\n", "\n", "use_pytorch_for_gpu_memory()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To test that it's working, we make a little function that allocates an array using cupy, and prints its size, along with the current size of PyTorch's memory pool. Notice the over-allocation: PyTorch grabs a *much* bigger chunk of memory than just our little array. That's why we need to have only one memory pool." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import cupy \n", "import torch.cuda\n", "\n", "def allocate_cupy_tensor(size):\n", " array = cupy.zeros((size,), dtype=\"f\")\n", " print(array.size, torch.cuda.max_memory_allocated())\n", " return array\n", "allocate_cupy_tensor(16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also see that even when we free the tensor, the memory isn't immediately released. On the other hand, we don't need to resize the memory pool when we make a second small allocation." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import tensorflow\n", "\n", "with tensorflow.device('/device:GPU:0'):\n", " arr = allocate_cupy_tensor(1000)\n", " arr = None\n", " arr = allocate_cupy_tensor(1000)\n", " arr = None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we make a huge allocation, we'll have to resize the pool though. Let's make sure the pool resizes properly, and that memory is freed when the tensors are removed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arr = allocate_cupy_tensor(1000)\n", "for _ in range(100):\n", " arr2 = allocate_cupy_tensor(900000)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 4 } thinc-9.0.0/examples/05_benchmarking_layers.ipynb000066400000000000000000000173741461023342500220350ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Benchmarking Thinc layers with a custom `benchmark` layer\n", "\n", "This notebook shows how to write a `benchmark` layer that can wrap any layer(s) in your network and that **logs the execution times** of the initialization, forward pass and backward pass. The benchmark layer can also be mapped to an operator like `@` to make it easy to add debugging to your network." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To log the results, we first set up a custom logger using Python's `logging` module. You could also just print the stats instead, but using `logging` is cleaner, since it lets other users modify the logger's behavior more easily, and separates the logs from other output and write it to a file (e.g. if you're benchmarking several layers during training). The following logging config will output the date and time, the name of the logger and the logged results." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import logging\n", "\n", "logger = logging.getLogger(\"thinc:benchmark\")\n", "if not logger.hasHandlers(): # prevent Jupyter from adding multiple loggers\n", " formatter = logging.Formatter('%(asctime)s %(name)s %(message)s', datefmt=\"%Y-%m-%d %H:%M:%S\")\n", " handler = logging.StreamHandler()\n", " handler.setFormatter(formatter)\n", " logger.addHandler(handler)\n", " logger.setLevel(logging.DEBUG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's a minimalistic time logger that can be initialized with the name of a given layer, and can track several events (e.g. `\"forward\"` and `\"backward\"`). When the `TimeLogger.end` method is called, the output is formatted nicely and the elapsed time is logged with the logger name and colored label." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from timeit import default_timer\n", "from wasabi import color\n", "\n", "\n", "class TimeLogger:\n", " def __init__(self, name):\n", " self.colors = {\"forward\": \"green\", \"backward\": \"blue\"}\n", " self.name = name\n", " self.timers = {}\n", " \n", " def start(self, name):\n", " self.timers[name] = default_timer()\n", " \n", " def end(self, name):\n", " result = default_timer() - self.timers[name]\n", " label = f\"{name.upper():<8}\"\n", " label = color(label, self.colors.get(name), bold=True)\n", " logger.debug(f\"{self.name:<12} | {label} | {result:.6f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `benchmark` layer now has to wrap the forward pass, backward pass and initialization of the layer it wraps and log the execution times. It then returns a Thinc model instance with the custom `forward` function and a custom `init` function. We'll also allow setting a custom `name` to make it easier to tell multiple wrapped benchmark layers apart." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Model\n", " \n", "def benchmark(layer, name=None):\n", " name = name if name is not None else layer.name\n", " t = TimeLogger(name)\n", " \n", " def init(model, X, Y):\n", " t.start(\"init\")\n", " result = layer.initialize(X, Y)\n", " t.end(\"init\")\n", " return result\n", " \n", " def forward(model, X, is_train):\n", " t.start(\"forward\")\n", " layer_Y, layer_callback = layer(X, is_train=is_train)\n", " t.end(\"forward\")\n", " \n", " def backprop(dY):\n", " t.start(\"backward\")\n", " result = layer_callback(dY)\n", " t.end(\"backward\")\n", " return result\n", " \n", " return layer_Y, backprop\n", " \n", " return Model(f\"benchmark:{layer.name}\", forward, init=init) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Usage examples\n", "\n", "### Using the `benchmark` layer as a function\n", "\n", "We can now wrap one or more layers (including nested layers) with the `benchmark` function. This is the original model:\n", "\n", "```python\n", "model = chain(Linear(1), Linear(1))\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy\n", "from thinc.api import chain, Linear\n", "\n", "X = numpy.zeros((1, 2), dtype=\"f\")\n", "\n", "model = benchmark(chain(benchmark(Linear(1)), Linear(1)), name=\"outer\")\n", "model.initialize(X=X)\n", "Y, backprop = model(X, is_train=False)\n", "dX = backprop(Y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using the `benchmark` layer as an operator\n", "\n", "Alternatively, we can also use `Model.define_operators` to map `benchmark` to an operator like `@`. The left argument of the operator is the first argument passed into the function (the layer) and the right argument is the second argument (the name). The following example wraps the whole network (two chained `Linear` layers) in a benchmark layer named `\"outer\"`, and the first `Linear` layer in a benchmark layer named `\"first\"`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "from thinc.api import Model\n", "\n", "with Model.define_operators({\">>\": chain, \"@\": benchmark}):\n", " model = (Linear(1) @ \"first\" >> Linear(1)) @ \"outer\"\n", " \n", "model.initialize(X=X)\n", "Y, backprop = model(X, is_train=True)\n", "dX = backprop(Y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using the `benchmark` layer during training" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Model, chain, Relu, Softmax, Adam\n", "\n", "n_hidden = 32\n", "dropout = 0.2\n", "\n", "with Model.define_operators({\">>\": chain, \"@\": benchmark}):\n", " model = (\n", " Relu(nO=n_hidden, dropout=dropout) @ \"relu1\"\n", " >> Relu(nO=n_hidden, dropout=dropout) @ \"relu2\"\n", " >> Softmax()\n", " )\n", "\n", "train_X = numpy.zeros((5, 784), dtype=\"f\")\n", "train_Y = numpy.zeros((540, 10), dtype=\"f\")\n", "\n", "model.initialize(X=train_X[:5], Y=train_Y[:5])\n", "optimizer = Adam(0.001)\n", "for i in range(10):\n", " for X, Y in model.ops.multibatch(8, train_X, train_Y, shuffle=True):\n", " Yh, backprop = model.begin_update(X)\n", " backprop(Yh - Y)\n", " model.finish_update(optimizer)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 } thinc-9.0.0/examples/05_visualizing_models.ipynb000066400000000000000000000134651461023342500217320ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Visualizing Thinc models (with shape inference)\n", "\n", "This is a simple notebook showing how you can easily visualize your Thinc models and their inputs and outputs using [Graphviz](https://www.graphviz.org/) and [`pydot`](https://github.com/pydot/pydot). If you're installing `pydot` via the notebook, make sure to restart your kernel (or Google Colab VM โ€“ [see here](https://stackoverflow.com/questions/49853303/how-to-install-pydot-graphviz-on-google-colab) for details) after installation." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\" pydot graphviz svgwrite" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by defining a model with a number of layers chained together using the `chain` combinator:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import chain, expand_window, Relu, Maxout, Linear, Softmax\n", "\n", "n_hidden = 32\n", "dropout = 0.2\n", "\n", "model= chain(\n", " expand_window(3),\n", " Relu(nO=n_hidden, dropout=dropout, normalize=True),\n", " Maxout(nO=n_hidden * 4),\n", " Linear(nO=n_hidden * 2),\n", " Relu(nO=n_hidden, dropout=dropout, normalize=True),\n", " Linear(nO=n_hidden),\n", " Relu(nO=n_hidden, dropout=dropout),\n", " Softmax(),\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's the visualization we want to achieve for this model: the **name of the layer** or combination of layers and the **input and output dimensions**. Note that `>>` refers to a chaining of layers.\n", "\n", "![](https://user-images.githubusercontent.com/13643239/72763790-b8ab3900-3be5-11ea-8ea7-91e4e9fbb181.png)\n", "\n", "This means we need to add a node for each layer, edges connecting the nodes to the previous node (except for the first/last), and labels like `\"name|(nO,nI)\"` โ€“ for instance, `\"maxout|(128,32)\"`. Here's a simple function that takes a Thinc layer (i.e. a `Model` instance) and returns a label with the layer name and its dimensions, if available:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_label(layer):\n", " layer_name = layer.name\n", " nO = layer.get_dim(\"nO\") if layer.has_dim(\"nO\") else \"?\"\n", " nI = layer.get_dim(\"nI\") if layer.has_dim(\"nI\") else \"?\"\n", " return f\"{layer.name}|({nO}, {nI})\".replace(\">\", \">\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now use `pydot` to create a visualization for a given model. You can customize the direction of the notes by setting `\"rankdir\"` (e.g. `\"TB\"` for \"top to bottom\") and adjust the font and arrow styling. To make the visualization render nicely in a notebook, we can call into IPython's utilities." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pydot\n", "from IPython.display import SVG, display\n", "\n", "def visualize_model(model):\n", " dot = pydot.Dot()\n", " dot.set(\"rankdir\", \"LR\")\n", " dot.set_node_defaults(shape=\"record\", fontname=\"arial\", fontsize=\"10\")\n", " dot.set_edge_defaults(arrowsize=\"0.7\")\n", " nodes = {}\n", " for i, layer in enumerate(model.layers):\n", " label = get_label(layer)\n", " node = pydot.Node(layer.id, label=label)\n", " dot.add_node(node)\n", " nodes[layer.id] = node\n", " if i == 0:\n", " continue\n", " from_node = nodes[model.layers[i - 1].id]\n", " to_node = nodes[layer.id]\n", " if not dot.get_edge(from_node, to_node):\n", " dot.add_edge(pydot.Edge(from_node, to_node))\n", " display(SVG(dot.create_svg()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Calling `visualize_model` on the model defined above will render the visualization. However, most dimensions will now show up as `(?, ?)`, instead of the *actual* dimensions as shown in the graph above. That's because Thinc allows **defining models with missing shapes** and is able to **infer the missing shapes from the data** when you call `model.initialize`. The model visualized here doesn't define all its shapes, so the labels are incomplete." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "visualize_model(model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To fill in the missing shapes, we can call `model.initialize` with examples of the expected input `X` and output `Y`. Running `visualize_model` again now shows the complete shapes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy\n", "\n", "X = numpy.zeros((5, 784), dtype=\"f\")\n", "Y = numpy.zeros((54000, 10), dtype=\"f\")\n", "model.initialize(X=X, Y=Y)\n", "\n", "visualize_model(model)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 } thinc-9.0.0/examples/06_predicting_like_terms.ipynb000066400000000000000000000543101461023342500223640ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Predicting Like Polynomial Terms\n", "\n", "Remember in Algebra how you had to combine \"like terms\" to simplify problems? \n", "\n", "You'd see expressions such as `60 + 2x^3 - 6x + x^3 + 17x` in which there are **5** total terms but only **4** are \"like terms\". \n", "\n", "`2x^3` and `x^3` are like, and `-6x` and `17x` are like, while `60` doesn't have any like siblings.\n", "\n", "Can we teach a model to predict that there are `4` like terms in the above expression?\n", "\n", "Let's give it a shot using [Mathy](https://mathy.ai) to generate math problems and [thinc](https://github.com/explosion/thinc) to build a regression model that outputs the number of like terms in each input problem." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install \"thinc>=8.0.0\" mathy_core" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sketch a Model\n", "\n", "Before we get started it can be good to have an idea of what input/output shapes we want for our model.\n", "\n", "We'll convert text math problems into lists of lists of integers, so our example (X) type can be represented using thinc's `Ints2d` type.\n", "\n", "The model will predict how many like terms there are in each sequence, so our output (Y) type can represented with the `Floats2d` type.\n", "\n", "Knowing the thinc types we want enables us to create an alias for our model, so we only have to type out the verbose generic signature once." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List\n", "from thinc.api import Model\n", "from thinc.types import Ints2d, Floats1d\n", "\n", "ModelX = Ints2d\n", "ModelY = Floats1d\n", "ModelT = Model[List[ModelX], ModelY]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Encode Text Inputs\n", "\n", "Mathy generates ascii-math problems and we have to encode them into integers that the model can process. \n", "\n", "To do this we'll build a vocabulary of all the possible characters we'll see, and map each input character to its index in the list.\n", "\n", "For math problems our vocabulary will include all the characters of the alphabet, numbers 0-9, and special characters like `*`, `-`, `.`, etc." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List\n", "from thinc.api import Model\n", "from thinc.types import Ints2d, Floats1d\n", "from thinc.api import Ops, get_current_ops\n", "\n", "vocab = \" .+-/^*()[]-01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n", "\n", "def encode_input(text: str) -> ModelX:\n", " ops: Ops = get_current_ops()\n", " indices: List[List[int]] = []\n", " for c in text:\n", " if c not in vocab:\n", " raise ValueError(f\"'{c}' missing from vocabulary in text: {text}\")\n", " indices.append([vocab.index(c)])\n", " return ops.asarray2i(indices)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It\n", "\n", "Let's try it out on some fixed data to be sure it works. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "outputs = encode_input(\"4+2\")\n", "assert outputs[0][0] == vocab.index(\"4\")\n", "assert outputs[1][0] == vocab.index(\"+\")\n", "assert outputs[2][0] == vocab.index(\"2\")\n", "print(outputs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generate Math Problems\n", "\n", "We'll use Mathy to generate random polynomial problems with a variable number of like terms. The generated problems will act as training data for our model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List, Optional, Set\n", "import random\n", "from mathy_core.problems import gen_simplify_multiple_terms\n", "\n", "def generate_problems(number: int, exclude: Optional[Set[str]] = None) -> List[str]:\n", " if exclude is None:\n", " exclude = set()\n", " problems: List[str] = []\n", " while len(problems) < number:\n", " text, complexity = gen_simplify_multiple_terms(\n", " random.randint(2, 6),\n", " noise_probability=1.0,\n", " noise_terms=random.randint(2, 10),\n", " op=[\"+\", \"-\"],\n", " )\n", " assert text not in exclude, \"duplicate problem generated!\"\n", " exclude.add(text)\n", " problems.append(text)\n", " return problems" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "generate_problems(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Count Like Terms\n", "\n", "Now that we can generate input problems, we'll need a function that can count the like terms in each one and return the value for use as a label.\n", "\n", "To accomplish this we'll use a few helpers from mathy to enumerate the terms and compare them to see if they're like." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import Optional, List, Dict\n", "from mathy_core import MathExpression, ExpressionParser, get_terms, get_term_ex, TermEx\n", "from mathy_core.problems import mathy_term_string\n", "\n", "parser = ExpressionParser()\n", "\n", "def count_like_terms(input_problem: str) -> int:\n", " expression: MathExpression = parser.parse(input_problem)\n", " term_nodes: List[MathExpression] = get_terms(expression)\n", " node_groups: Dict[str, List[MathExpression]] = {}\n", " for term_node in term_nodes:\n", " ex: Optional[TermEx] = get_term_ex(term_node)\n", " assert ex is not None, f\"invalid expression {term_node}\"\n", " key = mathy_term_string(variable=ex.variable, exponent=ex.exponent)\n", " if key == \"\":\n", " key = \"const\"\n", " if key not in node_groups:\n", " node_groups[key] = [term_node]\n", " else:\n", " node_groups[key].append(term_node)\n", " like_terms = 0\n", " for k, v in node_groups.items():\n", " if len(v) <= 1:\n", " continue\n", " like_terms += len(v)\n", " return like_terms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert count_like_terms(\"4x - 2y + q\") == 0\n", "assert count_like_terms(\"x + x + z\") == 2\n", "assert count_like_terms(\"4x + 2x - x + 7\") == 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generate Problem/Answer pairs\n", "\n", "Now that we can generate problems, count the number of like terms in them, and encode their text into integers, we have the pieces required to generate random problems and answers that we can train a neural network with.\n", "\n", "Let's write a function that will return a tuple of: the problem text, its encoded example form, and the output label." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import Tuple\n", "from thinc.api import Ops, get_current_ops\n", "\n", "def to_example(input_problem: str) -> Tuple[str, ModelX, ModelY]:\n", " ops: Ops = get_current_ops()\n", " encoded_input = encode_input(input_problem)\n", " like_terms = count_like_terms(input_problem)\n", " return input_problem, encoded_input, ops.asarray1f([like_terms])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "text, X, Y = to_example(\"x+2x\")\n", "assert text == \"x+2x\"\n", "assert X[0] == vocab.index(\"x\")\n", "assert Y[0] == 2\n", "print(text, X, Y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Build a Model\n", "\n", "Now that we can generate X/Y values, let's define our model and verify that it can process a single input/output.\n", "\n", "For this we'll use Thinc and the `define_operators` context manager to connect the pieces together using overloaded operators for `chain` and `clone` operations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List\n", "from thinc.model import Model\n", "from thinc.api import concatenate, chain, clone, list2ragged\n", "from thinc.api import reduce_sum, Mish, with_array, Embed, residual\n", "\n", "def build_model(n_hidden: int, dropout: float = 0.1) -> ModelT:\n", " with Model.define_operators({\">>\": chain, \"|\": concatenate, \"**\": clone}):\n", " model = (\n", " # Iterate over each element in the batch\n", " with_array(\n", " # Embed the vocab indices\n", " Embed(n_hidden, len(vocab), column=0)\n", " # Activate each batch of embedding sequences separately first\n", " >> Mish(n_hidden, dropout=dropout)\n", " )\n", " # Convert to ragged so we can use the reduction layers\n", " >> list2ragged()\n", " # Sum the features for each batch input\n", " >> reduce_sum()\n", " # Process with a small resnet\n", " >> residual(Mish(n_hidden, normalize=True)) ** 4\n", " # Convert (batch_size, n_hidden) to (batch_size, 1)\n", " >> Mish(1)\n", " )\n", " return model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It\n", "\n", "Let's pass an example through the model to make sure we have all the sizes right." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "text, X, Y = to_example(\"14x + 2y - 3x + 7x\")\n", "m = build_model(12)\n", "m.initialize([X], m.ops.asarray(Y, dtype=\"f\"))\n", "mY = m.predict([X])\n", "print(mY.shape)\n", "assert mY.shape == (1, 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generate Training Datasets\n", "\n", "Now that we can generate examples and we have a model that can process them, let's generate random unique training and evaluation datasets.\n", "\n", "For this we'll write another helper function that can generate (n) training examples and respects an exclude list to avoid letting examples from the training/test sets overlap." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import Tuple, Optional, Set, List\n", "\n", "DatasetTuple = Tuple[List[str], List[ModelX], List[ModelY]]\n", "\n", "def generate_dataset(\n", " size: int,\n", " exclude: Optional[Set[str]] = None,\n", ") -> DatasetTuple:\n", " ops: Ops = get_current_ops()\n", " texts: List[str] = generate_problems(size, exclude=exclude)\n", " examples: List[ModelX] = []\n", " labels: List[ModelY] = []\n", " for i, text in enumerate(texts):\n", " text, x, y = to_example(text)\n", " examples.append(x)\n", " labels.append(y)\n", "\n", " return texts, examples, labels" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It\n", "\n", "Generate a small dataset to be sure everything is working as expected" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "texts, x, y = generate_dataset(10)\n", "assert len(texts) == 10\n", "assert len(x) == 10\n", "assert len(y) == 10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Evaluate Model Performance\n", "\n", "We're almost ready to train our model, we just need to write a function that will check a given trained model against a given dataset and return a 0-1 score of how accurate it was.\n", "\n", "We'll use this function to print the score as training progresses and print final test predictions at the end of training." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List\n", "from wasabi import msg\n", "\n", "def evaluate_model(\n", " model: ModelT,\n", " *,\n", " print_problems: bool = False,\n", " texts: List[str],\n", " X: List[ModelX],\n", " Y: List[ModelY],\n", "):\n", " Yeval = model.predict(X)\n", " correct_count = 0\n", " print_n = 12\n", " if print_problems:\n", " msg.divider(f\"eval samples max({print_n})\")\n", " for text, y_answer, y_guess in zip(texts, Y, Yeval):\n", " y_guess = round(float(y_guess))\n", " correct = y_guess == int(y_answer)\n", " print_fn = msg.fail\n", " if correct:\n", " correct_count += 1\n", " print_fn = msg.good\n", " if print_problems and print_n > 0:\n", " print_n -= 1\n", " print_fn(f\"Answer[{int(y_answer[0])}] Guess[{y_guess}] Text: {text}\")\n", " if print_problems:\n", " print(f\"Model predicted {correct_count} out of {len(X)} correctly.\")\n", " return correct_count / len(X)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try It\n", "\n", "Let's try it out with an untrained model and expect to see a really sad score." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "texts, X, Y = generate_dataset(128)\n", "m = build_model(12)\n", "m.initialize(X, m.ops.asarray(Y, dtype=\"f\"))\n", "# Assume the model should do so poorly as to round down to 0\n", "assert round(evaluate_model(m, texts=texts, X=X, Y=Y)) == 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Train/Evaluate a Model\n", "\n", "The final helper function we need is one to train and evaluate a model given two input datasets. \n", "\n", "This function does a few things:\n", "\n", " 1. Create an Adam optimizer we can use for minimizing the model's prediction error.\n", " 2. Loop over the given training dataset (epoch) number of times.\n", " 3. For each epoch, make batches of (batch_size) examples. For each batch(X), predict the number of like terms (Yh) and subtract the known answers (Y) to get the prediction error. Update the model using the optimizer with the calculated error.\n", " 5. After each epoch, check the model performance against the evaluation dataset.\n", " 6. Save the model weights for the best score out of all the training epochs.\n", " 7. After all training is done, restore the best model and print results from the evaluation set." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from thinc.api import Adam\n", "from wasabi import msg\n", "import numpy\n", "from tqdm.auto import tqdm\n", "\n", "def train_and_evaluate(\n", " model: ModelT,\n", " train_tuple: DatasetTuple,\n", " eval_tuple: DatasetTuple,\n", " *,\n", " lr: float = 3e-3,\n", " batch_size: int = 64,\n", " epochs: int = 48,\n", ") -> float:\n", " (train_texts, train_X, train_y) = train_tuple\n", " (eval_texts, eval_X, eval_y) = eval_tuple\n", " msg.divider(\"Train and Evaluate Model\")\n", " msg.info(f\"Batch size = {batch_size}\\tEpochs = {epochs}\\tLearning Rate = {lr}\")\n", "\n", " optimizer = Adam(lr)\n", " best_score: float = 0.0\n", " best_model: Optional[bytes] = None\n", " for n in range(epochs):\n", " loss = 0.0\n", " batches = model.ops.multibatch(batch_size, train_X, train_y, shuffle=True)\n", " for X, Y in tqdm(batches, leave=False, unit=\"batches\"):\n", " Y = model.ops.asarray(Y, dtype=\"float32\")\n", " Yh, backprop = model.begin_update(X)\n", " err = Yh - Y\n", " backprop(err)\n", " loss += (err ** 2).sum()\n", " model.finish_update(optimizer)\n", " score = evaluate_model(model, texts=eval_texts, X=eval_X, Y=eval_y)\n", " if score > best_score:\n", " best_model = model.to_bytes()\n", " best_score = score\n", " print(f\"{n}\\t{score:.2f}\\t{loss:.2f}\")\n", "\n", " if best_model is not None:\n", " model.from_bytes(best_model)\n", " print(f\"Evaluating with best model\")\n", " score = evaluate_model(\n", " model, texts=eval_texts, print_problems=True, X=eval_X, Y=eval_y\n", " )\n", " print(f\"Final Score: {score}\")\n", " return score\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll generate the dataset first, so we can iterate on the model without having to spend time generating examples for each run. This also ensures we have the same dataset across different model runs, to make it easier to compare performance." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "train_size = 1024 * 8\n", "test_size = 2048\n", "seen_texts: Set[str] = set()\n", "with msg.loading(f\"Generating train dataset with {train_size} examples...\"):\n", " train_dataset = generate_dataset(train_size, seen_texts)\n", "msg.good(f\"Train set created with {train_size} examples.\")\n", "with msg.loading(f\"Generating eval dataset with {test_size} examples...\"):\n", " eval_dataset = generate_dataset(test_size, seen_texts)\n", "msg.good(f\"Eval set created with {test_size} examples.\")\n", "init_x = train_dataset[1][:2]\n", "init_y = train_dataset[2][:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we can build, train, and evaluate our model!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = build_model(64)\n", "model.initialize(init_x, init_y)\n", "train_and_evaluate(\n", " model, train_dataset, eval_dataset, lr=2e-3, batch_size=64, epochs=16\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Intermediate Exercise\n", "\n", "The model we built can train up to ~80% given 100 or more epochs. Improve the model architecture so that it trains to a similar accuracy while requiring fewer epochs or a smaller dataset size." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import List\n", "from thinc.model import Model\n", "from thinc.types import Array2d, Array1d\n", "from thinc.api import chain, clone, list2ragged, reduce_mean, Mish, with_array, Embed, residual\n", "\n", "def custom_model(n_hidden: int, dropout: float = 0.1) -> Model[List[Array2d], Array2d]:\n", " # Put your custom architecture here\n", " return build_model(n_hidden, dropout)\n", "\n", "model = custom_model(64)\n", "model.initialize(init_x, init_y)\n", "train_and_evaluate(\n", " model, train_dataset, eval_dataset, lr=2e-3, batch_size=64, epochs=16\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Advanced Exercise\n", "\n", "Rewrite the model to encode the whole expression with a BiLSTM, and then generate pairs of terms, using the BiLSTM vectors. Over each pair of terms, predict whether the terms are alike or unlike." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from dataclasses import dataclass\n", "from thinc.types import Array2d, Ragged\n", "from thinc.model import Model\n", "\n", "\n", "@dataclass\n", "class Comparisons:\n", " data: Array2d # Batch of vectors for each pair\n", " indices: Array2d # Int array of shape (N, 3), showing the (batch, term1, term2) positions\n", "\n", "def pairify() -> Model[Ragged, Comparisons]:\n", " \"\"\"Create pair-wise comparisons for items in a sequence. For each sequence of N\n", " items, there will be (N**2-N)/2 comparisons.\"\"\"\n", " ...\n", "\n", "def predict_over_pairs(model: Model[Array2d, Array2d]) -> Model[Comparisons, Comparisons]:\n", " \"\"\"Apply a prediction model over a batch of comparisons. Outputs a Comparisons\n", " object where the data is the scores. The prediction model should predict over\n", " two classes, True and False.\"\"\"\n", " ...\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 4 } thinc-9.0.0/examples/benchmarks/000077500000000000000000000000001461023342500165605ustar00rootroot00000000000000thinc-9.0.0/examples/benchmarks/lstm_tagger.py000066400000000000000000000105121461023342500214410ustar00rootroot00000000000000""" Compare tagging speed for LSTM, using dummy data. Results on CPU laptop: PyTorchLSTM.v1: Predicted 39017 4.033804399892688 Ys[0] 0.05000001 5.551115e-17 LSTM (NumpyOps): Predicted 39018 13.174870599992573 Ys[0] 0.05000001 5.551115e-17 So PyTorch is 3x faster currently. """ from typing import List import typer import tqdm import numpy.random from timeit import default_timer as timer from thinc.api import Model, Config, registry from thinc.api import chain, list2padded, with_array, with_padded from thinc.api import to_categorical, set_current_ops from thinc.api import Ops, NumpyOps, CupyOps, fix_random_seed, require_gpu from thinc.types import Ints1d, Ints2d, Floats2d, Padded CONFIG = """ [data] n_samples = 1000 n_tags = 20 n_vocab = 10000 length_mean = 50 length_variance = 5 [common] width = 300 [model] @layers = "LSTMTagger.v1" [model.embed] @layers = "Embed.v1" nO = ${common:width} nV = ${data:n_vocab} column = 0 [model.encode] @layers = "LSTM.v1" nO = ${common:width} nI = ${common:width} depth = 2 bi = true [model.predict] @layers = "Linear.v1" nO = ${data:n_tags} """ @registry.layers("LSTMTagger.v1") def build_tagger( embed: Model[Ints2d, Floats2d], encode: Model[Padded, Padded], predict: Model[Floats2d, Floats2d], ) -> Model[List[Ints1d], Padded]: model = chain( with_array(embed), with_padded(encode), with_array(predict), list2padded() ) model.set_ref("embed", embed) model.set_ref("encode", encode) model.set_ref("predict", model.layers[-1]) return model def get_dummy_data(n_samples, n_tags, n_vocab, length_mean, length_variance): Xs = [] Ys = [] for _ in range(n_samples): length = numpy.random.normal(size=1, scale=length_variance) + length_mean shape = (max(1, int(length)),) X = numpy.random.uniform(0, n_vocab - 1, shape) Y = numpy.random.uniform(0, n_tags - 1, shape) assert X.size, length assert Y.size, length Xs.append(X.reshape((-1, 1)).astype("i")) Ys.append(to_categorical(Y.astype("i"))) return Xs, Ys def run_forward(model, Xs, n_times=1): total = 0.0 for _ in range(n_times): for batch in tqdm.tqdm(Xs): Y = model.predict(batch) total += Y.data.sum() return float(total) def run_forward_backward(model, batches, n_times=1): total = 0.0 for _ in range(n_times): for X, Y in tqdm.tqdm(batches): Yh, get_dX = model.begin_update(X) get_dX(Yh) total += Yh.data.sum() return float(total) def set_backend(name, gpu_id): global CONFIG if name == "generic": set_current_ops(Ops()) else: if gpu_id == -1: set_current_ops(NumpyOps(use_blis=True)) else: set_current_ops(CupyOps()) if name == "pytorch": import torch torch.set_num_threads(1) CONFIG = CONFIG.replace("LSTM.v1", "PyTorchLSTM.v1") def main( numpy: bool = False, pytorch: bool = False, generic: bool = False, gpu_id: int = -1 ): global CONFIG fix_random_seed(0) if gpu_id >= 0: require_gpu(gpu_id) print("Set GPU", gpu_id) backends = {"pytorch": pytorch, "numpy": numpy, "generic": generic} for name, use_backend in backends.items(): if not use_backend: print(f"Skipping {name}") continue set_backend(name, gpu_id) print("Getting data") C = registry.resolve(Config().from_str(CONFIG)) model = C["model"] X, Y = get_dummy_data(**C["data"]) print("Copy to device") X = [model.ops.asarray(x) for x in X] Y = [model.ops.asarray(y) for y in Y] print("Begin init", len(X)) model.initialize(X=X[:5]) print("Pre-batch") n_words = sum(len(x) for x in X) batches = model.ops.multibatch(16, X, Y) batches = [(model.layers[0].predict(x), y) for x, y in batches] model.layers.pop(0) print("Start") start_time = timer() total = run_forward(model, [x for x, y in batches]) end_time = timer() print(name, n_words, total, end_time - start_time) start_time = timer() total = run_forward_backward(model, batches) end_time = timer() print(name, n_words, total, end_time - start_time) if __name__ == "__main__": typer.run(main) thinc-9.0.0/examples/benchmarks/mappers.py000066400000000000000000000076221461023342500206100ustar00rootroot00000000000000from thinc.api import remap_ids_v2 from thinc.api import premap_ids from thinc.api import chain, Embed, HashEmbed import time import random import numpy as np import cupy as cp N_symbols = 200000 N_tokens = 50000 N_batch = 500 N_columns = 4 N_dim = 300 mapper = {} numbers = list(range(N_symbols)) random.shuffle(numbers) for v, k in enumerate(numbers): mapper[k] = v class time_context: """Register the running time of a context.""" def __enter__(self): self.start = time.perf_counter() return self def __exit__(self, type, value, traceback): self.elapsed = time.perf_counter() - self.start def speed_test_no_column(): remap = remap_ids_v2(mapper) premap = premap_ids(mapper) keys = np.random.randint(0, N_symbols, N_tokens) with time_context() as elapsed: for i in range(100): remap(keys, False) remaptime = elapsed.elapsed with time_context() as elapsed: for i in range(100): premap(keys, False) premaptime = elapsed.elapsed print("remap", remaptime) print("premap", premaptime) print("speedup", remaptime / premaptime) def speed_test_column(): remap = remap_ids_v2(mapper, column=3) premap = premap_ids(mapper, column=3) keys = np.random.randint(0, N_symbols, (N_tokens, N_columns)) with time_context() as elapsed: for i in range(100): remap(keys, False) remaptime = elapsed.elapsed with time_context() as elapsed: for i in range(100): premap(keys, False) premaptime = elapsed.elapsed print("remap", remaptime) print("premap", premaptime) print("speedup", remaptime / premaptime) def speed_test_cupy(): remap = remap_ids_v2(mapper) premap = premap_ids(mapper) keys = cp.random.randint(0, N_symbols, N_tokens) with time_context() as elapsed: for i in range(100): remap(keys, False) remaptime = elapsed.elapsed with time_context() as elapsed: for i in range(100): premap(keys, False) premaptime = elapsed.elapsed print("remap", remaptime) print("premap", premaptime) print("speedup", remaptime / premaptime) def speed_test_with_embed(): remap = chain(remap_ids_v2(mapper), Embed(N_dim, N_symbols)) premap = chain(premap_ids(mapper), Embed(N_dim, N_symbols)) remap.initialize() premap.initialize() keys = np.random.randint(0, N_symbols, N_tokens) with time_context() as elapsed: for i in range(100): remap(keys, False) remaptime = elapsed.elapsed with time_context() as elapsed: for i in range(100): premap(keys, False) premaptime = elapsed.elapsed print("remap", remaptime) print("premap", premaptime) print("speedup", remaptime / premaptime) def speed_test_cupy_with_embed(): remap = chain(remap_ids_v2(mapper), Embed(N_dim, N_symbols)) premap = chain(premap_ids(mapper), Embed(N_dim, N_symbols)) remap.initialize() premap.initialize() keys = cp.random.randint(0, N_symbols, N_tokens) with time_context() as elapsed: for i in range(100): remap(keys, False) remaptime = elapsed.elapsed with time_context() as elapsed: for i in range(100): premap(keys, False) premaptime = elapsed.elapsed print("remap", remaptime) print("premap", premaptime) print("speedup", remaptime / premaptime) def speed_test_hashembed(): embed = HashEmbed(N_dim, N_symbols) embed.initialize() keys = np.random.randint(0, N_symbols, N_tokens) with time_context() as elapsed: for i in range(100): embed(keys, False) print(elapsed.elapsed) print("No columns") speed_test_no_column() print("Columns") speed_test_column() print("Cupy") speed_test_cupy() print("With Embed") speed_test_with_embed() print("Cupy With Embed") speed_test_cupy_with_embed() print("HashEmbed speed") speed_test_hashembed() thinc-9.0.0/examples/bloom_embeddings.ipynb000066400000000000000000002670341461023342500210130ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 3527, "status": "ok", "timestamp": 1648197799884, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "ssfd1qsSxtRS", "outputId": "7c6e6585-2362-4be2-da05-db00a0307fe6", "tags": [] }, "outputs": [], "source": [ "%pip install mmh3 numpy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Bloom embeddings algorithm\n", "\n", "In a normal embedding table, each word-string is mapped to a distinct ID.\n", "Usually these IDs will be sequential, so if you have a vocabulary of 100 words,\n", "your words will be mapped to numbers `range(100)`. The sequential IDs can then\n", "be used as indices into an embedding table: if you have 100 words in your\n", "vocabulary, you have 100 rows in the table, and each word receives its own\n", "vector.\n", "\n", "However, there's no limit to the number of unique words that might occur in a\n", "sample of text, while we definitely want a limited number of rows in our\n", "embedding table. Some of the rows in our table will therefore need to be shared\n", "between multiple words in our vocabulary. One obvious solution is to set aside a\n", "single vector in the table. Words 0-98 will each receive their own vector, while\n", "all other words are assigned to vector 99.\n", "\n", "However, this asks vector 99 to do a lot of work. What if we gave more vectors\n", "to the unknown words?" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "executionInfo": { "elapsed": 10, "status": "ok", "timestamp": 1648197799885, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "Eb895XpR-VUB" }, "outputs": [], "source": [ "def get_row(word_id, number_vector=100, number_oov=10):\n", " if word_id < (number_vector - number_oov):\n", " return word_id\n", " else:\n", " return number_vector + (word_id % number_oov)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This gives the model a little more resolution for the unknown words. If all\n", "out-of-vocabulary words are assigned the same vector, then they'll all look\n", "identical to the model. Even if the training data actually includes information\n", "that shows two different out-of-vocabulary words have important, different\n", "implications -- for instance, if one word is a strong indicator of positive\n", "sentiment, while the other is a strong indicator of negative sentiment -- the\n", "model won't be able to tell them apart. However, if we have 10 buckets for the\n", "unknown words, we might get lucky, and assign these words to different buckets.\n", "If so, the model would be able to learn that one of the unknown-word vectors\n", "makes positive sentiment more likely, while the other vector makes negative\n", "sentiment more likely.\n", "\n", "If this is good, then why not do more of it? Bloom embeddings are like an\n", "extreme version, where _every_ word is handled like the unknown words above:\n", "there are 100 vectors for the \"unknown\" portion, and 0 for the \"known\" portion.\n", "\n", "So far, this approach seems weird, but not necessarily good. The part that makes\n", "it unfairly effective is the next step: by simply doing the same thing multiple\n", "times, we can greatly improve the resolution, and have unique representations\n", "for far more words than we have vectors. The code in full:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "executionInfo": { "elapsed": 8, "status": "ok", "timestamp": 1648197799885, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "tTkqM3EixhWM" }, "outputs": [], "source": [ "import numpy\n", "import mmh3\n", "\n", "def allocate(n_vectors, n_dimensions):\n", " table = numpy.zeros((n_vectors, n_dimensions), dtype='f')\n", " table += numpy.random.uniform(-0.1, 0.1, table.size).reshape(table.shape)\n", " return table\n", "\n", "def get_vector(table, word):\n", " hash1 = mmh3.hash(word, seed=0)\n", " hash2 = mmh3.hash(word, seed=1)\n", " row1 = hash1 % table.shape[0]\n", " row2 = hash2 % table.shape[0]\n", " return table[row1] + table[row2]\n", "\n", "def update_vector(table, word, d_vector):\n", " hash1 = mmh3.hash(word, seed=0)\n", " hash2 = mmh3.hash(word, seed=1)\n", " row1 = hash1 % table.shape[0]\n", " row2 = hash2 % table.shape[0]\n", " table[row1] -= 0.001 * d_vector\n", " table[row2] -= 0.001 * d_vector" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this example, we've used two keys, assigned from two random hash functions.\n", "It's unlikely that two words will collide on both keys, so by simply summing the\n", "vectors together, we'll assign most words a unique representation.\n", "\n", "For the sake of illustration, let's step through a very small example,\n", "explicitly.\n", "\n", "Let's say we have this vocabulary of 20 words:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "executionInfo": { "elapsed": 8, "status": "ok", "timestamp": 1648197799885, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "QMaz-mr9xjPG" }, "outputs": [], "source": [ "vocab = ['apple', 'strawberry', 'orange', 'juice', 'drink', 'smoothie',\n", " 'eat', 'fruit', 'health', 'wellness', 'steak', 'fries', 'ketchup',\n", " 'burger', 'chips', 'lobster', 'caviar', 'service', 'waiter', 'chef']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll embed these into two dimensions. Normally this would give us a table of\n", "`(20, 2)` floats, which we would randomly initialise. With the hashing trick, we\n", "can make the table smaller. Let's give it 15 vectors:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "executionInfo": { "elapsed": 8, "status": "ok", "timestamp": 1648197799886, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "LNg60lvqxkmP" }, "outputs": [], "source": [ "normal_embed = numpy.random.uniform(-0.1, 0.1, (20, 2))\n", "hashed_embed = numpy.random.uniform(-0.1, 0.1, (15, 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the normal table, we want to map each word in our vocabulary to its own\n", "vector:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "executionInfo": { "elapsed": 5, "status": "ok", "timestamp": 1648197801914, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "9wFC_iR_xlBH" }, "outputs": [], "source": [ "word2id = {}\n", "def get_normal_vector(word, table):\n", " if word not in word2id.keys():\n", " word2id[word] = len(word2id)\n", " return table[word2id[word]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The hashed table only has 15 rows, so some words will have to share. We'll\n", "handle this by mapping the word into an arbitrary integer โ€“ called a \"hash\n", "value\". The hash function will return an arbitrary integer, which we'll mod into\n", "the range `(0, 15)`. Importantly, we need to be able to compute _multiple,\n", "distinct_ hash values for each key โ€“ so Python's built-in hash function is\n", "inconvenient. We'll therefore use MurmurHash.\n", "\n", "Let's see what keys we get for our 20 vocabulary items, using MurmurHash:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "executionInfo": { "elapsed": 4, "status": "ok", "timestamp": 1648197804508, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "Gs69d2KRxmg9" }, "outputs": [], "source": [ "hashes1 = [mmh3.hash(w, 1) % 15 for w in vocab]\n", "assert hashes1 == [3, 6, 4, 13, 8, 3, 13, 1, 9, 12, 11, 4, 2, 13, 5, 10, 0, 2, 10, 13]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, some keys are shared between multiple words, while 2/15 keys are\n", "unoccupied. This is obviously unideal! If multiple words have the same key,\n", "they'll map to the same vector โ€“ as far as the model is concerned, \"strawberry\"\n", "and \"heart\" will be indistinguishable. It won't be clear which word was used โ€“\n", "they have the same representation.\n", "\n", "To address this, we simply hash the words again, this time using a different\n", "seed โ€“ so that we get a different set of arbitrary keys:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "executionInfo": { "elapsed": 3, "status": "ok", "timestamp": 1648197804508, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "acpOxkljynPo" }, "outputs": [], "source": [ "from collections import Counter\n", "\n", "hashes2 = [mmh3.hash(w, 2) % 15 for w in vocab]\n", "assert len(Counter(hashes2).most_common()) == 12" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This one's even worse โ€“ 3 keys unoccupied! But our strategy is not to keep drawing until we get a favorable seed. Instead, consider this:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "executionInfo": { "elapsed": 3, "status": "ok", "timestamp": 1648197805024, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "W7tfxLQBytWP" }, "outputs": [], "source": [ "assert len(Counter(zip(hashes1, hashes2))) == 20" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By combining the results from the two hashes, our 20 words distribute perfectly,\n", "into 20 unique combinations. This makes sense: we expect to have some words\n", "overlapping on one of the keys, but we'd have to be very unlucky for a pair of\n", "words to overlap on _both_ keys.\n", "\n", "This means that if we simply add the two vectors together, each word once more\n", "has a unique representation:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 2, "status": "ok", "timestamp": 1648197805764, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "wI5yayZWyxVP", "outputId": "4f62b77d-709f-483b-a0bb-4e5fbe68d5fe" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "apple -0.033 -0.012\n", "strawberry -0.023 -0.037\n", "orange 0.158 -0.031\n", "juice -0.045 0.139\n", "drink 0.024 0.030\n", "smoothie 0.121 0.076\n", "eat -0.093 0.153\n", "fruit 0.083 0.052\n", "health 0.064 -0.046\n", "wellness 0.143 0.112\n", "steak 0.011 -0.097\n", "fries 0.036 0.041\n", "ketchup 0.081 0.029\n", "burger -0.045 0.139\n", "chips -0.118 -0.090\n", "lobster 0.016 -0.107\n", "caviar -0.033 -0.012\n", "service 0.081 0.029\n", "waiter 0.179 -0.038\n", "chef -0.047 0.062\n" ] } ], "source": [ "for word in vocab:\n", " key1 = mmh3.hash(word, 0) % 15\n", " key2 = mmh3.hash(word, 1) % 15\n", " vector = hashed_embed[key1] + hashed_embed[key2]\n", " print(word, '%.3f %.3f' % tuple(vector))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now have a function that maps our 20 words to 20 unique vectors โ€“ but we're\n", "storing weights for only 15 vectors in memory. Now the question is: will we be\n", "able to find values for these weights that let us actually map words to useful\n", "vectors?\n", "\n", "Let's do a quick experiment to see how this works. We'll assign \"true\" values\n", "for our little vocabulary, and see how well we can approximate them with our\n", "compressed table. To get the \"true\" values, we _could_ put the \"science\" in data\n", "science, and drag the words around into reasonable-looking clusters. But for our\n", "purposes, the actual \"true\" values don't matter. We'll therefore just do a\n", "simulation: we'll assign random vectors as the \"true\" state, and see if we can\n", "learn values for the hash embeddings that match them.\n", "\n", "The learning procedure will be a simple stochastic gradient descent:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "colab": { "background_save": true }, "executionInfo": { "elapsed": 3, "status": "aborted", "timestamp": 1648199186370, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "ET4n9AA5y0fX" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "499 43.47128495286\n" ] } ], "source": [ "import numpy\n", "import numpy.random as random\n", "import mmh3\n", "\n", "random.seed(0)\n", "nb_epoch = 500\n", "learn_rate = 0.001\n", "nr_hash_vector = 1000\n", "\n", "words = [str(i) for i in range(2000)]\n", "true_vectors = numpy.random.uniform(-0.1, 0.1, (len(words), 10))\n", "hash_vectors = numpy.random.uniform(-0.1, 0.1, (nr_hash_vector, 10))\n", "examples = list(zip(words, true_vectors))\n", "\n", "for epoch in range(nb_epoch):\n", " random.shuffle(examples)\n", " loss=0.\n", " for word, truth in examples:\n", " key1 = mmh3.hash(word, 0) % nr_hash_vector\n", " key2 = mmh3.hash(word, 1) % nr_hash_vector\n", " hash_vector = hash_vectors[key1] + hash_vectors[key2]\n", " diff = hash_vector - truth\n", " hash_vectors[key1] -= learn_rate * diff\n", " hash_vectors[key2] -= learn_rate * diff\n", " loss += (diff**2).sum()\n", "print(epoch, loss)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's worth taking some time to play with this simulation. You can start by doing\n", "some sanity checks:\n", "\n", "- How does the loss change with `nr_hash_vector`?\n", "- If you remove `key2`, does the loss go up?\n", "- What happens if you add more hash keys?\n", "- What happens as the vocabulary size increases?\n", "- What happens when more dimensions are added?\n", "- How sensitive are the hash embeddings to the initial conditions? If we change the random seed, do we ever get unlucky?\n", "\n", "If you play with the simulation for a while, you'll start to get a good feel for\n", "the dynamics, and hopefully you'll have a clear idea of why the technique works." ] }, { "cell_type": "markdown", "metadata": { "id": "TuRoY34yQb0v", "tags": [] }, "source": [ "## Bonus Section \n", "\n", "To make it easier for folks to try out a whole bunch of settings we'd added a little bit of code below that makes it easier to get relevant visuals." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 2919, "status": "ok", "timestamp": 1648200042349, "user": { "displayName": "Vincent D. Warmerdam", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gh4KYzhhhK0YDTnAQsUIaQPw-0dKIP-kLBID7nFdQ=s64", "userId": "05641618555626735638" }, "user_tz": -60 }, "id": "NPVKX_pbXJYs", "outputId": "fc046666-d690-426d-b8a7-dc557f12832d", "tags": [] }, "outputs": [], "source": [ "%pip install altair pandas" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "colab": { "background_save": true }, "id": "nHd1wo6m1q-J" }, "outputs": [], "source": [ "from functools import reduce \n", "\n", "\n", "def calc_losses(epochs=500, seed=0, learn_rate=0.001, nr_hash_vector=1000, n_hash=3, n_words=1000, size_vector=10):\n", " random.seed(seed)\n", " nb_epoch = epochs\n", " learn_rate = learn_rate\n", " nr_hash_vector = nr_hash_vector\n", "\n", " words = [str(i) for i in range(n_words)]\n", " true_vectors = numpy.random.uniform(-0.1, 0.1, (len(words), size_vector))\n", " hash_vectors = numpy.random.uniform(-0.1, 0.1, (nr_hash_vector, size_vector))\n", " examples = list(zip(words, true_vectors))\n", "\n", " losses = []\n", " for epoch in range(nb_epoch):\n", " random.shuffle(examples)\n", " loss=0.\n", " for word, truth in examples:\n", " keys = [mmh3.hash(word, k) % nr_hash_vector for k in range(n_hash)]\n", " hash_vector = reduce(lambda a, b: a + b, [hash_vectors[k] for k in keys])\n", " diff = hash_vector - truth\n", " for key in keys:\n", " hash_vectors[key] -= learn_rate * diff\n", " loss += (diff**2).sum()\n", " losses.append(loss)\n", " return losses\n", "\n", "data = []\n", "for n_hash in [1, 2, 3, 4, 5]:\n", " losses = calc_losses(nr_hash_vector=2_000, n_words=10_000, n_hash=n_hash, epochs=150)\n", " data = data + [{\"loss\": l, \"nr_hash_vector\": nr_hash_vector, \"n_hash\": str(n_hash), \"epoch\": e} for e, l in enumerate(losses)]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "colab": { "background_save": true }, "id": "P0Q0k9bjXMm3" }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "import altair as alt\n", "\n", "source = pd.DataFrame(data)\n", "\n", "(alt.Chart(source)\n", " .mark_line()\n", " .encode(x='epoch', y='loss', color='n_hash')\n", " .properties(width=600, height=250)\n", " .interactive())" ] } ], "metadata": { "colab": { "authorship_tag": "ABX9TyPAXtr/TeMWYmJkxrXcAPIT", "collapsed_sections": [], "name": "bloom_embeddings.ipynb", "version": "" }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.6" } }, "nbformat": 4, "nbformat_minor": 4 } thinc-9.0.0/examples/mnist.py000066400000000000000000000030671461023342500161550ustar00rootroot00000000000000""" PyTorch version: https://github.com/pytorch/examples/blob/master/mnist/main.py TensorFlow version: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist.py """ # pip install thinc ml_datasets typer from thinc.api import Model, chain, Relu, Softmax, Adam import ml_datasets from wasabi import msg from tqdm import tqdm import typer def main( n_hidden: int = 256, dropout: float = 0.2, n_iter: int = 10, batch_size: int = 128 ): # Define the model model: Model = chain( Relu(nO=n_hidden, dropout=dropout), Relu(nO=n_hidden, dropout=dropout), Softmax(), ) # Load the data (train_X, train_Y), (dev_X, dev_Y) = ml_datasets.mnist() # Set any missing shapes for the model. model.initialize(X=train_X[:5], Y=train_Y[:5]) train_data = model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True) dev_data = model.ops.multibatch(batch_size, dev_X, dev_Y) # Create the optimizer. optimizer = Adam(0.001) for i in range(n_iter): for X, Y in tqdm(train_data, leave=False): Yh, backprop = model.begin_update(X) backprop(Yh - Y) model.finish_update(optimizer) # Evaluate and print progress correct = 0 total = 0 for X, Y in dev_data: Yh = model.predict(X) correct += (Yh.argmax(axis=1) == Y.argmax(axis=1)).sum() total += Yh.shape[0] score = correct / total msg.row((i, f"{score:.3f}"), widths=(3, 5)) if __name__ == "__main__": typer.run(main) thinc-9.0.0/examples/transformers_tagger.py000066400000000000000000000173221461023342500211000ustar00rootroot00000000000000"""Train a transformer tagging model, using Huggingface's Transformers.""" # pip install thinc ml_datasets typer tqdm transformers torch from dataclasses import dataclass from typing import List, Optional, Tuple, Callable import torch from pathlib import Path from transformers import AutoTokenizer, AutoModel import thinc from thinc.api import PyTorchWrapper, Softmax, chain, with_array, Model, Config from thinc.api import torch2xp, xp2torch, SequenceCategoricalCrossentropy from thinc.api import prefer_gpu, use_pytorch_for_gpu_memory from thinc.types import Floats2d, ArgsKwargs import ml_datasets import tqdm import typer CONFIG = """ [model] @layers = "TransformersTagger.v1" starter = "bert-base-multilingual-cased" [optimizer] @optimizers = "RAdam.v1" weight_decay = 1e-8 [optimizer.learn_rate] @schedules = "warmup_linear.v1" initial_rate = 0.01 warmup_steps = 3000 total_steps = 6000 [training] batch_size = 128 words_per_subbatch = 2000 n_epoch = 10 """ def main(path: Optional[Path] = None, out_dir: Optional[Path] = None): if prefer_gpu(): print("Using gpu!") use_pytorch_for_gpu_memory() # You can edit the CONFIG string within the file, or copy it out to # a separate file and pass in the path. if path is None: config = Config().from_str(CONFIG) else: config = Config().from_disk(path) # resolve constructs objects whenever you have blocks with an @ key. # In the optimizer block we write @optimizers = "Adam.v1". This tells Thinc # to use registry.optimizers to fetch the "Adam.v1" function. You can # register your own functions as well and build up trees of objects. C = thinc.registry.resolve(config) words_per_subbatch = C["training"]["words_per_subbatch"] n_epoch = C["training"]["n_epoch"] batch_size = C["training"]["batch_size"] model = C["model"] optimizer = C["optimizer"] calculate_loss = SequenceCategoricalCrossentropy() (train_X, train_Y), (dev_X, dev_Y) = ml_datasets.ud_ancora_pos_tags() # Convert the outputs to cupy (if we're using that) train_Y = list(map(model.ops.asarray, train_Y)) dev_Y = list(map(model.ops.asarray, dev_Y)) # Pass in a small batch of data, to fill in missing shapes model.initialize(X=train_X[:5], Y=train_Y[:5]) for epoch in range(n_epoch): # Transformers often learn best with large batch sizes -- larger than # fits in GPU memory. But you don't have to backprop the whole batch # at once. Here we consider the "logical" batch size (number of examples # per update) separately from the physical batch size. batches = model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True) for outer_batch in tqdm.tqdm(batches, leave=False): # For the physical batch size, what we care about is the number # of words (considering padding too). We also want to sort by # length, for efficiency. for batch in minibatch_by_words(outer_batch, words_per_subbatch): inputs, truths = zip(*batch) guesses, backprop = model(inputs, is_train=True) backprop(calculate_loss.get_grad(guesses, truths)) # At the end of the batch, we call the optimizer with the accumulated # gradients, and advance the learning rate schedules. model.finish_update(optimizer) optimizer.step_schedules() # You might want to evaluate more often than once per epoch; that's up # to you. score = evaluate_sequences(model, dev_X, dev_Y, 128) print(epoch, f"{score:.3f}") if out_dir: model.to_disk(out_dir / f"{epoch}.bin") @dataclass class TokensPlus: """Dataclass to hold the output of the Huggingface 'batch_encode_plus' method.""" input_ids: torch.Tensor token_type_ids: torch.Tensor attention_mask: torch.Tensor input_len: List[int] overflowing_tokens: Optional[torch.Tensor] = None num_truncated_tokens: Optional[torch.Tensor] = None special_tokens_mask: Optional[torch.Tensor] = None @thinc.registry.layers("TransformersTagger.v1") def TransformersTagger( starter: str, n_tags: int = 17 ) -> Model[List[List[str]], List[Floats2d]]: return chain( TransformersTokenizer(starter), Transformer(starter), with_array(Softmax(nO=n_tags)), ) @thinc.registry.layers("transformers_tokenizer.v1") def TransformersTokenizer(name: str) -> Model[List[List[str]], TokensPlus]: def forward( model, texts: List[List[str]], is_train: bool ) -> Tuple[TokensPlus, Callable]: tokenizer = model.attrs["tokenizer"] token_data = tokenizer.batch_encode_plus( [(text, None) for text in texts], add_special_tokens=True, return_token_type_ids=True, return_attention_masks=True, return_input_lengths=True, return_tensors="pt", ) return TokensPlus(**token_data), lambda d_tokens: [] return Model( "tokenizer", forward, attrs={"tokenizer": AutoTokenizer.from_pretrained(name)}, ) @thinc.registry.layers("transformers_model.v1") def Transformer(name: str) -> Model[TokensPlus, List[Floats2d]]: return PyTorchWrapper( AutoModel.from_pretrained(name), convert_inputs=convert_transformer_inputs, convert_outputs=convert_transformer_outputs, ) def convert_transformer_inputs(model, tokens: TokensPlus, is_train): kwargs = { "input_ids": tokens.input_ids, "attention_mask": tokens.attention_mask, "token_type_ids": tokens.token_type_ids, } return ArgsKwargs(args=(), kwargs=kwargs), lambda dX: [] def convert_transformer_outputs(model, inputs_outputs, is_train): layer_inputs, torch_outputs = inputs_outputs torch_tokvecs: torch.Tensor = torch_outputs[0] # Free the memory as soon as we can torch_outputs = None lengths = list(layer_inputs.input_len) tokvecs: List[Floats2d] = model.ops.unpad(torch2xp(torch_tokvecs), lengths) # Remove the BOS and EOS markers. tokvecs = [arr[1:-1] for arr in tokvecs] def backprop(d_tokvecs: List[Floats2d]) -> ArgsKwargs: # Restore entries for bos and eos markers. shim = model.shims[0] row = model.ops.alloc2f(1, d_tokvecs[0].shape[1]) d_tokvecs = [model.ops.xp.vstack((row, arr, row)) for arr in d_tokvecs] return ArgsKwargs( args=(torch_tokvecs,), kwargs={ "grad_tensors": xp2torch(model.ops.pad(d_tokvecs, device=shim.device)) }, ) return tokvecs, backprop def evaluate_sequences( model, Xs: List[Floats2d], Ys: List[Floats2d], batch_size: int ) -> float: correct = 0.0 total = 0.0 for X, Y in model.ops.multibatch(batch_size, Xs, Ys): Yh = model.predict(X) for yh, y in zip(Yh, Y): correct += (y.argmax(axis=1) == yh.argmax(axis=1)).sum() total += y.shape[0] return float(correct / total) def minibatch_by_words(pairs, max_words): """Group pairs of sequences into minibatches under max_words in size, considering padding. The size of a padded batch is the length of its longest sequence multiplied by the number of elements in the batch. """ pairs = list(zip(*pairs)) pairs.sort(key=lambda xy: len(xy[0]), reverse=True) batch = [] for X, Y in pairs: batch.append((X, Y)) n_words = max(len(xy[0]) for xy in batch) * len(batch) if n_words >= max_words: # We went *over* the cap, so don't emit the batch with this # example -- move that example into the next one. yield batch[:-1] batch = [(X, Y)] if batch: yield batch if __name__ == "__main__": typer.run(main) thinc-9.0.0/examples/type_checking.py000066400000000000000000000026561461023342500176420ustar00rootroot00000000000000from typing import List from thinc.layers import Relu, Softmax, chain, reduce_max, concatenate from thinc.model import Model # Define Custom X/Y types MyModelX = List[List[float]] MyModelY = List[List[float]] model: Model[MyModelX, MyModelY] = chain( Relu(12), Relu(12, dropout=0.2), Softmax(), ) # ERROR: incompatible type "bool", expected "List[List[float]]" model(False) # ERROR: List item 0 has incompatible type "str"; expected "float" model.begin_update([["0"]]) # ERROR: incompatible type "bool", expected "List[List[float]]" model.predict(True) # This example should be run with mypy. This is an example of type-level checking # for network validity. # # We first define an invalid network. # It's invalid because reduce_max expects Array3d as input, while Relu produces # Array2d as output. chain has type-logic to verify input and output types # line up. # # You should see the error an error, # examples/howto/type_chain.py:10: error: Cannot infer type argument 2 of "chain" bad_model = chain(Relu(10), reduce_max(), Softmax()) concate_model = concatenate(Relu(10), reduce_max(), Relu(10), Relu(10)), reduce_max() concate_chain_model = chain( concatenate(Relu(10), reduce_max(), Relu(10), Relu(10)), reduce_max() ) # Now let's try it with a network that does work, just to be sure. good_model = chain(Relu(10), Relu(10), Softmax()) # Finally we can reveal_type on the good model, to see what it thinks. reveal_type(good_model) thinc-9.0.0/netlify.toml000066400000000000000000000001401461023342500151670ustar00rootroot00000000000000[build] base = "website" publish = "public" command = "npm run deploy" ignore = "false" thinc-9.0.0/pyproject.toml000066400000000000000000000005361461023342500155450ustar00rootroot00000000000000[build-system] requires = [ "setuptools", "cython>=0.25,<3.0", "murmurhash>=1.0.2,<1.1.0", "cymem>=2.0.2,<2.1.0", "preshed>=3.0.2,<3.1.0", "blis>=0.7.8,<0.8.0", "numpy>=1.15.0; python_version < '3.9'", "numpy>=1.25.0; python_version >= '3.9'", ] build-backend = "setuptools.build_meta" [tool.isort] profile = "black" thinc-9.0.0/requirements.txt000066400000000000000000000014511461023342500161120ustar00rootroot00000000000000# Explosion-provided dependencies murmurhash>=1.0.2,<1.1.0 cymem>=2.0.2,<2.1.0 preshed>=3.0.2,<3.1.0 blis>=0.7.8,<0.8.0 srsly>=2.4.0,<3.0.0 wasabi>=0.8.1,<1.2.0 catalogue>=2.0.4,<2.1.0 confection>=0.0.1,<1.0.0 ml_datasets>=0.2.0,<0.3.0; python_version < "3.11" # Third-party dependencies pydantic>=1.7.4,!=1.8,!=1.8.1,<3.0.0 numpy>=1.19.0 packaging>=20.0 # Development dependencies cython>=0.25.0,<3.0 hypothesis>=3.27.0,<6.72.2 pytest>=5.2.0,!=7.1.0 pytest-cov>=2.7.0,<5.0.0 coverage>=5.0.0,<8.0.0 mock>=2.0.0,<3.0.0 flake8>=3.5.0,<3.6.0 mypy>=1.5.0,<1.6.0; platform_machine != "aarch64" types-mock>=0.1.1 # Executing notebook tests ipykernel>=5.1.4,<5.2.0 nbconvert>=5.6.1,<6.2.0 nbformat>=5.0.4,<5.2.0 # Test to_disk/from_disk against pathlib.Path subclasses pathy>=0.3.5 black>=22.0,<23.0 isort>=5.0,<6.0 thinc-9.0.0/setup.cfg000066400000000000000000000072111461023342500144470ustar00rootroot00000000000000[metadata] description = A refreshing functional take on deep learning, compatible with your favorite libraries url = https://github.com/explosion/thinc author = Explosion author_email = contact@explosion.ai license = MIT long_description = file: README.md long_description_content_type = text/markdown classifiers = Development Status :: 5 - Production/Stable Environment :: Console Intended Audience :: Developers Intended Audience :: Science/Research License :: OSI Approved :: MIT License Operating System :: POSIX :: Linux Operating System :: MacOS :: MacOS X Operating System :: Microsoft :: Windows Programming Language :: Cython Programming Language :: Python :: 3 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 Topic :: Scientific/Engineering [options] zip_safe = false include_package_data = true python_requires = >=3.9 setup_requires = cython>=0.25,<3.0 numpy>=1.15.0 # We also need our Cython packages here to compile against cymem>=2.0.2,<2.1.0 preshed>=3.0.2,<3.1.0 murmurhash>=1.0.2,<1.1.0 blis>=0.7.8,<0.8.0 install_requires = # Explosion-provided dependencies blis>=0.7.8,<0.8.0 murmurhash>=1.0.2,<1.1.0 cymem>=2.0.2,<2.1.0 preshed>=3.0.2,<3.1.0 wasabi>=0.8.1,<1.2.0 srsly>=2.4.0,<3.0.0 catalogue>=2.0.4,<2.1.0 confection>=0.0.1,<1.0.0 # Third-party dependencies setuptools numpy>=1.19.0 pydantic>=1.7.4,!=1.8,!=1.8.1,<3.0.0 packaging>=20.0 [options.entry_points] pytest_randomly.random_seeder = thinc = thinc.api:fix_random_seed [options.extras_require] cuda = cupy>=5.0.0b4 cuda80 = cupy-cuda80>=5.0.0b4 cuda90 = cupy-cuda90>=5.0.0b4 cuda91 = cupy-cuda91>=5.0.0b4 cuda92 = cupy-cuda92>=5.0.0b4 cuda100 = cupy-cuda100>=5.0.0b4 cuda101 = cupy-cuda101>=5.0.0b4 cuda102 = cupy-cuda102>=5.0.0b4 cuda110 = cupy-cuda110>=5.0.0b4 cuda111 = cupy-cuda111>=5.0.0b4 cuda112 = cupy-cuda112>=5.0.0b4 cuda113 = cupy-cuda113>=5.0.0b4 cuda114 = cupy-cuda114>=5.0.0b4 cuda115 = cupy-cuda115>=5.0.0b4 cuda116 = cupy-cuda116>=5.0.0b4 cuda117 = cupy-cuda117>=5.0.0b4 cuda11x = cupy-cuda11x>=11.0.0 cuda12x = cupy-cuda12x>=11.5.0 cuda-autodetect = cupy-wheel>=11.0.0 datasets = ml_datasets>=0.2.0,<0.3.0 torch = torch>=1.6.0 tensorflow = tensorflow>=2.0.0,<2.6.0 mxnet = mxnet>=1.5.1,<1.6.0 [bdist_wheel] universal = false [sdist] formats = gztar [flake8] ignore = E203, E266, E501, E731, W503, E741 max-line-length = 80 select = B,C,E,F,W,T4,B9 exclude = thinc/__init__.py thinc/layers/__init__.py thinc/shims/__init__.py thinc/api.py thinc/types.py thinc/tests/mypy [tool:pytest] markers = slow [coverage:run] plugins = Cython.Coverage omit = **/tests/* thinc/types.py thinc/backends/cupy_ops.py thinc/backends/_custom_kernels.py thinc/backends/_cupy_allocators.py thinc/layers/staticvectors.py [coverage:report] show_missing = True exclude_lines = pragma: no cover # Don't complain about missing debug-only code: def __unicode__ def __repr__ if self\.debug # Don't complain if tests don't hit defensive assertion code: raise AssertionError raise NotImplementedError # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.: assert False [mypy] ignore_missing_imports = True no_implicit_optional = True plugins = pydantic.mypy, thinc.mypy [mypy-thinc.tests.*] implicit_reexport = True [mypy-thinc.tests.mypy.*] ignore_errors = True thinc-9.0.0/setup.py000066400000000000000000000066101461023342500143420ustar00rootroot00000000000000#!/usr/bin/env python import platform import sys from setuptools.command.build_ext import build_ext from sysconfig import get_path from setuptools import Extension, setup, find_packages from pathlib import Path import numpy from Cython.Build import cythonize from Cython.Compiler import Options # Preserve `__doc__` on functions and classes # http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#compiler-options Options.docstrings = True ACCELERATE = "thinc.backends._accelerate" APPLE_OPS = ["thinc.backends.apple_ops", ACCELERATE] PACKAGES = find_packages() MOD_NAMES = [ "thinc.backends.cblas", "thinc.backends.numpy_ops", "thinc.layers.sparselinear", "thinc.layers.premap_ids", ] + (APPLE_OPS if platform.system() == "Darwin" else []) COMPILE_OPTIONS = { "msvc": ["/Ox", "/EHsc"], "other": ["-O3", "-Wno-strict-prototypes", "-Wno-unused-function", "-std=c++11"], } COMPILER_DIRECTIVES = { "language_level": 3, "embedsignature": True, "annotation_typing": False, "profile": sys.version_info < (3, 12), } LINK_OPTIONS = {"msvc": [], "other": []} # By subclassing build_extensions we have the actual compiler that will be used # which is really known only after finalize_options # http://stackoverflow.com/questions/724664/python-distutils-how-to-get-a-compiler-that-is-going-to-be-used class build_ext_options: def build_options(self): if hasattr(self.compiler, "initialize"): self.compiler.initialize() self.compiler.platform = sys.platform[:6] for e in self.extensions: e.extra_compile_args = COMPILE_OPTIONS.get( self.compiler.compiler_type, COMPILE_OPTIONS["other"] ) e.extra_link_args = LINK_OPTIONS.get( self.compiler.compiler_type, LINK_OPTIONS["other"] ) class build_ext_subclass(build_ext, build_ext_options): def build_extensions(self): build_ext_options.build_options(self) build_ext.build_extensions(self) def clean(path): for path in path.glob("**/*"): if path.is_file() and path.suffix in (".so", ".cpp"): print(f"Deleting {path.name}") path.unlink() def setup_package(): root = Path(__file__).parent if len(sys.argv) > 1 and sys.argv[1] == "clean": return clean(root / "thinc") with (root / "thinc" / "about.py").open("r") as f: about = {} exec(f.read(), about) include_dirs = [numpy.get_include(), get_path("include")] ext_modules = [] for name in MOD_NAMES: mod_path = name.replace(".", "/") + ".pyx" if name == ACCELERATE: ext = Extension( name, [mod_path], language="c++", include_dirs=include_dirs, libraries=["blas"], ) else: ext = Extension(name, [mod_path], language="c++", include_dirs=include_dirs) ext_modules.append(ext) print("Cythonizing sources") ext_modules = cythonize( ext_modules, compiler_directives=COMPILER_DIRECTIVES, language_level=2 ) setup( name="thinc", packages=PACKAGES, version=about["__version__"], ext_modules=ext_modules, cmdclass={"build_ext": build_ext_subclass}, package_data={"": ["*.pyx", "*.pxd", "*.pxi", "*.cu", "*.hh"]}, ) if __name__ == "__main__": setup_package() thinc-9.0.0/thinc/000077500000000000000000000000001461023342500137325ustar00rootroot00000000000000thinc-9.0.0/thinc/__init__.pxd000066400000000000000000000000001461023342500161740ustar00rootroot00000000000000thinc-9.0.0/thinc/__init__.py000066400000000000000000000003251461023342500160430ustar00rootroot00000000000000# Necessary for some side-effects in Cython. Not sure I understand. import numpy from .about import __version__ from .config import registry # fmt: off __all__ = [ "registry", "__version__", ] # fmt: on thinc-9.0.0/thinc/about.py000066400000000000000000000000511461023342500154120ustar00rootroot00000000000000__version__ = "9.0.0" __release__ = True thinc-9.0.0/thinc/api.py000066400000000000000000000135701461023342500150630ustar00rootroot00000000000000from .backends import ( CupyOps, MPSOps, NumpyOps, Ops, get_current_ops, get_ops, set_current_ops, set_gpu_allocator, use_ops, use_pytorch_for_gpu_memory, use_tensorflow_for_gpu_memory, ) from .compat import enable_mxnet, enable_tensorflow, has_cupy from .config import Config, ConfigValidationError, registry from .initializers import ( configure_normal_init, glorot_uniform_init, normal_init, uniform_init, zero_init, ) from .layers import ( LSTM, CauchySimilarity, ClippedLinear, Dish, Dropout, Embed, Gelu, HardSigmoid, HardSwish, HardSwishMobilenet, HardTanh, HashEmbed, LayerNorm, Linear, Logistic, Maxout, Mish, MultiSoftmax, MXNetWrapper, ParametricAttention, ParametricAttention_v2, PyTorchLSTM, PyTorchRNNWrapper, PyTorchWrapper, PyTorchWrapper_v2, PyTorchWrapper_v3, Relu, ReluK, Sigmoid, Softmax, Softmax_v2, SparseLinear, SparseLinear_v2, Swish, TensorFlowWrapper, TorchScriptWrapper_v1, add, array_getitem, bidirectional, chain, clone, concatenate, expand_window, keras_subclass, list2array, list2padded, list2ragged, map_list, noop, padded2list, premap_ids, pytorch_to_torchscript_wrapper, ragged2list, reduce_first, reduce_last, reduce_max, reduce_mean, reduce_sum, remap_ids, remap_ids_v2, residual, resizable, siamese, sigmoid_activation, softmax_activation, strings2arrays, tuplify, uniqued, with_array, with_array2d, with_cpu, with_debug, with_flatten, with_flatten_v2, with_getitem, with_list, with_nvtx_range, with_padded, with_ragged, with_reshape, with_signpost_interval, ) from .loss import ( CategoricalCrossentropy, CosineDistance, L2Distance, SequenceCategoricalCrossentropy, ) from .model import ( Model, change_attr_values, deserialize_attr, serialize_attr, set_dropout_rate, wrap_model_recursive, ) from .optimizers import SGD, Adam, Optimizer, RAdam from .schedules import ( Schedule, compounding, constant, constant_then, cyclic_triangular, decaying, plateau, slanted_triangular, warmup_linear, ) from .shims import ( MXNetShim, PyTorchGradScaler, PyTorchShim, Shim, TensorFlowShim, TorchScriptShim, keras_model_fns, maybe_handshake_model, ) from .types import ArgsKwargs, Padded, Ragged, Unserializable from .util import ( DataValidationError, data_validation, fix_random_seed, get_array_module, get_torch_default_device, get_width, is_cupy_array, mxnet2xp, prefer_gpu, require_cpu, require_gpu, set_active_gpu, tensorflow2xp, to_categorical, to_numpy, torch2xp, xp2mxnet, xp2tensorflow, xp2torch, ) try: from .backends import AppleOps except ImportError: AppleOps = None # fmt: off __all__ = [ # .config "Config", "registry", "ConfigValidationError", # .initializers "normal_init", "uniform_init", "glorot_uniform_init", "zero_init", "configure_normal_init", # .loss "CategoricalCrossentropy", "L2Distance", "CosineDistance", "SequenceCategoricalCrossentropy", # .model "Model", "serialize_attr", "deserialize_attr", "set_dropout_rate", "change_attr_values", "wrap_model_recursive", # .shims "Shim", "PyTorchGradScaler", "PyTorchShim", "TensorFlowShim", "keras_model_fns", "MXNetShim", "TorchScriptShim", "maybe_handshake_model", # .optimizers "Adam", "RAdam", "SGD", "Optimizer", # .schedules "Schedule", "cyclic_triangular", "warmup_linear", "constant", "constant_then", "decaying", "slanted_triangular", "compounding", "plateau", # .types "Ragged", "Padded", "ArgsKwargs", "Unserializable", # .util "fix_random_seed", "is_cupy_array", "set_active_gpu", "prefer_gpu", "require_gpu", "require_cpu", "DataValidationError", "data_validation", "to_categorical", "get_width", "get_array_module", "to_numpy", "torch2xp", "xp2torch", "tensorflow2xp", "xp2tensorflow", "mxnet2xp", "xp2mxnet", "get_torch_default_device", # .compat "enable_mxnet", "enable_tensorflow", "has_cupy", # .backends "get_ops", "set_current_ops", "get_current_ops", "use_ops", "Ops", "AppleOps", "CupyOps", "MPSOps", "NumpyOps", "set_gpu_allocator", "use_pytorch_for_gpu_memory", "use_tensorflow_for_gpu_memory", # .layers "Dropout", "Embed", "expand_window", "HashEmbed", "LayerNorm", "Linear", "Maxout", "Mish", "MultiSoftmax", "Relu", "softmax_activation", "Softmax", "LSTM", "CauchySimilarity", "ParametricAttention", "Logistic", "resizable", "sigmoid_activation", "Sigmoid", "SparseLinear", "ClippedLinear", "ReluK", "HardTanh", "HardSigmoid", "Dish", "HardSwish", "HardSwishMobilenet", "Swish", "Gelu", "PyTorchWrapper", "PyTorchRNNWrapper", "PyTorchLSTM", "TensorFlowWrapper", "keras_subclass", "MXNetWrapper", "PyTorchWrapper_v2", "Softmax_v2", "PyTorchWrapper_v3", "SparseLinear_v2", "TorchScriptWrapper_v1", "ParametricAttention_v2", "add", "bidirectional", "chain", "clone", "concatenate", "noop", "residual", "uniqued", "siamese", "list2ragged", "ragged2list", "map_list", "with_array", "with_array2d", "with_padded", "with_list", "with_ragged", "with_flatten", "with_reshape", "with_getitem", "strings2arrays", "list2array", "list2ragged", "ragged2list", "list2padded", "padded2list", "remap_ids", "remap_ids_v2", "premap_ids", "array_getitem", "with_cpu", "with_debug", "with_nvtx_range", "with_signpost_interval", "tuplify", "with_flatten_v2", "pytorch_to_torchscript_wrapper", "reduce_first", "reduce_last", "reduce_max", "reduce_mean", "reduce_sum", ] # fmt: on thinc-9.0.0/thinc/backends/000077500000000000000000000000001461023342500155045ustar00rootroot00000000000000thinc-9.0.0/thinc/backends/__init__.pxd000066400000000000000000000000001461023342500177460ustar00rootroot00000000000000thinc-9.0.0/thinc/backends/__init__.py000066400000000000000000000123171461023342500176210ustar00rootroot00000000000000import contextlib import threading from contextvars import ContextVar from typing import Any, Callable, Dict, Optional, Type, cast from .. import registry from ..compat import cupy, has_cupy from ..util import ( assert_pytorch_installed, assert_tensorflow_installed, get_torch_default_device, is_cupy_array, require_cpu, ) from ._cupy_allocators import cupy_pytorch_allocator, cupy_tensorflow_allocator from ._param_server import ParamServer from .cupy_ops import CupyOps from .mps_ops import MPSOps from .numpy_ops import NumpyOps from .ops import Ops try: from .apple_ops import AppleOps except ImportError: AppleOps = None context_ops: ContextVar[Optional[Ops]] = ContextVar("context_ops", default=None) context_pools: ContextVar[dict] = ContextVar("context_pools", default={}) # Internal use of thread-local storage only for detecting cases where a Jupyter # notebook might not have preserved contextvars across cells. _GLOBAL_STATE = {"ops": None} # Thread-local state. _LOCAL_STATE = threading.local() def set_gpu_allocator(allocator: str) -> None: # pragma: no cover """Route GPU memory allocation via PyTorch or tensorflow. Raise an error if the given argument does not match either of the two. """ if allocator == "pytorch": use_pytorch_for_gpu_memory() elif allocator == "tensorflow": use_tensorflow_for_gpu_memory() else: raise ValueError( f"Invalid 'gpu_allocator' argument: '{allocator}'. Available allocators are: 'pytorch', 'tensorflow'" ) def use_pytorch_for_gpu_memory() -> None: # pragma: no cover """Route GPU memory allocation via PyTorch. This is recommended for using PyTorch and cupy together, as otherwise OOM errors can occur when there's available memory sitting in the other library's pool. We'd like to support routing Tensorflow memory allocation via PyTorch as well (or vice versa), but do not currently have an implementation for it. """ assert_pytorch_installed() if get_torch_default_device().type != "cuda": return pools = context_pools.get() if "pytorch" not in pools: pools["pytorch"] = cupy.cuda.MemoryPool(allocator=cupy_pytorch_allocator) cupy.cuda.set_allocator(pools["pytorch"].malloc) def use_tensorflow_for_gpu_memory() -> None: # pragma: no cover """Route GPU memory allocation via TensorFlow. This is recommended for using TensorFlow and cupy together, as otherwise OOM errors can occur when there's available memory sitting in the other library's pool. We'd like to support routing PyTorch memory allocation via Tensorflow as well (or vice versa), but do not currently have an implementation for it. """ assert_tensorflow_installed() pools = context_pools.get() if "tensorflow" not in pools: pools["tensorflow"] = cupy.cuda.MemoryPool(allocator=cupy_tensorflow_allocator) cupy.cuda.set_allocator(pools["tensorflow"].malloc) def _import_extra_cpu_backends(): try: from thinc_bigendian_ops import BigEndianOps except ImportError: pass def get_ops(name: str, **kwargs) -> Ops: """Get a backend object. The special name "cpu" returns the best available CPU backend.""" ops_by_name = {ops_cls.name: ops_cls for ops_cls in registry.ops.get_all().values()} # type: ignore cls: Optional[Callable[..., Ops]] = None if name == "cpu": _import_extra_cpu_backends() cls = ops_by_name.get("numpy") cls = ops_by_name.get("apple", cls) cls = ops_by_name.get("bigendian", cls) else: cls = ops_by_name.get(name) if cls is None: raise ValueError(f"Invalid backend: {name}") return cls(**kwargs) def get_array_ops(arr): """Return CupyOps for a cupy array, NumpyOps otherwise.""" if is_cupy_array(arr): return CupyOps() else: return NumpyOps() @contextlib.contextmanager def use_ops(name: str, **kwargs): """Change the backend to execute on for the scope of the block.""" current_ops = get_current_ops() set_current_ops(get_ops(name, **kwargs)) try: yield finally: set_current_ops(current_ops) def get_current_ops() -> Ops: """Get the current backend object.""" if context_ops.get() is None: require_cpu() return cast(Ops, context_ops.get()) def set_current_ops(ops: Ops) -> None: """Change the current backend object.""" context_ops.set(ops) _get_thread_state().ops = ops def contextvars_eq_thread_ops() -> bool: current_ops = context_ops.get() thread_ops = _get_thread_state().ops if type(current_ops) == type(thread_ops): return True return False def _get_thread_state() -> threading.local: """Get a thread-specific state variable that inherits from a global state when it's created.""" if not hasattr(_LOCAL_STATE, "initialized") or not _LOCAL_STATE.initialized: for name, value in _GLOBAL_STATE.items(): setattr(_LOCAL_STATE, name, value) _LOCAL_STATE.initialized = True return _LOCAL_STATE __all__ = [ "set_current_ops", "get_current_ops", "use_ops", "ParamServer", "Ops", "AppleOps", "CupyOps", "MPSOps", "NumpyOps", "has_cupy", ] thinc-9.0.0/thinc/backends/_accelerate.pxd000066400000000000000000000036701461023342500204560ustar00rootroot00000000000000cdef extern from "Accelerate/Accelerate.h": enum CBLAS_ORDER: CblasRowMajor, CblasColMajor enum CBLAS_TRANSPOSE: CblasNoTrans, CblasTrans, CblasConjTrans enum CBLAS_UPLO: CblasUpper, CblasLower enum CBLAS_DIAG: CblasNonUnit, CblasUnit enum CBLAS_SIDE: CblasLeft, CblasRight # BLAS level 1 routines void cblas_sswap(int M, float *x, int incX, float *y, int incY) nogil void cblas_sscal(int N, float alpha, float *x, int incX) nogil void cblas_scopy(int N, float *x, int incX, float *y, int incY) nogil void cblas_saxpy(int N, float alpha, float *x, int incX, float *y, int incY ) nogil float cblas_sdot(int N, float *x, int incX, float *y, int incY ) nogil float cblas_snrm2(int N, float *x, int incX) nogil float cblas_sasum(int N, float *x, int incX) nogil int cblas_isamax(int N, float *x, int incX) nogil # BLAS level 2 routines void cblas_sgemv(CBLAS_ORDER Order, CBLAS_TRANSPOSE TransA, int M, int N, float alpha, float *A, int lda, float *x, int incX, float beta, float *y, int incY) nogil void cblas_sger(CBLAS_ORDER Order, int M, int N, float alpha, float *x, int incX, float *y, int incY, float *A, int lda) nogil # BLAS level 3 routines void cblas_sgemm(CBLAS_ORDER Order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, int M, int N, int K, float alpha, float *A, int lda, float *B, int ldb, float beta, float *C, int ldc) nogil cdef void sgemm(bint TransA, bint TransB, int M, int N, int K, float alpha, const float* A, int lda, const float *B, int ldb, float beta, float* C, int ldc) nogil cdef void saxpy(int N, float alpha, const float* X, int incX, float *Y, int incY) nogil thinc-9.0.0/thinc/backends/_accelerate.pyx000066400000000000000000000036431461023342500205030ustar00rootroot00000000000000cimport numpy as np from libc.stdint cimport uintptr_t import numpy cpdef np.ndarray gemm(float[:, ::1] A, float[:, ::1] B, bint trans1=False, bint trans2=False, np.ndarray out=None): cdef int nM = A.shape[0] if not trans1 else A.shape[1] cdef int nK = A.shape[1] if not trans1 else A.shape[0] cdef int nK_b = B.shape[0] if not trans2 else B.shape[1] cdef int nN = B.shape[1] if not trans2 else B.shape[0] cdef float[:, ::1] C = out if out is None: out = numpy.empty((nM, nN), dtype="f") C = out else: if C.shape[0] != nM or C.shape[1] != nN: msg = "Shape mismatch for output matrix, was: (%d, %d), expected (%d, %d)" raise ValueError(msg % (C.shape[0], C.shape[1], nM, nN)) if nK != nK_b: msg = "Shape mismatch for gemm: (%d, %d), (%d, %d)" raise ValueError(msg % (nM, nK, nK_b, nN)) if nM == 0 or nK == 0 or nN == 0: return out cblas_sgemm( CblasRowMajor, CblasTrans if trans1 else CblasNoTrans, CblasTrans if trans2 else CblasNoTrans, nM, nN, nK, 1.0, &A[0, 0], A.shape[1], &B[0, 0], B.shape[1], 0.0, &C[0, 0], C.shape[1] ) return out cdef void sgemm(bint TransA, bint TransB, int M, int N, int K, float alpha, const float* A, int lda, const float *B, int ldb, float beta, float* C, int ldc) nogil: cblas_sgemm( CblasRowMajor, CblasTrans if TransA else CblasNoTrans, CblasTrans if TransB else CblasNoTrans, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc ) cdef void saxpy(int N, float alpha, const float* X, int incX, float *Y, int incY) nogil: cblas_saxpy(N, alpha, X, incX, Y, incY) thinc-9.0.0/thinc/backends/_cupy_allocators.py000066400000000000000000000042501461023342500214210ustar00rootroot00000000000000from typing import cast from ..compat import cupy, tensorflow, torch from ..types import ArrayXd from ..util import get_torch_default_device, tensorflow2xp def cupy_tensorflow_allocator(size_in_bytes: int): """Function that can be passed into cupy.cuda.set_allocator, to have cupy allocate memory via TensorFlow. This is important when using the two libraries together, as otherwise OOM errors can occur when there's available memory sitting in the other library's pool. """ size_in_bytes = max(1024, size_in_bytes) tensor = tensorflow.zeros((size_in_bytes // 4,), dtype=tensorflow.dtypes.float32) # type: ignore # We convert to cupy via dlpack, so that we can get a memory pointer. cupy_array = cast(ArrayXd, tensorflow2xp(tensor)) address = int(cupy_array.data) # cupy has a neat class to help us here. Otherwise it will try to free. memory = cupy.cuda.memory.UnownedMemory(address, size_in_bytes, cupy_array) # Now return a new memory pointer. return cupy.cuda.memory.MemoryPointer(memory, 0) def cupy_pytorch_allocator(size_in_bytes: int): device = get_torch_default_device() """Function that can be passed into cupy.cuda.set_allocator, to have cupy allocate memory via PyTorch. This is important when using the two libraries together, as otherwise OOM errors can occur when there's available memory sitting in the other library's pool. """ # Cupy was having trouble with very small allocations? size_in_bytes = max(1024, size_in_bytes) # We use pytorch's underlying FloatStorage type to avoid overhead from # creating a whole Tensor. # This turns out to be way faster than making FloatStorage? Maybe # a Python vs C++ thing I guess? torch_tensor = torch.zeros( (size_in_bytes // 4,), requires_grad=False, device=device ) # cupy has a neat class to help us here. Otherwise it will try to free. # I think this is a private API? It's not in the types. address = torch_tensor.data_ptr() # type: ignore memory = cupy.cuda.memory.UnownedMemory(address, size_in_bytes, torch_tensor) # Now return a new memory pointer. return cupy.cuda.memory.MemoryPointer(memory, 0) thinc-9.0.0/thinc/backends/_custom_kernels.cu000066400000000000000000000446061461023342500212430ustar00rootroot00000000000000// Use grid strided loops, described here: // https://devblogs.nvidia.com/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/ // This pattern ensures that all of the loop values are visited once, no matter // what grid parameters are used for the function. // We cannot include CUDA header for mathematical constants, since it requires // that the development headers of the CUDA toolkit are installed. template struct Constants {}; template <> struct Constants { static constexpr double INV_SQRT_2 = 0.7071067811865475; static constexpr double INV_SQRT_2PI = 0.3989422804014327; }; template <> struct Constants { static constexpr float INV_SQRT_2 = 0.70710677; static constexpr float INV_SQRT_2PI = 0.3989423; }; template __global__ void gather_add(U* out_bo, const U* table_to, const int* indices_bk, int T, int O, int B, int K) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int b = _loop_start; b < B; b += _loop_stride) { for (int k = 0; k < K; ++k) { int idx = indices_bk[b * K + k]; const U* table = table_to + idx * O; U* out = out_bo + b * O; for (int o = 0; o < O; ++o) { out[o] += table[o]; } } } } template __global__ void seq2col(T* output, const T* X, const int* lengths, int nW, int B, int I, int nL) { // Let's say nW is 1 (it usually is). Then we want to take: // 1a 1b 1c // 2a 2b 2c // 3a 3b 3c // And make // __ __ __ 1a 1b 1c 2a 2b 2c // 1a 1b 1c 2a 2b 2c 3a 3b 3c // 2a 2b 2c 3a 3b 3c __ __ __ // Where __ is padding. // Now let's say nW is 2. Then we want to take: // 1a 1b 1c // 2a 2b 2c // 3a 3b 3c // And make // __ __ __ __ __ __ 1a 1b 1c 2a 2b 2c 3a 3b 3c // __ __ __ 1a 1b 1c 2a 2b 2c 3a 3b 3c __ __ __ // 1a 1b 1c 2a 2b 2c 3a 3b 3c __ __ __ __ __ __ // * x_start=-6, x_end=9 : (0-2) * 3, (0+2+1) * 3 // * x_start=-3, x_end=13 : (1-2) * 3, (1+2+1) * 3 // * x_start=0, x_end=16 : (2-2) * 3, (2+2+1) * 3 // // If lengths > 1, then the sequence lengths dictate // the boundaries/padding rather than the begin/end // of X. int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; int nF = nW * 2 + 1; int seq = 0; int seq_start = 0; for (int b = _loop_start; b < B; b += _loop_stride) { // Find sequence sequence in which b lies. for (; seq < nL; ++seq) { if (b < seq_start + lengths[seq]) { break; } seq_start += lengths[seq]; } // Calculate the bounds of the sequence wherein b lies. int seq_end = seq_start + lengths[seq]; // Find the unconstrained window around b, which // may be out of the sequence bounds. int window_start = b - nW; int window_end = b + nW + 1; // Find the sequence-constrained window around b. int x_start = max(seq_start, window_start); int x_end = min(seq_end, window_end); int n_elems = x_end - x_start; // If the left window is cut short, we want to start by // the same amount in the output. int out_offset = x_start - window_start; for (int i = 0; i < n_elems * I; i++) { output[(b * I * nF) + (out_offset * I) + i] = X[(x_start * I) + i]; } } } template __global__ void pad(T* out, T const **seqs, int const *lengths, int stride, int N, int L) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < L * stride; i += _loop_stride) { for (int j = 0; j < N; ++j) { T const *seq = seqs[j]; if (i < lengths[j] * stride) { out[j * L * stride + i] = seq[i]; } else { out[j * L * stride + i] = T(); } } } } template __global__ void maxout(T* best, int* which, const T* cands, int B, int O, int P) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int bo = _loop_start; bo < B * O; bo += _loop_stride) { // Go to the candidates at the output we're working on const T* cands_bo = &cands[bo * P]; int best_idx = 0; T best_val = cands_bo[0]; for (int p = 1; p < P; ++p) { if (cands_bo[p] > best_val) { best_idx = p; best_val = cands_bo[p]; } } which[bo] = best_idx; best[bo] = best_val; } } template __global__ void clipped_linear(T* Y, const T* X, double slope, double offset, double min_val, double max_val, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T y = X[i] * slope + offset; Y[i] = min(max(y, min_val), max_val); } } template __global__ void dish(T* Y, const T* X, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; Y[i] = 0.5 * x * (x / sqrt(1 + x * x) + 1); } } template __global__ void gelu(T* Y, const T* X, double threshold, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; if (x >= threshold) { Y[i] = x; } else if (x <= -threshold) { Y[i] = 0.0; } else { T cdf = 0.5 * (1.0 + erf(Constants::INV_SQRT_2 * x)); Y[i] = x * cdf; } } } template __global__ void mish(T* Y, const T* X, double threshold, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; T one = 1.; for (int i = _loop_start; i < N; i += _loop_stride) { if (X[i] >= threshold) Y[i] = X[i]; else Y[i] = X[i] * tanh(log(one + exp(X[i]))); } } template __global__ void swish(T* Y, const T* X, double threshold, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { if (X[i] >= threshold) { Y[i] = X[i]; } else if (X[i] <= -threshold) { Y[i] = 0.0; } else { T logistic_cdf = 1.0 / (1.0 + exp(-X[i])); Y[i] = X[i] * logistic_cdf; } } } template __global__ void reduce_sum(U* output, const U* X, const int* lengths, int B, int T, int O) { // Compute sums of a batch of concatenated sequences int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int b = _loop_start; b < B; b += _loop_stride) { // Go to the regions we're working on U* output_b = &output[b*O]; // Find the sequence item we're working on int t = 0; for (int i=0; i < b; ++i) { t += lengths[i]; } int length = lengths[b]; // Each invocation of the kernel sums one batch. for (int i=0; i < length; ++i) // Iterate over rows { const U* X_t = &X[(t+i)*O]; for (int j=0; j < O; ++j) { output_b[j] += X_t[j]; } } } } template __global__ void reduce_max(U* maxes, int* which, const U* X, const int* lengths, int B, int T, int O) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int b = _loop_start; b < B; b += _loop_stride) { // Go to the regions we're working on U* maxes_b = &maxes[b*O]; int* which_b = &which[b*O]; // Find the sequence item we're working on const U* X_t = X; for (int i=0; i < b; ++i) { X_t += lengths[i] * O; } // Each invocation of the kernel maxes one sequence. // Start by assuming maxes are the first element. for (int i=0; i < O; ++i) { maxes_b[i] = X_t[i]; which_b[i] = 0; } int length = lengths[b]; for (int i=1; i < length; ++i) // Iterate over rows { X_t += O; for (int j=0; j < O; ++j) { if (X_t[j] > maxes_b[j]) { maxes_b[j] = X_t[j]; which_b[j] = i; } } } } } template __global__ void backprop_seq2col(T* d_seqs, const T* d_cols, const int* lengths, int nW, int B, int I, int nL) { // Here's what we're doing, if we had 2d indexing. //for i in range(B): // d_seq[i] += d_cols[i-2, 4] // d_seq[i] += d_cols[i-1, 3] // d_seq[i] += d_cols[i, 2] // d_seq[i] += d_cols[i+1, 1] // d_seq[i] += d_cols[i+2, 0] int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; int nF = nW * 2 + 1; int seq = 0; int seq_start = 0; for (int b = _loop_start; b < B; b += _loop_stride) { // Find sequence offset in which b lies. // Fixme: do not restart offset search for every b. for (; seq < nL; ++seq) { if (b < seq_start + lengths[seq]) { break; } seq_start += lengths[seq]; } // Calculate the bounds of the sequence wherein b lies. int seq_end = seq_start + lengths[seq]; // Find the unconstrained window around b, which // may be out of the sequence bounds. int window_start = b - nW; int window_end = b + nW + 1; // Find the sequence-constrained window around b. int d_seqs_start = max(seq_start, window_start); int d_seqs_end = min(seq_end, window_end); // The here update proceeds differently than the other seq2col // implementations. We have to do all the updates for the b in this loop // iteration, otherwise we get data races due to parallelism in CUDA. // // A batch item b occurs, given nw=1, in: // // position 0 in b - 1 (if present) <- window_start // position 1 in b // position 2 in b + 1 (if present) <- window_end // // The following loop sums the gradients for those occurrences. // b_w loops over [b - 1, b, b + 1] and computes the position // of b within the column gradients of [b - 1 ... b + 1]. for (int b_w = d_seqs_start; b_w < d_seqs_end; ++b_w) { int position = (2 * nW) - (b_w - window_start); int start = (b_w * I * nF) + (position * I); for (int i = 0; i < I; ++i) { d_seqs[(b*I + i)] += d_cols[start + i]; } } } } template __global__ void backprop_clipped_linear(T* dX, const T* dY, const T* X, double slope, double offset, double min_val, double max_val, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; T low = (min_val - offset) / slope; T high = (max_val - offset) / slope; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; if (low < x && x < high) { dX[i] = dY[i] * slope; } else { dX[i] = 0; } } } template __global__ void backprop_hard_swish(T* dX, const T* dY, const T* X, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { if (X[i] > 2.5) { dX[i] = dY[i]; } else if (X[i] < -2.5) { dX[i] = 0; } else { dX[i] = dY[i] * (X[i] * 0.4 + 0.5); } } } template __global__ void backprop_hard_swish_mobilenet(T* dX, const T* dY, const T* X, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { if (X[i] > 3.0) { dX[i] = dY[i]; } else if (X[i] < -3.0) { dX[i] = 0; } else { dX[i] = dY[i] * ((X[i] * 2.0 + 3.0) / 6.0); } } } template __global__ void backprop_dish(T* dX, const T* dY, const T* X, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; T x_sq = x * x; T x_sq_plus_one = x_sq + 1.0; dX[i] = dY[i] * (x/sqrt(x_sq_plus_one) - (0.5 * x * x_sq) / pow(x_sq_plus_one, static_cast(1.5)) + 0.5); } } template __global__ void backprop_gelu(T* dX, const T* dY, const T* X, double threshold, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; if (x >= threshold) { dX[i] = dY[i]; } else if (x <= -threshold) { dX[i] = 0.0; } else { T cdf = 0.5 * (1.0 + erf(Constants::INV_SQRT_2 * x)); T pdf = Constants::INV_SQRT_2PI * exp(-0.5 * x * x); dX[i] = dY[i] * (cdf + x * pdf); } } } template __global__ void backprop_maxout(T* dX, const T* dY, const int* which, int B, int O, int P) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int b = _loop_start; b < B; b += _loop_stride) { // Go to the regions we're working on T* dX_b = &dX[b*O*P]; const T* dY_b = &dY[b*O]; const int* which_b = &which[b*O]; for (int i=0; i < O; ++i) dX_b[(i*P)+which_b[i]] = dY_b[i]; } } template __global__ void backprop_mish(T* dX, const T* dY, const T* X, double threshold, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; if (x >= threshold) { dX[i] = dY[i]; } else { T exp_x = exp(x); T exp_2x = exp(2*x); T exp_3x = exp(3*x); T omega = (4. * (x+1)) + (4 * exp_2x) + exp_3x + exp_x * (4.*x+6); T delta = 2 * exp_x + exp_2x + 2; dX[i] = dY[i] * ((exp_x * omega) / (delta * delta)); } } } template __global__ void backprop_swish(T* dX, const T* dY, const T* X, const T* Y, double threshold, int N) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < N; i += _loop_stride) { T x = X[i]; T y = Y[i]; if (x >= threshold) { dX[i] = dY[i]; } else if (x <= -threshold) { dX[i] = 0.0; } else { T cdf = 1.0 / (1 + exp(-x)); T d = y + cdf * (1 - y); dX[i] = dY[i] * d; } } } template __global__ void backprop_reduce_sum(U* dX, const U* d_sum, const int* lengths, int B, int T, int O) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; int seq_start = 0; int b = 0; for (int t = _loop_start; t < T; t += _loop_stride) { // Find the sequence item we're working on while ((b < B) && (seq_start+lengths[b]) <= t) { seq_start += lengths[b]; b += 1; } if (lengths[b] == 0) continue; for (int i=0; i < O; ++i) { dX[t * O + i] = d_sum[b * O + i]; } } } template __global__ void backprop_reduce_mean(U* dX, const U* d_mean, const int* lengths, int B, int T, int O) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; int seq_start = 0; int b = 0; for (int t = _loop_start; t < T; t += _loop_stride) { // Find the sequence item we're working on while ((b < B) && (seq_start+lengths[b]) <= t) { seq_start += lengths[b]; b += 1; } if (lengths[b] == 0) continue; U* dX_t = &dX[t * O]; const U* d_mean_b = &d_mean[b * O]; int lengths_b = lengths[b]; for (int i=0; i < O; ++i) { dX_t[i] = d_mean_b[i] / lengths_b; } } } template __global__ void backprop_reduce_max(U* dX, const U* d_maxes, const int* which, const int* lengths, int B, int T, int O) { int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; int seq_start = 0; int b = 0; for (int t = _loop_start; t < T; t += _loop_stride) { // We're calculating the gradient of the unpooled sequences, from // the gradient of the maxes. In this loop, we're getting the gradient // of a single sequence item, t. We need to know the sequence index, // b. while ((b < B) && (seq_start+lengths[b]) <= t) { seq_start += lengths[b]; b += 1; } if (lengths[b] == 0) continue; // The "which" array tells us which rows were selected as the max. // So we need to find the index of our t in the sequence. int index_of_t = t-seq_start; // Get the rows we're dealing with, to avoid cluttering the loop // with the index math. U* dX_t = &dX[t*O]; const U* d_maxes_b = &d_maxes[b*O]; const int* which_b = &which[b*O]; // Now loop over our row. for (int i=0; i < O; ++i) { // If we used the value for this cell, // pass the gradient if (which_b[i] == index_of_t) dX_t[i] = d_maxes_b[i]; } } } thinc-9.0.0/thinc/backends/_custom_kernels.py000066400000000000000000000614321461023342500212600ustar00rootroot00000000000000import operator import re from collections import defaultdict from functools import reduce from pathlib import Path from typing import Callable, Optional, Tuple import numpy from ..compat import cupy, has_cupy_gpu PWD = Path(__file__).parent KERNELS_SRC = (PWD / "_custom_kernels.cu").read_text(encoding="utf8") KERNELS_LIST = [ "backprop_clipped_linear", "backprop_clipped_linear", "backprop_dish", "backprop_dish", "backprop_gelu", "backprop_gelu", "backprop_hard_swish", "backprop_hard_swish", "backprop_hard_swish_mobilenet", "backprop_hard_swish_mobilenet", "backprop_maxout", "backprop_maxout", "backprop_mish", "backprop_mish", "backprop_reduce_max", "backprop_reduce_max", "backprop_reduce_mean", "backprop_reduce_mean", "backprop_reduce_sum", "backprop_reduce_sum", "backprop_seq2col", "backprop_seq2col", "backprop_swish", "backprop_swish", "clipped_linear", "clipped_linear", "dish", "dish", "gather_add", "gather_add", "gelu", "gelu", "maxout", "maxout", "mish", "mish", "pad", "pad", "pad", "pad", "reduce_max", "reduce_max", "reduce_sum", "reduce_sum", "seq2col", "seq2col", "swish", "swish", ] KERNELS = ( cupy.RawModule( code=KERNELS_SRC, options=("--std=c++11",), name_expressions=KERNELS_LIST ) if has_cupy_gpu else None ) class LazyKernel: """Wraps around `cupy.RawModule` and `cupy.RawKernel` to verify CuPy availability and lazily compile the latter on first invocation. The default CuPy behaviour triggers the compilation as soon as the `cupy.RawKernel` object is accessed.""" name: str _kernel: Optional["cupy.RawKernel"] _compile_callback: Optional[Callable[[], "cupy.RawKernel"]] __slots__ = ["name", "_kernel", "_compile_callback"] def __init__( self, name: str, *, compile_callback: Optional[Callable[[], "cupy.RawKernel"]] = None, ) -> None: self.name = name self._kernel = None self._compile_callback = compile_callback def __call__(self, *args, **kwargs): self._compile_kernel() self._kernel(*args, **kwargs) def _compile_kernel(self): if self._kernel is not None: return if self._compile_callback is not None: self._kernel = self._compile_callback() elif KERNELS is not None: self._kernel = KERNELS.get_function(self.name) if self._kernel is None: raise ValueError(f"couldn't compile Cupy kernel '{self.name}'") def compile_mmh(): if not has_cupy_gpu: return None return cupy.RawKernel((PWD / "_murmur3.cu").read_text(encoding="utf8"), "hash_data") clipped_linear_kernel_float = LazyKernel("clipped_linear") clipped_linear_kernel_double = LazyKernel("clipped_linear") dish_kernel_float = LazyKernel("dish") dish_kernel_double = LazyKernel("dish") gather_add_kernel_float = LazyKernel("gather_add") gather_add_kernel_double = LazyKernel("gather_add") gelu_kernel_float = LazyKernel("gelu") gelu_kernel_double = LazyKernel("gelu") hash_data_kernel = LazyKernel("hash_data", compile_callback=compile_mmh) maxout_kernel_float = LazyKernel("maxout") maxout_kernel_double = LazyKernel("maxout") mish_kernel_float = LazyKernel("mish") mish_kernel_double = LazyKernel("mish") pad_kernel_float = LazyKernel("pad") pad_kernel_double = LazyKernel("pad") pad_kernel_int32 = LazyKernel("pad") pad_kernel_int64 = LazyKernel("pad") reduce_max_kernel_float = LazyKernel("reduce_max") reduce_max_kernel_double = LazyKernel("reduce_max") reduce_sum_kernel_float = LazyKernel("reduce_sum") reduce_sum_kernel_double = LazyKernel("reduce_sum") seq2col_kernel_float = LazyKernel("seq2col") seq2col_kernel_double = LazyKernel("seq2col") swish_kernel_float = LazyKernel("swish") swish_kernel_double = LazyKernel("swish") backprop_clipped_linear_kernel_double = LazyKernel("backprop_clipped_linear") backprop_clipped_linear_kernel_float = LazyKernel("backprop_clipped_linear") backprop_dish_kernel_double = LazyKernel("backprop_dish") backprop_dish_kernel_float = LazyKernel("backprop_dish") backprop_gelu_kernel_double = LazyKernel("backprop_gelu") backprop_gelu_kernel_float = LazyKernel("backprop_gelu") backprop_hard_swish_kernel_double = LazyKernel("backprop_hard_swish") backprop_hard_swish_kernel_float = LazyKernel("backprop_hard_swish") backprop_hard_swish_mobilenet_kernel_double = LazyKernel( "backprop_hard_swish_mobilenet" ) backprop_hard_swish_mobilenet_kernel_float = LazyKernel( "backprop_hard_swish_mobilenet" ) backprop_maxout_kernel_double = LazyKernel("backprop_maxout") backprop_maxout_kernel_float = LazyKernel("backprop_maxout") backprop_mish_kernel_double = LazyKernel("backprop_mish") backprop_mish_kernel_float = LazyKernel("backprop_mish") backprop_reduce_max_kernel_double = LazyKernel("backprop_reduce_max") backprop_reduce_max_kernel_float = LazyKernel("backprop_reduce_max") backprop_reduce_mean_kernel_double = LazyKernel("backprop_reduce_mean") backprop_reduce_mean_kernel_float = LazyKernel("backprop_reduce_mean") backprop_reduce_sum_kernel_double = LazyKernel("backprop_reduce_sum") backprop_reduce_sum_kernel_float = LazyKernel("backprop_reduce_sum") backprop_seq2col_kernel_double = LazyKernel("backprop_seq2col") backprop_seq2col_kernel_float = LazyKernel("backprop_seq2col") backprop_swish_kernel_double = LazyKernel("backprop_swish") backprop_swish_kernel_float = LazyKernel("backprop_swish") def _alloc(shape, dtype, *, zeros: bool = True): if zeros: return cupy.zeros(shape, dtype) else: return cupy.empty(shape, dtype) def _alloc_like(array, zeros: bool = True): if zeros: return cupy.zeros_like(array) else: return cupy.empty_like(array) def pad(seqs, round_to=1, *, threads_per_block=128, num_blocks=128): if round_to < 1: raise ValueError(f"Rounding for padding must at least be 1, was: {round_to}") for seq in seqs: _is_float_or_int_array(seq) seq_lens = [len(seq) for seq in seqs] max_seq_len = max(seq_lens) # Round the length to nearest bucket -- helps on GPU, to make similar # array sizes. max_seq_len += -max_seq_len % round_to seq_lens = cupy.array(seq_lens, dtype="int32") final_shape = (len(seqs), max_seq_len) + seqs[0].shape[1:] out = cupy.empty(final_shape, dtype=seqs[0].dtype) # Extract pointers from CuPy arrays, so that we can address # them in the CUDA kernel. ptrs = numpy.empty( ( len( seqs, ) ), "int64", ) for idx, seq in enumerate(seqs): ptrs[idx] = seq.data.ptr ptrs = cupy.array(ptrs) stride = reduce(operator.mul, seqs[0].shape[1:], 1) if out.dtype == "float32": pad_kernel_float( (num_blocks,), (threads_per_block,), (out, ptrs, seq_lens, stride, len(seqs), max_seq_len), ) elif out.dtype == "float64": pad_kernel_double( (num_blocks,), (threads_per_block,), (out, ptrs, seq_lens, stride, len(seqs), max_seq_len), ) elif out.dtype == "int32": pad_kernel_int32( (num_blocks,), (threads_per_block,), (out, ptrs, seq_lens, stride, len(seqs), max_seq_len), ) elif out.dtype == "int64": pad_kernel_int64( (num_blocks,), (threads_per_block,), (out, ptrs, seq_lens, stride, len(seqs), max_seq_len), ) return out def clipped_linear( X, *, inplace=False, slope=1.0, offset=0.0, min_val=0.0, max_val=1.0, threads_per_block=128, num_blocks=128, ): _is_float_array(X) out = X if not inplace: out = _alloc_like(X, zeros=False) if X.dtype == "float32": clipped_linear_kernel_float( (num_blocks,), (threads_per_block,), (out, X, slope, offset, min_val, max_val, X.size), ) else: clipped_linear_kernel_double( (num_blocks,), (threads_per_block,), (out, X, slope, offset, min_val, max_val, X.size), ) return out def gather_add(table, indices, *, threads_per_block=128, num_blocks=128): if table.ndim != 2: raise ValueError( f"gather_add expects table with dimensionality 2, was: {table.ndim}" ) if indices.ndim != 2: raise ValueError( f"gather_add expects indices with dimensionality 2, was: {indices.ndim}" ) _is_float_array(table) indices = indices.astype("int32") _check_indices(indices, table.shape[0]) B = indices.shape[0] K = indices.shape[1] T = table.shape[0] O = table.shape[1] out = _alloc((B, O), dtype=table.dtype, zeros=True) if table.dtype == "float32": gather_add_kernel_float( (num_blocks,), (threads_per_block,), (out, table, indices, T, O, B, K) ) else: gather_add_kernel_double( (num_blocks,), (threads_per_block,), (out, table, indices, T, O, B, K) ) return out def dish(X, *, inplace=False, threads_per_block=128, num_blocks=128): _is_float_array(X) out = X if not inplace: out = _alloc_like(X, zeros=False) if X.dtype == "float32": dish_kernel_float((num_blocks,), (threads_per_block,), (out, X, X.size)) else: dish_kernel_double((num_blocks,), (threads_per_block,), (out, X, X.size)) return out def gelu(X, *, inplace=False, threshold=6.0, threads_per_block=128, num_blocks=128): _is_float_array(X) out = X if not inplace: out = _alloc_like(X, zeros=False) if X.dtype == "float32": gelu_kernel_float( (num_blocks,), (threads_per_block,), (out, X, threshold, X.size) ) else: gelu_kernel_double( (num_blocks,), (threads_per_block,), (out, X, threshold, X.size) ) return out def check_seq2col_lengths(lengths, B): if lengths is None: lengths = cupy.array([B], dtype="int32") else: _check_lengths(lengths, B) return lengths def seq2col(seq, nW, *, lengths=None, threads_per_block=128, num_blocks=128): _is_float_array(seq) B = seq.shape[0] nF = nW * 2 + 1 I = seq.shape[1] lengths = check_seq2col_lengths(lengths, B) nL = lengths.shape[0] out = _alloc((B, I * nF), dtype=seq.dtype, zeros=True) if seq.size != 0 and lengths.size != 0: if seq.dtype == "float32": seq2col_kernel_float( (num_blocks,), (threads_per_block,), (out, seq, lengths, nW, B, I, nL) ) else: seq2col_kernel_double( (num_blocks,), (threads_per_block,), (out, seq, lengths, nW, B, I, nL) ) return out def maxout(X, *, threads_per_block=128, num_blocks=128): _is_float_array(X) B, I, P = X.shape out_shape = (B, I) best = _alloc(out_shape, dtype=X.dtype, zeros=False) which = _alloc(out_shape, dtype="i", zeros=False) if X.dtype == "float32": maxout_kernel_float( (num_blocks,), (threads_per_block,), (best, which, X, B, I, P) ) else: maxout_kernel_double( (num_blocks,), (threads_per_block,), (best, which, X, B, I, P) ) return best, which def mish(X, *, inplace=False, threshold=5, threads_per_block=128, num_blocks=128): _is_float_array(X) out = X if not inplace: out = _alloc_like(X, zeros=False) if X.dtype == "float32": mish_kernel_float( (num_blocks,), (threads_per_block,), (out, X, threshold, X.size) ) else: mish_kernel_double( (num_blocks,), (threads_per_block,), (out, X, threshold, X.size) ) return out def reduce_sum(X, lengths, *, threads_per_block=128, num_blocks=128): _is_float_array(X) B = len(lengths) T = X.shape[0] O = X.shape[1] _check_lengths(lengths, T) out = _alloc((B, O), dtype=X.dtype, zeros=True) if X.dtype == "float32": reduce_sum_kernel_float( (num_blocks,), (threads_per_block,), (out, X, lengths, B, T, O) ) else: reduce_sum_kernel_double( (num_blocks,), (threads_per_block,), (out, X, lengths, B, T, O) ) return out def reduce_mean(X, lengths, *, threads_per_block=128, num_blocks=128): _is_float_array(X) B = len(lengths) T = X.shape[0] O = X.shape[1] _check_lengths(lengths, T) out = _alloc((B, O), dtype=X.dtype, zeros=True) if X.dtype == "float32": reduce_sum_kernel_float( (num_blocks,), (threads_per_block,), (out, X, lengths, B, T, O) ) else: reduce_sum_kernel_double( (num_blocks,), (threads_per_block,), (out, X, lengths, B, T, O) ) # Avoid divide by zero out /= lengths.reshape((-1, 1)) + 1e-10 return out def reduce_max(X, lengths, *, threads_per_block=128, num_blocks=128): _is_float_array(X) B = len(lengths) T = X.shape[0] O = X.shape[1] _check_lengths(lengths, T, min_length=1) out_shape = (B, O) maxes = _alloc(out_shape, dtype=X.dtype, zeros=False) which = _alloc(out_shape, dtype="i", zeros=False) if X.dtype == "float32": reduce_max_kernel_float( (num_blocks,), (threads_per_block,), (maxes, which, X, lengths, B, T, O) ) else: reduce_max_kernel_double( (num_blocks,), (threads_per_block,), (maxes, which, X, lengths, B, T, O) ) return maxes, which def swish(X, *, inplace=False, threshold=17.0, threads_per_block=128, num_blocks=128): _is_float_array(X) out = X if not inplace: out = _alloc_like(X, zeros=False) if X.dtype == "float32": swish_kernel_float( (num_blocks,), (threads_per_block,), (out, X, threshold, X.size) ) else: swish_kernel_double( (num_blocks,), (threads_per_block,), (out, X, threshold, X.size) ) return out def backprop_seq2col(dY, nW, *, lengths=None, threads_per_block=128, num_blocks=128): _is_float_array(dY) B = dY.shape[0] nF = nW * 2 + 1 I = dY.shape[1] // nF lengths = check_seq2col_lengths(lengths, B) nL = lengths.shape[0] out = _alloc((B, I), dtype=dY.dtype, zeros=True) if dY.size != 0 and lengths.size != 0: if dY.dtype == "float32": backprop_seq2col_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, lengths, nW, B, I, nL) ) else: backprop_seq2col_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, lengths, nW, B, I, nL) ) return out def backprop_clipped_linear( dY, X, *, slope: float = 1.0, offset: float = 0.0, min_val: float = 0.0, max_val: float = 1.0, inplace: bool = False, threads_per_block=128, num_blocks=128, ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_clipped_linear_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, slope, offset, min_val, max_val, out.size), ) else: backprop_clipped_linear_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, slope, offset, min_val, max_val, out.size), ) return out def backprop_hard_swish( dY, X, *, inplace: bool = False, threads_per_block=128, num_blocks=128 ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_hard_swish_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, out.size) ) else: backprop_hard_swish_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, out.size) ) return out def backprop_hard_swish_mobilenet( dY, X, *, inplace: bool = False, threads_per_block=128, num_blocks=128 ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_hard_swish_mobilenet_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, out.size) ) else: backprop_hard_swish_mobilenet_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, out.size) ) return out def backprop_dish( dY, X, *, inplace: bool = False, threads_per_block=128, num_blocks=128, ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_dish_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, out.size) ) else: backprop_dish_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, out.size) ) return out def backprop_gelu( dY, X, *, inplace: bool = False, threshold=6.0, threads_per_block=128, num_blocks=128, ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_gelu_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, threshold, out.size) ) else: backprop_gelu_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, threshold, out.size) ) return out def backprop_maxout(dY, which, P, *, threads_per_block=128, num_blocks=128): _is_float_array(dY) B = dY.shape[0] I = dY.shape[1] out = _alloc((B, I, P), dtype=dY.dtype, zeros=True) _check_which_maxout(which, B, I, P) if dY.dtype == "float32": backprop_maxout_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, which, B, I, P) ) else: backprop_maxout_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, which, B, I, P) ) return out def backprop_mish( dY, X, *, inplace: bool = False, threshold=5, threads_per_block=128, num_blocks=128 ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_mish_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, threshold, dY.size) ) else: backprop_mish_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, threshold, dY.size) ) return out def backprop_reduce_sum(d_sums, lengths, *, threads_per_block=128, num_blocks=128): _is_float_array(d_sums) B = len(lengths) T = int(lengths.sum()) O = d_sums.shape[1] _check_lengths(lengths, T) out = _alloc((T, O), dtype=d_sums.dtype, zeros=False) if d_sums.dtype == "float32": backprop_reduce_sum_kernel_float( (num_blocks,), (threads_per_block,), (out, d_sums, lengths, B, T, O) ) else: backprop_reduce_sum_kernel_double( (num_blocks,), (threads_per_block,), (out, d_sums, lengths, B, T, O) ) return out def backprop_reduce_mean(d_means, lengths, *, threads_per_block=128, num_blocks=128): _is_float_array(d_means) B = len(lengths) T = int(lengths.sum()) O = d_means.shape[1] _check_lengths(lengths, T) out = _alloc((T, O), dtype=d_means.dtype, zeros=False) if d_means.dtype == "float32": backprop_reduce_mean_kernel_float( (num_blocks,), (threads_per_block,), (out, d_means, lengths, B, T, O) ) else: backprop_reduce_mean_kernel_double( (num_blocks,), (threads_per_block,), (out, d_means, lengths, B, T, O) ) return out def backprop_reduce_max( d_maxes, which, lengths, *, threads_per_block=128, num_blocks=128 ): _is_float_array(d_maxes) B = len(lengths) T = int(lengths.sum()) O = d_maxes.shape[1] _check_lengths(lengths, T, min_length=1) out = _alloc((T, O), dtype=d_maxes.dtype, zeros=True) _check_which_reduce_max(which, (B, O), lengths) if d_maxes.dtype == "float32": backprop_reduce_max_kernel_float( (num_blocks,), (threads_per_block,), (out, d_maxes, which, lengths, B, T, O) ) else: backprop_reduce_max_kernel_double( (num_blocks,), (threads_per_block,), (out, d_maxes, which, lengths, B, T, O) ) return out def backprop_swish( dY, X, Y, *, inplace=False, threshold=17.0, threads_per_block=128, num_blocks=128 ): _is_float_array(dY) _is_float_array(X, shape=dY.shape) _is_float_array(Y, shape=dY.shape) out = dY if not inplace: out = _alloc_like(dY, zeros=False) if dY.dtype == "float32": backprop_swish_kernel_float( (num_blocks,), (threads_per_block,), (out, dY, X, Y, threshold, out.size) ) else: backprop_swish_kernel_double( (num_blocks,), (threads_per_block,), (out, dY, X, Y, threshold, out.size) ) return out def hash(ids, seed, *, threads_per_block=128, num_blocks=128): out = _alloc((ids.shape[0], 4), dtype="uint32", zeros=True) # sizeof(uint32_t) * 4 out_size = 4 * 4 in_size = 8 # sizeof(uint64_t) # T = ids.shape[0] hash_data_kernel( (num_blocks,), (threads_per_block,), (out, ids, out_size, in_size, ids.shape[0], seed), ) return out def _is_float_array(out, *, shape: Optional[Tuple] = None): assert out.dtype in ( "float32", "float64", ), "CUDA kernel can only handle float32 and float64" if shape is not None and out.shape != shape: msg = f"array has incorrect shape, expected: {shape}, was: {out.shape}" raise ValueError(msg) def _is_float_or_int_array(out, *, shape: Optional[Tuple] = None): assert out.dtype in ( "float32", "float64", "int32", "int64", ), "CUDA kernel can only handle float32, float64, int32 and int64" if shape is not None and out.shape != shape: msg = f"array has incorrect shape, expected: {shape}, was: {out.shape}" raise ValueError(msg) def _check_lengths(lengths, n_elems: int, *, min_length=0): assert lengths.dtype == "int32", "lengths should be encoded as 32-bit integers" if not cupy.all(lengths >= min_length): raise ValueError(f"all sequence lengths must be >= {min_length}") if cupy.sum(lengths) != n_elems: raise IndexError("lengths must sum up to the batch size") def _check_indices(indices, n: int): assert indices.dtype == "int32", "indices should be encoded as 32-bit integers" if not _values_within_range(indices, 0, n): raise IndexError(f"index out of bounds, must be >= 0 && < {n}") def _check_which_maxout(which, B: int, I: int, P: int): shape = (B, I) msg = "maximum index (which) should be encoded as 32-bit integers" assert which.dtype == "int32", msg if which.shape != shape: msg = f"maximum index (which) has incorrect shape, expected: {shape}, was: {which.shape}" raise ValueError(msg) if not _values_within_range(which, 0, P): raise IndexError("maximum index (which) value out of bounds") _values_within_range = ( cupy.ReductionKernel( "T x, T lower, T upper", "bool r", "x >= lower && x < upper", "a & b", "r = a", "true", "within_range", ) if has_cupy_gpu else None ) def _check_which_reduce_max(which, shape: Tuple, lengths): msg = "maximum index (which) should be encoded as 32-bit integers" assert which.dtype == "int32", msg if which.shape != shape: msg = f"maximum index (which) has incorrect shape, expected: {shape}, was: {which.shape}" raise ValueError(msg) if not cupy.all((which >= 0) & (which < cupy.expand_dims(lengths, -1))): raise IndexError("maximum index (which) value out of bounds") thinc-9.0.0/thinc/backends/_murmur3.cu000066400000000000000000000121321461023342500176050ustar00rootroot00000000000000//----------------------------------------------------------------------------- // MurmurHash3 was written by Austin Appleby, and is placed in the public // domain. The author hereby disclaims copyright to this source code. // Note - The x86 and x64 versions do _not_ produce the same results, as the // algorithms are optimized for their respective platforms. You can still // compile and run any of them on any platform, but your performance with the // non-native version will be less than optimal. /* * This version is taken from https://github.com/PeterScott/murmur3 * and modified to work with CUDA. */ // Including stdint.h is a pain in cupy, so just put the declarations in. // Beware that long int is not 64bit on all platforms! // e.g. Windows requires a 'long long' to get to 64 bit. typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef signed char int8_t; typedef int int32_t; const unsigned long int test_var = 0; const int size = sizeof(test_var); #if size == 64 typedef unsigned long int uint64_t; typedef long int int64_t; #else typedef unsigned long long uint64_t; typedef long long int64_t; #endif //----------------------------------------------------------------------------- // Platform-specific functions and macros #define FORCE_INLINE __device__ static inline FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r ) { return (x << r) | (x >> (64 - r)); } #define ROTL64(x,y) rotl64(x,y) #define BIG_CONSTANT(x) (x##LLU) //----------------------------------------------------------------------------- // Block read - if your platform needs to do endian-swapping or can only // handle aligned reads, do the conversion here #define getblock(p, i) (p[i]) //----------------------------------------------------------------------------- // Finalization mix - force all bits of a hash block to avalanche __device__ static inline FORCE_INLINE uint32_t fmix32 ( uint32_t h ) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } //---------- __device__ static inline FORCE_INLINE uint64_t fmix64 ( uint64_t k ) { k ^= k >> 33; k *= BIG_CONSTANT(0xff51afd7ed558ccd); k ^= k >> 33; k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); k ^= k >> 33; return k; } //----------------------------------------------------------------------------- __device__ void MurmurHash3_x64_128 ( const void * key, const int len, const uint32_t seed, void * out ) { const uint8_t * data = (const uint8_t*)key; const int nblocks = len / 16; int i; uint64_t h1 = seed; uint64_t h2 = seed; uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); //---------- // body const uint64_t * blocks = (const uint64_t *)(data); for(i = 0; i < nblocks; i++) { uint64_t k1 = getblock(blocks,i*2+0); uint64_t k2 = getblock(blocks,i*2+1); k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; } //---------- // tail const uint8_t * tail = (const uint8_t*)(data + nblocks*16); uint64_t k1 = 0; uint64_t k2 = 0; switch(len & 15) { case 15: k2 ^= (uint64_t)(tail[14]) << 48; case 14: k2 ^= (uint64_t)(tail[13]) << 40; case 13: k2 ^= (uint64_t)(tail[12]) << 32; case 12: k2 ^= (uint64_t)(tail[11]) << 24; case 11: k2 ^= (uint64_t)(tail[10]) << 16; case 10: k2 ^= (uint64_t)(tail[ 9]) << 8; case 9: k2 ^= (uint64_t)(tail[ 8]) << 0; k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; case 8: k1 ^= (uint64_t)(tail[ 7]) << 56; case 7: k1 ^= (uint64_t)(tail[ 6]) << 48; case 6: k1 ^= (uint64_t)(tail[ 5]) << 40; case 5: k1 ^= (uint64_t)(tail[ 4]) << 32; case 4: k1 ^= (uint64_t)(tail[ 3]) << 24; case 3: k1 ^= (uint64_t)(tail[ 2]) << 16; case 2: k1 ^= (uint64_t)(tail[ 1]) << 8; case 1: k1 ^= (uint64_t)(tail[ 0]) << 0; k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; }; //---------- // finalization h1 ^= len; h2 ^= len; h1 += h2; h2 += h1; h1 = fmix64(h1); h2 = fmix64(h2); h1 += h2; h2 += h1; ((uint64_t*)out)[0] = h1; ((uint64_t*)out)[1] = h2; } //----------------------------------------------------------------------------- // Write a stream of hash values for an input stream. Each output may have up to 128 bits // of entropy. Input size should be specified in bytes. extern "C" __global__ void hash_data(char* dest, const char* src, size_t out_size, size_t in_size, size_t n_items, uint32_t seed) { char entropy[16]; // 128/8=16 int _loop_start = blockIdx.x * blockDim.x + threadIdx.x; int _loop_stride = blockDim.x * gridDim.x; for (int i = _loop_start; i < n_items; i += _loop_stride) { const char* src_i = &src[i*in_size]; char* dest_i = &dest[i*out_size]; MurmurHash3_x64_128(src_i, in_size, seed, entropy); for (int j=0; j < out_size; ++j) dest_i[j] = entropy[j]; } } thinc-9.0.0/thinc/backends/_param_server.py000066400000000000000000000052641461023342500207120ustar00rootroot00000000000000from typing import Any, Dict, Optional, Tuple from ..types import FloatsXd from ..util import get_array_module KeyT = Tuple[int, str] class ParamServer: """Serve parameters for a single process.""" _params: Dict[KeyT, FloatsXd] = {} _grads: Dict[KeyT, FloatsXd] = {} proxy: Optional[Any] def __init__( self, params: Dict[KeyT, FloatsXd] = {}, grads: Dict[KeyT, FloatsXd] = {}, *, proxy=None ): self._params = dict(params) self._grads = dict(grads) # Allow a 'proxy' to be provided to support remote parameters. This # is experimental, it's the mechanism we use in the Ray integration. self.proxy = proxy @property def param_keys(self) -> Tuple[KeyT, ...]: """Get the names of registered parameter (including unset).""" return tuple(self._params.keys()) @property def grad_keys(self) -> Tuple[KeyT, ...]: return tuple([key for key in self.param_keys if self.has_grad(*key)]) def has_param(self, model_id: int, name: str) -> bool: return (model_id, name) in self._params def has_grad(self, model_id: int, name: str) -> bool: return (model_id, name) in self._grads def get_param(self, model_id: int, name: str) -> FloatsXd: key = (model_id, name) if self.proxy is not None: self._params[key] = self.proxy.get_param(model_id, name) return self._params[key] def get_grad(self, model_id: int, name: str) -> FloatsXd: key = (model_id, name) return self._grads[key] def set_param(self, model_id: int, name: str, value: FloatsXd) -> None: if self.proxy is not None: self.proxy.set_param(model_id, name, value) self._params[(model_id, name)] = value def set_grad(self, model_id: int, name: str, value: FloatsXd) -> None: if self.proxy is not None: self.proxy.set_grad(model_id, name, value) else: self._grads[(model_id, name)] = value def inc_grad(self, model_id: int, name: str, value: FloatsXd) -> None: key = (model_id, name) if self.proxy is not None: self.proxy.inc_grad(model_id, name, value) elif not self.has_grad(model_id, name): # pragma: no cover if hasattr(value, "copy"): # Adjustment for Jax self._grads[key] = value.copy() elif not value.flags["C_CONTIGUOUS"]: xp = get_array_module(value) self._grads[(model_id, name)] = xp.ascontiguousarray(value) else: self._grads[(model_id, name)] = value else: self._grads[(model_id, name)] += value thinc-9.0.0/thinc/backends/apple_ops.pyx000066400000000000000000000017641461023342500202400ustar00rootroot00000000000000from typing import Optional import numpy from ._accelerate import gemm from ._accelerate cimport saxpy, sgemm from .cblas cimport CBlas, set_saxpy, set_sgemm from .. import registry from ..types import Floats2d from .numpy_ops import NumpyOps @registry.ops("AppleOps") class AppleOps(NumpyOps): """Thinc Ops class that calls into Apple's native libraries for some operations. Other operations fall back to numpy.""" name = "apple" xp = numpy def cblas(self) -> CBlas: cdef CBlas cblas = CBlas() set_saxpy(cblas, saxpy) set_sgemm(cblas, sgemm) return cblas def gemm( self, x: Floats2d, y: Floats2d, out: Optional[Floats2d] = None, trans1: bool = False, trans2: bool = False, ) -> Floats2d: """Perform General Matrix Multiplication (GeMM) and optionally store the result in the specified output variable. """ return gemm(x, y, out=out, trans1=trans1, trans2=trans2) thinc-9.0.0/thinc/backends/cblas.pxd000066400000000000000000000037521461023342500173140ustar00rootroot00000000000000from libcpp.memory cimport shared_ptr ctypedef void (*sgemm_ptr)(bint transA, bint transB, int M, int N, int K, float alpha, const float* A, int lda, const float* B, int ldb, float beta, float* C, int ldc) nogil ctypedef void (*dgemm_ptr)(bint transA, bint transB, int M, int N, int K, double alpha, const double* A, int lda, const double* B, int ldb, double beta, double* C, int ldc) nogil ctypedef void (*saxpy_ptr)(int N, float alpha, const float* X, int incX, float *Y, int incY) nogil ctypedef void (*daxpy_ptr)(int N, double alpha, const double* X, int incX, double *Y, int incY) nogil ctypedef void (*sscal_ptr)(int N, float alpha, float* X, int incX) nogil ctypedef void (*dscal_ptr)(int N, double alpha, double* X, int incX) nogil # Forward-declaration of the BlasFuncs struct. This struct must be opaque, so # that consumers of the CBlas class cannot become dependent on its size or # ordering. cdef struct BlasFuncs cdef class CBlas: cdef shared_ptr[BlasFuncs] ptr # Note: the following functions are intentionally standalone. If we make them # methods of CBlas, Cython will generate and use a vtable. This makes it # impossible to add new BLAS functions later without breaking the ABI. # # See https://github.com/explosion/thinc/pull/700 for more information. cdef daxpy_ptr daxpy(CBlas cblas) nogil cdef saxpy_ptr saxpy(CBlas cblas) nogil cdef sgemm_ptr sgemm(CBlas cblas) nogil cdef dgemm_ptr dgemm(CBlas cblas) nogil cdef sscal_ptr sscal(CBlas cblas) nogil cdef dscal_ptr dscal(CBlas cblas) nogil cdef void set_daxpy(CBlas cblas, daxpy_ptr daxpy) nogil cdef void set_saxpy(CBlas cblas, saxpy_ptr saxpy) nogil cdef void set_sgemm(CBlas cblas, sgemm_ptr sgemm) nogil cdef void set_dgemm(CBlas cblas, dgemm_ptr dgemm) nogil cdef void set_sscal(CBlas cblas, sscal_ptr sscal) nogil cdef void set_dscal(CBlas cblas, dscal_ptr dscal) nogil thinc-9.0.0/thinc/backends/cblas.pyx000066400000000000000000000040341461023342500173330ustar00rootroot00000000000000# cython: profile=False cimport blis.cy from cython.operator cimport dereference as deref from libcpp.memory cimport make_shared # Single- and double-precision wrappers for `blis.cy.scalv` cdef void blis_sscal(int N, float alpha, float* X, int incX) nogil: blis.cy.scalv(blis.cy.NO_CONJUGATE, N, alpha, X, incX) cdef void blis_dscal(int N, double alpha, double* X, int incX) nogil: blis.cy.scalv(blis.cy.NO_CONJUGATE, N, alpha, X, incX) cdef struct BlasFuncs: daxpy_ptr daxpy saxpy_ptr saxpy sgemm_ptr sgemm dgemm_ptr dgemm sscal_ptr sscal dscal_ptr dscal cdef class CBlas: __slots__ = [] def __init__(self): """Construct a CBlas instance set to use BLIS implementations of the supported BLAS functions.""" cdef BlasFuncs funcs funcs.daxpy = blis.cy.daxpy funcs.saxpy = blis.cy.saxpy funcs.sgemm = blis.cy.sgemm funcs.dgemm = blis.cy.dgemm funcs.sscal = blis_sscal funcs.dscal = blis_dscal self.ptr = make_shared[BlasFuncs](funcs) cdef daxpy_ptr daxpy(CBlas cblas) nogil: return deref(cblas.ptr).daxpy cdef saxpy_ptr saxpy(CBlas cblas) nogil: return deref(cblas.ptr).saxpy cdef sgemm_ptr sgemm(CBlas cblas) nogil: return deref(cblas.ptr).sgemm cdef dgemm_ptr dgemm(CBlas cblas) nogil: return deref(cblas.ptr).dgemm cdef sscal_ptr sscal(CBlas cblas) nogil: return deref(cblas.ptr).sscal cdef dscal_ptr dscal(CBlas cblas) nogil: return deref(cblas.ptr).dscal cdef void set_daxpy(CBlas cblas, daxpy_ptr daxpy) nogil: deref(cblas.ptr).daxpy = daxpy cdef void set_saxpy(CBlas cblas, saxpy_ptr saxpy) nogil: deref(cblas.ptr).saxpy = saxpy cdef void set_sgemm(CBlas cblas, sgemm_ptr sgemm) nogil: deref(cblas.ptr).sgemm = sgemm cdef void set_dgemm(CBlas cblas, dgemm_ptr dgemm) nogil: deref(cblas.ptr).dgemm = dgemm cdef void set_sscal(CBlas cblas, sscal_ptr sscal) nogil: deref(cblas.ptr).sscal = sscal cdef void set_dscal(CBlas cblas, dscal_ptr dscal) nogil: deref(cblas.ptr).dscal = dscal thinc-9.0.0/thinc/backends/cpu_kernels.hh000066400000000000000000000344111461023342500203420ustar00rootroot00000000000000#ifndef CPU_KERNELS_HH #define CPU_KERNELS_HH #include #include #include #include #include #include // Ideally we'd use an alias declaration for a generic definition of // *axpy. But Cython doesn't support alias declarations yet: // // https://github.com/cython/cython/issues/3272 // // template // using axpy = void (*)(int N, T alpha, const T* X, int incX, // T *Y, int incY); // // So, instead we'll do this the pre-C++11 way: template struct axpy { typedef void (*ptr)(int N, T alpha, const T* X, int incX, T *Y, int incY); }; // All elementwise functions, such as most activations, work in-place. template struct argmax_result { T max; L max_idx; }; template argmax_result argmax(T const *arr, L len) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); argmax_result r { arr[0], 0 }; for (L i = 1; i < len; ++i) { if (arr[i] > r.max) { r.max = arr[i]; r.max_idx = i; } } return r; } // The next two templates define argmax for a fixed number of elements. template argmax_result argmax(T a) { static_assert(std::is_floating_point::value, "Argument should be floating point"); argmax_result acc { a, 0 }; return acc; } template argmax_result argmax(T a, Args... args) { static_assert(std::is_floating_point::value, "Arguments should be floating point"); auto acc = argmax(args...); if (acc.max > a) { acc.max_idx += 1; } else { acc.max_idx = 0; acc.max = a; } return acc; } template void vec_add(A* X, const A* Y, A scale, L N) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (L i = 0; i < N; ++i) X[i] += scale * Y[i]; } template void cpu_maxout(A* best__bo, L* which__bo, const A* cands__bop, L B, L O, L P) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); // For small inputs, we use an unrolled argmax. if (P == 2) { for (int i = 0; i < B * O; ++i) { A const *input = cands__bop + i * P; auto r = argmax(input[0], input[1]); which__bo[i] = r.max_idx; best__bo[i] = r.max; } } else if (P == 3) { for (int i = 0; i < B * O; ++i) { A const *input = cands__bop + i * P; auto r = argmax(input[0], input[1], input[2]); which__bo[i] = r.max_idx; best__bo[i] = r.max; } } else { for (int i = 0; i < B * O; ++i) { auto r = argmax(cands__bop + i * P, P); which__bo[i] = r.max_idx; best__bo[i] = r.max; } } } template void cpu_backprop_maxout(A* dX__bop, const A* dX__bo, const L* which__bo, L B, L O, L P) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (L b = 0; b < B; ++b) { for (L o = 0; o < O; ++o) { if (*which__bo >= P) { throw std::out_of_range(std::string("index ") + std::to_string(*which__bo) + " is out of bounds for maxout with size " + std::to_string(P)); } dX__bop[*which__bo] = *dX__bo; dX__bop += P; dX__bo += 1; which__bo += 1; } } } template void cpu_reduce_max(A* maxes__bo, L* which__bo, const A* X__to, const L* lengths__b, L B, L T, L O) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (const L* length = lengths__b; length < lengths__b + B; ++length) { if (*length <= 0) throw std::invalid_argument(std::string("all sequence lengths must be > 0, was: ") + std::to_string(*length)); else if (*length > T) { throw std::out_of_range("lengths must sum up to the number of rows"); } T -= *length; std::memcpy(maxes__bo, X__to, O * sizeof(*maxes__bo)); X__to += O; for (L i = 1; i < *length; ++i) { for (L j = 0; j < O; ++j) { if (X__to[j] > maxes__bo[j]) { maxes__bo[j] = X__to[j]; which__bo[j] = i; } } X__to += O; } maxes__bo += O; which__bo += O; } } template void cpu_backprop_reduce_max(A* dX__to, const A* d_maxes__bo, const L* which__bo, const L* lengths__b, L B, L T, L O) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (const L* length = lengths__b; length < lengths__b + B; ++length) { for (L i = 0; i < O; ++i) { L item = which__bo[i]; if (item >= *length) { throw std::out_of_range(std::string("index ") + std::to_string(item) + " is out of bounds for maxout with length " + std::to_string(*length)); } dX__to[item * O + i] = d_maxes__bo[i]; } dX__to += *length * O; d_maxes__bo += O; which__bo += O; } } template void cpu_reduce_mean(A* means__bo, const A* X__to, const L* lengths__b, L B, L T, L O) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (const L* length = lengths__b; length < lengths__b + B; ++length) { if (*length < 0) { throw std::invalid_argument(std::string("all sequence lengths must be >= 0, was: ") + std::to_string(*length)); } else if (length == 0) { means__bo += O; continue; } else if (*length > T) { throw std::out_of_range("lengths must sum up to the number of rows"); } T -= *length; A scale = 1. / *length; for (L i = 0; i < *length; ++i) { vec_add(means__bo, X__to, scale, O); X__to += O; } means__bo += O; } } template void cpu_backprop_reduce_mean(A* dX__to, const A* d_means__bo, const L* lengths__b, L B, L T, L O) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (const L* length = lengths__b; length < lengths__b + B; ++length) { A scale = 1. / *length; for (L i = 0; i < *length; ++i) { vec_add(dX__to, d_means__bo, scale, O); dX__to += O; } d_means__bo += O; } } template void cpu_mish(A* Y, L N, A threshold) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (L i = 0; i < N; ++i) { if (Y[i] < threshold) { Y[i] *= std::tanh(std::log(1.0 + std::exp(Y[i]))); } } } template void cpu_backprop_mish(A* dX, const A* X, L N, A threshold) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (L i = 0; i < N; ++i) { A x = X[i]; if (x < threshold) { A exp_x = std::exp(x); A exp_2x = std::exp(2 * x); A exp_3x = std::exp(3 * x); A omega = (4. * (x + 1)) + (4 * exp_2x) + exp_3x + exp_x * (4. * x + 6); A delta = 2. * exp_x + exp_2x + 2.; dX[i] = dX[i] * ((exp_x * omega) / (delta * delta)); } } } template void cpu_reduce_sum(A* sums__bo, const A* X__to, const L* lengths__b, L B, L T, L O) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (const L* length = lengths__b; length < lengths__b + B; ++length) { if (*length < 0) { throw std::invalid_argument(std::string("all sequence lengths must be >= 0, was: ") + std::to_string(*length)); } else if (length == 0) { sums__bo += O; continue; } else if (*length > T) { throw std::out_of_range("lengths must sum up to the number of rows"); } T -= *length; for (L i = 0; i < *length; ++i) { vec_add(sums__bo, X__to, static_cast(1.0), O); X__to += O; } sums__bo += O; } } template void cpu_backprop_reduce_sum(A* dX__to, const A* d_sums__bo, const L* lengths__b, L B, L T, L O) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (const L* length = lengths__b; length < lengths__b + B; ++length) { for (L i = 0; i < *length; ++i) { vec_add(dX__to, d_sums__bo, static_cast(1.0), O); dX__to += O; } d_sums__bo += O; } } template void cpu_relu(A* X, L N) { static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); for (L i = 0; i < N; ++i) { if (X[i] <= 0.0) { X[i] = 0.0; } } } template void seq2col(A* output, const A* X, const L* lengths, L nW, L B, L I, L nL) { // Let's say nW is 1 (it usually is). Then we want to take: // 1a 1b 1c // 2a 2b 2c // 3a 3b 3c // And make // __ __ __ 1a 1b 1c 2a 2b 2c // 1a 1b 1c 2a 2b 2c 3a 3b 3c // 2a 2b 2c 3a 3b 3c __ __ __ // Where __ is padding. // Now let's say nW is 2. Then we want to take: // 1a 1b 1c // 2a 2b 2c // 3a 3b 3c // And make // __ __ __ __ __ __ 1a 1b 1c 2a 2b 2c 3a 3b 3c // __ __ __ 1a 1b 1c 2a 2b 2c 3a 3b 3c __ __ __ // 1a 1b 1c 2a 2b 2c 3a 3b 3c __ __ __ __ __ __ // * x_start=-6, x_end=9 : (0-2) * 3, (0+2+1) * 3 // * x_start=-3, x_end=13 : (1-2) * 3, (1+2+1) * 3 // * x_start=0, x_end=16 : (2-2) * 3, (2+2+1) * 3 // If lengths > 1, then the sequence lengths dictate // the boundaries/padding rather than the begin/end // of X. static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); L nF = nW * 2 + 1; L seq_start = 0; for (L i = 0; i < nL; ++i) { // Calculate the bounds of the next sequence. L seq_end = seq_start + lengths[i]; for (L j = seq_start; j < seq_end; ++j) { // Find the unconstrained window around b, which // may be out of the sequence bounds. L window_start = j - nW; L window_end = j + nW + 1; // Find the sequence-constrained window around b. L x_start = std::max(seq_start, window_start); L x_end = std::min(seq_end, window_end); L n_elems = x_end - x_start; L out_offset = x_start - window_start; std::memcpy(output + (j * nF * I) + (out_offset * I), X + (x_start * I), n_elems * I * sizeof(*output)); } seq_start += lengths[i]; } } template void backprop_seq2col(A* d_seqs, const A* d_cols, const L* lengths, L B, L I, L nW, L nL) { // here's what we're doing, if we had 2d indexing. // for i in range(b): // d_seq[i] += d_cols[i-2, 4] // d_seq[i] += d_cols[i-1, 3] // d_seq[i] += d_cols[i, 2] // d_seq[i] += d_cols[i+1, 1] // d_seq[i] += d_cols[i+2, 0] static_assert(std::is_floating_point::value, "Array should be floating point"); static_assert(std::is_integral::value, "Array length should be integral"); L nF = nW * 2 + 1; L seq_start = 0; for (L i = 0; i < nL; ++i) { // Calculate the bounds of the next sequence. L seq_end = seq_start + lengths[i]; for (L j = seq_start; j < seq_end; ++j) { // Find the unconstrained window around b, which // may be out of the sequence bounds. L window_begin = j - nW; L window_end = j + nW + 1; // Find the sequence-constrained window around b. L d_seqs_begin = std::max(seq_start, window_begin); L d_seqs_end = std::min(seq_end, window_end); L n_elems = d_seqs_end - d_seqs_begin; // If the left window is cut short, we want to // start by the same amount in the output. L out_offset = d_seqs_begin - window_begin; vec_add(d_seqs + d_seqs_begin * I, d_cols + (j * nF * I) + (out_offset * I), static_cast(1.), n_elems * I); } seq_start += lengths[i]; } } template void cpu_gather_add(typename axpy::ptr axpy, F* out_bo, const F* table_to, const I* indices_bk, L T, L O, L B, L K) { for (L b = 0; b < B; ++b) { for (L k = 0; k < K; ++k) { I idx = indices_bk[b * K + k]; if (idx > T) { throw std::out_of_range("Embedding index out-of-bounds"); } axpy(O, 1.0, table_to + idx * O, 1, out_bo + b * O, 1); } } } #endif // CPU_KERNELS_HH thinc-9.0.0/thinc/backends/cupy_ops.py000066400000000000000000000312261461023342500177230ustar00rootroot00000000000000import numpy from .. import registry from ..compat import cublas, cupy, cupyx from ..types import DeviceTypes from ..util import ( is_cupy_array, is_mxnet_gpu_array, is_tensorflow_gpu_array, is_torch_cuda_array, mxnet2xp, tensorflow2xp, torch2xp, ) from . import _custom_kernels from .numpy_ops import NumpyOps from .ops import Ops @registry.ops("CupyOps") class CupyOps(Ops): name = "cupy" xp = cupy _xp2 = cupyx def __init__( self, device_type: DeviceTypes = "gpu", device_id: int = 0, **kwargs ) -> None: self.device_type = device_type self.device_id = device_id def to_numpy(self, data, *, byte_order=None): if not isinstance(data, numpy.ndarray): data = data.get() if byte_order: dtype = data.dtype.newbyteorder(byte_order) data = numpy.asarray(data, dtype=dtype) return data def gather_add(self, table, indices): if table.dtype in ("float32", "float64"): return _custom_kernels.gather_add(table, indices) else: return super().gather_add(table, indices) def dish(self, X, inplace=False): if X.dtype in ("float32", "float64"): return _custom_kernels.dish(X, inplace=inplace) else: return super().dish(X, inplace=inplace) def backprop_dish(self, dY, X, inplace=False): if X.dtype == dY.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_dish(dY, X, inplace=inplace) else: return super().backprop_dish(dY, X, inplace=inplace) def gelu(self, X, inplace=False): if X.dtype in ("float32", "float64"): return _custom_kernels.gelu(X, inplace=inplace, threshold=6.0) else: return super().gelu(X, inplace=inplace) def backprop_gelu(self, dY, X, inplace=False): if X.dtype == dY.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_gelu(dY, X, inplace=inplace, threshold=6.0) else: return super().backprop_gelu(dY, X, inplace=inplace) def gemm(self, x, y, out=None, trans1=False, trans2=False): if isinstance(x, numpy.ndarray) or isinstance(y, numpy.ndarray): raise ValueError( "Encountered a numpy array when processing with cupy. " "Did you call model.ops.asarray on your data?" ) if trans1: x = x.T if trans2: y = y.T if out is None: return self.xp.dot(x, y) else: self.xp.dot(x, y, out=out) return out def asarray(self, data, dtype=None): # We'll try to perform a zero-copy conversion if possible. if is_cupy_array(data): array = self.xp.asarray(data, dtype=dtype) elif is_torch_cuda_array(data): array = torch2xp(data) elif is_tensorflow_gpu_array(data): array = tensorflow2xp(data) elif is_mxnet_gpu_array(data): array = mxnet2xp(data) else: array = self.xp.array(data, dtype=dtype) if dtype is not None: array = array.astype(dtype=dtype, copy=False) return array def pad(self, seqs, round_to=1): """Perform padding on a list of arrays so that they each have the same length, by taking the maximum dimension across each axis. This only works on non-empty sequences with the same `ndim` and `dtype`. """ # TODO: This should be generalized to handle different ranks if not seqs: raise ValueError("Cannot pad empty sequence") if len(set(seq.ndim for seq in seqs)) != 1: raise ValueError("Cannot pad sequences with different ndims") if len(set(seq.dtype for seq in seqs)) != 1: raise ValueError("Cannot pad sequences with different dtypes") if len(set(seq.shape[1:] for seq in seqs)) != 1: raise ValueError("Cannot pad sequences that differ on other dimensions") # Our CUDA kernel can currently only handle C contiguous arrays. if not all(seq.flags["C_CONTIGUOUS"] for seq in seqs) or seqs[0].dtype not in ( "float32", "float64", "int32", "int64", ): return super().pad(seqs, round_to) return _custom_kernels.pad(seqs, round_to) def maxout(self, X): if X.dtype in ("float32", "float64"): return _custom_kernels.maxout(X) else: return super().maxout(X) def backprop_maxout(self, dY, which, P): if dY.dtype in ("float32", "float64") and which.dtype == "int32": return _custom_kernels.backprop_maxout(dY, which, P) else: return super().backprop_maxout(dY, which, P) def relu(self, X, inplace=False): if not inplace: return X * (X > 0) else: X *= X > 0 return X def backprop_relu(self, dY, Y, inplace=False): if not inplace: return dY * (Y > 0) dY *= Y > 0 return dY def clipped_linear( self, X, slope: float = 1.0, offset: float = 0.0, min_val: float = 0.0, max_val: float = 1.0, inplace: bool = False, ): if X.dtype in ("float32", "float64"): return _custom_kernels.clipped_linear( X, inplace=inplace, slope=slope, offset=offset, min_val=min_val, max_val=max_val, ) else: return super().clipped_linear( X, inplace=inplace, slope=slope, offset=offset, min_val=min_val, max_val=max_val, ) def backprop_clipped_linear( self, dY, X, slope: float = 1.0, offset: float = 0.0, min_val: float = 0.0, max_val: float = 1.0, inplace: bool = False, ): if X.dtype == dY.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_clipped_linear( dY, X, slope=slope, offset=offset, min_val=min_val, max_val=max_val, inplace=inplace, ) else: return super().backprop_clipped_linear( dY=dY, X=X, slope=slope, offset=offset, min_val=min_val, max_val=max_val, inplace=inplace, ) def backprop_hard_swish(self, dY, X, inplace: bool = False): if X.dtype == dY.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_hard_swish(dY, X, inplace=inplace) else: return super().backprop_hard_swish(dY, X, inplace=inplace) def backprop_hard_swish_mobilenet(self, dY, X, inplace: bool = False): if X.dtype == dY.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_hard_swish_mobilenet(dY, X, inplace=inplace) else: return super().backprop_hard_swish_mobilenet(dY, X, inplace=inplace) def mish(self, X, threshold=20.0, inplace=False): if X.dtype in ("float32", "float64"): return _custom_kernels.mish(X, inplace=inplace, threshold=threshold) else: return super().mish(X, threshold, inplace) def backprop_mish(self, dY, X, threshold=20.0, inplace=False): if X.dtype == dY.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_mish( dY, X, inplace=inplace, threshold=threshold ) else: return super().backprop_mish(dY, X, threshold, inplace) def swish(self, X, inplace=False): if X.dtype in ("float32", "float64"): return _custom_kernels.swish(X, inplace=inplace, threshold=17.0) else: return super().swish(X, inplace=inplace) def backprop_swish(self, dY, X, Y, inplace=False): if X.dtype == dY.dtype == Y.dtype and X.dtype in ("float32", "float64"): return _custom_kernels.backprop_swish( dY, X, Y, inplace=inplace, threshold=17.0 ) else: return super().backprop_swish(dY, X, Y, inplace=inplace) def clip_gradient(self, gradient, threshold): # We do not use CuPy's linalg.norm, since it uses scalar reductions # using one CUDA block. This is a lot slower than the cuBLAS # implementation. def frobenius_norm(X): X_vec = X.reshape(-1) return cublas.nrm2(X_vec) grad_norm = cupy.maximum(frobenius_norm(gradient), 1e-12) gradient *= cupy.minimum(threshold, grad_norm) / grad_norm return gradient def seq2col(self, seq, nW, *, lengths=None): """Given an (M, N) sequence of vectors, return an (M, N*(nW*2+1)) sequence. The new sequence is constructed by concatenating nW preceding and succeeding vectors onto each column in the sequence, to extract a window of features. """ if seq.dtype in ("float32", "float64") and ( lengths is None or lengths.dtype == "int32" ): return _custom_kernels.seq2col(seq, nW, lengths=lengths) else: return super().seq2col(seq, nW, lengths=lengths) def backprop_seq2col(self, dY, nW, *, lengths=None): if dY.dtype in ("float32", "float64") and ( lengths is None or lengths.dtype == "int32" ): return _custom_kernels.backprop_seq2col(dY, nW, lengths=lengths) else: return super().backprop_seq2col(dY, nW, lengths=lengths) def reduce_mean(self, X, lengths): if X.dtype in ("float32", "float64") and lengths.dtype == "int32": return _custom_kernels.reduce_mean(X, lengths=lengths) else: super().reduce_mean(X, lengths) def backprop_reduce_mean(self, d_means, lengths): if d_means.dtype in ("float32", "float64") and lengths.dtype == "int32": return _custom_kernels.backprop_reduce_mean(d_means, lengths) else: super().backprop_reduce_mean(d_means, lengths) def reduce_max(self, X, lengths): if X.dtype in ("float32", "float64") and lengths.dtype == "int32": return _custom_kernels.reduce_max(X, lengths) else: super().reduce_max(X, lengths) def backprop_reduce_max(self, d_maxes, which, lengths): if ( d_maxes.dtype in ("float32", "float64") and which.dtype == "int32" and lengths.dtype == "int32" ): return _custom_kernels.backprop_reduce_max(d_maxes, which, lengths) else: super().backprop_reduce_max(d_maxes, which, lengths) def reduce_sum(self, X, lengths): if X.dtype in ("float32", "float64") and lengths.dtype == "int32": return _custom_kernels.reduce_sum(X, lengths) else: return super().reduce_sum(X, lengths) def backprop_reduce_sum(self, d_sums, lengths): if d_sums.dtype in ("float32", "float64") and lengths.dtype == "int32": return _custom_kernels.backprop_reduce_sum(d_sums, lengths) else: return super().backprop_reduce_sum(d_sums, lengths) def hash(self, ids, seed): return _custom_kernels.hash(ids, seed) def scatter_add(self, table, indices, values): self._xp2.scatter_add(table, indices, values) def adam( self, weights, gradient, mom1, mom2, beta1, beta2, eps, learn_rate, mod_rate=1.0 ): _check_compatible_shape(weights, gradient) _check_compatible_shape(weights, mom1) _check_compatible_shape(weights, mom2) adam_kernel( gradient, learn_rate, 1 - beta1, 1 - beta2, eps, weights, mom1, mom2 ) gradient.fill(0) return weights, gradient, mom1, mom2 def position_encode(self, N, D, period=10000, out=None): positions = NumpyOps().position_encode(N, D, period=period, out=out) return self.asarray(positions) if cupy is not None: adam_kernel = cupy.ElementwiseKernel( "T grad, T lr, T one_minus_beta1, T one_minus_beta2, T eps", "T param, T m, T v", """m += one_minus_beta1 * (grad - m); v += one_minus_beta2 * (grad * grad - v); param -= lr * m / (sqrt(v) + eps);""", "adam", ) else: adam_kernel = None def _check_compatible_shape(u, v): if u.shape != v.shape: msg = f"arrays have incompatible shapes: {u.shape} and {v.shape}" raise ValueError(msg) thinc-9.0.0/thinc/backends/mps_ops.py000066400000000000000000000011741461023342500175410ustar00rootroot00000000000000from typing import TYPE_CHECKING import numpy from .. import registry from ..compat import has_apple_ops from .numpy_ops import NumpyOps from .ops import Ops if TYPE_CHECKING: # Type checking does not work with dynamic base classes, since MyPy cannot # determine against which base class to check. So, always derive from Ops # during type checking. _Ops = Ops else: if has_apple_ops: from .apple_ops import AppleOps _Ops = AppleOps else: _Ops = NumpyOps @registry.ops("MPSOps") class MPSOps(_Ops): """Ops class for Metal Performance shaders.""" name = "mps" xp = numpy thinc-9.0.0/thinc/backends/numpy_ops.pxd000066400000000000000000000037051461023342500202570ustar00rootroot00000000000000from .cblas cimport saxpy_ptr ctypedef double[:, ::1] double2d_t ctypedef double[:, :, ::1] double3d_t ctypedef float[:, ::1] float2d_t ctypedef float[:, :, ::1] float3d_t ctypedef int[:, ::1] int2d_t ctypedef unsigned int[:, ::1] uint2d_t cdef fused ints2d_ft: int2d_t uint2d_t cdef fused reals2d_ft: float2d_t double2d_t cdef fused reals3d_ft: float3d_t double3d_t cdef extern from "cpu_kernels.hh": cdef cppclass axpy[T]: ctypedef void (*ptr)(int N, T alpha, const T* X, int incX, T *Y, int incY); void cpu_maxout[A, L](A* best__bo, L* which__bo, const A* cands_bop, L B, L O, L P) void cpu_backprop_maxout[A, L](A* dX__bop, const A* dX__bo, const L* which__bo, L B, L O, L P) except + void cpu_reduce_max[A, L](A* maxes__bo, L* which_bo, const A* X__to, const L* lengths__b, L B, L T, L O) except + void cpu_backprop_reduce_max[A, L](A* dX__to, const A* d_maxes__bo, const L* which__bo, const L* lengths__b, L B, L T, L O) except + void cpu_reduce_mean[A, L](A* means__bo, const A* X__to, const L* lengths__b, L B, L T, L O) except + void cpu_backprop_reduce_mean[A, L](A* dX__to, const A* d_means__bo, const L* lengths__b, L B, L T, L O) void cpu_mish[A, L](A* Y, L N, A threshold) void cpu_backprop_mish[A, L](A* dX, const A* X, L N, A threshold) void cpu_reduce_sum[A, L](A* sums__bo, const A* X__to, const L* lengths__b, L B, L T, L O) except + void cpu_backprop_reduce_sum[A, L](A* dX__to, const A* d_sums__bo, const L* lengths__b, L B, L T, L O) void cpu_relu[A, L](A* X, L N) void backprop_seq2col[A, L](A* d_seqs, const A* d_cols, const L* lengths, L B, L I, L nW, L nL) void seq2col[A, L](A* output, const A* X, const L* lengths, L nW, L B, L I, L nL) void cpu_gather_add[F, I, L](axpy[F].ptr axpy, F* out_bo, const F* table_to, const I* indices_bk, L T, L O, L B, L K) except + thinc-9.0.0/thinc/backends/numpy_ops.pyx000066400000000000000000001125561461023342500203110ustar00rootroot00000000000000# cython: cdivision=True # cython: infer_types=True from collections.abc import Sized from typing import Optional import numpy cimport cython cimport numpy as np from cymem.cymem cimport Pool from libc.math cimport isnan from libc.stdint cimport uint32_t, uint64_t from libc.stdlib cimport calloc, free, malloc from libc.string cimport memcpy, memset from murmurhash.mrmr cimport hash64 from preshed.maps cimport PreshMap from .. import registry from ..types import ArrayXd, DeviceTypes, DTypes, Shape from ..util import copy_array, get_array_module from .cblas cimport CBlas, daxpy, dgemm, saxpy, sgemm, sscal from ..compat import has_blis from .ops import Ops, _split_weights, _transpose_weights, _untranspose_unsplit_weights cdef extern from "math.h": float logf(float x) nogil float sqrtf(float x) nogil float expf(float x) nogil float tanhf(float x) nogil float sinf(float x) nogil float cosf(float x) nogil @registry.ops("NumpyOps") class NumpyOps(Ops): name = "numpy" xp = numpy def __init__( self, device_type: DeviceTypes = "cpu", device_id: int = -1, *, use_blis: bool = True ) -> None: self.device_type = device_type self.device_id = device_id self.use_blis = use_blis if self.use_blis and not has_blis: raise ValueError("BLIS support requires blis: pip install blis") def asarray(self, data, dtype=None): if isinstance(data, self.xp.ndarray): array = data elif hasattr(data, 'numpy'): # Handles PyTorch Tensor array = data.numpy() elif hasattr(data, "get"): array = data.get() else: array = self.xp.array(data, dtype=dtype) if dtype is not None: array = array.astype(dtype=dtype, copy=False) return array def alloc(self, shape: Shape, *, dtype: Optional[DTypes] = "float32", zeros: bool = True) -> ArrayXd: if zeros: return self.xp.zeros(shape, dtype=dtype) else: return self.xp.empty(shape, dtype=dtype) def cblas(self) -> CBlas: return CBlas() def gemm(self, np.ndarray x, np.ndarray y, *, np.ndarray out=None, trans1=False, trans2=False): if x.ndim != 2: raise ValueError(f"Provided 'x' array should be 2-dimensional, but found {x.ndim} dimension(s).") if y.ndim != 2: raise ValueError(f"Provided 'y' array should be 2-dimensional, but found {y.ndim} dimension(s).") if not self.use_blis: # delegate to base Ops return super().gemm(x, y, out=out, trans1=trans1, trans2=trans2) x = self.as_contig(x) y = self.as_contig(y) cdef int nM = x.shape[0] if not trans1 else x.shape[1] cdef int nK = x.shape[1] if not trans1 else x.shape[0] cdef int nK_b = y.shape[0] if not trans2 else y.shape[1] cdef int nN = y.shape[1] if not trans2 else y.shape[0] if nK != nK_b: msg = "Shape mismatch for blis.gemm: (%d, %d), (%d, %d)" raise ValueError(msg % (nM, nK, nK_b, nN)) if out is not None: out = self.as_contig(out) else: # Can be uninitialized as 'beta' is zero. out = numpy.empty((nM, nN), dtype=x.dtype) cblas = self.cblas() if x.dtype == "float32" and y.dtype == "float32" and out.dtype == "float32": sgemm(cblas)(trans1, trans2, nM, nN, nK, 1.0, (x.data), x.shape[1], (y.data), y.shape[1], 0.0, (out.data), out.shape[1]) elif x.dtype == "float64" and y.dtype == "float64" and out.dtype == "float64": dgemm(cblas)(trans1, trans2, nM, nN, nK, 1.0, (x.data), x.shape[1], (y.data), y.shape[1], 0.0, (out.data), out.shape[1]) else: raise ValueError(f"unsupported or mismatching array data types; got '{x.dtype}', '{y.dtype}', '{out.dtype}'") return out def relu(self, np.ndarray X, inplace=False): cdef np.ndarray Y if X.dtype == "float32": Y = _inplace_or_copy(X, inplace) cpu_relu(Y.data, Y.size) return Y elif X.dtype == "float64": Y = _inplace_or_copy(X, inplace) cpu_relu(Y.data, Y.size) return Y else: return super().relu(X, inplace=inplace) def backprop_relu(self, np.ndarray dY, np.ndarray Y, inplace=False): _check_compatible_shape(dY, Y) cdef size_t size = Y.size cdef float* dX_ptr cdef const float* Y_ptr = Y.data cdef np.ndarray dX if dY.dtype == "float32" and Y.dtype == "float32": dX = _inplace_or_copy(dY, inplace) dX_ptr = dX.data for i in range(size): if Y_ptr[i] <= 0: dX_ptr[i] = 0. return dX else: return super().backprop_relu(dY, Y, inplace) def lstm_forward_training( self, np.ndarray params, np.ndarray H0, np.ndarray C0, np.ndarray X, np.ndarray size_at_t ): assert H0.shape[0] == C0.shape[0] assert H0.shape[1] == C0.shape[1] Y, fwd_state = lstm_forward_training(self.cblas(), params, H0, C0, X, size_at_t) return Y, fwd_state def lstm_forward_inference( self, np.ndarray params, np.ndarray H0, np.ndarray C0, np.ndarray X, np.ndarray size_at_t ): Y, _ = lstm_forward_training(self.cblas(), params, H0, C0, X, size_at_t) return Y def backprop_lstm( self, np.ndarray dY, np.ndarray lengths, np.ndarray params, fwd_state ): dX, d_params = backprop_lstm(self.cblas(), dY, lengths, params, fwd_state) return dX, d_params def maxout(self, reals3d_ft X): cdef int B = X.shape[0] cdef int O = X.shape[1] cdef int P = X.shape[2] cdef np.ndarray best cdef np.ndarray which = self.alloc(shape=(B, O), dtype='int32', zeros=False) if reals3d_ft is float3d_t: best = self.alloc(shape=(B, O), dtype="float32", zeros=False) if len(X) > 0: cpu_maxout(best.data, which.data, &X[0, 0, 0], B, O, P) else: best = self.alloc(shape=(B, O), dtype="float64", zeros=False) if len(X) > 0: cpu_maxout(best.data, which.data, &X[0, 0, 0], B, O, P) return best, which def backprop_maxout(self, reals2d_ft dY, int[:, ::1] which, int P): cdef int B = dY.shape[0] cdef int O = dY.shape[1] cdef np.ndarray dX if reals2d_ft == float2d_t: dX = numpy.zeros((B, O, P), dtype='float32') cpu_backprop_maxout(dX.data, &dY[0, 0], &which[0, 0], B, O, P) else: dX = numpy.zeros((B, O, P), dtype='float64') cpu_backprop_maxout(dX.data, &dY[0, 0], &which[0, 0], B, O, P) return dX def mish(self, np.ndarray X, threshold=20.0, inplace: bool = False): cdef np.ndarray Y if X.dtype == "float32": Y = _inplace_or_copy(X, inplace) cpu_mish(Y.data, Y.size, threshold) return Y elif X.dtype == "float64": Y = _inplace_or_copy(X, inplace) cpu_mish(Y.data, Y.size, threshold) return Y else: return super().mish(X, inplace=inplace) def backprop_mish(self, np.ndarray dY, np.ndarray X, threshold=20.0, inplace=False): _check_compatible_shape(dY, X) cdef np.ndarray dX if dY.dtype == "float32" and X.dtype == "float32": dX = _inplace_or_copy(dY, inplace) cpu_backprop_mish(dX.data, X.data, X.size, threshold) return dX elif dY.dtype == "float64" and X.dtype == "float64": dX = _inplace_or_copy(dY, inplace) cpu_backprop_mish(dX.data, X.data, X.size, threshold) return dX else: return super().backprop_mish(dY, X, threshold, inplace) def seq2col(self, np.ndarray seq, int nW, *, int[::1] lengths=None): """Given an (M, N) sequence of vectors, return an (M, N*(nW*2+1)) sequence. The new sequence is constructed by concatenating nW preceding and succeeding vectors onto each column in the sequence, to extract a window of features. """ # Note: the type of seq should be changed to reals2d_ft once # cython/cython#4697 is fixed. The following checks can then be # removed, because they are guaranteed by the reals2d_ft # type. if seq.ndim != 2: msg = f"seq2col requires sequence array of dimensionality 2, was {seq.ndim}" raise ValueError(msg) if not seq.flags.c_contiguous: msg = f"seq2col requires sequence array that is in C order and contiguous" raise ValueError(msg) cdef int B = seq.shape[0] cdef int I = seq.shape[1] lengths = check_seq2col_lengths(self, lengths, B) cdef int nL = lengths.shape[0] cdef np.ndarray cols if seq.dtype == "float32": cols = self.alloc((B, (2*nW + 1) * I), dtype="float32") if seq.size != 0 and lengths.size != 0: seq2col(cols.data, seq.data, &lengths[0], nW, B, I, nL) return cols elif seq.dtype == "float64": cols = self.alloc((B, (2*nW + 1) * I), dtype="float64") if seq.size != 0 and lengths.size != 0: seq2col(cols.data, seq.data, &lengths[0], nW, B, I, nL) return cols else: return super().seq2col(seq, nW, lengths=lengths) def backprop_seq2col(self, np.ndarray dY, int nW, *, int[::1] lengths=None): # Note: the type of dY should be changed to reals2d_ft once # cython/cython#4697 is fixed. The following checks can then be # removed, because they are guaranteed by the reals2d_ft # type. if dY.ndim != 2: msg = f"backprop_seq2col requires gradient array of dimensionality 2, was {dY.ndim}" raise ValueError(msg) if not dY.flags.c_contiguous: msg = f"backprop_seq2col requires gradient array that is in C order and contiguous" raise ValueError(msg) cdef int B = dY.shape[0] cdef int nF = nW*2+1 cdef int I = dY.shape[1] / nF lengths = check_seq2col_lengths(self, lengths, B) cdef int nL = lengths.shape[0] cdef np.ndarray dX if dY.dtype == "float32": dX = self.alloc((B, I), dtype='float32') if dY.size != 0 and lengths.size != 0: backprop_seq2col(dX.data, dY.data, &lengths[0], B, I, nW, nL) return dX elif dY.dtype == "float64": dX = self.alloc((B, I), dtype='float64') if dY.size != 0 and lengths.size != 0: backprop_seq2col(dX.data, dY.data, &lengths[0], B, I, nW, nL) return dX else: return super().backprop_seq2col(dY, nW, lengths=lengths) @cython.boundscheck(False) @cython.wraparound(False) def hash(self, const uint64_t[::1] ids, uint32_t seed): """Hash a sequence of 64-bit keys into a table with 4 32-bit keys.""" # Written to mirror the GPU implementation cdef np.ndarray[uint32_t, ndim=2] keys = self.alloc((ids.shape[0], 4), dtype='uint32') cdef int i cdef uint32_t* dest = keys.data for i in range(len(ids)): MurmurHash3_x86_128_uint64(ids[i], seed, &dest[i*4]) return keys def reduce_mean(self, reals2d_ft X, int[::1] lengths): cdef int B = lengths.shape[0] cdef int O = X.shape[1] cdef int T = X.shape[0] if B == 0 or O == 0: if reals2d_ft is float2d_t: return numpy.zeros(shape=(B, O), dtype="float32") else: return numpy.zeros(shape=(B, O), dtype="float64") cdef np.ndarray means if reals2d_ft is float2d_t: means = numpy.zeros(shape=(B, O), dtype="float32") cpu_reduce_mean(means.data, &X[0, 0], &lengths[0], B, T, O) else: means = numpy.zeros(shape=(B, O), dtype="float64") cpu_reduce_mean(means.data, &X[0, 0], &lengths[0], B, T, O) return means def backprop_reduce_mean(self, reals2d_ft d_means, int[::1] lengths): cdef int B = lengths.shape[0] cdef int O = d_means.shape[1] cdef int T = 0 for length in lengths[:B]: if length < 0: raise ValueError(f"all sequence lengths must be >= 0, got {length}") T += length if T == 0 or O == 0: if reals2d_ft is float2d_t: return numpy.zeros(shape=(T, O), dtype="float32") else: return numpy.zeros(shape=(T, O), dtype="float64") cdef np.ndarray dX if reals2d_ft is float2d_t: dX = numpy.zeros((T, O), dtype="float32") cpu_backprop_reduce_mean(dX.data, &d_means[0,0], &lengths[0], B, T, O) else: dX = numpy.zeros((T, O), dtype="float64") cpu_backprop_reduce_mean(dX.data, &d_means[0,0], &lengths[0], B, T, O) return dX def reduce_sum(self, reals2d_ft X, int[::1] lengths): cdef int B = lengths.shape[0] cdef int O = X.shape[1] cdef int T = X.shape[0] if B == 0 or O == 0: if reals2d_ft is float2d_t: return numpy.zeros(shape=(B, O), dtype="float32") else: return numpy.zeros(shape=(B, O), dtype="float64") cdef np.ndarray sums if reals2d_ft is float2d_t: sums = numpy.zeros(shape=(B, O), dtype="float32") cpu_reduce_sum(sums.data, &X[0, 0], &lengths[0], B, T, O) else: sums = numpy.zeros(shape=(B, O), dtype="float64") cpu_reduce_sum(sums.data, &X[0, 0], &lengths[0], B, T, O) return sums def backprop_reduce_sum(self, reals2d_ft d_sums, int[::1] lengths): cdef int B = lengths.shape[0] cdef int O = d_sums.shape[1] cdef int T = 0 for length in lengths[:B]: if length < 0: raise ValueError(f"all sequence lengths must be >= 0, got {length}") T += length if T == 0 or O == 0: if reals2d_ft is float2d_t: return numpy.zeros(shape=(T, O), dtype="float32") else: return numpy.zeros(shape=(T, O), dtype="float64") cdef np.ndarray dX if reals2d_ft is float2d_t: dX = numpy.zeros((T, O), dtype="float32") cpu_backprop_reduce_sum(dX.data, &d_sums[0,0], &lengths[0], B, T, O) else: dX = numpy.zeros((T, O), dtype="float64") cpu_backprop_reduce_sum(dX.data, &d_sums[0,0], &lengths[0], B, T, O) return dX def reduce_max(self, reals2d_ft X, int[::1] lengths): cdef int B = lengths.shape[0] cdef int O = X.shape[1] cdef int T = X.shape[0] # Needs to be zero-initialized as we start by assuming that the first element is the max value. cdef np.ndarray which = self.alloc(shape=(B, O), dtype="i", zeros=True) if B == 0 or O == 0: if reals2d_ft is float2d_t: return numpy.zeros(shape=(B, O), dtype="float32"), which else: return numpy.zeros(shape=(B, O), dtype="float64"), which cdef np.ndarray maxes if reals2d_ft is float2d_t: maxes = self.alloc(shape=(B, O), dtype="float32", zeros=False) cpu_reduce_max(maxes.data, which.data, &X[0, 0], &lengths[0], B, T, O) else: maxes = self.alloc(shape=(B, O), dtype="float64", zeros=False) cpu_reduce_max(maxes.data, which.data, &X[0, 0], &lengths[0], B, T, O) return maxes, which def backprop_reduce_max(self, reals2d_ft d_maxes, int[:, ::1] which, int[::1] lengths): cdef int B = lengths.shape[0] cdef int O = d_maxes.shape[1] cdef int T = 0 for length in lengths[:B]: if length <= 0: raise ValueError(f"all sequence lengths must be > 0, got {length}") T += length if T == 0 or O == 0: if reals2d_ft is float2d_t: return numpy.zeros(shape=(T, O), dtype="float32") else: return numpy.zeros(shape=(T, O), dtype="float64") cdef np.ndarray dX if reals2d_ft is float2d_t: dX = numpy.zeros((T, O), dtype="float32") cpu_backprop_reduce_max(dX.data, &d_maxes[0,0], &which[0, 0], &lengths[0], B, T, O) else: dX = numpy.zeros((T, O), dtype="float64") cpu_backprop_reduce_max(dX.data, &d_maxes[0,0], &which[0, 0], &lengths[0], B, T, O) return dX def gather_add(self, reals2d_ft table, ints2d_ft indices): cdef CBlas cblas = self.cblas() rows = indices.shape[0] dims = table.shape[1] cdef np.ndarray output if reals2d_ft is float2d_t: output = self.xp.zeros((rows, dims), dtype="float32") cpu_gather_add(saxpy(cblas), output.data, &table[0, 0], &indices[0, 0], table.shape[0], dims, rows, indices.shape[1]) else: output = self.xp.zeros((rows, dims), dtype="float64") cpu_gather_add(daxpy(cblas), output.data, &table[0, 0], &indices[0, 0], table.shape[0], dims, rows, indices.shape[1]) return output def scatter_add(self, np.ndarray table, np.ndarray indices, np.ndarray values): if table.dtype == 'float32' \ and indices.dtype == 'int32' \ and values.dtype == 'float32' \ and table.flags.c_contiguous \ and indices.flags.c_contiguous \ and values.flags.c_contiguous \ and indices.ndim == 1 \ and table.ndim == 2 \ and values.ndim == 2 \ and values.shape[0] == indices.shape[0] \ and values.shape[1] == table.shape[1]: cpu_scatter_add(self.cblas(), table.data, indices.data, values.data, indices.shape[0], table.shape[1]) else: self.xp.add.at(table, indices, values) @cython.boundscheck(False) @cython.wraparound(False) def adam(self, np.ndarray[np.float32_t] weights, np.ndarray[np.float32_t] gradient, np.ndarray[np.float32_t] mom1, np.ndarray[np.float32_t] mom2, const float beta1, const float beta2, float eps, float learn_rate, float mod_rate=1.): _check_compatible_shape(weights, gradient) _check_compatible_shape(weights, mom1) _check_compatible_shape(weights, mom2) cdef CBlas cblas = self.cblas() _adam_momentum(cblas, gradient.data, mom1.data, mom2.data, weights.shape[0], beta1, beta2, eps, learn_rate) saxpy(cblas)(weights.shape[0], -learn_rate, gradient.data, 1, weights.data, 1) memset(gradient.data, 0, gradient.size * sizeof(float)) return weights, gradient, mom1, mom2 def ngrams(self, int n, const uint64_t[::1] keys): if n < 1: return self.alloc((0,), dtype="uint64") keys_ = &keys[0] length = max(0, keys.shape[0]-(n-1)) cdef np.ndarray output_ = self.alloc((length,), dtype="uint64") output = output_.data for i in range(keys.shape[0]-(n-1)): output[i] = hash64(&keys_[i], n*sizeof(keys_[0]), 0) return output_ def position_encode(self, int N, int D, int period=10000, out=None): cdef np.ndarray out_ if out is None: out_ = self.alloc((N, D), zeros=False) else: out_ = out assert out_.shape[0] == N assert out_.shape[1] == D cpu_position_encode(out_.data, period, N, D) return out_ def check_seq2col_lengths(ops, lengths, B): if lengths is None: lengths = ops.asarray1i([B]) else: assert ops.xp.all(ops.xp.array(lengths) >= 0), "All sequence lengths must be >= 0" assert ops.xp.sum(lengths) == B, "The lengths must sum up to the batch length" return lengths cdef void cpu_position_encode(float* output, float period, int N, int D) nogil: cdef float pos, d cdef int j cdef float dimensions = D for i in range(N): pos = i j = 0 d = 0 while (j+1) < D: d = j output[j] = sinf(pos / period ** (2 * d / dimensions)) output[j+1] = cosf(pos / period ** (2 * d / dimensions)) j += 2 if j < D: output[j] = sinf(pos / period ** (2 * d / dimensions)) output += D cdef void cpu_scatter_add(CBlas cblas, float* dest, const int* indices, const float* src, int nr_id, int nr_col) nogil: cdef int i for i in range(nr_id): id_ = indices[i] if id_ >= 0: saxpy(cblas)(nr_col, 1., &src[i*nr_col], 1, &dest[id_*nr_col], 1) @cython.cdivision(True) cdef void _adam_momentum(CBlas cblas, float* gradient, float* mom1, float* mom2, int nr_weight, float beta1, float beta2, float eps, float learn_rate) nogil: # Calculate Adam on CPU, fused. # Assumes the learning rate adjustment is calculated by the caller; # a_t = learn_rate * sqrt(1-beta2**timestep) / (1-beta1**timestep) cdef float one_minus_beta1 = 1-beta1 cdef float one_minus_beta2 = 1-beta2 cdef float m1, m2, g cdef int i # Blockwise implementation is a bit faster. Adam is slooow :( cdef float[64] buff cdef int steps = nr_weight // 64 if steps * 64 < nr_weight: steps += 1 idx = 0 for i in range(steps): step_size = min(64, nr_weight-idx) sscal(cblas)(step_size, beta1, mom1, 1) saxpy(cblas)(step_size, one_minus_beta1, gradient, 1, mom1, 1) sscal(cblas)(step_size, beta2, mom2, 1) for j in range(step_size): mom2[j] += one_minus_beta2 * gradient[j] ** 2 for j in range(step_size): buff[j] = sqrtf(mom2[j]) for j in range(step_size): buff[j] += eps for j in range(step_size): buff[j] = mom1[j] / buff[j] for j in range(step_size): gradient[j] = buff[j] mom1 += step_size mom2 += step_size gradient += step_size idx += step_size def lstm_forward_training(CBlas cblas, np.ndarray params, np.ndarray c_init, np.ndarray h_init, np.ndarray X, np.ndarray lengths ): xp = numpy depth = c_init.shape[0] dirs = c_init.shape[1] nO = c_init.shape[2] N = X.shape[0] nI = X.shape[1] nT = lengths.shape[0] cdef int batch_size = lengths[0] # Preallocate these so we can pass them through for loop. cdef np.ndarray G = xp.zeros((depth, dirs, X.shape[0], nO * 4), dtype="f") cdef np.ndarray Y = xp.zeros((depth, dirs, X.shape[0], nO), dtype="f") cdef np.ndarray C = xp.zeros((depth, dirs, X.shape[0], nO), dtype="f") cdef np.ndarray Yt2 = numpy.zeros((batch_size, nO), dtype="f") cdef np.ndarray Ct2 = numpy.zeros((batch_size, nO), dtype="f") cdef int params_i = 0 cdef int seq_i = 0 orig_X = X cdef int i cdef np.ndarray Yid cdef np.ndarray Cid cdef np.ndarray Gid cdef np.ndarray Wx cdef np.ndarray Wh cdef np.ndarray bias for i in range(depth): nI = X.shape[1] for d in range(dirs): # The inits are shaped (depth, dirs, nO). We add the internal dimension # to make them set correctly. Yt2[:] = h_init[i, d].reshape((1, nO)) Ct2[:] = c_init[i, d].reshape((1, nO)) layer_params, params_i = _split_weights(params, i, nO, nI, params_i) Wx, Wh, bias = _transpose_weights(layer_params) Yid = Y[i, d] Cid = C[i, d] Gid = G[i, d] _lstm_forward_training( cblas, d, N, nO, nI, nT, Gid, Yid.data, Cid.data, X.data, Wx.data, Wh.data, bias, lengths.data, Yt2.data, Ct2.data ) H = Y[i].transpose((1, 0, 2)).reshape((N, -1)) if dirs == 2: H = xp.ascontiguousarray(H) X = H return H, (Y, G, C, orig_X) cdef int _lstm_forward_training( CBlas cblas, int d, int N, int nO, int nI, int nT, np.ndarray G, float* Y, float* C, float* X, float* Wx, float* Wh, np.ndarray bias, int* lengths, float* Yt2, float* Ct2, ) except -1: cdef double one = 1.0 sgemm(cblas)(False, True, N, nO*4, nI, one, X, nI, Wx, nI, one, G.data, nO*4 ) cdef int t, batch_size cdef int seq_i = 0 if d == 0 else N cdef int i, j cdef np.ndarray Gt3_ for t in range(nT): if d == 0: batch_size = lengths[t] else: batch_size = lengths[nT-(t+1)] seq_i -= batch_size # Prepare the inputs Yt3 = &Y[seq_i*nO] Ct3 = &C[seq_i*nO] Gt3_ = G[seq_i : seq_i+batch_size] Gt3 = Gt3_.data # Now do the actual calculation sgemm(cblas)(False, True, batch_size, nO*4, nO, one, Yt2, nO, Wh, nO, one, Gt3, nO*4 ) # This is super weird: if we remove this add, it gets slower? I guess # it does cache prefetching or something? # It's annoying though --- it means I can't really refactor further, # because speed goes down if I remove this. Gt3_ += bias #for i in range(batch_size): # for j in range(nO*4): # Gt3[i*nO*4+j] += bias[j] cpu_lstm_activate_fwd(Gt3, batch_size, nO) cpu_lstm_gates_fwd(Yt3, Ct3, Gt3, Ct2, batch_size, nO) if d == 0: seq_i += batch_size # We need to keep a full-sized array here, padded with the sequence-start # values. This isn't necessary for the l2r part, but for the r2l part # it's necessary, as we otherwise would have the previous step smaller # than the current. memcpy(Yt2, Yt3, sizeof(Yt3[0]) * batch_size * nO) memcpy(Ct2, Ct3, sizeof(Ct3[0]) * batch_size * nO) def backprop_lstm(CBlas cblas, np.ndarray dY, np.ndarray lengths, np.ndarray params, fwd_state): xp = numpy cdef np.ndarray Y cdef np.ndarray G cdef np.ndarray C cdef np.ndarray X cdef np.ndarray Yid cdef np.ndarray Cid cdef np.ndarray Gid cdef np.ndarray Wx, Wh, bias cdef np.ndarray dWx, dWh, d_bias cdef np.ndarray dYid Y, G, C, X = fwd_state cdef int depth = C.shape[0] cdef int dirs = C.shape[1] cdef int N = C.shape[2] cdef int nO = C.shape[3] cdef int nI = X.shape[1] cdef int batch_size = lengths[0] cdef int nT = lengths.shape[0] # We don't need to store all the cells for all the layers. cdef np.ndarray dC = xp.zeros((N, nO), dtype=C.dtype) cdef np.ndarray dG = xp.zeros((N, nO*4), dtype=C.dtype) cdef np.ndarray d_params = xp.zeros((params.shape[0],), dtype=params.dtype) # Collect the params and slices. It makes it a bit easier to get the indexing # right, when we're iterating backwards. params_i = 0 all_layer_params = [] for i in range(depth): all_layer_params.append([]) n_inputs = nI if i == 0 else (nO * dirs) for d in range(dirs): layer_params, params_i = _split_weights(params, i, nO, n_inputs, params_i) layer_params = _transpose_weights(layer_params) all_layer_params[-1].append((layer_params, params_i)) params_i = 0 all_layer_grads = [] for i in range(depth): all_layer_grads.append([]) n_inputs = nI if i == 0 else (nO * dirs) for d in range(dirs): layer_grads, params_i = _split_weights(params, i, nO, n_inputs, params_i) layer_grads = _transpose_weights(layer_grads) all_layer_grads[-1].append((layer_grads, params_i)) # Similarly, we want to compute the indices first indices = [] seq_i = 0 for batch_size in lengths: indices.append((seq_i, batch_size)) seq_i += batch_size cdef np.ndarray dX Xs = [X] + [Y[i].transpose(1, 0, 2).reshape((N, -1)) for i in range(depth-1)] dXs = [xp.zeros((X.shape[0], X.shape[1]), dtype=X.dtype) for X in Xs] # Okay, now do the actual looping for i in reversed(range(depth)): dY = dY.reshape((N, dirs, nO)).transpose((1, 0, 2)) dX = dXs[i] X = Xs[i] if dirs >= 2: dY = numpy.ascontiguousarray(dY) for d in range(dirs): Wx, Wh, bias = all_layer_params[i][d][0] dWx, dWh, d_bias = all_layer_grads[i][d][0] assert Wx.shape[1] == dWx.shape[1] == X.shape[1] == dX.shape[1], (Wx.shape[1], dWx.shape[1], X.shape[1], dX.shape[1]) dYid = dY[d] dC.fill(0.) dG.fill(0.) Cid = C[i, d] Gid = G[i, d] Yid = Y[i, d] assert (Cid.shape[0], Cid.shape[1]) == (N, nO) assert (Yid.shape[0], Yid.shape[1]) == (N, nO) assert (Gid.shape[0], Gid.shape[1]) == (N, nO*4) assert (dYid.shape[0], dYid.shape[1]) == (N, nO) assert (dC.shape[0], dC.shape[1]) == (N, nO) assert (dG.shape[0], dG.shape[1]) == (N, nO*4) _lstm_backward_training(cblas, d, N, nO, dX.shape[1], nT, dX.data, dYid.data, dC.data, dG.data, dWx.data, dWh.data, d_bias.data, Cid.data, Gid.data, Yid.data, X.data, Wx.data, Wh.data, list(indices) ) dY = dX assert dX.shape[1] == X.shape[1] grad_parts = [] for layer_grads in all_layer_grads: for dir_grads, _ in layer_grads: grad_parts.append(_untranspose_unsplit_weights(dir_grads)) return dX, numpy.concatenate(grad_parts) cdef int _lstm_backward_training( CBlas cblas, int d, int N, int nO, int nI, int nT, float* dX, float* dY, float* dC, float* dG, float* dWx, float* dWh, float* d_bias, const float* C, const float* G, const float* Y, const float* X, const float* Wx, const float* Wh, indices, ) except -1: cdef int seq_t2 cdef int seq_t3 cdef double one = 1.0 if d == 0: seq_t3, size_t3 = indices[-1] indices = indices[:-1] indices.reverse() else: seq_t3, size_t3 = indices[0] indices = indices[1:] cdef int batch_size for seq_t2, size_t2 in indices: dGt3 = &dG[seq_t3*nO*4] dXt3 = &dX[seq_t3*nI] dYt3 = &dY[seq_t3*nO] dCt3 = &dC[seq_t3*nO] dYt2 = &dY[seq_t2*nO] dCt2 = &dC[seq_t2*nO] Ct3 = &C[seq_t3*nO] Gt3 = &G[seq_t3*nO*4] Ct2 = &C[seq_t2*nO] batch_size = min(size_t2, size_t3) cpu_lstm_gates_bwd(dGt3, dCt2, dYt3, dCt3, Gt3, Ct3, Ct2, batch_size * nO ) # Backprop hidden-to-hidden w.r.t. hidden. # dYt2 += dGt3 @ Wh sgemm(cblas)(False, False, batch_size, nO, nO*4, one, dGt3, nO*4, Wh, nO, one, dYt2, nO ) seq_t3 = seq_t2 size_t3 = size_t2 # Backprop input-to-hidden w.r.t. weights. # dWx += dG @ X sgemm(cblas)(True, False, nO*4, nI, N, one, dG, nO*4, X, nI, one, dWx, nI ) # Backprop hidden-to-hidden w.r.t weights. # dWh += dG @ Y sgemm(cblas)(True, False, nO*4, nO, N, one, dG, nO*4, Y, nO, one, dWh, nO ) # Backprop bias for i in range(N): for j in range(nO*4): d_bias[j] += dG[i*nO*4+j] # Backprop input-to-hidden w.r.t. input sgemm(cblas)(False, False, N, nI, nO*4, one, dG, nO*4, Wx, nI, one, dX, nI ) cdef inline float dsigmoid(float y) nogil: return y*(1-y) cdef inline float dtanh(float y) nogil: return 1-y**2 cdef void cpu_lstm_activate_fwd(float* gates, int B, int N) nogil: """Apply sigmoid activation in-place to columns 0, 1, 2 and tanh to column 3. The data is assumed to have the gates in the last dimension. """ # This just does the following, but unrolled slightly to give # a better chance at simd. # # gates[g+i+0] = sigmoid(gates[g+i+0]) # gates[g+i+1] = sigmoid(gates[g+i+1]) # gates[g+i+2] = sigmoid(gates[g+i+2]) # gates[g+i+3] = tanh(gates[g+i+3]) # # I would've hoped the compiler would find this itself? It seems to make # it like, 10% faster. It feels like a dumb thing to do but it's not much # code. The problem with this sort of thing is it needs to be rebenchmarked # later...It's fine to revert this at a later date to the simpler loop. # Shrug. The weird thing is, why should the batch entries be a good loop # stride here? Surely something to do with cache lines would make more sense? cdef int i, b, g g = 0 for b in range(B): g = b * N * 4 end = g + N*4 while g < end: gates[g+0] = expf(-gates[g+0]) gates[g+1] = expf(-gates[g+1]) gates[g+2] = expf(-gates[g+2]) g += 4 g = b * N * 4 while g < end: gates[g+0] += 1 gates[g+1] += 1 gates[g+2] += 1 g += 4 g = b * N * 4 while g < end: gates[g+0] = 1.0 / gates[g+0] gates[g+1] = 1.0 / gates[g+1] gates[g+2] = 1.0 / gates[g+2] g += 4 g = b * N * 4 while g < end: gates[g+3] = tanhf(gates[g+3]) g += 4 cdef void cpu_lstm_gates_fwd(float* hiddens, float* cells, const float* gates, const float* prevcells, int B, int N) nogil: cdef float hf, hi, ho, hc, ct2, ct3 cdef int i, b, g, c, h g = 0 c = 0 h = 0 while g < B*N*4: hf = gates[g+0] hi = gates[g+1] ho = gates[g+2] hc = gates[g+3] ct2 = prevcells[c] ct3 = hf * ct2 + hi * hc hiddens[h] = tanhf(ct3) * ho cells[c] = ct3 g += 4 c += 1 h += 1 cdef void cpu_lstm_gates_bwd( float* dGt3, float* dCt2, const float* dYt3, const float* dCt3, const float* Gt3, const float* Ct3, const float* Ct2, int N ) nogil: cdef int i cdef float ct2, ct3, hf, hi, ho, hc, tanh_ct3 cdef float d_ho, d_tanh_ct3, dct3, d_hi, d_hc, d_hf for i in range(N): ct2 = Ct2[i] ct3 = Ct3[i] dct3 = dCt3[i] dyt3 = dYt3[i] hf = Gt3[i*4+0] hi = Gt3[i*4+1] ho = Gt3[i*4+2] hc = Gt3[i*4+3] tanh_ct3 = tanhf(ct3) # 3b: Yt3 = tanhCt3 * ho d_ho = dyt3 * tanh_ct3 d_tanh_ct3 = dyt3 * ho # 3a: tanhCt3 = tanh(Ct3) dct3 += d_tanh_ct3 * dtanh(tanh_ct3) # 2b: Ct3 += hi * hc d_hi = dct3 * hc d_hc = dct3 * hi # 2a: Ct3 = hf * Ct2 d_hf = dct3 * ct2 dCt2[i] = dct3 * hf dGt3[i*4+0] = d_hf * dsigmoid(hf) # 1a dGt3[i*4+1] = d_hi * dsigmoid(hi) # 1b dGt3[i*4+2] = d_ho * dsigmoid(ho) # 1c dGt3[i*4+3] = d_hc * dtanh(hc) # 1d cdef void MurmurHash3_x86_128_uint64( const uint64_t val, const uint32_t seed, uint32_t *out ) nogil: cdef uint64_t h1, h2 h1 = val h1 *= 0x87c37b91114253d5ull h1 = (h1 << 31) | (h1 >> 33) h1 *= 0x4cf5ad432745937full h1 ^= seed h1 ^= 8 h2 = seed h2 ^= 8 h1 += h2 h2 += h1 h1 ^= h1 >> 33 h1 *= 0xff51afd7ed558ccdull h1 ^= h1 >> 33 h1 *= 0xc4ceb9fe1a85ec53ull h1 ^= h1 >> 33 h2 ^= h2 >> 33 h2 *= 0xff51afd7ed558ccdull h2 ^= h2 >> 33 h2 *= 0xc4ceb9fe1a85ec53ull h2 ^= h2 >> 33 h1 += h2 h2 += h1 out[0] = h1 & 0xffffffffu out[1] = h1 >> 32 out[2] = h2 & 0xffffffffu out[3] = h2 >> 32 def _check_compatible_shape(u: np.ndarray, v: np.ndarray): if u.shape != v.shape: msg = f"arrays have incompatible shapes: {u.shape} and {v.shape}" raise ValueError(msg) cdef inline np.ndarray _inplace_or_copy(np.ndarray X, inplace): if inplace: return X else: return numpy.array(X) thinc-9.0.0/thinc/backends/ops.py000066400000000000000000001625161461023342500166720ustar00rootroot00000000000000import itertools import math from typing import ( Any, Iterator, List, Optional, Sequence, Tuple, Type, TypeVar, Union, cast, overload, ) import numpy from ..types import ( Array1d, Array2d, Array3d, Array4d, ArrayXd, Batchable, DeviceTypes, DTypes, DTypesFloat, DTypesInt, Floats1d, Floats2d, Floats3d, Floats4d, FloatsXd, FloatsXdT, Generator, Ints1d, Ints2d, Ints3d, Ints4d, IntsXd, List2d, ListXd, Padded, Shape, SizedGenerator, Xp, _Floats, ) from ..util import get_array_module, is_xp_array, to_numpy from .cblas import CBlas ArrayT = TypeVar("ArrayT", bound=ArrayXd) FloatsT = TypeVar("FloatsT", bound=_Floats) SQRT2PI = math.sqrt(2.0 / math.pi) INV_SQRT2 = 1.0 / math.sqrt(2.0) INV_SQRT_2PI = 1.0 / math.sqrt(2.0 * math.pi) class Ops: name: str = "base" xp: Xp = numpy def __init__( self, device_type: DeviceTypes = "cpu", device_id: int = -1, **kwargs ) -> None: self.device_type = device_type self.device_id = device_id def cblas(self) -> CBlas: """Return C BLAS function table.""" err = f"{type(self).__name__} does not provide C BLAS functions" raise NotImplementedError(err) def to_numpy(self, data, *, byte_order=None): # pragma: no cover if isinstance(data, numpy.ndarray): if byte_order: dtype = data.dtype.newbyteorder(byte_order) data = numpy.asarray(data, dtype=dtype) return data else: raise ValueError("Cannot convert non-numpy from base Ops class") def minibatch( self, size: Union[int, Generator], sequence: Batchable, *, shuffle: bool = False, buffer: int = 1, ) -> SizedGenerator: """Iterate slices from a sequence, optionally shuffled. Slices may be either views or copies of the underlying data. The `size` argument may be either an integer, or a sequence of integers. If a sequence, a new size is drawn before every output. If shuffle is True, shuffled batches are produced by first generating an index array, shuffling it, and then using it to slice into the sequence. An internal queue of `buffer` items is accumulated before being each output. Buffering is useful for some devices, to allow the network to run asynchronously without blocking on every batch. """ if not hasattr(sequence, "__len__"): err = f"Can't minibatch data. Expected sequence, got {type(sequence)}" raise ValueError(err) sizes = self._get_batch_sizes( len(sequence), itertools.repeat(size) if isinstance(size, int) else size ) indices = numpy.arange(len(sequence)) # This is a bit convoluted, but it's a time where convenience makes # trickery worthwhile: instead of being an actual generator, we # return our SizedGenerator object, which provides a __len__. def _iter_items(): if shuffle: numpy.random.shuffle(indices) queue = [] i = 0 for size in sizes: size = int(size) queue.append(self._get_batch(sequence, indices[i : i + size])) if len(queue) >= buffer: yield from queue queue = [] i += size yield from queue return SizedGenerator(_iter_items, len(sizes)) def multibatch( self, size: Union[int, Generator], sequence: Batchable, *others: Batchable, shuffle: bool = False, buffer: int = 1, ) -> SizedGenerator: """Minibatch one or more sequences of data, and yield lists with one batch per sequence. See ops.minibatch. """ # You'd think we could just do this by calling into minibatch and zip... # But the shuffling makes it really hard. sequences = (sequence,) + tuple(others) if not all(hasattr(seq, "__len__") for seq in sequences): values = ", ".join([f"{type(seq)}" for seq in sequences]) err = f"Can't multibatch data. Expected sequences, got {values}" raise ValueError(err) sizes = self._get_batch_sizes( len(sequence), itertools.repeat(size) if isinstance(size, int) else size ) indices = numpy.arange(len(sequence)) def _iter_items(): if shuffle: numpy.random.shuffle(indices) queue = [] i = 0 for size in sizes: size = int(size) idx_batch = indices[i : i + size] queue.append([]) for sequence in sequences: queue[-1].append(self._get_batch(sequence, idx_batch)) if len(queue) >= buffer: yield from queue queue = [] i += size yield from queue return SizedGenerator(_iter_items, len(sizes)) def _get_batch(self, sequence, indices): if isinstance(sequence, list): subseq = [sequence[i] for i in indices] elif isinstance(sequence, tuple): subseq = tuple(sequence[i] for i in indices) else: subseq = sequence[indices] if is_xp_array(subseq): subseq = self.as_contig(self.xp.asarray(subseq)) return subseq def _get_batch_sizes(self, length: int, sizes: Iterator[int]): output = [] i = 0 while i < length: output.append(next(sizes)) i += output[-1] return output def seq2col( self, seq: Floats2d, nW: int, *, lengths: Optional[Ints1d] = None ) -> Floats2d: """Given an (M, N) sequence of vectors, return an (M, N*(nW*2+1)) sequence. The new sequence is constructed by concatenating nW preceding and succeeding vectors onto each column in the sequence, to extract a window of features. """ # This is a test implementation that only supports nW=1 and lengths=None assert nW == 1 assert lengths == None B = seq.shape[0] I = seq.shape[1] cols = self.alloc3f(B, (nW * 2 + 1), I) # Copy left contexts. The last words aren't the left-context for anything. cols[nW:, :nW] = self.reshape3f(seq[:-nW], -1, nW, I) cols[:, nW] = seq cols[:-nW, nW + 1 :] = self.reshape3f(seq[nW:], -1, nW, I) return self.reshape2f(cols, B, I * (2 * nW + 1)) def backprop_seq2col( self, dY: Floats2d, nW: int, *, lengths: Optional[Ints1d] = None ) -> Floats2d: """The reverse/backward operation of the `seq2col` function: calculate the gradient of the original `(M, N)` sequence, as a function of the gradient of the output `(M, N*(nW*2+1))` sequence. """ # This is a test implementation that only supports nW=1 and lengths=None assert nW == 1 assert lengths == None nF = nW * 2 + 1 B = dY.shape[0] I = dY.shape[1] // nF # Having trouble getting the kernel to work... dX = self.alloc2f(B, I) dY3d = self.reshape3f(dY, B, nF, I) dX[:-nW] += self.reshape2f(dY3d[nW:, :nW], -1, I) dX += dY3d[:, nW] dX[nW:] += self.reshape2f(dY3d[:-nW, nW + 1 :], -1, I) return dX def gemm( self, x: Floats2d, y: Floats2d, out: Optional[Floats2d] = None, trans1: bool = False, trans2: bool = False, ) -> Floats2d: """Perform General Matrix Multiplication (GeMM) and optionally store the result in the specified output variable. """ if trans1: x = x.T if trans2: y = y.T if out is None: return self.xp.dot(x, y) else: self.xp.dot(x, y, out=out) return out def tile(self, X: Floats2d, reps: int) -> Floats2d: return self.xp.tile(X, reps) def affine(self, X: Floats2d, W: Floats2d, b: Floats1d) -> Floats2d: """Apply a weights layer and a bias to some inputs, i.e. Y = X @ W.T + b """ Y = self.gemm(X, W, trans2=True) Y += b return Y @overload def flatten( self, X: List[Floats2d], dtype: Optional[DTypes] = None, pad: int = 0, ndim_if_empty: int = 2, ) -> Floats2d: ... @overload def flatten( self, X: List[Ints1d], dtype: Optional[DTypes] = None, pad: int = 0, ndim_if_empty: int = 2, ) -> Ints1d: ... @overload def flatten( self, X: List2d, dtype: Optional[DTypes] = None, pad: int = 0, ndim_if_empty: int = 2, ) -> Array2d: ... # further specific typed signatures can be added as necessary @overload def flatten( self, X: ListXd, dtype: Optional[DTypes] = None, pad: int = 0, ndim_if_empty: int = 2, ) -> ArrayXd: ... @overload def flatten( self, X: Sequence[ArrayXd], dtype: Optional[DTypes] = None, pad: int = 0, ndim_if_empty: int = 2, ) -> ArrayXd: ... def flatten( self, X: Sequence[ArrayXd], dtype: Optional[DTypes] = None, pad: int = 0, ndim_if_empty: int = 2, ) -> ArrayXd: """Flatten a list of arrays into one large array.""" if X is None or len(X) == 0: return self.alloc((0,) * ndim_if_empty, dtype=dtype or "f") xp = get_array_module(X[0]) shape_if_empty = X[0].shape X = [x for x in X if x.size != 0] if len(X) == 0: return self.alloc(shape_if_empty, dtype=dtype or "f") if int(pad) >= 1: padded = [] for x in X: padded.append(xp.zeros((pad,) + x.shape[1:], dtype=x.dtype)) padded.append(x) padded.append(xp.zeros((pad,) + x.shape[1:], dtype=x.dtype)) X = padded result = xp.concatenate(X) if dtype is not None: result = xp.asarray(result, dtype=dtype) return result @overload def unflatten(self, X: Floats2d, lengths: Ints1d, pad: int = 0) -> List[Floats2d]: ... @overload def unflatten(self, X: Ints1d, lengths: Ints1d, pad: int = 0) -> List[Ints1d]: ... @overload def unflatten(self, X: Array2d, lengths: Ints1d, pad: int = 0) -> List2d: ... # further specific typed signatures can be added as necessary @overload def unflatten(self, X: ArrayXd, lengths: Ints1d, pad: int = 0) -> ListXd: ... def unflatten(self, X: ArrayXd, lengths: Ints1d, pad: int = 0) -> ListXd: """The reverse/backward operation of the `flatten` function: unflatten a large array into a list of arrays according to the given lengths. """ # cupy.split requires lengths to be in CPU memory. lengths = to_numpy(lengths) if pad > 0: lengths = numpy.where(lengths > 0, lengths + pad, 0) # type: ignore unflat = self.xp.split(X, numpy.cumsum(lengths))[:-1] # type: ignore if pad > 0: unflat = [a[pad:] for a in unflat] assert len(unflat) == len(lengths) return unflat @overload def pad(self, seqs: List[Ints2d], round_to=1) -> Ints3d: ... @overload # noqa: F811 def pad(self, seqs: List[Floats2d], round_to=1) -> Floats3d: ... def pad( # noqa: F811 self, seqs: Union[List[Ints2d], List[Floats2d]], round_to=1 ) -> Array3d: """Perform padding on a list of arrays so that they each have the same length, by taking the maximum dimension across each axis. This only works on non-empty sequences with the same `ndim` and `dtype`. """ if round_to < 1: raise ValueError( f"Rounding for padding must at least be 1, was: {round_to}" ) # TODO: This should be generalized to handle different ranks if not seqs: raise ValueError("Cannot pad empty sequence") if len(set(seq.ndim for seq in seqs)) != 1: raise ValueError("Cannot pad sequences with different ndims") if len(set(seq.dtype for seq in seqs)) != 1: raise ValueError("Cannot pad sequences with different dtypes") if len(set(seq.shape[1:] for seq in seqs)) != 1: raise ValueError("Cannot pad sequences that differ on other dimensions") # Find the maximum dimension along each axis. That's what we'll pad to. max_seq_len = max(len(seq) for seq in seqs) # Round the length to nearest bucket -- helps on GPU, to make similar # array sizes. max_seq_len += -max_seq_len % round_to final_shape = (len(seqs), max_seq_len) + seqs[0].shape[1:] output: Array3d = cast(Array3d, self.alloc(final_shape, dtype=seqs[0].dtype)) for i, arr in enumerate(seqs): # It's difficult to convince this that the dtypes will match. output[i, : arr.shape[0]] = arr # type: ignore[assignment, call-overload] return output def unpad(self, padded: Array3d, lengths: List[int]) -> List2d: """The reverse/backward operation of the `pad` function: transform an array back into a list of arrays, each with their original length. """ output = [] for i, length in enumerate(lengths): output.append(padded[i, :length]) return cast(List2d, output) def list2padded(self, seqs: List2d) -> Padded: """Pack a sequence of 2d arrays into a Padded datatype.""" if not seqs: return Padded( self.alloc3f(0, 0, 0), self.alloc1i(0), self.alloc1i(0), self.alloc1i(0) ) elif len(seqs) == 1: data = self.reshape3(seqs[0], seqs[0].shape[0], 1, seqs[0].shape[1]) size_at_t = self.asarray1i([1] * data.shape[0]) lengths = self.asarray1i([data.shape[0]]) indices = self.asarray1i([0]) return Padded(data, size_at_t, lengths, indices) lengths_indices = [(len(seq), i) for i, seq in enumerate(seqs)] lengths_indices.sort(reverse=True) indices_ = [i for length, i in lengths_indices] lengths_ = [length for length, i in lengths_indices] nS = max([seq.shape[0] for seq in seqs]) nB = len(seqs) nO = seqs[0].shape[1] # Reorder the sequences, by length. This looks the same in either # direction: you're swapping elements between their original and sorted # position. seqs = cast(List2d, [seqs[i] for i in indices_]) arr: Array3d = self.pad(seqs) assert arr.shape == (nB, nS, nO), (nB, nS, nO) arr = self.as_contig(arr.transpose((1, 0, 2))) assert arr.shape == (nS, nB, nO) # Build a lookup table so we can find how big the batch is at point t. batch_size_at_t_ = [0 for _ in range(nS)] current_size = len(lengths_) for t in range(nS): while current_size and t >= lengths_[current_size - 1]: current_size -= 1 batch_size_at_t_[t] = current_size assert sum(lengths_) == sum(batch_size_at_t_) return Padded( arr, self.asarray1i(batch_size_at_t_), self.asarray1i(lengths_), self.asarray1i(indices_), ) def padded2list(self, padded: Padded) -> List2d: """Unpack a Padded datatype to a list of 2-dimensional arrays.""" data = padded.data indices = to_numpy(padded.indices) lengths = to_numpy(padded.lengths) unpadded: List[Optional[Array2d]] = [None] * len(lengths) # Transpose from (length, batch, data) to (batch, length, data) data = self.as_contig(data.transpose((1, 0, 2))) for i in range(data.shape[0]): unpadded[indices[i]] = data[i, : int(lengths[i])] return cast(List2d, unpadded) def get_dropout_mask(self, shape: Shape, drop: Optional[float]) -> FloatsXd: """Create a random mask for applying dropout, with a certain percent of the mask (defined by `drop`) will contain zeros. The neurons at those positions will be deactivated during training, resulting in a more robust network and less overfitting. """ if drop is None or drop <= 0: return self.xp.ones(shape, dtype="f") elif drop >= 1.0: return self.alloc_f(shape) coinflips = self.xp.random.uniform(0.0, 1.0, shape) mask = (coinflips >= drop) / (1.0 - drop) return cast(FloatsXd, self.asarray(mask, dtype="float32")) def alloc1f( self, d0: int, *, dtype: Optional[DTypesFloat] = "float32", zeros: bool = True, ) -> Floats1d: return cast(Floats1d, self.alloc((d0,), dtype=dtype, zeros=zeros)) def alloc2f( self, d0: int, d1: int, *, dtype: Optional[DTypesFloat] = "float32", zeros: bool = True, ) -> Floats2d: return cast(Floats2d, self.alloc((d0, d1), dtype=dtype, zeros=zeros)) def alloc3f( self, d0: int, d1: int, d2: int, *, dtype: Optional[DTypesFloat] = "float32", zeros: bool = True, ) -> Floats3d: return cast(Floats3d, self.alloc((d0, d1, d2), dtype=dtype, zeros=zeros)) def alloc4f( self, d0: int, d1: int, d2: int, d3: int, *, dtype: Optional[DTypesFloat] = "float32", zeros: bool = True, ) -> Floats4d: return cast(Floats4d, self.alloc((d0, d1, d2, d3), dtype=dtype, zeros=zeros)) def alloc_f( self, shape: Shape, *, dtype: Optional[DTypesFloat] = "float32", zeros: bool = True, ) -> FloatsXd: return cast(FloatsXd, self.alloc(shape, dtype=dtype, zeros=zeros)) def alloc1i( self, d0: int, *, dtype: Optional[DTypesInt] = "int32", zeros: bool = True, ) -> Ints1d: return cast(Ints1d, self.alloc((d0,), dtype=dtype, zeros=zeros)) def alloc2i( self, d0: int, d1: int, *, dtype: Optional[DTypesInt] = "int32", zeros: bool = True, ) -> Ints2d: return cast(Ints2d, self.alloc((d0, d1), dtype=dtype, zeros=zeros)) def alloc3i( self, d0: int, d1: int, d2: int, *, dtype: Optional[DTypesInt] = "int32", zeros: bool = True, ) -> Ints3d: return cast(Ints3d, self.alloc((d0, d1, d2), dtype=dtype, zeros=zeros)) def alloc4i( self, d0: int, d1: int, d2: int, d3: int, *, dtype: Optional[DTypesInt] = "int32", zeros: bool = True, ) -> Ints4d: return cast(Ints4d, self.alloc((d0, d1, d2, d3), dtype=dtype, zeros=zeros)) def alloc_i( self, shape: Shape, *, dtype: Optional[DTypesInt] = "int32", zeros: bool = True, ) -> IntsXd: return cast(IntsXd, self.alloc(shape, dtype=dtype, zeros=zeros)) def alloc( self, shape: Shape, *, dtype: Optional[DTypes] = "float32", zeros: bool = True, ) -> Any: """Allocate an array of a certain shape.""" if isinstance(shape, int): shape = (shape,) if zeros: return self.xp.zeros(shape, dtype=dtype) else: return self.xp.empty(shape, dtype=dtype) def reshape1(self, array: ArrayXd, d0: int) -> Array1d: return cast(Array1d, self.reshape(array, (d0,))) def reshape2(self, array: ArrayXd, d0: int, d1: int) -> Array2d: return cast(Array2d, self.reshape(array, (d0, d1))) def reshape3(self, array: ArrayXd, d0: int, d1: int, d2: int) -> Array3d: return cast(Array3d, self.reshape(array, (d0, d1, d2))) def reshape4(self, array: ArrayXd, d0: int, d1: int, d2: int, d3: int) -> Array4d: return cast(Array4d, self.reshape(array, (d0, d1, d2, d3))) def reshape1f(self, array: FloatsXd, d0: int) -> Floats1d: return cast(Floats1d, self.reshape(array, (d0,))) def reshape2f(self, array: FloatsXd, d0: int, d1: int) -> Floats2d: return cast(Floats2d, self.reshape(array, (d0, d1))) def reshape3f(self, array: FloatsXd, d0: int, d1: int, d2: int) -> Floats3d: return cast(Floats3d, self.reshape(array, (d0, d1, d2))) def reshape4f( self, array: FloatsXd, d0: int, d1: int, d2: int, d3: int ) -> Floats4d: return cast(Floats4d, self.reshape(array, (d0, d1, d2, d3))) def reshape_f(self, array: FloatsXd, shape: Shape) -> FloatsXd: return self.reshape(array, shape) def reshape1i(self, array: IntsXd, d0: int) -> Ints1d: return cast(Ints1d, self.reshape(array, (d0,))) def reshape2i(self, array: IntsXd, d0: int, d1: int) -> Ints2d: return cast(Ints2d, self.reshape(array, (d0, d1))) def reshape3i(self, array: IntsXd, d0: int, d1: int, d2: int) -> Ints3d: return cast(Ints3d, self.reshape(array, (d0, d1, d2))) def reshape4i(self, array: IntsXd, d0: int, d1: int, d2: int, d3: int) -> Ints4d: return cast(Ints4d, self.reshape(array, (d0, d1, d2, d3))) def reshape_i(self, array: IntsXd, shape: Shape) -> IntsXd: return self.reshape(array, shape) def reshape(self, array: ArrayT, shape: Shape) -> ArrayT: """Reshape an array.""" if isinstance(shape, int): shape = (shape,) return cast(ArrayT, array.reshape(shape)) def asarray4f( self, data: Union[Floats4d, Sequence[Sequence[Sequence[Sequence[float]]]]], *, dtype: Optional[DTypes] = "float32", ) -> Floats4d: return cast(Floats4d, self.asarray(data, dtype=dtype)) def asarray3f( self, data: Union[Floats3d, Sequence[Sequence[Sequence[float]]]], *, dtype: Optional[DTypes] = "float32", ) -> Floats3d: return cast(Floats3d, self.asarray(data, dtype=dtype)) def asarray2f( self, data: Union[Floats2d, Sequence[Sequence[float]]], *, dtype: Optional[DTypes] = "float32", ) -> Floats2d: return cast(Floats2d, self.asarray(data, dtype=dtype)) def asarray1f( self, data: Union[Floats1d, Sequence[float]], *, dtype: Optional[DTypes] = "float32", ) -> Floats1d: return cast(Floats1d, self.asarray(data, dtype=dtype)) def asarray_f( self, data: Union[FloatsXd, Sequence[Any]], *, dtype: Optional[DTypes] = "float32", ) -> FloatsXd: return cast(FloatsXd, self.asarray(data, dtype=dtype)) def asarray1i( self, data: Union[Ints1d, Sequence[int]], *, dtype: Optional[DTypes] = "int32" ) -> Ints1d: return cast(Ints1d, self.asarray(data, dtype=dtype)) def asarray2i( self, data: Union[Ints2d, Sequence[Sequence[int]]], *, dtype: Optional[DTypes] = "int32", ) -> Ints2d: return cast(Ints2d, self.asarray(data, dtype=dtype)) def asarray3i( self, data: Union[Ints3d, Sequence[Sequence[Sequence[int]]]], *, dtype: Optional[DTypes] = "int32", ) -> Ints3d: return cast(Ints3d, self.asarray(data, dtype=dtype)) def asarray4i( self, data: Union[Ints4d, Sequence[Sequence[Sequence[Sequence[int]]]]], *, dtype: Optional[DTypes] = "int32", ) -> Ints4d: return cast(Ints4d, self.asarray(data, dtype=dtype)) def asarray_i( self, data: Union[IntsXd, Sequence[Any]], *, dtype: Optional[DTypes] = "int32" ) -> IntsXd: return cast(IntsXd, self.asarray(data, dtype=dtype)) def asarray( self, data: Union[ArrayXd, Sequence[ArrayXd], Sequence[Any]], *, dtype: Optional[DTypes] = None, ) -> ArrayXd: """Ensure a given array is of the correct type.""" if isinstance(data, self.xp.ndarray): if dtype is None: return data elif data.dtype == dtype: return data else: return self.xp.asarray(data, dtype=dtype) elif hasattr(data, "numpy"): # Handles PyTorch Tensor return data.numpy() # type: ignore[union-attr] elif dtype is not None: return self.xp.array(data, dtype=dtype) else: return self.xp.array(data) def as_contig(self, data: ArrayT, dtype: Optional[DTypes] = None) -> ArrayT: """Allow the backend to make a contiguous copy of an array. Implementations of `Ops` do not have to make a copy or make it contiguous if that would not improve efficiency for the execution engine. """ if data.flags["C_CONTIGUOUS"] and dtype in (None, data.dtype): return data kwargs = {"dtype": dtype} if dtype is not None else {} return self.xp.ascontiguousarray(data, **kwargs) def sigmoid(self, X: FloatsXdT, *, inplace: bool = False) -> FloatsXdT: if inplace: # To prevent overflows and help with regularization/numerical stability X = self.xp.clip(X, -20.0, 20.0, out=X) self.xp.exp(-X, out=X) X += 1.0 X **= -1.0 return X else: X = self.xp.clip(X, -20.0, 20.0) return 1.0 / (1.0 + self.xp.exp(-X)) def backprop_sigmoid( self, dY: FloatsXdT, Y: FloatsXdT, *, inplace: bool = False ) -> FloatsXdT: if inplace: self.dsigmoid(Y, inplace=True) Y *= dY return Y else: return dY * self.dsigmoid(Y, inplace=inplace) def dsigmoid(self, Y: FloatsXdT, *, inplace: bool = False) -> FloatsXdT: if inplace: Y *= 1 - Y return Y else: return Y * (1.0 - Y) def dtanh(self, Y: FloatsT, *, inplace: bool = False) -> FloatsT: if inplace: Y **= 2 Y *= -1.0 Y += 1.0 return Y else: return 1 - Y**2 def softmax( self, x: FloatsT, *, inplace: bool = False, axis: int = -1, temperature: float = 1.0, ) -> FloatsT: if temperature != 1.0: x = x / temperature maxes = self.xp.max(x, axis=axis, keepdims=True) shifted = x - maxes new_x = self.xp.exp(shifted) new_x /= new_x.sum(axis=axis, keepdims=True) return new_x def softmax_sequences( self, Xs: Floats2d, lengths: Ints1d, *, inplace: bool = False, axis: int = -1 ) -> Floats2d: if Xs.ndim >= 3: err = f"Softmax currently only supports 2d. Got: {Xs.ndim}" raise NotImplementedError(err) # This loses almost no fidelity, and helps the numerical stability. Xs = self.xp.clip(Xs, -20.0, 20.0) new_x = self.xp.exp(Xs) summed = self.backprop_reduce_sum(self.reduce_sum(new_x, lengths), lengths) new_x /= summed return new_x def backprop_softmax( self, Y: FloatsT, dY: FloatsT, *, axis: int = -1, temperature: float = 1.0 ) -> FloatsT: if temperature != 1.0: dY = dY / temperature dX = Y * dY dX -= Y * dX.sum(axis=axis, keepdims=True) return dX def backprop_softmax_sequences( self, dY: Floats2d, Y: Floats2d, lengths: Ints1d ) -> Floats2d: dX = Y * dY sum_dX = self.backprop_reduce_sum(self.reduce_sum(dX, lengths), lengths) dX -= Y * sum_dX return dX def lstm_forward_training( self, params: Floats1d, H0: Floats3d, C0: Floats3d, X: Floats2d, size_at_t: Ints1d, ) -> Tuple[Floats2d, Tuple]: assert H0.shape == C0.shape assert H0.shape[1] == C0.shape[1] Y, fwd_state = lstm_forward_training(params, H0, C0, X, size_at_t) return Y, fwd_state def lstm_forward_inference( self, params: Floats1d, H0: Floats3d, C0: Floats3d, X: Floats2d, size_at_t: Ints1d, ) -> Floats2d: Y, _ = lstm_forward_training(params, H0, C0, X, size_at_t) return Y def backprop_lstm( self, dY: Floats2d, lengths: Ints1d, params: Floats1d, fwd_state: Tuple ) -> Tuple[Floats2d, Floats1d]: dX, d_params = backprop_lstm(dY, lengths, params, fwd_state) return dX, d_params def maxout(self, X: Floats3d) -> Tuple[Floats2d, Ints2d]: which = X.argmax(axis=-1) return X.max(axis=-1), which def backprop_maxout(self, dY: Floats2d, which: Ints2d, P: int) -> Floats3d: dX = self.alloc3f(dY.shape[0], dY.shape[1], P, dtype=dY.dtype) for b in range(dY.shape[0]): for o in range(dY.shape[1]): dX[b, o, which[b, o]] = dY[b, o] return dX def relu(self, X: Floats2d, inplace: bool = False) -> Floats2d: if not inplace: return X * (X > 0) else: X *= X > 0 return X def backprop_relu( self, dY: Floats2d, Y: Floats2d, inplace: bool = False ) -> Floats2d: if not inplace: return dY * (Y > 0) dY *= Y > 0 return dY def clipped_linear( self, X: FloatsXdT, slope: float = 1.0, offset: float = 0.0, min_val: float = 0.0, max_val: float = 1.0, inplace: bool = False, ) -> FloatsXdT: if inplace: X *= slope X += offset return self.xp.clip(X, min_val, max_val, out=X) out = X * slope + offset return self.xp.clip(out, min_val, max_val) def backprop_clipped_linear( self, dY: FloatsXdT, X: FloatsXdT, slope: float = 1.0, offset: float = 0.0, min_val: float = 0.0, max_val: float = 1.0, inplace: bool = False, ) -> FloatsXdT: low = (min_val - offset) / slope high = (max_val - offset) / slope slope = self.xp.float64(slope).astype(X.dtype) zero = self.xp.float64(0.0).astype(X.dtype) dX = self.xp.where((low < X) & (X < high), slope, zero) if inplace: dY *= dX return dY return dY * dX def relu_k(self, X: FloatsXdT, n: float = 6.0, inplace: bool = False) -> FloatsXdT: return self.clipped_linear(X, max_val=n, inplace=inplace) def backprop_relu_k( self, dY: FloatsXdT, X: FloatsXdT, n: float = 6.0, inplace: bool = False ) -> FloatsXdT: return self.backprop_clipped_linear(dY, X, max_val=n, inplace=inplace) def hard_sigmoid(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: return self.clipped_linear(X, slope=0.2, offset=0.5, inplace=inplace) def backprop_hard_sigmoid( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: return self.backprop_clipped_linear(dY, X, slope=0.2, offset=0.5) def hard_tanh(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: return self.clipped_linear(X, min_val=-1.0, max_val=1.0, inplace=inplace) def backprop_hard_tanh( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: return self.backprop_clipped_linear(dY, X, min_val=-1.0, max_val=1.0) def swish(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: if inplace: X *= self.sigmoid(X) return X out = X * self.sigmoid(X) return out def backprop_swish( self, dY: FloatsXdT, X: FloatsXdT, Y: FloatsXdT, inplace: bool = False ) -> FloatsXdT: Y = Y + self.sigmoid(X) * (1 - Y) if inplace: dY *= Y return dY out = dY * Y return out # Following https://www.scitepress.org/Papers/2019/74696/74696.pdf def hard_swish(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: if inplace: X *= self.hard_sigmoid(X) return X out = X * self.hard_sigmoid(X) return out def backprop_hard_swish( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: dX = X * 0.4 + 0.5 dX[X > 2.5] = 1.0 dX[X < -2.5] = 0 if inplace: dY *= dX return dY return dY * dX # From https://arxiv.org/pdf/1905.02244v5.pdf def hard_swish_mobilenet(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: if inplace: X *= self.relu_k(X + 3) / 6 return X return X * (self.relu_k(X + 3) / 6) def backprop_hard_swish_mobilenet( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: dX = (1 / 6) * (X * 2.0 + 3.0) dX[X > 3.0] = 1.0 dX[X < -3.0] = 0 if inplace: dY *= dX return dY return dX * dY def dish(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: tmp = self.xp.square(X) tmp += 1.0 self.xp.sqrt(tmp, out=tmp) tmp = X / tmp tmp += 1 tmp *= 0.5 if inplace: X *= tmp return X else: return X * tmp def backprop_dish( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: x_sq = self.xp.square(X) x_sq_plus_one = x_sq + 1.0 deriv = X / self.xp.sqrt(x_sq_plus_one) second = 0.5 * X * x_sq second /= x_sq_plus_one**1.5 deriv -= second deriv += 0.5 if inplace: dY *= deriv return dY else: return dY * deriv # Code snippet taken from: # https://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/ def erf(self, X: FloatsXdT) -> FloatsXdT: # save the sign of x sign = self.xp.sign(X) X = self.xp.abs(X) a1 = 0.254829592 a2 = -0.284496736 a3 = 1.421413741 a4 = -1.453152027 a5 = 1.061405429 p = 0.3275911 t = 1.0 / (1.0 + p * X) y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * self.xp.exp( -X * X ) out = sign * y out = out.astype(X.dtype) return out def sechsq(self, X: FloatsXdT) -> FloatsXdT: # Avoid overflow in cosh. Clipping at |20| has an error of 1.7e-17. X = self.xp.clip(X, -20.0, 20.0) return (1 / self.xp.cosh(X)) ** 2 def gelu_approx(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: tmp = 1.0 + self.xp.tanh(SQRT2PI * (X + 0.044715 * self.xp.power(X, 3))) tmp *= 0.5 tmp = tmp.astype(X.dtype) if inplace: X *= tmp return X else: Y = self.xp.array(X) Y *= tmp return Y def backprop_gelu_approx( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: dX = cast(FloatsXdT, self.alloc_f(X.shape)) Xp3 = self.xp.power(X, 3) tmp = 0.5 * self.xp.tanh(0.0356774 * Xp3 + 0.797885 * X) tmp += (0.0535161 * Xp3 + 0.398942 * X) * self.sechsq( 0.0356774 * Xp3 + 0.797885 * X ) tmp += 0.5 dX += tmp if inplace: dY *= dX return dY return dY * dX def gelu(self, X: FloatsXdT, inplace: bool = False) -> FloatsXdT: # GELU(x) = x ยท ฮฆ(x) cdf = gaussian_cdf(self, X) if inplace: X *= cdf return X return X * cdf def backprop_gelu( self, dY: FloatsXdT, X: FloatsXdT, inplace: bool = False ) -> FloatsXdT: # GELU'(x) = ฮฆ(x) + x ยท PDF(x) dX = gaussian_cdf(self, X) + X * gaussian_pdf(self, X) if inplace: dY *= dX return dY return dY * dX def mish( self, X: FloatsXdT, threshold: float = 20.0, inplace: bool = False ) -> FloatsXdT: tmp = X * self.xp.tanh(self.xp.log(1.0 + self.xp.exp(X))) Y = self.xp.where(X >= threshold, X, tmp) if inplace: X[:] = Y return X else: return Y def backprop_mish( self, dY: FloatsXdT, X: Floats2d, threshold: float = 20.0, inplace: bool = False, ) -> FloatsXdT: if dY.shape != X.shape: msg = f"arrays have incompatible shapes: {dY.shape} and {X.shape}" raise ValueError(msg) xp = get_array_module(X) indices = X < threshold Xsub = X[indices] dYsub = dY[indices] omega = 4.0 * (Xsub + 1.0) omega += 4.0 * xp.exp(2.0 * Xsub) omega += xp.exp(3.0 * Xsub) omega += xp.exp(Xsub) * ((4.0 * Xsub) + 6.0) delta = xp.exp(Xsub) + 1.0 delta *= delta delta += 1.0 dXsub = dYsub * ((xp.exp(Xsub) * omega) / (delta**2)) # Gradient when above threshold will ignore softplus. if inplace: out = dY else: out = xp.copy(dY) out[indices] = dXsub return out def update_averages( self, ema: FloatsT, weights: FloatsT, t: int, max_decay: float = 0.9999 ) -> None: # Internals for optimizer decay = (1.0 + t) / (10.0 + t) if decay > max_decay: decay = max_decay ema -= (1 - decay) * (ema - weights) def adam( self, weights: Floats1d, gradient: Floats1d, mom1: Floats1d, mom2: Floats1d, beta1: float, beta2: float, eps: float, learn_rate: float, mod_rate: float = 1.0, ) -> Tuple[Floats1d, Floats1d, Floats1d, Floats1d]: _check_compatible_shape(weights, gradient) _check_compatible_shape(weights, mom1) _check_compatible_shape(weights, mom2) # Internals for optimizer mom1 *= beta1 mom2 *= beta2 mom1 += gradient * (1.0 - beta1) mom2 += gradient * gradient * (1.0 - beta2) # Here we assume learn rate is calculated by the caller. # cdef weight_t a_t = learn_rate * sqrt(1-beta2**hp.t) / (1-beta1**hp.t); weights -= learn_rate * (mom1 / (mod_rate * self.xp.sqrt(mom2) + eps)) return weights, gradient, mom1, mom2 def clip_gradient(self, gradient: FloatsT, threshold: float) -> FloatsT: # Internals for optimizer xp = get_array_module(gradient) grad_norm = xp.linalg.norm(gradient) if grad_norm >= threshold: gradient *= threshold / grad_norm return gradient def logloss(self, y_true: FloatsT, y_pred: FloatsT) -> float: # Currently not used log_yp = self.xp.log(y_pred + 1e-8) loss = (y_true * log_yp) + (1 - y_true) * self.xp.log((1 - y_pred) + 1e-8) return -loss def reduce_sum(self, X: Floats2d, lengths: Ints1d) -> Floats2d: Y = self.alloc2f(lengths.shape[0], X.shape[1], zeros=False) start = 0 for i, length in enumerate(lengths): if length < 0: raise ValueError(f"all sequence lengths must be >= 0, got {length}") elif start + length > X.shape[0]: raise IndexError("lengths must sum up to the number of rows") elif length: Y[i] = X[start : start + length].sum(axis=0) start += length else: Y[i] = 0.0 return Y def reduce_first(self, X: Floats2d, lengths: Ints1d) -> Tuple[Floats2d, Ints1d]: if lengths.size == 0: return self.alloc2f(0, X.shape[1]), lengths if not self.xp.all(lengths > 0): raise ValueError(f"all sequence lengths must be > 0") starts_ends = self.alloc1i(lengths.shape[0] + 1, zeros=False) starts_ends[0] = 0 starts_ends[1:] = lengths.cumsum() if starts_ends[-1] != X.shape[0]: raise IndexError("lengths must sum up to the number of rows") return X[starts_ends[:-1]], starts_ends def reduce_last(self, X: Floats2d, lengths: Ints1d) -> Tuple[Floats2d, Ints1d]: if lengths.size == 0: return self.alloc2f(0, X.shape[1]), lengths if not self.xp.all(lengths > 0): raise ValueError(f"all sequence lengths must be > 0") lasts = lengths.cumsum() - 1 if lasts[-1] + 1 != X.shape[0]: raise IndexError("lengths must sum up to the number of rows") return X[lasts], lasts def reduce_mean(self, X: Floats2d, lengths: Ints1d) -> Floats2d: Y = self.alloc2f(lengths.shape[0], X.shape[1], zeros=False) start = 0 for i, length in enumerate(lengths): if length < 0: raise ValueError(f"all sequence lengths must be >= 0, got {length}") elif start + length > X.shape[0]: raise IndexError("lengths must sum up to the number of rows") elif length: Y[i] = X[start : start + length].mean(axis=0) else: Y[i] = 0.0 start += length return Y def reduce_max(self, X: Floats2d, lengths: Ints1d) -> Tuple[Floats2d, Ints2d]: Y = self.alloc2f(lengths.shape[0], X.shape[1], dtype=X.dtype, zeros=False) which = self.alloc2i(lengths.shape[0], X.shape[1], zeros=False) start = 0 for i, length in enumerate(lengths): if length <= 0: raise ValueError(f"all sequence lengths must be > 0, got {length}") elif start + length > X.shape[0]: raise IndexError("lengths must sum up to the number of rows") elif length: which[i] = X[start : start + length].argmax(axis=0) Y[i] = X[start : start + length].max(axis=0) start += length return Y, which def backprop_reduce_first( self, d_firsts: Floats2d, starts_ends: Ints1d ) -> Floats2d: if starts_ends.size == 0: return self.alloc2f(0, d_firsts.shape[1], dtype=d_firsts.dtype, zeros=True) elif starts_ends.size == 1: raise ValueError(f"starts_ends must not have size 1") dX = self.alloc2f( int(starts_ends[-1]), d_firsts.shape[1], dtype=d_firsts.dtype, zeros=True ) dX[starts_ends[:-1]] = d_firsts return dX def backprop_reduce_last(self, d_lasts: Floats2d, lasts: Ints1d) -> Floats2d: if lasts.size == 0: return self.alloc2f(0, d_lasts.shape[1], dtype=d_lasts.dtype, zeros=True) dX = self.alloc2f( int(lasts[-1]) + 1, d_lasts.shape[1], dtype=d_lasts.dtype, zeros=True ) dX[lasts] = d_lasts return dX def backprop_reduce_sum(self, d_sums: Floats2d, lengths: Ints1d) -> Floats2d: dX = self.alloc2f( lengths.sum(), d_sums.shape[1], dtype=d_sums.dtype, zeros=False ) start = 0 for i, length in enumerate(lengths): if length < 0: raise ValueError(f"all sequence lengths must be >= 0, got {length}") dX[start : start + length] = d_sums[i] start += length return dX def backprop_reduce_mean(self, d_means: Floats2d, lengths: Ints1d) -> Floats2d: dX = self.alloc2f( lengths.sum(), d_means.shape[1], dtype=d_means.dtype, zeros=False ) start = 0 for i, length in enumerate(lengths): if length < 0: raise ValueError(f"all sequence lengths must be >= 0, got {length}") dX[start : start + length] = d_means[i] / length start += length return dX def backprop_reduce_max( self, d_maxes: Floats2d, which: Ints2d, lengths: Ints1d ) -> Floats2d: dX = self.alloc2f(lengths.sum(), d_maxes.shape[1], dtype=d_maxes.dtype) start = 0 for i, length in enumerate(lengths): if length <= 0: raise ValueError(f"all sequence lengths must be > 0, got {length}") self.xp.put_along_axis( dX[start : start + length], which[i].reshape((1, -1)), d_maxes[i], 0 ) start += length return dX def hash(self, ids: Ints1d, seed: int) -> Ints2d: """Hash a sequence of 64-bit keys into a table with 4 32-bit keys, using murmurhash3. """ from .numpy_ops import NumpyOps numpy_ops = NumpyOps() return self.asarray2i( numpy_ops.hash(numpy_ops.asarray(ids, dtype="uint64"), seed) ) def ngrams(self, n: int, keys: Ints1d) -> Ints1d: from .numpy_ops import NumpyOps numpy_ops = NumpyOps() return self.asarray1i( numpy_ops.ngrams(n, numpy_ops.asarray(keys, dtype="uint64")) ) def position_encode( self, N: int, D: int, period: int = 10000, out: Optional[Floats2d] = None ) -> Floats2d: # Currently internals only from .numpy_ops import NumpyOps numpy_ops = NumpyOps() return self.asarray2f(numpy_ops.position_encode(N, D, period, out)) def gather_add(self, table: Floats2d, indices: Ints2d) -> Floats2d: return table[indices].sum(axis=1) # type: ignore[return-value] def scatter_add( self, table: FloatsXd, indices: IntsXd, values: FloatsXd ) -> FloatsXd: return self.xp.add.at(table, indices, values) def insert_into(self, shape, Xs): """Maybe don't need this? Just a quicky to get Jax working.""" output = self.alloc(shape, dtype=Xs[0].dtype) for i, x in enumerate(Xs): output[i, : x.shape[0]] = x return output """ LSTM Notation (kind of involved, but made it a lot easier to write) X: Inputs Y: Outputs (aka hiddens) C: Cells G: Gates (Output of non-linearity, i.e. lstm_gates(X @ W.T) A: Activations (X @ W.T, before non-linearity) Imagine we have the input: batch = [ ["apple", "banana", "cantaloupe", "date", "elderberry"], ["aardvark", "bat", "capybara", "dingo", "elephant"] ] The input variable X will have one vector per word, so X[0, 1] will be banana's vector, X[0, 1, 0] will be a float, the first element of that vector. We're computing an output variable Y of shape (nL, nB, nO), so that Y[0, 1] is the output variable of banana. A problem with variables for RNNs is keeping the timesteps straight. It's hard to distinguish the current, previous, and next timesteps. To solve this problem, we follow the convention that **we are at timestep 3**. Additionally, the variables for Y and C are offset by one, as the 0th elements have the initial hiddens and initial cells. So: t=3 Xt3: The input vectors for 'dingo' and 'date', i.e. X[t] Yt3: The output vectors for 'dingo' and 'date', i.e. Y[t+1] (Y is offset.) Ct2: The cells calculated at 'c...', that are the input for 'd...' Ct3: The cells calculated at 'd...', that are the input for 'e...' At3: The activations at 'd...' Gt3: The gates at 'd...' """ def lstm_forward_training( params: Floats1d, c_init: Floats3d, h_init: Floats3d, X: Floats2d, lengths: Ints1d ) -> Tuple[Floats2d, Tuple]: xp = get_array_module(params) depth, dirs, nO = c_init.shape N, nI = X.shape batch_size = lengths[0] # Preallocate these so we can pass them through for loop. G = cast(Floats4d, xp.zeros((depth, dirs, X.shape[0], nO * 4), dtype="f")) Y = cast(Floats4d, xp.zeros((depth, dirs, X.shape[0], nO), dtype="f")) C = cast(Floats4d, xp.zeros((depth, dirs, X.shape[0], nO), dtype="f")) Yt2 = cast(Floats2d, xp.zeros((batch_size, nO), dtype="f")) Ct2 = cast(Floats2d, xp.zeros((batch_size, nO), dtype="f")) # Compute the start and end indices first. indices = [] start = 0 for batch_size in lengths: indices.append((start, start + batch_size)) start += batch_size params_i = 0 orig_X = X for i in range(depth): nI = X.shape[1] for d in range(dirs): # The inits are shaped (depth, dirs, nO). We add the internal dimension # to make them set correctly. Yt2 = h_init[i, d].reshape((1, nO)) # type: ignore[assignment] Ct2 = c_init[i, d].reshape((1, nO)) # type: ignore[assignment] layer_params, params_i = _split_weights(params, i, nO, nI, params_i) Wx, Wh, bias = _transpose_weights(layer_params) G[i, d] += xp.dot(X, Wx.T) G[i, d] += bias for start, end in indices if d == 0 else reversed(indices): # When we iterate left-to-right, t2 might be longer than t3. Yt2 = Yt2[: end - start] Ct2 = Ct2[: end - start] # But in right-to-left, it's the opposite: t3 can be longer. Gt3 = G[i, d, start:end] Gt3 = Gt3[: Yt2.shape[0]] Gt3 += xp.dot(Yt2, Wh.T) Gt3_ = cast(Floats3d, Gt3.reshape((-1, nO, 4))) hf = sigmoid(Gt3_[:, :, 0]) hi = sigmoid(Gt3_[:, :, 1]) ho = sigmoid(Gt3_[:, :, 2]) hc = xp.tanh(Gt3_[:, :, 3]) Ct3 = hf * Ct2 Ct3 += hi * hc # Store results Gt3 = ( xp.hstack((hf, hi, ho, hc)) .reshape((-1, 4, nO)) .transpose((0, 2, 1)) .reshape((-1, nO * 4)) ) # Fix the endpoint to account for shorter slices when iterating # reversed. Not 100% sure this is right. If there's a bug, look # here? end = min(end, start + ho.shape[0]) Y[i, d, start:end] = xp.tanh(Ct3) * ho G[i, d, start:end] = Gt3 C[i, d, start:end] = Ct3 # Set the t2 variables to the current t3 variables. Ct2 = Ct3 Yt2 = Y[i, d, start:end] H = cast(Floats2d, Y[i].transpose((1, 0, 2)).reshape((N, -1))) if dirs == 2: H = xp.ascontiguousarray(H) X = H return H, (Y, G, C, orig_X) def backprop_lstm(dY: Floats2d, lengths: Ints1d, params: Floats1d, fwd_state: Tuple): xp = get_array_module(params) Y: Floats4d G: Floats4d C: Floats4d X: Floats2d Wx: Floats2d Wh: Floats2d bias: Floats1d dWx: Floats2d dWh: Floats2d d_bias: Floats1d Y, G, C, X = fwd_state depth, dirs, N, nO = C.shape nI = X.shape[1] batch_size = lengths[0] # We don't need to store all the cells for all the layers. dC = cast(Floats2d, xp.zeros((N, nO), dtype=C.dtype)) dG = cast(Floats2d, xp.zeros((N, nO * 4), dtype=C.dtype)) d_params = cast(Floats1d, xp.zeros((params.shape[0],), dtype=params.dtype)) # Collect the params and slices. It makes it a bit easier to get the indexing # right, when we're iterating backwards. params_i = 0 all_layer_params: List[List[Tuple[Tuple[Floats2d, Floats2d, Floats1d], int]]] = [] for i in range(depth): all_layer_params.append([]) n_inputs = nI if i == 0 else (nO * dirs) for d in range(dirs): layer_params, params_i = _split_weights(params, i, nO, n_inputs, params_i) layer_params = _transpose_weights(layer_params) all_layer_params[-1].append((layer_params, params_i)) params_i = 0 all_layer_grads: List[List[Tuple[Tuple[Floats2d, Floats2d, Floats1d], int]]] = [] for i in range(depth): all_layer_grads.append([]) n_inputs = nI if i == 0 else (nO * dirs) for d in range(dirs): layer_grads, params_i = _split_weights(d_params, i, nO, n_inputs, params_i) layer_grads = _transpose_weights(layer_grads) all_layer_grads[-1].append((layer_grads, params_i)) # Similarly, we want to compute the indices first indices = [] start = 0 for batch_size in lengths: indices.append((start, start + batch_size)) start += batch_size Xs = [X] + [ cast(Floats2d, Y[i].transpose((1, 0, 2)).reshape((N, -1))) for i in range(depth - 1) ] dXs = [xp.zeros((X.shape[0], X.shape[1]), dtype=X.dtype) for X in Xs] # Okay, now do the actual looping for i in reversed(range(depth)): dY3d = cast(Floats3d, dY.reshape((N, dirs, nO)).transpose((1, 0, 2))) dX = dXs[i] X = Xs[i] if dirs >= 2: dY3d = xp.ascontiguousarray(dY3d) for d in range(dirs): Wx, Wh, bias = all_layer_params[i][d][0] dWx, dWh, d_bias = all_layer_grads[i][d][0] if d == 0: start_t3, end_t3 = indices[-1] layer_indices = indices[:-1] layer_indices.reverse() else: start_t3, end_t3 = indices[0] layer_indices = indices[1:] for start_t2, end_t2 in layer_indices: size = min(end_t2 - start_t2, end_t3 - start_t3) dGt3, dCt2 = backprop_lstm_gates( dY3d[d, start_t3 : start_t3 + size], dC[start_t3 : start_t3 + size], G[i, d, start_t3 : start_t3 + size], C[i, d, start_t3 : start_t3 + size], C[i, d, start_t2 : start_t2 + size], ) # Backprop hidden-to-hidden w.r.t. hidden. dY3d[d, start_t2 : start_t2 + size] += dGt3 @ Wh # Update iteration variables dC[start_t2 : start_t2 + size] = dCt2 start_t3 = start_t2 end_t3 = end_t2 # Backprop input-to-hidden w.r.t. weights. dWx += dG.T @ X # Backprop hidden-to-hidden w.r.t. weights. dWh += dG.T @ Y[i, d] # Backprop bias d_bias += dG.sum(axis=0) # Backprop input-to-hidden w.r.t. input dX += dG @ Wx dY = dX assert dX.shape[1] == X.shape[1] grad_parts = [] for layer_grads in all_layer_grads: for dir_grads, _ in layer_grads: grad_parts.append(_untranspose_unsplit_weights(dir_grads)) return dX, xp.concatenate(grad_parts) def _split_weights(params: Floats1d, i: int, nO: int, nI: int, params_i: int): Wx_size = 4 * nO * nI bx_size = 4 * nO Wh_size = 4 * nO * nO bh_size = 4 * nO Wx = params[params_i : params_i + Wx_size].reshape((4 * nO, nI)) params_i += Wx_size bx = params[params_i : params_i + bx_size].reshape((4 * nO,)) params_i += bx_size Wh = params[params_i : params_i + Wh_size].reshape((4 * nO, nO)) params_i += Wh_size bh = params[params_i : params_i + bh_size].reshape((4 * nO,)) params_i += bh_size return ((Wx, bx), (Wh, bh)), params_i def _transpose_weights(params): # Transpose the parameters so that the gates are the last dimension. This # makes it easier to fuse. (Wx, bx), (Wh, bh) = params xp = get_array_module(Wx) Wx = Wx.reshape((4, -1, Wx.shape[-1])) Wx = Wx.transpose((1, 0, 2)).reshape((-1, Wx.shape[-1])) bx = bx.reshape((4, -1)).transpose((1, 0)).reshape((-1,)) Wh = Wh.reshape((4, -1, Wh.shape[-1])) Wh = Wh.transpose((1, 0, 2)).reshape((-1, Wh.shape[-1])) bh = bh.reshape((4, -1)).transpose((1, 0)).reshape((-1,)) ascontig = xp.ascontiguousarray Wx = ascontig(Wx) Wh = ascontig(Wh) bias = ascontig(bx) + bh return Wx, Wh, bias def _untranspose_unsplit_weights(params): Wx, Wh, bias = params xp = get_array_module(Wx) nO = Wh.shape[1] nI = Wx.shape[1] Wx = Wx.reshape((-1, 4, nI)).transpose((1, 0, 2)).reshape((-1, nI)) Wh = Wh.reshape((-1, 4, nO)).transpose((1, 0, 2)).reshape((-1, nO)) bias = bias.reshape((-1, 4)).transpose((1, 0)).reshape((-1,)) zeros = xp.zeros(bias.shape, dtype="f") return xp.concatenate((Wx.ravel(), bias, Wh.ravel(), zeros)) def backprop_lstm_gates( dYt3: Floats2d, dCt3: Floats2d, Gt3: Floats2d, Ct3: Floats2d, Ct2: Floats2d ) -> Tuple[Floats2d, Floats2d]: # See above for notation. Step numbering refers to forward_lstm_gates xp = get_array_module(dYt3) hf, hi, ho, hc = xp.split(Gt3, 4, axis=-1) assert hf.shape[0] == hi.shape[0] == ho.shape[0] == hc.shape[0] assert hf.shape[0] == dYt3.shape[0] == dCt3.shape[0] == Ct3.shape[0] == Ct2.shape[0] tanhCt3 = xp.tanh(Ct3) # 3b: Yt3 = tanhCt3 * ho d_ho = dYt3 * tanhCt3 d_tanhCt3 = dYt3 * ho # 3a: tanhCt3 = tanh(Ct3) dCt3 += d_tanhCt3 * dtanh(tanhCt3) # 2b: Ct3 += hi * hc d_hi = dCt3 * hc d_hc = dCt3 * hi # 2a: Ct3 = hf * Ct2 d_hf = dCt3 * Ct2 dCt2 = dCt3 * hf d_At3_hc = d_hc * dtanh(hc) # 1d d_At3_ho = d_ho * dsigmoid(ho) # 1c d_At3_hi = d_hi * dsigmoid(hi) # 1b d_At3_hf = d_hf * dsigmoid(hf) # 1a dAt3 = xp.concatenate((d_At3_hf, d_At3_hi, d_At3_ho, d_At3_hc), axis=-1) return dAt3, dCt2 def sigmoid(X, out=None): xp = get_array_module(X) # To prevent overflows and help with regularization/numerical stability X = xp.clip(X, -20.0, 20.0) return 1.0 / (1.0 + xp.exp(-X)) def dsigmoid(Y: ArrayT) -> ArrayT: return Y * (1.0 - Y) def dtanh(Y: ArrayT) -> ArrayT: return 1 - Y**2 def gaussian_cdf(ops: Ops, X: FloatsXdT) -> FloatsXdT: """Gaussian CDF for distribution with mean 0 and stdev 1.""" return 0.5 * (1.0 + ops.erf(INV_SQRT2 * X)) def gaussian_pdf(ops: Ops, X: FloatsXdT) -> FloatsXdT: """Gaussian PDF for distribution with mean 0 and stdev 1.""" return INV_SQRT_2PI * ops.xp.exp(-0.5 * X * X) def _check_compatible_shape(u: FloatsXd, v: FloatsXd): if u.shape != v.shape: msg = f"arrays have incompatible shapes: {u.shape} and {v.shape}" raise ValueError(msg) thinc-9.0.0/thinc/compat.py000066400000000000000000000063071461023342500155750ustar00rootroot00000000000000import platform import warnings from packaging.version import Version try: # pragma: no cover import cupy import cupy.cublas import cupyx has_cupy = True cublas = cupy.cublas cupy_version = Version(cupy.__version__) try: cupy.cuda.runtime.getDeviceCount() has_cupy_gpu = True except cupy.cuda.runtime.CUDARuntimeError: has_cupy_gpu = False if cupy_version.major >= 10: # fromDlpack was deprecated in v10.0.0. cupy_from_dlpack = cupy.from_dlpack else: cupy_from_dlpack = cupy.fromDlpack except (ImportError, AttributeError): cublas = None cupy = None cupyx = None cupy_version = Version("0.0.0") has_cupy = False cupy_from_dlpack = None has_cupy_gpu = False try: # pragma: no cover import torch import torch.utils.dlpack has_torch = True has_torch_cuda_gpu = torch.cuda.device_count() != 0 has_torch_mps = hasattr(torch.backends, "mps") and torch.backends.mps.is_built() has_torch_mps_gpu = has_torch_mps and torch.backends.mps.is_available() has_torch_gpu = has_torch_cuda_gpu torch_version = Version(str(torch.__version__)) has_torch_amp = ( torch_version >= Version("1.9.0") and not torch.cuda.amp.common.amp_definitely_not_available() ) except ImportError: # pragma: no cover torch = None # type: ignore has_torch = False has_torch_cuda_gpu = False has_torch_gpu = False has_torch_mps = False has_torch_mps_gpu = False has_torch_amp = False torch_version = Version("0.0.0") def enable_tensorflow(): warn_msg = ( "Built-in TensorFlow support will be removed in Thinc v9. If you need " "TensorFlow support in the future, you can transition to using a " "custom copy of the current TensorFlowWrapper in your package or " "project." ) warnings.warn(warn_msg, DeprecationWarning) global tensorflow, has_tensorflow, has_tensorflow_gpu import tensorflow import tensorflow.experimental.dlpack has_tensorflow = True has_tensorflow_gpu = len(tensorflow.config.get_visible_devices("GPU")) > 0 tensorflow = None has_tensorflow = False has_tensorflow_gpu = False def enable_mxnet(): warn_msg = ( "Built-in MXNet support will be removed in Thinc v9. If you need " "MXNet support in the future, you can transition to using a " "custom copy of the current MXNetWrapper in your package or " "project." ) warnings.warn(warn_msg, DeprecationWarning) global mxnet, has_mxnet import mxnet has_mxnet = True mxnet = None has_mxnet = False try: import h5py except ImportError: # pragma: no cover h5py = None try: # pragma: no cover import os_signpost has_os_signpost = True except ImportError: os_signpost = None has_os_signpost = False try: # pragma: no cover import blis has_blis = True except ImportError: blis = None has_blis = False # AppleOps is available unconditionally on macOS. has_apple_ops = platform.system() == "Darwin" has_gpu = has_cupy_gpu or has_torch_mps_gpu __all__ = [ "cupy", "cupyx", "torch", "tensorflow", "mxnet", "h5py", "os_signpost", ] thinc-9.0.0/thinc/config.py000066400000000000000000000024011461023342500155460ustar00rootroot00000000000000import catalogue import confection from confection import VARIABLE_RE, Config, ConfigValidationError, Promise from .types import Decorator class registry(confection.registry): # fmt: off optimizers: Decorator = catalogue.create("thinc", "optimizers", entry_points=True) schedules: Decorator = catalogue.create("thinc", "schedules", entry_points=True) layers: Decorator = catalogue.create("thinc", "layers", entry_points=True) losses: Decorator = catalogue.create("thinc", "losses", entry_points=True) initializers: Decorator = catalogue.create("thinc", "initializers", entry_points=True) datasets: Decorator = catalogue.create("thinc", "datasets", entry_points=True) ops: Decorator = catalogue.create("thinc", "ops", entry_points=True) # fmt: on @classmethod def create(cls, registry_name: str, entry_points: bool = False) -> None: """Create a new custom registry.""" if hasattr(cls, registry_name): raise ValueError(f"Registry '{registry_name}' already exists") reg: Decorator = catalogue.create( "thinc", registry_name, entry_points=entry_points ) setattr(cls, registry_name, reg) __all__ = ["Config", "registry", "ConfigValidationError", "Promise", "VARIABLE_RE"] thinc-9.0.0/thinc/initializers.py000066400000000000000000000073721461023342500170230ustar00rootroot00000000000000from typing import Callable, cast import numpy from .backends import Ops from .config import registry from .types import FloatsXd, Shape from .util import partial # TODO: Harmonize naming with Keras, and fill in missing entries # https://keras.io/initializers/ We should also have He normal/uniform # and probably lecun normal/uniform. # Initialize via numpy, before copying to ops. This makes it easier to work with # the different backends, because the backend won't affect the randomization. def lecun_normal_init(ops: Ops, shape: Shape) -> FloatsXd: scale = numpy.sqrt(1.0 / shape[1]) return ops.asarray_f(cast(FloatsXd, numpy.random.normal(0, scale, shape))) @registry.initializers("lecun_normal_init.v1") def configure_lecun_normal_init() -> Callable[[Shape], FloatsXd]: return partial(lecun_normal_init) def he_normal_init(ops: Ops, shape: Shape) -> FloatsXd: scale = numpy.sqrt(2.0 / shape[1]) return ops.asarray_f(cast(FloatsXd, numpy.random.normal(0, scale, shape))) @registry.initializers("he_normal_init.v1") def configure_he_normal_init() -> Callable[[Shape], FloatsXd]: return partial(he_normal_init) def glorot_normal_init(ops: Ops, shape: Shape) -> FloatsXd: scale = numpy.sqrt(2.0 / (shape[1] + shape[0])) return ops.asarray_f(cast(FloatsXd, numpy.random.normal(0, scale, shape))) @registry.initializers("glorot_normal_init.v1") def configure_glorot_normal_init() -> Callable[[Shape], FloatsXd]: return partial(glorot_normal_init) def he_uniform_init(ops: Ops, shape: Shape) -> FloatsXd: scale = numpy.sqrt(6.0 / shape[1]) return ops.asarray_f(cast(FloatsXd, numpy.random.uniform(-scale, scale, shape))) @registry.initializers("he_uniform_init.v1") def configure_he_uniform_init() -> Callable[[Shape], FloatsXd]: return partial(he_uniform_init) def lecun_uniform_init(ops: Ops, shape: Shape) -> FloatsXd: scale = numpy.sqrt(3.0 / shape[1]) return ops.asarray_f(cast(FloatsXd, numpy.random.uniform(-scale, scale, shape))) @registry.initializers("lecun_uniform_init.v1") def configure_lecun_uniform_init() -> Callable[[Shape], FloatsXd]: return partial(lecun_uniform_init) def glorot_uniform_init(ops: Ops, shape: Shape) -> FloatsXd: scale = numpy.sqrt(6.0 / (shape[0] + shape[1])) return ops.asarray_f(cast(FloatsXd, numpy.random.uniform(-scale, scale, shape))) @registry.initializers("glorot_uniform_init.v1") def configure_glorot_uniform_init() -> Callable[[Shape], FloatsXd]: return partial(glorot_uniform_init) def zero_init(ops: Ops, shape: Shape) -> FloatsXd: return ops.alloc_f(shape) @registry.initializers("zero_init.v1") def configure_zero_init() -> Callable[[FloatsXd], FloatsXd]: return partial(zero_init) def uniform_init( ops: Ops, shape: Shape, *, lo: float = -0.1, hi: float = 0.1 ) -> FloatsXd: values = numpy.random.uniform(lo, hi, shape) return ops.asarray_f(cast(FloatsXd, values.astype("float32"))) @registry.initializers("uniform_init.v1") def configure_uniform_init( *, lo: float = -0.1, hi: float = 0.1 ) -> Callable[[FloatsXd], FloatsXd]: return partial(uniform_init, lo=lo, hi=hi) def normal_init(ops: Ops, shape: Shape, *, mean: float = 0) -> FloatsXd: size = int(ops.xp.prod(ops.xp.asarray(shape))) inits = cast(FloatsXd, numpy.random.normal(scale=mean, size=size).astype("float32")) inits = ops.reshape_f(inits, shape) return ops.asarray_f(inits) @registry.initializers("normal_init.v1") def configure_normal_init(*, mean: float = 0) -> Callable[[FloatsXd], FloatsXd]: return partial(normal_init, mean=mean) __all__ = [ "normal_init", "uniform_init", "glorot_uniform_init", "zero_init", "lecun_uniform_init", "he_uniform_init", "glorot_normal_init", "he_normal_init", "lecun_normal_init", ] thinc-9.0.0/thinc/layers/000077500000000000000000000000001461023342500152315ustar00rootroot00000000000000thinc-9.0.0/thinc/layers/__init__.py000066400000000000000000000104541461023342500173460ustar00rootroot00000000000000# Weights layers # Combinators from .add import add # Array manipulation from .array_getitem import array_getitem from .bidirectional import bidirectional from .cauchysimilarity import CauchySimilarity from .chain import chain from .clipped_linear import ClippedLinear, HardSigmoid, HardTanh, ReluK from .clone import clone from .concatenate import concatenate from .dish import Dish from .dropout import Dropout from .embed import Embed from .expand_window import expand_window from .gelu import Gelu from .hard_swish import HardSwish from .hard_swish_mobilenet import HardSwishMobilenet from .hashembed import HashEmbed from .layernorm import LayerNorm from .linear import Linear # Data-type transfers from .list2array import list2array from .list2padded import list2padded from .list2ragged import list2ragged from .logistic import Logistic from .lstm import LSTM, PyTorchLSTM from .map_list import map_list from .maxout import Maxout from .mish import Mish from .multisoftmax import MultiSoftmax from .mxnetwrapper import MXNetWrapper from .noop import noop from .padded2list import padded2list from .parametricattention import ParametricAttention from .parametricattention_v2 import ParametricAttention_v2 from .premap_ids import premap_ids from .pytorchwrapper import ( PyTorchRNNWrapper, PyTorchWrapper, PyTorchWrapper_v2, PyTorchWrapper_v3, ) from .ragged2list import ragged2list # Pooling from .reduce_first import reduce_first from .reduce_last import reduce_last from .reduce_max import reduce_max from .reduce_mean import reduce_mean from .reduce_sum import reduce_sum from .relu import Relu from .remap_ids import remap_ids, remap_ids_v2 from .residual import residual from .resizable import resizable from .siamese import siamese from .sigmoid import Sigmoid from .sigmoid_activation import sigmoid_activation from .softmax import Softmax, Softmax_v2 from .softmax_activation import softmax_activation from .sparselinear import SparseLinear, SparseLinear_v2 from .strings2arrays import strings2arrays from .swish import Swish from .tensorflowwrapper import TensorFlowWrapper, keras_subclass from .torchscriptwrapper import TorchScriptWrapper_v1, pytorch_to_torchscript_wrapper from .tuplify import tuplify from .uniqued import uniqued from .with_array import with_array from .with_array2d import with_array2d from .with_cpu import with_cpu from .with_debug import with_debug from .with_flatten import with_flatten from .with_flatten_v2 import with_flatten_v2 from .with_getitem import with_getitem from .with_list import with_list from .with_nvtx_range import with_nvtx_range from .with_padded import with_padded from .with_ragged import with_ragged from .with_reshape import with_reshape from .with_signpost_interval import with_signpost_interval # fmt: off __all__ = [ "CauchySimilarity", "Linear", "Dropout", "Embed", "expand_window", "HashEmbed", "LayerNorm", "LSTM", "Maxout", "Mish", "MultiSoftmax", "ParametricAttention", "ParametricAttention_v2", "PyTorchLSTM", "PyTorchWrapper", "PyTorchWrapper_v2", "PyTorchWrapper_v3", "PyTorchRNNWrapper", "Relu", "sigmoid_activation", "Sigmoid", "softmax_activation", "Softmax", "Softmax_v2", "SparseLinear", "SparseLinear_v2", "TensorFlowWrapper", "TorchScriptWrapper_v1", "add", "bidirectional", "chain", "clone", "concatenate", "noop", "residual", "uniqued", "siamese", "reduce_first", "reduce_last", "reduce_max", "reduce_mean", "reduce_sum", "resizable", "list2array", "list2ragged", "list2padded", "ragged2list", "padded2list", "with_reshape", "with_getitem", "with_array", "with_array2d", "with_cpu", "with_list", "with_ragged", "with_padded", "with_flatten", "with_flatten_v2", "with_debug", "with_nvtx_range", "with_signpost_interval", "remap_ids", "remap_ids_v2", "premap_ids", "softmax_activation", "Logistic", "Sigmoid", "ClippedLinear", "ReluK", "HardTanh", "HardSigmoid", "Dish", "HardSwish", "HardSwishMobilenet", "Swish", "Gelu", "keras_subclass", "MXNetWrapper", "map_list", "strings2arrays", "array_getitem", "tuplify", "pytorch_to_torchscript_wrapper", ] # fmt: on thinc-9.0.0/thinc/layers/add.py000066400000000000000000000043051461023342500163350ustar00rootroot00000000000000from typing import Any, Callable, Dict, Optional, Tuple, TypeVar from ..config import registry from ..model import Model from ..types import ArrayXd, XY_XY_OutT from ..util import get_width InT = TypeVar("InT", bound=Any) OutT = TypeVar("OutT", bound=ArrayXd) @registry.layers("add.v1") def add( layer1: Model[InT, OutT], layer2: Model[InT, OutT], *layers: Model ) -> Model[InT, XY_XY_OutT]: """Compose two or more models `f`, `g`, etc, such that their outputs are added, i.e. `add(f, g)(x)` computes `f(x) + g(x)`. """ layers = (layer1, layer2) + layers if layers[0].name == "add": layers[0].layers.extend(layers[1:]) return layers[0] # only add an nI dimension if each sub-layer has one dims: Dict[str, Optional[int]] = {"nO": None} if all(node.has_dim("nI") in [True, None] for node in layers): dims = {"nO": None, "nI": None} return Model("add", forward, init=init, dims=dims, layers=layers) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: if not model.layers: return X, lambda dY: dY Y, first_callback = model.layers[0](X, is_train=is_train) callbacks = [] for layer in model.layers[1:]: layer_Y, layer_callback = layer(X, is_train=is_train) Y += layer_Y callbacks.append(layer_callback) def backprop(dY: InT) -> OutT: dX = first_callback(dY) for callback in callbacks: dX += callback(dY) return dX return Y, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is not None: if model.has_dim("nI") is not False: model.set_dim("nI", get_width(X)) for layer in model.layers: if layer.has_dim("nI") is not False: layer.set_dim("nI", get_width(X)) if Y is not None: if model.has_dim("nO") is not False: model.set_dim("nO", get_width(Y)) for layer in model.layers: if layer.has_dim("nO") is not False: layer.set_dim("nO", get_width(Y)) for layer in model.layers: layer.initialize(X=X, Y=Y) model.set_dim("nO", model.layers[0].get_dim("nO")) thinc-9.0.0/thinc/layers/array_getitem.py000066400000000000000000000030631461023342500204410ustar00rootroot00000000000000from typing import Sequence, Tuple, TypeVar, Union from ..model import Model from ..types import ArrayXd, FloatsXd, IntsXd AxisIndex = Union[int, slice, Sequence[int]] Index = Union[AxisIndex, Tuple[AxisIndex, ...]] ArrayTXd = TypeVar("ArrayTXd", bound=ArrayXd) def array_getitem(index: Index) -> Model[ArrayTXd, ArrayTXd]: """Index into input arrays, and return the subarrays. index: A valid numpy-style index. Multi-dimensional indexing can be performed by passing in a tuple, and slicing can be performed using the slice object. For instance, X[:, :-1] would be (slice(None, None), slice(None, -1)). """ return Model("array-getitem", forward, attrs={"index": index}) def floats_getitem(index: Index) -> Model[FloatsXd, FloatsXd]: """Index into input arrays, and return the subarrays. This delegates to `array_getitem`, but allows type declarations. """ return Model("floats-getitem", forward, attrs={"index": index}) def ints_getitem(index: Index) -> Model[IntsXd, IntsXd]: """Index into input arrays, and return the subarrays. This delegates to `array_getitem`, but allows type declarations. """ return Model("ints-getitem", forward, attrs={"index": index}) def forward(model, X, is_train): index = model.attrs["index"] shape = X.shape dtype = X.dtype def backprop_get_column(dY): dX = model.ops.alloc(shape, dtype=dtype) dX[index] = dY return dX if len(X) == 0: return X, backprop_get_column Y = X[index] return Y, backprop_get_column thinc-9.0.0/thinc/layers/bidirectional.py000066400000000000000000000042171461023342500204170ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..backends import Ops from ..config import registry from ..model import Model from ..types import Padded InT = Padded OutT = Padded @registry.layers("bidirectional.v1") def bidirectional( l2r: Model[InT, OutT], r2l: Optional[Model[InT, OutT]] = None ) -> Model[InT, OutT]: """Stitch two RNN models into a bidirectional layer. Expects squared sequences.""" if r2l is None: r2l = l2r.copy() return Model(f"bi{l2r.name}", forward, layers=[l2r, r2l], init=init) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: l2r, r2l = model.layers X_rev = _reverse(model.ops, X) l2r_Z, bp_l2r_Z = l2r(X, is_train) r2l_Z, bp_r2l_Z = r2l(X_rev, is_train) Z = _concatenate(model.ops, l2r_Z, r2l_Z) def backprop(dZ: OutT) -> InT: d_l2r_Z, d_r2l_Z = _split(model.ops, dZ) dX_l2r = bp_l2r_Z(d_l2r_Z) dX_r2l = bp_r2l_Z(d_r2l_Z) return _sum(dX_l2r, dX_r2l) return Z, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: (Y1, Y2) = _split(model.ops, Y) if Y is not None else (None, None) model.layers[0].initialize(X=X, Y=Y1) model.layers[1].initialize(X=X, Y=Y2) def _reverse(ops: Ops, Xp: Padded) -> Padded: return Padded(Xp.data[::1], Xp.size_at_t, Xp.lengths, Xp.indices) def _concatenate(ops: Ops, l2r: Padded, r2l: Padded) -> Padded: return Padded( ops.xp.concatenate((l2r.data, r2l.data), axis=-1), l2r.size_at_t, l2r.lengths, l2r.indices, ) def _split(ops: Ops, Xp: Padded) -> Tuple[Padded, Padded]: half = Xp.data.shape[-1] // 2 # I don't know how to write these ellipsis in the overloads :( X_l2r = Xp.data[cast(Tuple[slice, slice], (..., slice(None, half)))] X_r2l = Xp.data[cast(Tuple[slice, slice], (..., slice(half)))] return ( Padded(X_l2r, Xp.size_at_t, Xp.lengths, Xp.indices), Padded(X_r2l, Xp.size_at_t, Xp.lengths, Xp.indices), ) def _sum(Xp: Padded, Yp: Padded) -> Padded: return Padded(Xp.data + Yp.data, Xp.size_at_t, Xp.lengths, Xp.indices) thinc-9.0.0/thinc/layers/cauchysimilarity.py000066400000000000000000000033141461023342500211670ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width InT = Tuple[Floats2d, Floats2d] OutT = Floats1d @registry.layers("CauchySimilarity.v1") def CauchySimilarity(nI: Optional[int] = None) -> Model[InT, OutT]: """Compare input vectors according to the Cauchy similarity function proposed by Chen (2013). Primarily used within Siamese neural networks. """ return Model( "cauchy_similarity", forward, init=init, dims={"nI": nI, "nO": 1}, params={"W": None}, ) def forward( model: Model[InT, OutT], X1_X2: InT, is_train: bool ) -> Tuple[OutT, Callable]: X1, X2 = X1_X2 W = cast(Floats2d, model.get_param("W")) diff = X1 - X2 square_diff = diff**2 total = (W * square_diff).sum(axis=1) sim, bp_sim = inverse(total) def backprop(d_sim: OutT) -> InT: d_total = bp_sim(d_sim) d_total = model.ops.reshape2f(d_total, -1, 1) model.inc_grad("W", (d_total * square_diff).sum(axis=0)) d_square_diff = W * d_total d_diff = 2 * d_square_diff * diff return (d_diff, -d_diff) return sim, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is not None: model.set_dim("nI", get_width(X[0])) # Initialize weights to 1 W = model.ops.alloc1f(model.get_dim("nI")) W += 1 model.set_param("W", W) def inverse(total: OutT) -> Tuple[OutT, Callable]: inv = 1.0 / (1 + total) def backward(d_inverse: OutT) -> OutT: return d_inverse * (-1 / (total + 1) ** 2) return inv, backward thinc-9.0.0/thinc/layers/chain.py000066400000000000000000000065641461023342500167000ustar00rootroot00000000000000from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import XY_YZ_OutT from ..util import get_width InT = TypeVar("InT") MidT = TypeVar("MidT") OutT = TypeVar("OutT") # Keep this function so we can provide variable arguments via the config @registry.layers("chain.v1") def chain_no_types(*layer: Model) -> Model: return chain(*layer) def chain( layer1: Model[InT, MidT], layer2: Model[MidT, Any], *layers: Model[Any, Any] ) -> Model[InT, XY_YZ_OutT]: """Compose two models `f` and `g` such that they become layers of a single feed-forward model that computes `g(f(x))`. Also supports chaining more than 2 layers. Note that the type checking for additional layers is carried out by the Thinc Mypy plugin. """ all_layers: List[Model[Any, Any]] = [layer1, layer2] all_layers.extend(layers) dims: Dict[str, Optional[int]] = {"nO": None} # set input dimension only if first layer has one - should be "False" otherwise if all_layers[0].has_dim("nI") is True: dims["nI"] = all_layers[0].get_dim("nI") if all_layers[0].has_dim("nI") is None: dims["nI"] = None # set output dimension according to last layer if all_layers[-1].has_dim("nO") is True: dims["nO"] = all_layers[-1].get_dim("nO") model: Model[InT, XY_YZ_OutT] = Model( ">>".join(layer.name for layer in all_layers), forward, init=init, dims=dims, layers=all_layers, ) return model def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: """Apply the layers of `model` in sequence, feeding the output from one layer into the next. """ callbacks = [] for layer in model.layers: Y, inc_layer_grad = layer(X, is_train=is_train) callbacks.append(inc_layer_grad) X = Y def backprop(dY: OutT) -> InT: for callback in reversed(callbacks): dX = callback(dY) dY = dX return dX return Y, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is None and Y is None: for layer in model.layers: layer.initialize() if model.layers[0].has_dim("nI"): model.set_dim("nI", model.layers[0].get_dim("nI")) if model.layers[-1].has_dim("nO"): model.set_dim("nO", model.layers[-1].get_dim("nO")) # Try to set nO on each layer, where available. # Shape inference is tricky, especially for the output. The policy is: # if a layer has an unset nO, we use the final Y (if provided). For other # layers, Y=None. curr_input = X for layer in model.layers: if layer.has_dim("nO") is None: layer.initialize(X=curr_input, Y=Y) else: layer.initialize(X=curr_input) if curr_input is not None: curr_input = layer.predict(curr_input) if model.layers[0].has_dim("nI"): model.set_dim("nI", model.layers[0].get_dim("nI")) if model.has_dim("nO") is None: try: nO = get_width(curr_input) # type: ignore[arg-type] model.set_dim("nO", nO) except ValueError: if model.layers[-1].has_dim("nO"): nO = model.layers[-1].get_dim("nO") model.set_dim("nO", nO) thinc-9.0.0/thinc/layers/clipped_linear.py000066400000000000000000000105371461023342500205630ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import glorot_uniform_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm @registry.layers("ClippedLinear.v1") def ClippedLinear( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, slope: float = 1.0, offset: float = 0.0, min_val: float = 0.0, max_val: float = 1.0, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init model_attrs = { "slope": slope, "offset": offset, "min_val": min_val, "max_val": max_val, } model: Model[Floats2d, Floats2d] = Model( "clipped_linear", forward=forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, attrs=model_attrs, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward( model: Model[Floats2d, Floats2d], X: Floats2d, is_train: bool, ) -> Tuple[Floats2d, Callable]: slope = model.attrs["slope"] offset = model.attrs["offset"] min_val = model.attrs["min_val"] max_val = model.attrs["max_val"] W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_preact = model.ops.affine(X, W, b) Y = model.ops.clipped_linear(Y_preact, slope, offset, min_val, max_val) def backprop(dY: Floats2d) -> Floats2d: dY = model.ops.backprop_clipped_linear( dY, Y_preact, slope, offset, min_val, max_val, inplace=False ) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[Floats2d, Floats2d], X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) @registry.layers("HardSigmoid.v1") def HardSigmoid( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init return ClippedLinear( nO=nO, nI=nI, init_W=init_W, dropout=dropout, normalize=normalize, slope=0.2, offset=0.5, ) @registry.layers("HardTanh.v1") def HardTanh( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init return ClippedLinear( nO=nO, nI=nI, init_W=init_W, dropout=dropout, normalize=normalize, min_val=-1.0, max_val=1.0, ) @registry.layers("ReluK.v1") def ReluK( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, k: float = 6.0, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init return ClippedLinear( nO=nO, nI=nI, init_W=init_W, dropout=dropout, normalize=normalize, min_val=0.0, max_val=k, ) thinc-9.0.0/thinc/layers/clone.py000066400000000000000000000012101461023342500166750ustar00rootroot00000000000000from typing import List, TypeVar, cast from ..config import registry from ..model import Model from .chain import chain from .noop import noop InT = TypeVar("InT") OutT = TypeVar("OutT") @registry.layers("clone.v1") def clone(orig: Model[InT, OutT], n: int) -> Model[InT, OutT]: """Construct `n` copies of a layer, with distinct weights. i.e. `clone(f, 3)(x)` computes f(f'(f''(x))). """ if n == 0: return cast(Model[InT, OutT], noop()) elif n == 1: return orig layers: List[Model] = [orig] for i in range(n - 1): layers.append(orig.copy()) return cast(Model[InT, OutT], chain(*layers)) thinc-9.0.0/thinc/layers/concatenate.py000066400000000000000000000121041461023342500200650ustar00rootroot00000000000000from typing import ( Any, Callable, Dict, List, Optional, Sequence, Tuple, TypeVar, Union, cast, ) from ..backends import NumpyOps from ..config import registry from ..model import Model from ..types import Array2d, Ragged, XY_XY_OutT from ..util import get_width from .noop import noop NUMPY_OPS = NumpyOps() InT = TypeVar("InT", bound=Any) OutT = TypeVar("OutT", bound=Union[Array2d, Sequence[Array2d], Ragged]) @registry.layers("concatenate.v1") def concatenate(*layers: Model) -> Model[InT, XY_XY_OutT]: """Compose two or more models `f`, `g`, etc, such that their outputs are concatenated, i.e. `concatenate(f, g)(x)` computes `hstack(f(x), g(x))`. Also supports chaining more than 2 layers. """ if not layers: return cast(Model[InT, XY_XY_OutT], noop()) elif len(layers) == 1: return layers[0] elif layers[0]._func is forward: layers[0].layers.extend(layers[1:]) return layers[0] # only add an nI dimension if each sub-layer has one dims: Dict[str, Optional[int]] = {"nO": None} if all(node.has_dim("nI") in [True, None] for node in layers): dims = {"nO": None, "nI": None} return Model( "|".join(layer.name for layer in layers), forward, init=init, dims=dims, layers=layers, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: Ys, callbacks = zip(*[layer(X, is_train=is_train) for layer in model.layers]) if isinstance(Ys[0], list): data_l, backprop = _list_forward(model, X, Ys, callbacks, is_train) return cast(OutT, data_l), backprop elif isinstance(Ys[0], Ragged): data_r, backprop = _ragged_forward(model, X, Ys, callbacks, is_train) return cast(OutT, data_r), backprop else: data_a, backprop = _array_forward(model, X, Ys, callbacks, is_train) return cast(OutT, data_a), backprop def _array_forward( model: Model[InT, OutT], X, Ys: List, callbacks, is_train: bool ) -> Tuple[Array2d, Callable]: widths = [Y.shape[1] for Y in Ys] output = model.ops.xp.hstack(Ys) def backprop(d_output: Array2d) -> InT: dY = model.ops.as_contig(d_output[:, : widths[0]]) dX = callbacks[0](dY) start = widths[0] add_gradients = hasattr(dX, "__add__") or hasattr(dX, "__iadd__") add_gradients_data = hasattr(dX, "data") and ( hasattr(dX.data, "__add__") or hasattr(dX.data, "__iadd__") ) for bwd, width in zip(callbacks[1:], widths[1:]): dY = model.ops.as_contig(d_output[:, start : start + width]) gradient = bwd(dY) if add_gradients: dX += gradient elif add_gradients_data: dX.data += gradient.data start += width return dX return output, backprop def _ragged_forward( model: Model[InT, OutT], X, Ys: List, callbacks, is_train: bool ) -> Tuple[Ragged, Callable]: widths = [Y.dataXd.shape[1] for Y in Ys] output = Ragged(model.ops.xp.hstack([y.data for y in Ys]), Ys[0].lengths) def backprop(d_output: Ragged) -> InT: d_array = d_output.data dY = Ragged(model.ops.as_contig(d_array[:, : widths[0]]), d_output.lengths) dX = callbacks[0](dY) start = widths[0] for bwd, width in zip(callbacks[1:], widths[1:]): dY = Ragged( model.ops.as_contig(d_array[:, start : start + width]), d_output.lengths ) dX += bwd(dY) start += width return dX return output, backprop def _list_forward( model: Model[InT, OutT], X, Ys: List, callbacks, is_train: bool ) -> Tuple[Sequence[Array2d], Callable]: def backprop(d_output: Sequence[Array2d]) -> InT: d_out_array = model.ops.xp.concatenate(d_output, axis=0) dY = model.ops.as_contig(d_out_array[:, : widths[0]]) # We want to generalize unflatten later. dY = model.ops.unflatten(dY, lengths) dX = callbacks[0](dY) start = widths[0] for bwd, width in zip(callbacks[1:], widths[1:]): dY = model.ops.as_contig(d_out_array[:, start : start + width]) dY = model.ops.unflatten(dY, lengths) dX += bwd(dY) start += width return dX lengths = NUMPY_OPS.asarray1i([len(x) for x in X]) Ys = [model.ops.xp.concatenate(Y, axis=0) for Y in Ys] widths = [Y.shape[1] for Y in Ys] out_array = model.ops.xp.hstack(Ys) return model.ops.unflatten(out_array, lengths), backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is not None: if model.has_dim("nI") is not False: model.set_dim("nI", get_width(X)) for layer in model.layers: if layer.has_dim("nI") is not False: layer.set_dim("nI", get_width(X)) for layer in model.layers: layer.initialize(X=X, Y=Y) if all([layer.has_dim("nO") for layer in model.layers]): model.set_dim("nO", sum(layer.get_dim("nO") for layer in model.layers)) thinc-9.0.0/thinc/layers/dish.py000066400000000000000000000041011461023342500165260ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import he_normal_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm @registry.layers("Dish.v1") def Dish( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = he_normal_init if init_b is None: init_b = zero_init model: Model[Floats2d, Floats2d] = Model( "dish", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward( model: Model[Floats2d, Floats2d], X: Floats2d, is_train: bool ) -> Tuple[Floats2d, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_preact = model.ops.affine(X, W, b) Y = model.ops.dish(Y_preact) def backprop(dY: Floats2d) -> Floats2d: dY = model.ops.backprop_dish(dY, X, inplace=False) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[Floats2d, Floats2d], X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/dropout.py000066400000000000000000000056131461023342500173040ustar00rootroot00000000000000from typing import Callable, List, Sequence, Tuple, TypeVar, Union, cast from ..config import registry from ..model import Model from ..types import ArrayXd, Padded, Ragged InT = TypeVar("InT", bound=Union[ArrayXd, Sequence[ArrayXd], Ragged, Padded]) @registry.layers("Dropout.v1") def Dropout(rate: float = 0.0) -> Model[InT, InT]: """Help prevent overfitting by adding a random distortion to the input data during training. Specifically, cells of the input are zeroed with probability determined by the `rate` argument. """ return Model("dropout", forward, attrs={"dropout_rate": rate, "is_enabled": True}) def forward(model: Model[InT, InT], X: InT, is_train: bool) -> Tuple[InT, Callable]: rate = model.attrs["dropout_rate"] is_enabled = model.attrs["is_enabled"] and is_train if rate == 0 or not is_enabled: return X, lambda dY: dY elif isinstance(X, Ragged): data_r, backprop = _dropout_ragged(model, X, is_train) return cast(InT, data_r), backprop elif isinstance(X, Padded): data_p, backprop = _dropout_padded(model, X, is_train) return cast(InT, data_p), backprop elif isinstance(X, Sequence): data_l, backprop = _dropout_lists(model, X, is_train) return cast(InT, data_l), backprop else: data_a, backprop = _dropout_array(model, cast(ArrayXd, X), is_train) return cast(InT, data_a), backprop def _dropout_array( model: Model[InT, InT], X: ArrayXd, is_train: bool ) -> Tuple[ArrayXd, Callable]: rate = model.attrs["dropout_rate"] mask = model.ops.get_dropout_mask(X.shape, rate) def backprop(dY: ArrayXd) -> ArrayXd: return dY * mask return cast(ArrayXd, X * mask), backprop def _dropout_padded( model: Model[InT, InT], Xp: Padded, is_train: bool ) -> Tuple[Padded, Callable]: X = Xp.data mask = model.ops.get_dropout_mask(X.shape, model.attrs["dropout_rate"]) Y = X * mask def backprop(dYp: Padded) -> Padded: return Padded(dYp.data * mask, dYp.size_at_t, dYp.lengths, dYp.indices) return Padded(Y, Xp.size_at_t, Xp.lengths, Xp.indices), backprop def _dropout_ragged( model: Model[InT, InT], Xr: Ragged, is_train: bool ) -> Tuple[Ragged, Callable]: X = Xr.data lengths = Xr.lengths mask = model.ops.get_dropout_mask(X.shape, model.attrs["dropout_rate"]) Y = X * mask def backprop(dYr: Ragged) -> Ragged: return Ragged(dYr.data * mask, dYr.lengths) return Ragged(Y, lengths), backprop def _dropout_lists( model: Model[InT, InT], Xs: Sequence[ArrayXd], is_train: bool ) -> Tuple[Sequence[ArrayXd], Callable]: rate = model.attrs["dropout_rate"] masks = [model.ops.get_dropout_mask(X.shape, rate) for X in Xs] Ys = [X * mask for X, mask in zip(Xs, masks)] def backprop(dYs: List[ArrayXd]) -> List[ArrayXd]: return [dY * mask for dY, mask in zip(dYs, masks)] return Ys, backprop thinc-9.0.0/thinc/layers/embed.py000066400000000000000000000052021461023342500166560ustar00rootroot00000000000000from typing import Callable, Dict, Optional, Tuple, TypeVar, Union, cast from ..config import registry from ..initializers import uniform_init from ..model import Model from ..types import Floats1d, Floats2d, Ints1d, Ints2d from ..util import get_width, partial from .array_getitem import ints_getitem from .chain import chain InT = TypeVar("InT", bound=Union[Ints1d, Ints2d]) OutT = Floats2d @registry.layers("Embed.v1") def Embed( nO: Optional[int] = None, nV: Optional[int] = None, *, column: Optional[int] = None, initializer: Optional[Callable] = None, dropout: Optional[float] = None ) -> Model[InT, OutT]: """Map integers to vectors, using a fixed-size lookup table.""" attrs: Dict[str, Union[None, int, float]] = {} if initializer is None: initializer = uniform_init if dropout is not None: attrs["dropout_rate"] = dropout model: Model = Model( "embed", forward, init=partial(init, initializer), attrs=attrs, dims={"nO": nO, "nV": nV}, params={"E": None}, ) if column is not None: # This is equivalent to array[:, column]. What you're actually doing # there is passing in a tuple: array[(:, column)], except in the context # of array indexing, the ":" creates an object slice(0, None). # So array[:, column] is array.__getitem__(slice(0), column). model = chain(ints_getitem((slice(0, None), column)), model) model.attrs["column"] = column return cast(Model[InT, OutT], model) def forward( model: Model[Ints1d, OutT], ids: Ints1d, is_train: bool ) -> Tuple[OutT, Callable]: vectors = cast(Floats2d, model.get_param("E")) nO = vectors.shape[1] nN = ids.shape[0] dropout: Optional[float] = model.attrs.get("dropout_rate") output = vectors[ids] drop_mask = None if is_train: drop_mask = cast(Floats1d, model.ops.get_dropout_mask((nO,), dropout)) if drop_mask is not None: output *= drop_mask def backprop(d_output: OutT) -> Ints1d: if drop_mask is not None: d_output *= drop_mask d_vectors = model.ops.alloc2f(*vectors.shape) model.ops.scatter_add(d_vectors, ids, d_output) model.inc_grad("E", d_vectors) dX = model.ops.alloc1i(nN) return dX return output, backprop def init( initializer: Callable, model: Model[Ints1d, OutT], X: Optional[Ints1d] = None, Y: Optional[OutT] = None, ) -> None: if Y is not None: model.set_dim("nO", get_width(Y)) shape = (model.get_dim("nV"), model.get_dim("nO")) model.set_param("E", initializer(model.ops, shape)) thinc-9.0.0/thinc/layers/expand_window.py000066400000000000000000000031501461023342500204500ustar00rootroot00000000000000from typing import Callable, Tuple, TypeVar, Union, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged InT = TypeVar("InT", Floats2d, Ragged) @registry.layers("expand_window.v1") def expand_window(window_size: int = 1) -> Model[InT, InT]: """For each vector in an input, construct an output vector that contains the input and a window of surrounding vectors. This is one step in a convolution. """ return Model("expand_window", forward, attrs={"window_size": window_size}) def forward(model: Model[InT, InT], X: InT, is_train: bool) -> Tuple[InT, Callable]: if isinstance(X, Ragged): return _expand_window_ragged(model, X) else: return _expand_window_floats(model, X) def _expand_window_floats( model: Model[InT, InT], X: Floats2d ) -> Tuple[Floats2d, Callable]: nW = model.attrs["window_size"] if len(X) > 0: Y = model.ops.seq2col(X, nW) else: assert len(X) == 0 Y = model.ops.tile(X, (nW * 2) + 1) def backprop(dY: Floats2d) -> Floats2d: return model.ops.backprop_seq2col(dY, nW) return Y, backprop def _expand_window_ragged( model: Model[InT, InT], Xr: Ragged ) -> Tuple[Ragged, Callable]: nW = model.attrs["window_size"] Y = Ragged( model.ops.seq2col(cast(Floats2d, Xr.data), nW, lengths=Xr.lengths), Xr.lengths ) def backprop(dYr: Ragged) -> Ragged: return Ragged( model.ops.backprop_seq2col( cast(Floats2d, dYr.data), nW, lengths=Xr.lengths ), Xr.lengths, ) return Y, backprop thinc-9.0.0/thinc/layers/gelu.py000066400000000000000000000041101461023342500165330ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import he_normal_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm @registry.layers("Gelu.v1") def Gelu( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = he_normal_init if init_b is None: init_b = zero_init model: Model[Floats2d, Floats2d] = Model( "gelu", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward( model: Model[Floats2d, Floats2d], X: Floats2d, is_train: bool ) -> Tuple[Floats2d, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_preact = model.ops.affine(X, W, b) Y = model.ops.gelu(Y_preact) def backprop(dY: Floats2d) -> Floats2d: dY = model.ops.backprop_gelu(dY, Y_preact, inplace=False) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[Floats2d, Floats2d], X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/hard_swish.py000066400000000000000000000041431461023342500177400ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import he_normal_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm @registry.layers("HardSwish.v1") def HardSwish( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = he_normal_init if init_b is None: init_b = zero_init model: Model[Floats2d, Floats2d] = Model( "hardswish", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward( model: Model[Floats2d, Floats2d], X: Floats2d, is_train: bool ) -> Tuple[Floats2d, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_preact = model.ops.affine(X, W, b) Y = model.ops.hard_swish(Y_preact) def backprop(dY: Floats2d) -> Floats2d: dY = model.ops.backprop_hard_swish(dY, Y_preact, inplace=False) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[Floats2d, Floats2d], X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/hard_swish_mobilenet.py000066400000000000000000000042221461023342500217740ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import he_normal_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm @registry.layers("HardSwishMobilenet.v1") def HardSwishMobilenet( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = he_normal_init if init_b is None: init_b = zero_init model: Model[Floats2d, Floats2d] = Model( "hardswishmobilenet", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward( model: Model[Floats2d, Floats2d], X: Floats2d, is_train: bool ) -> Tuple[Floats2d, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_preact = model.ops.affine(X, W, b) Y = model.ops.hard_swish_mobilenet(Y_preact) def backprop(dY: Floats2d) -> Floats2d: dY = model.ops.backprop_hard_swish_mobilenet(dY, Y_preact, inplace=False) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[Floats2d, Floats2d], X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/hashembed.py000066400000000000000000000070371461023342500175320ustar00rootroot00000000000000from typing import Any, Callable, Dict, Optional, Tuple, TypeVar, Union, cast from ..config import registry from ..initializers import uniform_init from ..model import Model from ..types import Floats1d, Floats2d, Ints1d, Ints2d from ..util import partial from .array_getitem import ints_getitem from .chain import chain InT = TypeVar("InT", bound=Union[Ints1d, Ints2d]) OutT = Floats2d @registry.layers("HashEmbed.v1") def HashEmbed( nO: int, nV: int, *, seed: Optional[int] = None, column: Optional[int] = None, initializer: Optional[Callable] = None, dropout: Optional[float] = None ) -> Model[InT, OutT]: """ An embedding layer that uses the โ€œhashing trickโ€ to map keys to distinct values. The hashing trick involves hashing each key four times with distinct seeds, to produce four likely differing values. Those values are modded into the table, and the resulting vectors summed to produce a single result. Because itโ€™s unlikely that two different keys will collide on all four โ€œbucketsโ€, most distinct keys will receive a distinct vector under this scheme, even when the number of vectors in the table is very low. """ attrs: Dict[str, Any] = {"column": column, "seed": seed} if initializer is None: initializer = uniform_init if dropout is not None: attrs["dropout_rate"] = dropout model: Model = Model( "hashembed", forward, init=partial(init, initializer), params={"E": None}, dims={"nO": nO, "nV": nV, "nI": None}, attrs=attrs, ) if seed is None: model.attrs["seed"] = model.id if column is not None: # This is equivalent to array[:, column]. What you're actually doing # there is passing in a tuple: array[(:, column)], except in the context # of array indexing, the ":" creates an object slice(0, None). # So array[:, column] is array.__getitem__(slice(0), column). model = chain(ints_getitem((slice(0, None), column)), model) model.attrs["column"] = column return cast(Model[InT, OutT], model) def forward( model: Model[Ints1d, OutT], ids: Ints1d, is_train: bool ) -> Tuple[OutT, Callable]: vectors = cast(Floats2d, model.get_param("E")) nV = vectors.shape[0] nO = vectors.shape[1] if len(ids) == 0: output: Floats2d = model.ops.alloc2f(0, nO, dtype=vectors.dtype) else: ids = model.ops.as_contig(ids, dtype="uint64") nN = ids.shape[0] seed: int = model.attrs["seed"] keys = model.ops.hash(ids, seed) % nV output = model.ops.gather_add(vectors, keys) drop_mask = None if is_train: dropout: Optional[float] = model.attrs.get("dropout_rate") drop_mask = cast(Floats1d, model.ops.get_dropout_mask((nO,), dropout)) if drop_mask is not None: output *= drop_mask def backprop(d_vectors: OutT) -> Ints1d: if drop_mask is not None: d_vectors *= drop_mask dE = model.ops.alloc2f(*vectors.shape) keysT = model.ops.as_contig(keys.T, dtype="i") for i in range(keysT.shape[0]): model.ops.scatter_add(dE, keysT[i], d_vectors) model.inc_grad("E", dE) dX = model.ops.alloc1i(nN) return dX return output, backprop def init( initializer: Callable, model: Model[Ints1d, OutT], X: Optional[Ints1d] = None, Y: Optional[OutT] = None, ) -> None: E = initializer(model.ops, (model.get_dim("nV"), model.get_dim("nO"))) model.set_param("E", E) thinc-9.0.0/thinc/layers/layernorm.py000066400000000000000000000047461461023342500176260ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..backends import Ops from ..config import registry from ..model import Model from ..types import Floats2d from ..util import get_width InT = Floats2d @registry.layers("LayerNorm.v1") def LayerNorm(nI: Optional[int] = None) -> Model[InT, InT]: return Model( "layernorm", forward, init=init, dims={"nI": nI, "nO": nI}, params={"G": None, "b": None}, ) def forward(model: Model[InT, InT], X: InT, is_train: bool) -> Tuple[InT, Callable]: N, mu, var = _get_moments(model.ops, X) Xhat = (X - mu) * var ** (-1.0 / 2.0) Y, backprop_rescale = _begin_update_scale_shift(model, Xhat) def backprop(dY: InT) -> InT: dY = backprop_rescale(dY) dist, sum_dy, sum_dy_dist = _get_d_moments(model.ops, dY, X, mu) d_xhat = N * dY - sum_dy - dist * var ** (-1.0) * sum_dy_dist d_xhat *= var ** (-1.0 / 2) d_xhat /= N return d_xhat return Y, backprop def init( model: Model[InT, InT], X: Optional[InT] = None, Y: Optional[InT] = None ) -> None: if X is not None: X_width = get_width(X) model.set_dim("nI", X_width) model.set_dim("nO", X_width) elif Y is not None: Y_width = get_width(Y) model.set_dim("nI", Y_width) model.set_dim("nO", Y_width) nI = model.get_dim("nI") if not model.has_dim("nO"): model.set_dim("nO", nI) model.set_param("G", model.ops.alloc1f(nI) + 1) model.set_param("b", model.ops.alloc1f(nI)) assert model.get_dim("nO") is not None def _begin_update_scale_shift(model: Model[InT, InT], X: InT) -> Tuple[InT, Callable]: G = model.get_param("G") b = model.get_param("b") Y = X * G Y += b def finish_update_scale_shift(dY: InT) -> InT: model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("G", (dY * X).sum(axis=0)) return dY * G return Y, finish_update_scale_shift def _get_moments(ops: Ops, X: Floats2d) -> Tuple[Floats2d, Floats2d, Floats2d]: # TODO: Do mean methods mu: Floats2d = X.mean(axis=1, keepdims=True) var: Floats2d = X.var(axis=1, keepdims=True) + 1e-08 return cast(Floats2d, ops.asarray_f([X.shape[1]])), mu, var def _get_d_moments( ops: Ops, dy: Floats2d, X: Floats2d, mu: Floats2d ) -> Tuple[Floats2d, Floats2d, Floats2d]: dist = X - mu return ( dist, ops.xp.sum(dy, axis=1, keepdims=True), ops.xp.sum(dy * dist, axis=1, keepdims=True), ) thinc-9.0.0/thinc/layers/linear.py000066400000000000000000000032701461023342500170570ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import glorot_uniform_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial InT = Floats2d OutT = Floats2d @registry.layers("Linear.v1") def Linear( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, ) -> Model[InT, OutT]: """Multiply inputs by a weights matrix and adds a bias vector.""" if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init return Model( "linear", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y = model.ops.gemm(X, W, trans2=True) Y += b def backprop(dY: OutT) -> InT: model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/list2array.py000066400000000000000000000015551461023342500177050ustar00rootroot00000000000000from typing import Callable, List, Tuple, TypeVar from ..backends import NumpyOps from ..config import registry from ..model import Model from ..types import Array2d NUMPY_OPS = NumpyOps() OutT = TypeVar("OutT", bound=Array2d) InT = List[OutT] @registry.layers("list2array.v1") def list2array() -> Model[InT, OutT]: """Transform sequences to ragged arrays if necessary and return the data from the ragged array. If sequences are already ragged, do nothing. A ragged array is a tuple (data, lengths), where data is the concatenated data. """ return Model("list2array", forward) def forward(model: Model[InT, OutT], Xs: InT, is_train: bool) -> Tuple[OutT, Callable]: lengths = NUMPY_OPS.asarray1i([len(x) for x in Xs]) def backprop(dY: OutT) -> InT: return model.ops.unflatten(dY, lengths) return model.ops.flatten(Xs), backprop thinc-9.0.0/thinc/layers/list2padded.py000066400000000000000000000011561461023342500200050ustar00rootroot00000000000000from typing import Callable, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import List2d, Padded InT = TypeVar("InT", bound=List2d) OutT = Padded @registry.layers("list2padded.v1") def list2padded() -> Model[InT, OutT]: """Create a layer to convert a list of array inputs into Padded.""" return Model(f"list2padded", forward) def forward(model: Model[InT, OutT], Xs: InT, is_train: bool) -> Tuple[OutT, Callable]: Yp = model.ops.list2padded(Xs) def backprop(dYp: OutT) -> InT: return cast(InT, model.ops.padded2list(dYp)) return Yp, backprop thinc-9.0.0/thinc/layers/list2ragged.py000066400000000000000000000015371461023342500200200ustar00rootroot00000000000000from typing import Callable, List, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import ArrayXd, ListXd, Ragged InT = TypeVar("InT", bound=ListXd) OutT = Ragged @registry.layers("list2ragged.v1") def list2ragged() -> Model[InT, OutT]: """Transform sequences to ragged arrays if necessary and return the ragged array. If sequences are already ragged, do nothing. A ragged array is a tuple (data, lengths), where data is the concatenated data. """ return Model("list2ragged", forward) def forward(model: Model[InT, OutT], Xs: InT, is_train: bool) -> Tuple[OutT, Callable]: def backprop(dYr: OutT) -> InT: return cast(InT, model.ops.unflatten(dYr.data, dYr.lengths)) lengths = model.ops.asarray1i([len(x) for x in Xs]) return Ragged(model.ops.flatten(Xs), lengths), backprop thinc-9.0.0/thinc/layers/logistic.py000066400000000000000000000011411461023342500174150ustar00rootroot00000000000000from typing import Callable, Tuple from ..config import registry from ..model import Model from ..types import Floats2d InT = Floats2d OutT = Floats2d @registry.layers("Logistic.v1") def Logistic() -> Model[InT, OutT]: """Deprecated in favor of `sigmoid_activation` layer, for more consistent naming. """ return Model("logistic", forward) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: Y = model.ops.sigmoid(X, inplace=False) def backprop(dY: OutT) -> InT: return dY * model.ops.dsigmoid(Y, inplace=False) return Y, backprop thinc-9.0.0/thinc/layers/lstm.py000066400000000000000000000144631461023342500165720ustar00rootroot00000000000000from functools import partial from typing import Callable, Optional, Tuple, cast from ..backends import Ops from ..config import registry from ..initializers import glorot_uniform_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d, Floats4d, Padded, Ragged from ..util import get_width from .noop import noop @registry.layers("LSTM.v1") def LSTM( nO: Optional[int] = None, nI: Optional[int] = None, *, bi: bool = False, depth: int = 1, dropout: float = 0.0, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, ) -> Model[Padded, Padded]: if depth == 0: msg = "LSTM depth must be at least 1. Maybe we should make this a noop?" raise ValueError(msg) if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init model: Model[Padded, Padded] = Model( "lstm", forward, dims={"nO": nO, "nI": nI, "depth": depth, "dirs": 1 + int(bi)}, attrs={"registry_name": "LSTM.v1", "dropout_rate": dropout}, params={"LSTM": None, "HC0": None}, init=partial(init, init_W, init_b), ) return model @registry.layers("PyTorchLSTM.v1") def PyTorchLSTM( nO: int, nI: int, *, bi: bool = False, depth: int = 1, dropout: float = 0.0 ) -> Model[Padded, Padded]: import torch.nn from .pytorchwrapper import PyTorchRNNWrapper from .with_padded import with_padded if depth == 0: return noop() # type: ignore[misc] nH = nO if bi: nH = nO // 2 pytorch_rnn = PyTorchRNNWrapper( torch.nn.LSTM(nI, nH, depth, bidirectional=bi, dropout=dropout) ) pytorch_rnn.set_dim("nO", nO) pytorch_rnn.set_dim("nI", nI) return with_padded(pytorch_rnn) def init( init_W: Callable, init_b: Callable, model: Model, X: Optional[Padded] = None, Y: Optional[Padded] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) nH = int(model.get_dim("nO") / model.get_dim("dirs")) nI = model.get_dim("nI") depth = model.get_dim("depth") dirs = model.get_dim("dirs") # It's easiest to use the initializer if we alloc the weights separately # and then stick them all together afterwards. The order matters here: # we need to keep the same format that CuDNN expects. params = [] # Convenience init_W = partial(init_W, model.ops) init_b = partial(init_b, model.ops) layer_nI = nI for i in range(depth): for j in range(dirs): # Input-to-gates weights and biases. params.append(init_W((nH, layer_nI))) params.append(init_W((nH, layer_nI))) params.append(init_W((nH, layer_nI))) params.append(init_W((nH, layer_nI))) params.append(init_b((nH,))) params.append(init_b((nH,))) params.append(init_b((nH,))) params.append(init_b((nH,))) # Hidden-to-gates weights and biases params.append(init_W((nH, nH))) params.append(init_W((nH, nH))) params.append(init_W((nH, nH))) params.append(init_W((nH, nH))) params.append(init_b((nH,))) params.append(init_b((nH,))) params.append(init_b((nH,))) params.append(init_b((nH,))) layer_nI = nH * dirs model.set_param("LSTM", model.ops.xp.concatenate([p.ravel() for p in params])) model.set_param("HC0", zero_init(model.ops, (2, depth, dirs, nH))) size = model.get_param("LSTM").size expected = 4 * dirs * nH * (nH + nI) + dirs * (8 * nH) for _ in range(1, depth): expected += 4 * dirs * (nH + nH * dirs) * nH + dirs * (8 * nH) assert size == expected, (size, expected) def forward( model: Model[Padded, Padded], Xp: Padded, is_train: bool ) -> Tuple[Padded, Callable]: dropout = model.attrs["dropout_rate"] Xr = _padded_to_packed(model.ops, Xp) LSTM = cast(Floats1d, model.get_param("LSTM")) HC0 = cast(Floats4d, model.get_param("HC0")) H0 = HC0[0] C0 = HC0[1] if is_train: # Apply dropout over *weights*, not *activations*. RNN activations are # heavily correlated, so dropout over the activations is less effective. # This trick was explained in Yarin Gal's thesis, and popularised by # Smerity in the AWD-LSTM. It also means we can do the dropout outside # of the backend, improving compatibility. mask = cast(Floats1d, model.ops.get_dropout_mask(LSTM.shape, dropout)) LSTM = LSTM * mask Y, fwd_state = model.ops.lstm_forward_training( LSTM, H0, C0, cast(Floats2d, Xr.data), Xr.lengths ) else: Y = model.ops.lstm_forward_inference( LSTM, H0, C0, cast(Floats2d, Xr.data), Xr.lengths ) fwd_state = tuple() assert Y.shape == (Xr.data.shape[0], Y.shape[1]), (Xr.data.shape, Y.shape) Yp = _packed_to_padded(model.ops, Ragged(Y, Xr.lengths), Xp) def backprop(dYp: Padded) -> Padded: assert fwd_state dYr = _padded_to_packed(model.ops, dYp) dX, dLSTM = model.ops.backprop_lstm( cast(Floats2d, dYr.data), dYr.lengths, LSTM, fwd_state ) dLSTM *= mask model.inc_grad("LSTM", dLSTM) return _packed_to_padded(model.ops, Ragged(dX, dYr.lengths), dYp) return Yp, backprop def _padded_to_packed(ops: Ops, Xp: Padded) -> Ragged: """Strip padding from a padded sequence.""" assert Xp.lengths.sum() == Xp.size_at_t.sum(), ( Xp.lengths.sum(), Xp.size_at_t.sum(), ) Y = ops.alloc2f(Xp.lengths.sum(), Xp.data.shape[2]) start = 0 for t in range(Xp.size_at_t.shape[0]): batch_size = Xp.size_at_t[t] Y[start : start + batch_size] = Xp.data[t, :batch_size] # type: ignore[assignment] start += batch_size return Ragged(Y, Xp.size_at_t) def _packed_to_padded(ops: Ops, Xr: Ragged, Xp: Padded) -> Padded: Y = ops.alloc3f(Xp.data.shape[0], Xp.data.shape[1], Xr.data.shape[1]) X = cast(Floats2d, Xr.data) start = 0 for t in range(Xp.size_at_t.shape[0]): batch_size = Xp.size_at_t[t] Y[t, :batch_size] = X[start : start + batch_size] start += batch_size return Padded(Y, size_at_t=Xp.size_at_t, lengths=Xp.lengths, indices=Xp.indices) thinc-9.0.0/thinc/layers/map_list.py000066400000000000000000000020031461023342500174060ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar from ..model import Model InT = TypeVar("InT") OutT = TypeVar("OutT") def map_list(layer: Model[InT, OutT]) -> Model[List[InT], List[OutT]]: """Create a model that maps a child layer across list inputs.""" return Model("map_list", forward, layers=[layer], init=init) def forward( model: Model[List[InT], List[OutT]], Xs: List[InT], is_train: bool ) -> Tuple[List[OutT], Callable[[List[OutT]], List[InT]]]: layer = model.layers[0] Ys = [] callbacks = [] for X in Xs: Y, get_dX = layer(X, is_train) Ys.append(Y) callbacks.append(get_dX) def backprop_map_list(dYs: List[OutT]) -> List[InT]: return [callback(dY) for callback, dY in zip(callbacks, dYs)] return Ys, backprop_map_list def init( model: Model[List[InT], List[OutT]], X: Optional[List[InT]] = None, Y: Optional[List[OutT]] = None, ) -> None: model.layers[0].initialize(X=X[0] if X else None, Y=Y[0] if Y else None) thinc-9.0.0/thinc/layers/maxout.py000066400000000000000000000050421461023342500171210ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import glorot_uniform_init, zero_init from ..model import Model from ..types import Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm InT = Floats2d OutT = Floats2d @registry.layers("Maxout.v1") def Maxout( nO: Optional[int] = None, nI: Optional[int] = None, nP: Optional[int] = 3, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[InT, OutT]: if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init model: Model[InT, OutT] = Model( "maxout", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI, "nP": nP}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[InT, OutT], Dropout(dropout))) return model def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: nO = model.get_dim("nO") nP = model.get_dim("nP") nI = model.get_dim("nI") b = model.get_param("b") W = model.get_param("W") W = model.ops.reshape2f(W, nO * nP, nI) Y = model.ops.gemm(X, W, trans2=True) Y += model.ops.reshape1f(b, nO * nP) Z = model.ops.reshape3f(Y, Y.shape[0], nO, nP) best, which = model.ops.maxout(Z) def backprop(d_best: OutT) -> InT: dZ = model.ops.backprop_maxout(d_best, which, nP) # TODO: Add sum methods for Floats3d model.inc_grad("b", dZ.sum(axis=0)) # type: ignore[call-overload] dY = model.ops.reshape2f(dZ, dZ.shape[0], nO * nP) dW = model.ops.reshape3f(model.ops.gemm(dY, X, trans1=True), nO, nP, nI) model.inc_grad("W", dW) return model.ops.gemm(dY, model.ops.reshape2f(W, nO * nP, nI)) return best, backprop def init( init_W: Callable, init_b: Callable, model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) W_shape = (model.get_dim("nO"), model.get_dim("nP"), model.get_dim("nI")) model.set_param("W", init_W(model.ops, W_shape)) model.set_param("b", init_b(model.ops, (model.get_dim("nO"), model.get_dim("nP")))) thinc-9.0.0/thinc/layers/mish.py000066400000000000000000000043351461023342500165500ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import glorot_uniform_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm InT = Floats2d OutT = Floats2d @registry.layers("Mish.v1") def Mish( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[InT, OutT]: """Dense layer with mish activation. https://arxiv.org/pdf/1908.08681.pdf """ if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init model: Model[InT, OutT] = Model( "mish", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, cast(Model[InT, OutT], LayerNorm(nI=nO))) if dropout is not None: model = chain(model, cast(Model[InT, OutT], Dropout(dropout))) return model def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_pre_mish = model.ops.gemm(X, W, trans2=True) Y_pre_mish += b Y = model.ops.mish(Y_pre_mish) def backprop(dY: OutT) -> InT: dY_pre_mish = model.ops.backprop_mish(dY, Y_pre_mish) model.inc_grad("W", model.ops.gemm(dY_pre_mish, X, trans1=True)) model.inc_grad("b", dY_pre_mish.sum(axis=0)) dX = model.ops.gemm(dY_pre_mish, W) return dX return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/multisoftmax.py000066400000000000000000000033501461023342500203400ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width InT = Floats2d OutT = Floats2d @registry.layers("MultiSoftmax.v1") def MultiSoftmax(nOs: Tuple[int, ...], nI: Optional[int] = None) -> Model[InT, OutT]: """Neural network layer that predicts several multi-class attributes at once. For instance, we might predict one class with 6 variables, and another with 5. We predict the 11 neurons required for this, and then softmax them such that columns 0-6 make a probability distribution and columns 6-11 make another. """ return Model( "multisoftmax", forward, init=init, dims={"nO": sum(nOs), "nI": nI}, attrs={"nOs": nOs}, params={"W": None, "b": None}, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: nOs = model.attrs["nOs"] W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) def backprop(dY: OutT) -> InT: model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) model.inc_grad("b", dY.sum(axis=0)) return model.ops.gemm(dY, W) Y = model.ops.gemm(X, W, trans2=True) Y += b i = 0 for out_size in nOs: model.ops.softmax(Y[:, i : i + out_size], inplace=True) i += out_size return Y, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is not None: model.set_dim("nI", get_width(X)) nO = model.get_dim("nO") nI = model.get_dim("nI") model.set_param("W", model.ops.alloc2f(nO, nI)) model.set_param("b", model.ops.alloc1f(nO)) thinc-9.0.0/thinc/layers/mxnetwrapper.py000066400000000000000000000102711461023342500203400ustar00rootroot00000000000000from typing import Any, Callable, Optional, Tuple, Type from ..config import registry from ..model import Model from ..shims import MXNetShim from ..types import ArgsKwargs from ..util import convert_recursive, is_mxnet_array, is_xp_array, mxnet2xp, xp2mxnet @registry.layers("MXNetWrapper.v1") def MXNetWrapper( mxnet_model, convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, model_class: Type[Model] = Model, model_name: str = "mxnet", ) -> Model[Any, Any]: """Wrap a MXNet model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a MXNet optimizer and call optimizer.step() after each batch. Your MXNet model's forward method can take arbitrary args and kwargs, but must return either a single tensor as output or a tuple. You may find the MXNet register_forward_hook helpful if you need to adapt the output. The convert functions are used to map inputs and outputs to and from your MXNet model. Each function should return the converted output, and a callback to use during the backward pass. So: Xmxnet, get_dX = convert_inputs(X) Ymxnet, mxnet_backprop = model.shims[0](Xmxnet, is_train) Y, get_dYmxnet = convert_outputs(Ymxnet) To allow maximum flexibility, the MXNetShim expects ArgsKwargs objects on the way into the forward and backward passes. The ArgsKwargs objects will be passed straight into the model in the forward pass, and straight into `mxnet.autograd.backward` during the backward pass. """ if convert_inputs is None: convert_inputs = convert_mxnet_default_inputs if convert_outputs is None: convert_outputs = convert_mxnet_default_outputs return model_class( model_name, forward, attrs={"convert_inputs": convert_inputs, "convert_outputs": convert_outputs}, shims=[MXNetShim(mxnet_model)], ) def forward(model: Model, X: Any, is_train: bool) -> Tuple[Any, Callable]: """Return the output of the wrapped MXNet model for the given input, along with a callback to handle the backward pass. """ convert_inputs = model.attrs["convert_inputs"] convert_outputs = model.attrs["convert_outputs"] Xmxnet, get_dX = convert_inputs(model, X, is_train) Ymxnet, mxnet_backprop = model.shims[0](Xmxnet, is_train) Y, get_dYmxnet = convert_outputs(model, (X, Ymxnet), is_train) def backprop(dY: Any) -> Any: dYmxnet = get_dYmxnet(dY) dXmxnet = mxnet_backprop(dYmxnet) dX = get_dX(dXmxnet) return dX return Y, backprop # Default conversion functions def convert_mxnet_default_inputs( model: Model, X: Any, is_train: bool ) -> Tuple[ArgsKwargs, Callable[[ArgsKwargs], Any]]: xp2mxnet_ = lambda x: xp2mxnet(x, requires_grad=is_train) converted = convert_recursive(is_xp_array, xp2mxnet_, X) if isinstance(converted, ArgsKwargs): def reverse_conversion(dXmxnet): return convert_recursive(is_mxnet_array, mxnet2xp, dXmxnet) return converted, reverse_conversion elif isinstance(converted, dict): def reverse_conversion(dXmxnet): dX = convert_recursive(is_mxnet_array, mxnet2xp, dXmxnet) return dX.kwargs return ArgsKwargs(args=tuple(), kwargs=converted), reverse_conversion elif isinstance(converted, (tuple, list)): def reverse_conversion(dXmxnet): dX = convert_recursive(is_mxnet_array, mxnet2xp, dXmxnet) return dX.args return ArgsKwargs(args=tuple(converted), kwargs={}), reverse_conversion else: def reverse_conversion(dXmxnet): dX = convert_recursive(is_mxnet_array, mxnet2xp, dXmxnet) return dX.args[0] return ArgsKwargs(args=(converted,), kwargs={}), reverse_conversion def convert_mxnet_default_outputs(model: Model, X_Ymxnet: Any, is_train: bool): X, Ymxnet = X_Ymxnet Y = convert_recursive(is_mxnet_array, mxnet2xp, Ymxnet) def reverse_conversion(dY: Any) -> ArgsKwargs: dYmxnet = convert_recursive(is_xp_array, xp2mxnet, dY) return ArgsKwargs(args=((Ymxnet,),), kwargs={"head_grads": dYmxnet}) return Y, reverse_conversion thinc-9.0.0/thinc/layers/noop.py000066400000000000000000000007771461023342500165710ustar00rootroot00000000000000from typing import Callable, Tuple, TypeVar from ..config import registry from ..model import Model InOutT = TypeVar("InOutT") @registry.layers("noop.v1") def noop(*layers: Model) -> Model[InOutT, InOutT]: """Transform a sequences of layers into a null operation.""" return Model("noop", forward, layers=layers) def forward( model: Model[InOutT, InOutT], X: InOutT, is_train: bool ) -> Tuple[InOutT, Callable]: def backprop(dY: InOutT) -> InOutT: return dY return X, backprop thinc-9.0.0/thinc/layers/padded2list.py000066400000000000000000000012761461023342500200100ustar00rootroot00000000000000from typing import Callable, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import List2d, Padded InT = Padded OutT = TypeVar("OutT", bound=List2d) @registry.layers("padded2list.v1") def padded2list() -> Model[InT, OutT]: """Create a layer to convert a Padded input into a list of arrays.""" return Model(f"padded2list", forward) def forward( model: Model[InT, OutT], Xp: InT, is_train: bool ) -> Tuple[OutT, Callable[[OutT], InT]]: Ys = cast(OutT, model.ops.padded2list(Xp)) def backprop(dYs: OutT) -> InT: dYp = model.ops.list2padded(dYs) assert isinstance(dYp, Padded) return dYp return Ys, backprop thinc-9.0.0/thinc/layers/parametricattention.py000066400000000000000000000040701461023342500216610ustar00rootroot00000000000000from typing import Callable, Optional, Tuple from ..config import registry from ..model import Model from ..types import Ragged from ..util import get_width InT = Ragged OutT = Ragged @registry.layers("ParametricAttention.v1") def ParametricAttention(nO: Optional[int] = None) -> Model[InT, OutT]: """Weight inputs by similarity to a learned vector""" return Model("para-attn", forward, init=init, params={"Q": None}, dims={"nO": nO}) def forward(model: Model[InT, OutT], Xr: InT, is_train: bool) -> Tuple[OutT, Callable]: Q = model.get_param("Q") attention, bp_attention = _get_attention(model.ops, Q, Xr.dataXd, Xr.lengths) output, bp_output = _apply_attention(model.ops, attention, Xr.dataXd, Xr.lengths) def backprop(dYr: OutT) -> InT: dX, d_attention = bp_output(dYr.dataXd) dQ, dX2 = bp_attention(d_attention) model.inc_grad("Q", dQ.ravel()) dX += dX2 return Ragged(dX, dYr.lengths) return Ragged(output, Xr.lengths), backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is not None: model.set_dim("nO", get_width(X)) # Randomly initialize the parameter, as though it were an embedding. Q = model.ops.alloc1f(model.get_dim("nO")) Q += model.ops.xp.random.uniform(-0.1, 0.1, Q.shape) model.set_param("Q", Q) def _get_attention(ops, Q, X, lengths): attention = ops.gemm(X, ops.reshape2f(Q, -1, 1)) attention = ops.softmax_sequences(attention, lengths) def get_attention_bwd(d_attention): d_attention = ops.backprop_softmax_sequences(d_attention, attention, lengths) dQ = ops.gemm(X, d_attention, trans1=True) dX = ops.xp.outer(d_attention, Q) return dQ, dX return attention, get_attention_bwd def _apply_attention(ops, attention, X, lengths): output = X * attention def apply_attention_bwd(d_output): d_attention = (X * d_output).sum(axis=1, keepdims=True) dX = d_output * attention return dX, d_attention return output, apply_attention_bwd thinc-9.0.0/thinc/layers/parametricattention_v2.py000066400000000000000000000056341461023342500222770ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged from ..util import get_width from .noop import noop InT = Ragged OutT = Ragged KEY_TRANSFORM_REF: str = "key_transform" @registry.layers("ParametricAttention.v2") def ParametricAttention_v2( *, key_transform: Optional[Model[Floats2d, Floats2d]] = None, nO: Optional[int] = None ) -> Model[InT, OutT]: if key_transform is None: key_transform = noop() """Weight inputs by similarity to a learned vector""" return Model( "para-attn", forward, init=init, params={"Q": None}, dims={"nO": nO}, refs={KEY_TRANSFORM_REF: key_transform}, layers=[key_transform], ) def forward(model: Model[InT, OutT], Xr: InT, is_train: bool) -> Tuple[OutT, Callable]: Q = model.get_param("Q") key_transform = model.get_ref(KEY_TRANSFORM_REF) attention, bp_attention = _get_attention( model.ops, Q, key_transform, Xr.dataXd, Xr.lengths, is_train ) output, bp_output = _apply_attention(model.ops, attention, Xr.dataXd, Xr.lengths) def backprop(dYr: OutT) -> InT: dX, d_attention = bp_output(dYr.dataXd) dQ, dX2 = bp_attention(d_attention) model.inc_grad("Q", dQ.ravel()) dX += dX2 return Ragged(dX, dYr.lengths) return Ragged(output, Xr.lengths), backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: key_transform = model.get_ref(KEY_TRANSFORM_REF) width = get_width(X) if X is not None else None if width: model.set_dim("nO", width) if key_transform.has_dim("nO"): key_transform.set_dim("nO", width) # Randomly initialize the parameter, as though it were an embedding. Q = model.ops.alloc1f(model.get_dim("nO")) Q += model.ops.xp.random.uniform(-0.1, 0.1, Q.shape) model.set_param("Q", Q) X_array = X.dataXd if X is not None else None Y_array = Y.dataXd if Y is not None else None key_transform.initialize(X_array, Y_array) def _get_attention(ops, Q, key_transform, X, lengths, is_train): K, K_bp = key_transform(X, is_train=is_train) attention = ops.gemm(K, ops.reshape2f(Q, -1, 1)) attention = ops.softmax_sequences(attention, lengths) def get_attention_bwd(d_attention): d_attention = ops.backprop_softmax_sequences(d_attention, attention, lengths) dQ = ops.gemm(K, d_attention, trans1=True) dY = ops.xp.outer(d_attention, Q) dX = K_bp(dY) return dQ, dX return attention, get_attention_bwd def _apply_attention(ops, attention, X, lengths): output = X * attention def apply_attention_bwd(d_output): d_attention = (X * d_output).sum(axis=1, keepdims=True) dX = d_output * attention return dX, d_attention return output, apply_attention_bwd thinc-9.0.0/thinc/layers/premap_ids.pyx000066400000000000000000000044131461023342500201200ustar00rootroot00000000000000# cython: binding=True, infer_types=True, profile=False import numpy from preshed.maps cimport PreshMap from typing import Callable, Dict, Mapping, Optional, Tuple, Union, cast from ..config import registry from ..model import Model from ..types import Ints1d, Ints2d from ..util import to_numpy InT = Union[Ints1d, Ints2d] OutT = Ints2d cdef lookup(PreshMap mapping, long[:] keys, long default): """ Faster dict.get(keys, default) for the case when the "dict" is a Dict[int, int] converted to PreshMap and the "keys" is a numpy integer vector. """ cdef int maxi = len(keys) result = numpy.empty(maxi, dtype="int") cdef long[:] result_view = result for i in range(maxi): v = mapping[keys[i]] if v is None: result_view[i] = default else: result_view[i] = v return result @registry.layers("premap_ids.v1") def premap_ids( mapping_table: Mapping[int, int], default: int = 0, *, column: Optional[int] = None ): """Remap integer inputs to integers a mapping table, usually as a preprocess before embeddings.""" mapper = PreshMap(initial_size=len(mapping_table)) for k, v in mapping_table.items(): if not (isinstance(k, int) and isinstance(v, int)): raise ValueError( "mapping_table has to be of type Mapping[int, int], " f"but found {k}, {type(k)} and {v}, {type(v)}" ) mapper[k] = v return Model( "premap_ids", forward, attrs={ "mapping_table": mapper, "default": default, "column": column } ) def forward( model: Model, inputs: InT, is_train: bool ) -> Tuple[OutT, Callable]: table = model.attrs["mapping_table"] default = model.attrs["default"] column = model.attrs["column"] # Have to convert to numpy anyways, because # cupy ints don't work together with Python ints. if column is None: idx = to_numpy(inputs) else: idx = to_numpy(cast(Ints2d, inputs)[:, column]) result = lookup(table, idx, default) arr = model.ops.asarray2i(result) output = model.ops.reshape2i(arr, -1, 1) def backprop(dY: OutT) -> InT: return model.ops.xp.empty(dY.shape) # type: ignore return output, backprop thinc-9.0.0/thinc/layers/pytorchwrapper.py000066400000000000000000000302271461023342500207000ustar00rootroot00000000000000from typing import Any, Callable, Dict, Optional, Tuple, cast from ..compat import torch from ..config import registry from ..model import Model from ..shims import PyTorchGradScaler, PyTorchShim from ..types import ArgsKwargs, Floats3d, Padded from ..util import ( convert_recursive, is_torch_array, is_xp_array, partial, torch2xp, xp2torch, ) @registry.layers("PyTorchRNNWrapper.v1") def PyTorchRNNWrapper( pytorch_model: Any, convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, ) -> Model[Padded, Padded]: """Wrap a PyTorch RNN model for use in Thinc.""" if convert_inputs is None: convert_inputs = convert_rnn_inputs if convert_outputs is None: convert_outputs = convert_rnn_outputs return cast( Model[Padded, Padded], PyTorchWrapper( pytorch_model, convert_inputs=convert_inputs, convert_outputs=convert_outputs, ), ) @registry.layers("PyTorchWrapper.v1") def PyTorchWrapper( pytorch_model: Any, convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, ) -> Model[Any, Any]: """Wrap a PyTorch model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a PyTorch optimizer and call optimizer.step() after each batch. See examples/wrap_pytorch.py Your PyTorch model's forward method can take arbitrary args and kwargs, but must return either a single tensor as output or a tuple. You may find the PyTorch register_forward_hook helpful if you need to adapt the output. The convert functions are used to map inputs and outputs to and from your PyTorch model. Each function should return the converted output, and a callback to use during the backward pass. So: Xtorch, get_dX = convert_inputs(X) Ytorch, torch_backprop = model.shims[0](Xtorch, is_train) Y, get_dYtorch = convert_outputs(Ytorch) To allow maximum flexibility, the PyTorchShim expects ArgsKwargs objects on the way into the forward and backward passed. The ArgsKwargs objects will be passed straight into the model in the forward pass, and straight into `torch.autograd.backward` during the backward pass. """ if convert_inputs is None: convert_inputs = convert_pytorch_default_inputs if convert_outputs is None: convert_outputs = convert_pytorch_default_outputs return Model( "pytorch", forward, attrs={"convert_inputs": convert_inputs, "convert_outputs": convert_outputs}, shims=[PyTorchShim(pytorch_model)], dims={"nI": None, "nO": None}, ) @registry.layers("PyTorchWrapper.v2") def PyTorchWrapper_v2( pytorch_model: Any, convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, mixed_precision: bool = False, grad_scaler: Optional[PyTorchGradScaler] = None, device: Optional["torch.device"] = None, ) -> Model[Any, Any]: """Wrap a PyTorch model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a PyTorch optimizer and call optimizer.step() after each batch. See examples/wrap_pytorch.py Your PyTorch model's forward method can take arbitrary args and kwargs, but must return either a single tensor as output or a tuple. You may find the PyTorch register_forward_hook helpful if you need to adapt the output. The convert functions are used to map inputs and outputs to and from your PyTorch model. Each function should return the converted output, and a callback to use during the backward pass. So: Xtorch, get_dX = convert_inputs(X) Ytorch, torch_backprop = model.shims[0](Xtorch, is_train) Y, get_dYtorch = convert_outputs(Ytorch) To allow maximum flexibility, the PyTorchShim expects ArgsKwargs objects on the way into the forward and backward passed. The ArgsKwargs objects will be passed straight into the model in the forward pass, and straight into `torch.autograd.backward` during the backward pass. mixed_precision: Enable mixed-precision. This changes whitelisted ops to run in half precision for better performance and lower memory use. grad_scaler: The gradient scaler to use for mixed-precision training. If this argument is set to "None" and mixed precision is enabled, a gradient scaler with the default configuration is used. device: The PyTorch device to run the model on. When this argument is set to "None", the default device for the currently active Thinc ops is used. """ if convert_inputs is None: convert_inputs = convert_pytorch_default_inputs if convert_outputs is None: convert_outputs = convert_pytorch_default_outputs return Model( "pytorch", forward, attrs={"convert_inputs": convert_inputs, "convert_outputs": convert_outputs}, shims=[ PyTorchShim( pytorch_model, mixed_precision=mixed_precision, grad_scaler=grad_scaler, device=device, ) ], dims={"nI": None, "nO": None}, ) @registry.layers("PyTorchWrapper.v3") def PyTorchWrapper_v3( pytorch_model: "torch.nn.Module", convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, mixed_precision: bool = False, grad_scaler: Optional[PyTorchGradScaler] = None, device: Optional["torch.device"] = None, serialize_model: Optional[Callable[[Any], bytes]] = None, deserialize_model: Optional[Callable[[Any, bytes, "torch.device"], Any]] = None, ) -> Model[Any, Any]: """Wrap a PyTorch model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a PyTorch optimizer and call optimizer.step() after each batch. See examples/wrap_pytorch.py Your PyTorch model's forward method can take arbitrary args and kwargs, but must return either a single tensor or a tuple. You may find the PyTorch register_forward_hook helpful if you need to adapt the output. The convert functions are used to map inputs and outputs to and from your PyTorch model. Each function should return the converted output, and a callback to use during the backward pass. So: Xtorch, get_dX = convert_inputs(X) Ytorch, torch_backprop = model.shims[0](Xtorch, is_train) Y, get_dYtorch = convert_outputs(Ytorch) To allow maximum flexibility, the PyTorchShim expects ArgsKwargs objects on the way into the forward and backward passed. The ArgsKwargs objects will be passed straight into the model in the forward pass, and straight into `torch.autograd.backward` during the backward pass. mixed_precision: Enable mixed-precision. This changes whitelisted ops to run in half precision for better performance and lower memory use. grad_scaler: The gradient scaler to use for mixed-precision training. If this argument is set to "None" and mixed precision is enabled, a gradient scaler with the default configuration is used. device: The PyTorch device to run the model on. When this argument is set to "None", the default device for the currently active Thinc ops is used. serialize_model: Callback that receives the wrapped PyTorch model as its argument and returns a "bytes" representation of the same. The representation should contain all the necessary information to fully deserialize the model. When set to "None", the default serializer serializes the model's parameters. deserialize_model: Callback that receives the default PyTorch model (passed to the constructor), the serialized "bytes" representation and a PyTorch device. It should return a fully deserialized model on the target device as its result. When set to "None", the default deserializer deserializes the model's parameters. """ if convert_inputs is None: convert_inputs = convert_pytorch_default_inputs if convert_outputs is None: convert_outputs = convert_pytorch_default_outputs return Model( "pytorch", forward, attrs={"convert_inputs": convert_inputs, "convert_outputs": convert_outputs}, shims=[ PyTorchShim( pytorch_model, mixed_precision=mixed_precision, grad_scaler=grad_scaler, device=device, serialize_model=serialize_model, deserialize_model=deserialize_model, ) ], dims={"nI": None, "nO": None}, ) def forward(model: Model, X: Any, is_train: bool) -> Tuple[Any, Callable]: """Return the output of the wrapped PyTorch model for the given input, along with a callback to handle the backward pass. """ convert_inputs = model.attrs["convert_inputs"] convert_outputs = model.attrs["convert_outputs"] Xtorch, get_dX = convert_inputs(model, X, is_train) Ytorch, torch_backprop = model.shims[0](Xtorch, is_train) Y, get_dYtorch = convert_outputs(model, (X, Ytorch), is_train) def backprop(dY: Any) -> Any: dYtorch = get_dYtorch(dY) dXtorch = torch_backprop(dYtorch) dX = get_dX(dXtorch) return dX return Y, backprop # Default conversion functions def convert_pytorch_default_inputs( model: Model, X: Any, is_train: bool ) -> Tuple[ArgsKwargs, Callable[[ArgsKwargs], Any]]: shim = cast(PyTorchShim, model.shims[0]) xp2torch_ = lambda x: xp2torch(x, requires_grad=is_train, device=shim.device) converted = convert_recursive(is_xp_array, xp2torch_, X) if isinstance(converted, ArgsKwargs): def reverse_conversion(dXtorch): return convert_recursive(is_torch_array, torch2xp, dXtorch) return converted, reverse_conversion elif isinstance(converted, dict): def reverse_conversion(dXtorch): dX = convert_recursive(is_torch_array, torch2xp, dXtorch) return dX.kwargs return ArgsKwargs(args=tuple(), kwargs=converted), reverse_conversion elif isinstance(converted, (tuple, list)): def reverse_conversion(dXtorch): dX = convert_recursive(is_torch_array, torch2xp, dXtorch) return dX.args return ArgsKwargs(args=tuple(converted), kwargs={}), reverse_conversion else: def reverse_conversion(dXtorch): dX = convert_recursive(is_torch_array, torch2xp, dXtorch) return dX.args[0] return ArgsKwargs(args=(converted,), kwargs={}), reverse_conversion def convert_pytorch_default_outputs(model: Model, X_Ytorch: Any, is_train: bool): shim = cast(PyTorchShim, model.shims[0]) X, Ytorch = X_Ytorch Y = convert_recursive(is_torch_array, torch2xp, Ytorch) def reverse_conversion(dY: Any) -> ArgsKwargs: dYtorch = convert_recursive( is_xp_array, partial(xp2torch, device=shim.device), dY ) return ArgsKwargs(args=((Ytorch,),), kwargs={"grad_tensors": dYtorch}) return Y, reverse_conversion # BiLSTM conversion functions def convert_rnn_inputs(model: Model, Xp: Padded, is_train: bool): shim = cast(PyTorchShim, model.shims[0]) size_at_t = Xp.size_at_t lengths = Xp.lengths indices = Xp.indices def convert_from_torch_backward(d_inputs: ArgsKwargs) -> Padded: dX = torch2xp(d_inputs.args[0]) return Padded(dX, size_at_t, lengths, indices) # type: ignore output = ArgsKwargs( args=(xp2torch(Xp.data, requires_grad=True, device=shim.device), None), kwargs={}, ) return output, convert_from_torch_backward def convert_rnn_outputs(model: Model, inputs_outputs: Tuple, is_train): shim = cast(PyTorchShim, model.shims[0]) Xp, (Ytorch, _) = inputs_outputs def convert_for_torch_backward(dYp: Padded) -> ArgsKwargs: dYtorch = xp2torch(dYp.data, requires_grad=True, device=shim.device) return ArgsKwargs(args=(Ytorch,), kwargs={"grad_tensors": dYtorch}) Y = cast(Floats3d, torch2xp(Ytorch)) Yp = Padded(Y, Xp.size_at_t, Xp.lengths, Xp.indices) return Yp, convert_for_torch_backward thinc-9.0.0/thinc/layers/ragged2list.py000066400000000000000000000014051461023342500200120ustar00rootroot00000000000000from typing import Callable, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import ListXd, Ragged InT = Ragged OutT = TypeVar("OutT", bound=ListXd) @registry.layers("ragged2list.v1") def ragged2list() -> Model[InT, OutT]: """Transform sequences from a ragged format into lists.""" return Model("ragged2list", forward) def forward(model: Model[InT, OutT], Xr: InT, is_train: bool) -> Tuple[OutT, Callable]: lengths = Xr.lengths def backprop(dXs: OutT) -> InT: return Ragged(model.ops.flatten(dXs, pad=0), lengths) # type:ignore[arg-type] # type ignore necessary for older versions of Mypy/Pydantic data = cast(OutT, model.ops.unflatten(Xr.dataXd, Xr.lengths)) return data, backprop thinc-9.0.0/thinc/layers/reduce_first.py000066400000000000000000000014571461023342500202700ustar00rootroot00000000000000from typing import Callable, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged from ..util import ArrayInfo InT = Ragged OutT = Floats2d @registry.layers("reduce_first.v1") def reduce_first() -> Model[InT, OutT]: """Reduce ragged-formatted sequences to their first element.""" return Model("reduce_first", forward) def forward( model: Model[InT, OutT], Xr: InT, is_train: bool ) -> Tuple[OutT, Callable[[OutT], InT]]: Y, starts_ends = model.ops.reduce_first(cast(Floats2d, Xr.data), Xr.lengths) array_info = ArrayInfo.from_array(Y) def backprop(dY: OutT) -> InT: array_info.check_consistency(dY) dX = model.ops.backprop_reduce_first(dY, starts_ends) return Ragged(dX, Xr.lengths) return Y, backprop thinc-9.0.0/thinc/layers/reduce_last.py000066400000000000000000000014341461023342500200770ustar00rootroot00000000000000from typing import Callable, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged from ..util import ArrayInfo InT = Ragged OutT = Floats2d @registry.layers("reduce_last.v1") def reduce_last() -> Model[InT, OutT]: """Reduce ragged-formatted sequences to their last element.""" return Model("reduce_last", forward) def forward( model: Model[InT, OutT], Xr: InT, is_train: bool ) -> Tuple[OutT, Callable[[OutT], InT]]: Y, lasts = model.ops.reduce_last(cast(Floats2d, Xr.data), Xr.lengths) array_info = ArrayInfo.from_array(Y) def backprop(dY: OutT) -> InT: array_info.check_consistency(dY) dX = model.ops.backprop_reduce_last(dY, lasts) return Ragged(dX, Xr.lengths) return Y, backprop thinc-9.0.0/thinc/layers/reduce_max.py000066400000000000000000000013201461023342500177130ustar00rootroot00000000000000from typing import Callable, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged from ..util import ArrayInfo InT = Ragged OutT = Floats2d @registry.layers("reduce_max.v1") def reduce_max() -> Model[InT, OutT]: return Model("reduce_max", forward) def forward(model: Model[InT, OutT], Xr: InT, is_train: bool) -> Tuple[OutT, Callable]: Y, which = model.ops.reduce_max(cast(Floats2d, Xr.data), Xr.lengths) lengths = Xr.lengths array_info = ArrayInfo.from_array(Y) def backprop(dY: OutT) -> InT: array_info.check_consistency(dY) return Ragged(model.ops.backprop_reduce_max(dY, which, lengths), lengths) return Y, backprop thinc-9.0.0/thinc/layers/reduce_mean.py000066400000000000000000000013101461023342500200450ustar00rootroot00000000000000from typing import Callable, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged from ..util import ArrayInfo InT = Ragged OutT = Floats2d @registry.layers("reduce_mean.v1") def reduce_mean() -> Model[InT, OutT]: return Model("reduce_mean", forward) def forward(model: Model[InT, OutT], Xr: InT, is_train: bool) -> Tuple[OutT, Callable]: Y = model.ops.reduce_mean(cast(Floats2d, Xr.data), Xr.lengths) lengths = Xr.lengths array_info = ArrayInfo.from_array(Y) def backprop(dY: OutT) -> InT: array_info.check_consistency(dY) return Ragged(model.ops.backprop_reduce_mean(dY, lengths), lengths) return Y, backprop thinc-9.0.0/thinc/layers/reduce_sum.py000066400000000000000000000013021461023342500177320ustar00rootroot00000000000000from typing import Callable, Tuple, cast from ..config import registry from ..model import Model from ..types import Floats2d, Ragged from ..util import ArrayInfo InT = Ragged OutT = Floats2d @registry.layers("reduce_sum.v1") def reduce_sum() -> Model[InT, OutT]: return Model("reduce_sum", forward) def forward(model: Model[InT, OutT], Xr: InT, is_train: bool) -> Tuple[OutT, Callable]: Y = model.ops.reduce_sum(cast(Floats2d, Xr.data), Xr.lengths) lengths = Xr.lengths array_info = ArrayInfo.from_array(Y) def backprop(dY: OutT) -> InT: array_info.check_consistency(dY) return Ragged(model.ops.backprop_reduce_sum(dY, lengths), lengths) return Y, backprop thinc-9.0.0/thinc/layers/relu.py000066400000000000000000000040111461023342500165460ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import glorot_uniform_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm InT = Floats2d OutT = Floats2d @registry.layers("Relu.v1") def Relu( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[InT, OutT]: if init_W is None: init_W = glorot_uniform_init if init_b is None: init_b = zero_init model: Model[InT, OutT] = Model( "relu", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y = model.ops.affine(X, W, b) Y = model.ops.relu(Y) def backprop(dY: OutT) -> InT: dY = model.ops.backprop_relu(dY, Y) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/remap_ids.py000066400000000000000000000060001461023342500175420ustar00rootroot00000000000000from typing import Any, Callable, Dict, Hashable, Optional, Sequence, Tuple, Union, cast from ..config import registry from ..model import Model from ..types import DTypes, Ints1d, Ints2d from ..util import is_xp_array, to_numpy InT = Union[Sequence[Hashable], Ints1d, Ints2d] OutT = Ints2d InT_v1 = Sequence[Any] OutT_v1 = Ints2d @registry.layers("remap_ids.v1") def remap_ids( mapping_table: Dict[Any, int] = {}, default: int = 0, dtype: DTypes = "i" ) -> Model[InT_v1, OutT_v1]: """Remap string or integer inputs using a mapping table, usually as a preprocess before embeddings. The mapping table can be passed in on input, or updated after the layer has been created. The mapping table is stored in the "mapping_table" attribute. """ return Model( "remap_ids", forward, attrs={"mapping_table": mapping_table, "dtype": dtype, "default": default}, ) def forward( model: Model[InT_v1, OutT_v1], inputs: InT_v1, is_train: bool ) -> Tuple[OutT, Callable]: table = model.attrs["mapping_table"] default = model.attrs["default"] dtype = model.attrs["dtype"] values = [table.get(x, default) for x in inputs] arr = model.ops.asarray2i(values, dtype=dtype) output = model.ops.reshape2i(arr, -1, 1) def backprop(dY: OutT_v1) -> InT: return [] return output, backprop @registry.layers("remap_ids.v2") def remap_ids_v2( mapping_table: Optional[Union[Dict[int, int], Dict[str, int]]] = None, default: int = 0, *, column: Optional[int] = None ) -> Model[InT, OutT]: """Remap string or integer inputs using a mapping table, usually as a preprocessing step before embeddings. The mapping table can be passed in on input, or updated after the layer has been created. The mapping table is stored in the "mapping_table" attribute. Two dimensional arrays can be provided as input in which case the 'column' chooses which column to process. This is useful to work together with FeatureExtractor in spaCy. """ return Model( "remap_ids", forward_v2, attrs={"mapping_table": mapping_table, "default": default, "column": column}, ) def forward_v2( model: Model[InT, OutT], inputs: InT, is_train: bool ) -> Tuple[OutT, Callable]: table = model.attrs["mapping_table"] if table is None: raise ValueError("'mapping table' not set") default = model.attrs["default"] column = model.attrs["column"] if is_xp_array(inputs): xp_input = True if column is not None: idx = to_numpy(cast(Ints2d, inputs)[:, column]) else: idx = to_numpy(inputs) else: xp_input = False idx = inputs values = [table.get(x, default) for x in idx] arr = model.ops.asarray2i(values, dtype="i") output = model.ops.reshape2i(arr, -1, 1) def backprop(dY: OutT) -> InT: if xp_input: return model.ops.xp.empty(dY.shape) # type: ignore else: return [] return output, backprop thinc-9.0.0/thinc/layers/residual.py000066400000000000000000000040541461023342500174160ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar from ..config import registry from ..model import Model from ..types import Floats1d, Floats2d, Floats3d, Floats4d, FloatsXd, Padded, Ragged # fmt: off InT = TypeVar( "InT", List[Floats1d], List[Floats2d], List[Floats3d], List[Floats4d], Ragged, Padded, FloatsXd, Floats1d, Floats2d, Floats3d, Floats4d) # fmt: on @registry.layers("residual.v1") def residual(layer: Model[InT, InT]) -> Model[InT, InT]: return Model( f"residual({layer.name})", forward, init=init, layers=[layer], dims={ "nO": layer.get_dim("nO") if layer.has_dim("nO") else None, "nI": layer.get_dim("nI") if layer.has_dim("nI") else None, }, ) def forward(model: Model[InT, InT], X: InT, is_train: bool) -> Tuple[InT, Callable]: def backprop(d_output: InT) -> InT: dX = backprop_layer(d_output) if isinstance(d_output, list): return [d_output[i] + dX[i] for i in range(len(d_output))] elif isinstance(d_output, Ragged): return Ragged(d_output.data + dX.data, dX.lengths) elif isinstance(X, Padded): dX.data += d_output.data return dX else: return d_output + dX Y, backprop_layer = model.layers[0](X, is_train) if isinstance(X, list): return [X[i] + Y[i] for i in range(len(X))], backprop elif isinstance(X, Ragged): return Ragged(X.data + Y.data, X.lengths), backprop elif isinstance(X, Padded): Y.data += X.data return Y, backprop else: return X + Y, backprop def init( model: Model[InT, InT], X: Optional[InT] = None, Y: Optional[InT] = None ) -> None: first_layer = model.layers[0] if first_layer.has_dim("nO") is None: first_layer.initialize(X=X, Y=Y) else: first_layer.initialize(X=X) if first_layer.has_dim("nO"): model.set_dim("nO", first_layer.get_dim("nO")) if first_layer.has_dim("nI"): model.set_dim("nI", first_layer.get_dim("nI")) thinc-9.0.0/thinc/layers/resizable.py000066400000000000000000000053031461023342500175640ustar00rootroot00000000000000from typing import Callable, Optional, TypeVar from ..config import registry from ..model import Model from ..types import Floats2d InT = TypeVar("InT") OutT = TypeVar("OutT") @registry.layers("resizable.v1") def resizable(layer, resize_layer: Callable) -> Model[InT, OutT]: """Container that holds one layer that can change dimensions.""" return Model( f"resizable({layer.name})", forward, init=init, layers=[layer], attrs={"resize_layer": resize_layer}, dims={name: layer.maybe_get_dim(name) for name in layer.dim_names}, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool): layer = model.layers[0] Y, callback = layer(X, is_train=is_train) def backprop(dY: OutT) -> InT: return callback(dY) return Y, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: layer = model.layers[0] layer.initialize(X, Y) def resize_model(model: Model[InT, OutT], new_nO): old_layer = model.layers[0] new_layer = model.attrs["resize_layer"](old_layer, new_nO) model.layers[0] = new_layer return model def resize_linear_weighted( layer: Model[Floats2d, Floats2d], new_nO, *, fill_defaults=None ) -> Model[Floats2d, Floats2d]: """Create a resized copy of a layer that has parameters W and b and dimensions nO and nI.""" assert not layer.layers assert not layer.ref_names assert not layer.shims # return the original layer if it wasn't initialized or if nO didn't change if layer.has_dim("nO") is None: layer.set_dim("nO", new_nO) return layer elif new_nO == layer.get_dim("nO"): return layer elif layer.has_dim("nI") is None: layer.set_dim("nO", new_nO, force=True) return layer dims = {name: layer.maybe_get_dim(name) for name in layer.dim_names} dims["nO"] = new_nO new_layer: Model[Floats2d, Floats2d] = Model( layer.name, layer._func, dims=dims, params={name: None for name in layer.param_names}, init=layer.init, attrs=layer.attrs, refs={}, ops=layer.ops, ) new_layer.initialize() for name in layer.param_names: if layer.has_param(name): filler = 0 if not fill_defaults else fill_defaults.get(name, 0) _resize_parameter(name, layer, new_layer, filler=filler) return new_layer def _resize_parameter(name, layer, new_layer, filler=0): larger = new_layer.get_param(name) smaller = layer.get_param(name) # copy the original weights larger[: len(smaller)] = smaller # set the new weights larger[len(smaller) :] = filler new_layer.set_param(name, larger) thinc-9.0.0/thinc/layers/siamese.py000066400000000000000000000031161461023342500172320ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, TypeVar from ..config import registry from ..model import Model from ..types import ArrayXd from ..util import get_width LayerT = TypeVar("LayerT") SimT = TypeVar("SimT") InT = Tuple[LayerT, LayerT] OutT = TypeVar("OutT", bound=ArrayXd) @registry.layers("siamese.v1") def siamese( layer: Model[LayerT, SimT], similarity: Model[Tuple[SimT, SimT], OutT] ) -> Model[InT, OutT]: return Model( f"siamese({layer.name}, {similarity.name})", forward, init=init, layers=[layer, similarity], dims={"nI": layer.get_dim("nI"), "nO": similarity.get_dim("nO")}, ) def forward( model: Model[InT, OutT], X1_X2: InT, is_train: bool ) -> Tuple[OutT, Callable]: X1, X2 = X1_X2 vec1, bp_vec1 = model.layers[0](X1, is_train) vec2, bp_vec2 = model.layers[0](X2, is_train) output, bp_output = model.layers[1]((vec1, vec2), is_train) def finish_update(d_output: OutT) -> InT: d_vec1, d_vec2 = bp_output(d_output) d_input1 = bp_vec1(d_vec1) d_input2 = bp_vec2(d_vec2) return (d_input1, d_input2) return output, finish_update def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is not None: model.layers[0].set_dim("nI", get_width(X[1])) model.layers[0].initialize(X=X[0]) X = (model.layers[0].predict(X[0]), model.layers[0].predict(X[1])) model.layers[1].initialize(X=X, Y=Y) model.set_dim("nI", model.layers[0].get_dim("nI")) model.set_dim("nO", model.layers[1].get_dim("nO")) thinc-9.0.0/thinc/layers/sigmoid.py000066400000000000000000000036311461023342500172410ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial InT = Floats2d OutT = Floats2d @registry.layers("Sigmoid.v1") def Sigmoid( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, ) -> Model[InT, OutT]: """A dense layer, followed by a sigmoid (logistic) activation function. This is usually used instead of the Softmax layer as an output for multi-label classification. """ if init_W is None: init_W = zero_init if init_b is None: init_b = zero_init return Model( "sigmoid", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y = model.ops.affine(X, W, b) Y = model.ops.sigmoid(Y) def backprop(dY: InT) -> OutT: dY = model.ops.backprop_sigmoid(dY, Y, inplace=False) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is not None and model.has_dim("nI") is None: model.set_dim("nI", get_width(X)) if Y is not None and model.has_dim("nO") is None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/sigmoid_activation.py000066400000000000000000000012141461023342500214550ustar00rootroot00000000000000from typing import Callable, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import FloatsXdT @registry.layers("sigmoid_activation.v1") def sigmoid_activation() -> Model[FloatsXdT, FloatsXdT]: return Model("sigmoid_activation", forward) def forward( model: Model[FloatsXdT, FloatsXdT], X: FloatsXdT, is_train: bool ) -> Tuple[FloatsXdT, Callable]: Y = model.ops.sigmoid(X, inplace=False) def backprop(dY: FloatsXdT) -> FloatsXdT: return cast( FloatsXdT, dY * model.ops.dsigmoid(Y, inplace=False), # type:ignore[operator] ) return Y, backprop thinc-9.0.0/thinc/layers/softmax.py000066400000000000000000000062451461023342500172730ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import ArrayInfo, get_width, partial InT = Floats2d OutT = Floats2d @registry.layers("Softmax.v1") def Softmax( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, ) -> Model[InT, OutT]: if init_W is None: init_W = zero_init if init_b is None: init_b = zero_init return Model( "softmax", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, attrs={"softmax_normalize": True, "softmax_temperature": 1.0}, ) @registry.layers("Softmax.v2") def Softmax_v2( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, normalize_outputs: bool = True, temperature: float = 1.0, ) -> Model[InT, OutT]: if init_W is None: init_W = zero_init if init_b is None: init_b = zero_init validate_temperature(temperature) return Model( "softmax", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, attrs={ "softmax_normalize": normalize_outputs, "softmax_temperature": temperature, }, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: normalize = model.attrs["softmax_normalize"] or is_train temperature = model.attrs["softmax_temperature"] validate_temperature(temperature) W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y = model.ops.affine(X, W, b) if normalize: Y = model.ops.softmax(Y, temperature=temperature) array_info = ArrayInfo.from_array(Y) def backprop(dY: InT) -> OutT: array_info.check_consistency(dY) if temperature != 1.0: dY = dY / temperature model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) def backprop_unnormalized(dY: InT): msg = "backprop is not supported for an unnormalized Softmax layer" raise ValueError(msg) if normalize: return Y, backprop else: return Y, backprop_unnormalized def init( init_W: Callable, init_b: Callable, model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None, ) -> None: if X is not None and model.has_dim("nI") is None: model.set_dim("nI", get_width(X)) if Y is not None and model.has_dim("nO") is None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) def validate_temperature(temperature): if temperature <= 0.0: msg = "softmax temperature must not be zero or negative" raise ValueError(msg) thinc-9.0.0/thinc/layers/softmax_activation.py000066400000000000000000000010361461023342500215050ustar00rootroot00000000000000from typing import Callable, Tuple from ..config import registry from ..model import Model from ..types import Floats2d InT = Floats2d OutT = Floats2d @registry.layers("softmax_activation.v1") def softmax_activation() -> Model[InT, OutT]: return Model("softmax_activation", forward) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: Y = model.ops.softmax(X, inplace=False) def backprop(dY: OutT) -> InT: return model.ops.backprop_softmax(Y, dY, axis=-1) return Y, backprop thinc-9.0.0/thinc/layers/sparselinear.pyx000066400000000000000000000177571461023342500205040ustar00rootroot00000000000000# cython: infer_types=True, cdivision=True, bounds_check=False, wraparound=False, profile=False cimport cython cimport numpy as np from libc.stdint cimport int32_t, uint32_t, uint64_t from typing import Callable, Optional, Tuple from ..backends import CupyOps, NumpyOps from ..config import registry from ..model import Model from ..types import ArrayXd from ..util import get_array_module, get_width, is_cupy_array, is_numpy_array InT = Tuple[ArrayXd, ArrayXd, ArrayXd] OutT = ArrayXd @cython.binding(True) @registry.layers("SparseLinear.v1") def SparseLinear(nO: Optional[int] = None, length: int = 2 ** 18): # NB: We can't have generic return type annotation if we want function to # be bound (and inspectable): https://github.com/cython/cython/issues/2753 return Model( "sparse_linear", forward, init=init, params={"W": None, "b": None}, dims={"nO": nO, "length": length}, attrs={"v1_indexing": True}, ) @cython.binding(True) @registry.layers("SparseLinear.v2") def SparseLinear_v2(nO: Optional[int] = None, length: int = 2 ** 18): # NB: We can't have generic return type annotation if we want function to # be bound (and inspectable): https://github.com/cython/cython/issues/2753 return Model( "sparse_linear", forward, init=init, params={"W": None, "b": None}, dims={"nO": nO, "length": length}, attrs={"v1_indexing": False}, ) @cython.binding(True) def forward(model: Model, keys_values_lengths: InT, is_train: bool) -> Tuple[OutT, Callable]: # NB: We can't have generic Model annotation if we want function to # be bound (and inspectable): https://github.com/cython/cython/issues/2753 keys, values, lengths = keys_values_lengths if is_cupy_array(keys): # Currently we don't have a GPU-compatible implementation of this function :( # It sucks, but at least we can get the correct result by copying to CPU. return _begin_gpu_update(model, keys, values, lengths) else: return _begin_cpu_update(model, keys, values, lengths) def init(model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None) -> Model[InT, OutT]: if Y is not None: model.set_dim("nO", get_width(Y)) nO = model.get_dim("nO") length = model.get_dim("length") model.set_param("W", model.ops.alloc((nO * length,), dtype="f")) model.set_param("b", model.ops.alloc((nO,), dtype="f")) return model def _begin_gpu_update(model: Model[InT, OutT], keys: ArrayXd, values: ArrayXd, lengths: ArrayXd) -> Tuple[ArrayXd, Callable]: xp = get_array_module(keys) scores_cpu, callback = _begin_cpu_update(model, keys.get(), values.get(), lengths.get()) def backprop_gpu_update(d_scores: ArrayXd) -> Tuple[ArrayXd, ArrayXd, ArrayXd]: callback(d_scores.get()) return (keys, values, lengths) return xp.asarray(scores_cpu), backprop_gpu_update def _begin_cpu_update(model, np.ndarray keys, np.ndarray values, np.ndarray lengths): cdef int nO = model.get_dim("nO") cdef int length = model.get_dim("length") cdef np.ndarray W = model.get_param("W") cdef np.ndarray b = model.get_param("b") cdef np.ndarray scores = model.ops.alloc((len(lengths), nO)) cdef bint v1_indexing = model.attrs["v1_indexing"] scores += b set_scoresC(scores.data, keys.data, values.data, lengths.data, lengths.shape[0], nO, W.data, length, v1_indexing) return scores, _finish_linear_update(model, keys, values, lengths) class _finish_linear_update: """Move this out of a closure, into its own callable object, to avoid pickling errors :(.""" def __init__(self, model, keys, values, lengths): self.model = model self.keys = keys self.values = values self.lengths = lengths def __call__(self, float[:, ::1] d_scores): nO = self.model.get_dim("nO") length = self.model.get_dim("length") cdef np.ndarray d_weights = self.model.ops.alloc((nO*length,)) cdef np.ndarray d_bias = self.model.ops.alloc((nO,)) cdef np.ndarray keys = self.keys cdef np.ndarray values = self.values cdef np.ndarray lengths = self.lengths cdef bint v1_indexing = self.model.attrs["v1_indexing"] set_gradientC(d_weights.data, keys.data, values.data, lengths.data, lengths.shape[0], nO, &d_scores[0,0], length, v1_indexing) cdef int i, j for i in range(d_scores.shape[0]): for j in range(d_scores.shape[1]): d_bias[j] += d_scores[i, j] self.model.inc_grad("W", d_weights) self.model.inc_grad("b", d_bias) return (self.keys, self.values, self.lengths) # v1_indexing is invalid and only uses a subset of the weight matrix, v1 # indexing is provided here for compatibility. See #752 for more information. cdef void set_scoresC(float* scores, const uint64_t* keys, const float* values, const int32_t* lengths, int batch_size, int nr_out, const float* weights, int nr_weight, bint v1_indexing) nogil: cdef uint32_t idx1, idx2 cdef uint32_t hash1, hash2 for length in lengths[:batch_size]: for i in range(length): hash1 = MurmurHash3_x86_32_uint64(keys[i], 0) hash2 = MurmurHash3_x86_32_uint64(keys[i], 1) if v1_indexing: idx1 = hash1 & (nr_weight-1) idx2 = hash2 & (nr_weight-1) else: idx1 = hash1 % nr_weight idx2 = hash2 % nr_weight value = values[i] for clas in range(nr_out): if v1_indexing: scores[clas] += weights[idx1 + clas] * value scores[clas] += weights[idx2 + clas] * value else: scores[clas] += weights[(clas * nr_weight) + idx1] * value scores[clas] += weights[(clas * nr_weight) + idx2] * value scores += nr_out keys += length values += length # v1_indexing is invalid and only uses a subset of the weight matrix, v1 # indexing is provided here for compatibility. See #752 for more information. cdef void set_gradientC(float* d_weights, const uint64_t* keys, const float* values, const int32_t* lengths, int batch_size, int nr_out, const float* d_scores, int nr_weight, bint v1_indexing) nogil: cdef uint32_t idx1, idx2 cdef uint32_t hash1, hash2 for length in lengths[:batch_size]: for i in range(length): hash1 = MurmurHash3_x86_32_uint64(keys[i], 0) hash2 = MurmurHash3_x86_32_uint64(keys[i], 1) if v1_indexing: idx1 = hash1 & (nr_weight-1) idx2 = hash2 & (nr_weight-1) else: idx1 = hash1 % nr_weight idx2 = hash2 % nr_weight value = values[i] for clas in range(nr_out): if v1_indexing: d_weights[idx1 + clas] += d_scores[clas] * value d_weights[idx2 + clas] += d_scores[clas] * value else: d_weights[(clas * nr_weight) + idx1] += d_scores[clas] * value d_weights[(clas * nr_weight) + idx2] += d_scores[clas] * value d_scores += nr_out keys += length values += length cdef uint32_t MurmurHash3_x86_32_uint64(uint64_t key, uint32_t seed) nogil: cdef uint32_t h1 = seed cdef uint32_t c1 = 0xcc9e2d51u cdef uint32_t c2 = 0x1b873593u cdef uint32_t k1 k1 = key & 0xffffffffu k1 *= c1 k1 = (k1 << 15) | (k1 >> 17) k1 *= c2 h1 ^= k1 h1 = (h1 << 13) | (h1 >> 19) h1 = h1*5+0xe6546b64u k1 = key >> 32 k1 *= c1 k1 = (k1 << 15) | (k1 >> 17) k1 *= c2 h1 ^= k1 h1 = (h1 << 13) | (h1 >> 19) h1 = h1*5+0xe6546b64u h1 ^= 8 h1 ^= h1 >> 16 h1 *= 0x85ebca6bu h1 ^= h1 >> 13 h1 *= 0xc2b2ae35u h1 ^= h1 >> 16 return h1 thinc-9.0.0/thinc/layers/strings2arrays.py000066400000000000000000000016711461023342500206050ustar00rootroot00000000000000from ctypes import c_uint64 from typing import Callable, List, Sequence, Tuple from murmurhash import hash_unicode from ..config import registry from ..model import Model from ..types import Ints2d InT = Sequence[Sequence[str]] OutT = List[Ints2d] @registry.layers("strings2arrays.v1") def strings2arrays() -> Model[InT, OutT]: """Transform a sequence of string sequences to a list of arrays.""" return Model("strings2arrays", forward) def forward(model: Model[InT, OutT], Xs: InT, is_train: bool) -> Tuple[OutT, Callable]: # Cast 32-bit (signed) integer to 64-bit unsigned, since such casting # is deprecated in NumPy. hashes = [[c_uint64(hash_unicode(word)).value for word in X] for X in Xs] hash_arrays = [model.ops.asarray1i(h, dtype="uint64") for h in hashes] arrays = [model.ops.reshape2i(array, -1, 1) for array in hash_arrays] def backprop(dX: OutT) -> InT: return [] return arrays, backprop thinc-9.0.0/thinc/layers/swish.py000066400000000000000000000041201461023342500167350ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, cast from ..config import registry from ..initializers import he_normal_init, zero_init from ..model import Model from ..types import Floats1d, Floats2d from ..util import get_width, partial from .chain import chain from .dropout import Dropout from .layernorm import LayerNorm @registry.layers("Swish.v1") def Swish( nO: Optional[int] = None, nI: Optional[int] = None, *, init_W: Optional[Callable] = None, init_b: Optional[Callable] = None, dropout: Optional[float] = None, normalize: bool = False, ) -> Model[Floats2d, Floats2d]: if init_W is None: init_W = he_normal_init if init_b is None: init_b = zero_init model: Model[Floats2d, Floats2d] = Model( "swish", forward, init=partial(init, init_W, init_b), dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) if normalize: model = chain(model, LayerNorm(nI=nO)) if dropout is not None: model = chain(model, cast(Model[Floats2d, Floats2d], Dropout(dropout))) return model def forward( model: Model[Floats2d, Floats2d], X: Floats2d, is_train: bool ) -> Tuple[Floats2d, Callable]: W = cast(Floats2d, model.get_param("W")) b = cast(Floats1d, model.get_param("b")) Y_preact = model.ops.affine(X, W, b) Y = model.ops.swish(Y_preact) def backprop(dY: Floats2d) -> Floats2d: dY = model.ops.backprop_swish(dY, Y_preact, Y, inplace=False) model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", model.ops.gemm(dY, X, trans1=True)) return model.ops.gemm(dY, W) return Y, backprop def init( init_W: Callable, init_b: Callable, model: Model[Floats2d, Floats2d], X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None, ) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) model.set_param("W", init_W(model.ops, (model.get_dim("nO"), model.get_dim("nI")))) model.set_param("b", init_b(model.ops, (model.get_dim("nO"),))) thinc-9.0.0/thinc/layers/tensorflowwrapper.py000066400000000000000000000146251461023342500214160ustar00rootroot00000000000000# mypy: ignore-errors from typing import Any, Callable, Dict, Optional, Tuple, Type, TypeVar import srsly from ..compat import tensorflow as tf from ..model import Model from ..shims import TensorFlowShim, keras_model_fns, maybe_handshake_model from ..types import ArgsKwargs, ArrayXd from ..util import ( assert_tensorflow_installed, convert_recursive, is_tensorflow_array, is_xp_array, tensorflow2xp, xp2tensorflow, ) InT = TypeVar("InT") OutT = TypeVar("OutT") InFunc = TypeVar("InFunc") XType = TypeVar("XType", bound=ArrayXd) YType = TypeVar("YType", bound=ArrayXd) def keras_subclass( name: str, X: XType, Y: YType, input_shape: Tuple[int, ...], compile_args: Optional[Dict[str, Any]] = None, ) -> Callable[[InFunc], InFunc]: """Decorate a custom keras subclassed model with enough information to serialize and deserialize it reliably in the face of the many restrictions on keras subclassed models. name (str): The unique namespace string to use to represent this model class. X (Any): A sample X input for performing a forward pass on the network. Y (Any): A sample Y input for performing a backward pass on the network. input_shape (Tuple[int, ...]): A set of input shapes for building the network. compile: Arguments to pass directly to the keras `model.compile` call. RETURNS (Callable): The decorated class. """ compile_defaults = {"optimizer": "adam", "loss": "mse"} if compile_args is None: compile_args = compile_defaults else: compile_args = {**compile_defaults, **compile_args} def call_fn(clazz): clazz.catalogue_name = property(lambda inst: name) clazz.eg_shape = property(lambda inst: input_shape) clazz.eg_compile = property(lambda inst: compile_args) clazz.eg_x = property(lambda inst: X) clazz.eg_y = property(lambda inst: Y) @keras_model_fns(name) def create_component(*call_args, **call_kwargs): return clazz(*call_args, **call_kwargs) # Capture construction args and store them on the instance wrapped_init = clazz.__init__ def __init__(self, *args, **kwargs): wrapped_init(self, *args, **kwargs) try: srsly.json_dumps(args) srsly.json_dumps(kwargs) except BaseException as _err: raise ValueError( "In order to serialize Keras Subclass models, the constructor " "arguments must be serializable. This allows thinc to recreate " "the code-based model with the same configuration.\n" f"The encountered error is: {_err}" ) self.eg_args = ArgsKwargs(args, kwargs) clazz.__init__ = __init__ return clazz return call_fn def TensorFlowWrapper( tensorflow_model: Any, convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, optimizer: Optional[Any] = None, model_class: Type[Model] = Model, model_name: str = "tensorflow", ) -> Model[InT, OutT]: """Wrap a TensorFlow model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a TensorFlow optimizer and call optimizer.apply_gradients after each batch. """ assert_tensorflow_installed() if not isinstance(tensorflow_model, tf.keras.models.Model): err = f"Expected tf.keras.models.Model, got: {type(tensorflow_model)}" raise ValueError(err) tensorflow_model = maybe_handshake_model(tensorflow_model) if convert_inputs is None: convert_inputs = _convert_inputs if convert_outputs is None: convert_outputs = _convert_outputs return model_class( model_name, forward, shims=[TensorFlowShim(tensorflow_model, optimizer=optimizer)], attrs={"convert_inputs": convert_inputs, "convert_outputs": convert_outputs}, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: """Return the output of the wrapped TensorFlow model for the given input, along with a callback to handle the backward pass. """ convert_inputs = model.attrs["convert_inputs"] convert_outputs = model.attrs["convert_outputs"] tensorflow_model = model.shims[0] X_tensorflow, get_dX = convert_inputs(model, X, is_train) if is_train: Y_tensorflow, tensorflow_backprop = tensorflow_model(X_tensorflow, is_train) else: Y_tensorflow = tensorflow_model(X_tensorflow, is_train) Y, get_dY_tensorflow = convert_outputs(model, Y_tensorflow, is_train) def backprop(dY: OutT) -> InT: dY_tensorflow = get_dY_tensorflow(dY) dX_tensorflow = tensorflow_backprop(dY_tensorflow) return get_dX(dX_tensorflow) return Y, backprop # Default conversion functions # These are pretty much the same as the PyTorch one, but I think we should # leave the duplication -- I think the abstraction could get pretty messy, # and then may need to be undone, as there can always be different specifics. def _convert_inputs(model, X, is_train): xp2tensorflow_ = lambda x: xp2tensorflow(x, requires_grad=is_train) converted = convert_recursive(is_xp_array, xp2tensorflow_, X) if isinstance(converted, ArgsKwargs): def reverse_conversion(dXtf): return convert_recursive(is_tensorflow_array, tensorflow2xp, dXtf) return converted, reverse_conversion elif isinstance(converted, dict): def reverse_conversion(dXtf): dX = convert_recursive(is_tensorflow_array, tensorflow2xp, dXtf) return dX.kwargs return ArgsKwargs(args=tuple(), kwargs=converted), reverse_conversion elif isinstance(converted, (tuple, list)): def reverse_conversion(dXtf): dX = convert_recursive(is_tensorflow_array, tensorflow2xp, dXtf) return dX.args return ArgsKwargs(args=converted, kwargs={}), reverse_conversion else: def reverse_conversion(dXtf): dX = convert_recursive(is_tensorflow_array, tensorflow2xp, dXtf) return dX.args[0] return ArgsKwargs(args=(converted,), kwargs={}), reverse_conversion def _convert_outputs(model, Ytf, is_train): Y = convert_recursive(is_tensorflow_array, tensorflow2xp, Ytf) def reverse_conversion(dY): return convert_recursive(is_xp_array, xp2tensorflow, dY) return Y, reverse_conversion thinc-9.0.0/thinc/layers/torchscriptwrapper.py000066400000000000000000000063141461023342500215540ustar00rootroot00000000000000from typing import Any, Callable, Optional from ..compat import torch from ..model import Model from ..shims import PyTorchGradScaler, PyTorchShim, TorchScriptShim from .pytorchwrapper import ( convert_pytorch_default_inputs, convert_pytorch_default_outputs, forward, ) def TorchScriptWrapper_v1( torchscript_model: Optional["torch.jit.ScriptModule"] = None, convert_inputs: Optional[Callable] = None, convert_outputs: Optional[Callable] = None, mixed_precision: bool = False, grad_scaler: Optional[PyTorchGradScaler] = None, device: Optional["torch.device"] = None, ) -> Model[Any, Any]: """Wrap a TorchScript model, so that it has the same API as Thinc models. torchscript_model: The TorchScript module. A value of `None` is also possible to construct a shim to deserialize into. convert_inputs: Function that converts inputs and gradients that should be passed to the model to Torch tensors. convert_outputs: Function that converts model outputs and gradients from Torch tensors Thinc arrays. mixed_precision: Enable mixed-precision. This changes whitelisted ops to run in half precision for better performance and lower memory use. grad_scaler: The gradient scaler to use for mixed-precision training. If this argument is set to "None" and mixed precision is enabled, a gradient scaler with the default configuration is used. device: The PyTorch device to run the model on. When this argument is set to "None", the default device for the currently active Thinc ops is used. """ if convert_inputs is None: convert_inputs = convert_pytorch_default_inputs if convert_outputs is None: convert_outputs = convert_pytorch_default_outputs return Model( "pytorch_script", forward, attrs={"convert_inputs": convert_inputs, "convert_outputs": convert_outputs}, shims=[ TorchScriptShim( model=torchscript_model, mixed_precision=mixed_precision, grad_scaler=grad_scaler, device=device, ) ], dims={"nI": None, "nO": None}, ) def pytorch_to_torchscript_wrapper(model: Model): """Convert a PyTorch wrapper to a TorchScript wrapper. The embedded PyTorch `Module` is converted to `ScriptModule`. """ shim = model.shims[0] if not isinstance(shim, PyTorchShim): raise ValueError("Expected PyTorchShim when converting a PyTorch wrapper") convert_inputs = model.attrs["convert_inputs"] convert_outputs = model.attrs["convert_outputs"] pytorch_model = shim._model if not isinstance(pytorch_model, torch.nn.Module): raise ValueError("PyTorchShim does not wrap a PyTorch module") torchscript_model = torch.jit.script(pytorch_model) grad_scaler = shim._grad_scaler mixed_precision = shim._mixed_precision device = shim.device return TorchScriptWrapper_v1( torchscript_model, convert_inputs=convert_inputs, convert_outputs=convert_outputs, mixed_precision=mixed_precision, grad_scaler=grad_scaler, device=device, ) thinc-9.0.0/thinc/layers/tuplify.py000066400000000000000000000037421461023342500173050ustar00rootroot00000000000000from typing import Any, Optional, Tuple, TypeVar from ..config import registry from ..model import Model InT = TypeVar("InT") OutT = Tuple @registry.layers("tuplify.v1") def tuplify( layer1: Model[InT, Any], layer2: Model[InT, Any], *layers ) -> Model[InT, Tuple]: """Send a separate copy of the input to each child layer, and join the outputs of the children into a tuple on the way out. Typically used to provide both modified data and the original input to a downstream layer. """ layers = (layer1, layer2) + layers names = [layer.name for layer in layers] return Model( "tuple(" + ", ".join(names) + ")", tuplify_forward, init=init, layers=layers, dims={"nI": None}, ) def tuplify_forward(model, X, is_train): Ys = [] backprops = [] for layer in model.layers: Y, backprop = layer(X, is_train) Ys.append(Y) backprops.append(backprop) def backprop_tuplify(dYs): dXs = [bp(dY) for bp, dY in zip(backprops, dYs)] dX = dXs[0] for dx in dXs[1:]: dX += dx return dX return tuple(Ys), backprop_tuplify def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: if X is None and Y is None: for layer in model.layers: layer.initialize() if model.layers[0].has_dim("nI"): model.set_dim("nI", model.layers[0].get_dim("nI")) # Try to set nO on each layer, where available. # All layers have the same input, and the output should map directly from the # given Y, if provided. for ii, layer in enumerate(model.layers): if Y is not None and layer.has_dim("nO") is None: layer.initialize(X=X, Y=Y[ii]) else: layer.initialize(X=X) if model.layers[0].has_dim("nI"): model.set_dim("nI", model.layers[0].get_dim("nI")) # this model can have an input dimension, but can't have an output dimension thinc-9.0.0/thinc/layers/uniqued.py000066400000000000000000000040151461023342500172550ustar00rootroot00000000000000from typing import Callable, Optional, Tuple import numpy from ..config import registry from ..model import Model from ..types import Floats2d, Ints2d InT = Ints2d OutT = Floats2d @registry.layers("uniqued.v1") def uniqued(layer: Model, *, column: int = 0) -> Model[InT, OutT]: """Group inputs to a layer, so that the layer only has to compute for the unique values. The data is transformed back before output, and the same transformation is applied for the gradient. Effectively, this is a cache local to each minibatch. """ return Model( f"uniqued({layer.name})", forward, init=init, layers=[layer], dims={"nO": None, "nI": None}, attrs={"column": column}, ) def forward(model: Model[InT, OutT], X: InT, is_train: bool) -> Tuple[OutT, Callable]: column: int = model.attrs["column"] layer = model.layers[0] if X.size < 2: return layer(X, is_train) keys = X[:, column] if not isinstance(keys, numpy.ndarray): keys = keys.get() # pragma: no cover uniq_keys, ind, inv, counts = layer.ops.xp.unique( keys, return_index=True, return_inverse=True, return_counts=True ) counts = model.ops.reshape2i(counts, -1, 1) X_uniq = X[ind] Y_uniq, bp_Y_uniq = layer(X_uniq, is_train) Y = Y_uniq[inv].reshape((X.shape[0],) + Y_uniq.shape[1:]) uniq_shape = tuple(Y_uniq.shape) def backprop(dY: OutT) -> InT: dY_uniq = layer.ops.alloc2f(*uniq_shape) layer.ops.scatter_add(dY_uniq, layer.ops.asarray_i(inv), dY) d_uniques = bp_Y_uniq(dY_uniq) # This confusing bit of indexing "ununiques" return (d_uniques / counts)[inv] return Y, backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: layer = model.layers[0] layer.initialize(X=X, Y=Y) if layer.has_dim("nI"): model.set_dim("nI", layer.get_dim("nI")) # pragma: no cover if layer.has_dim("nO"): model.set_dim("nO", layer.get_dim("nO")) thinc-9.0.0/thinc/layers/with_array.py000066400000000000000000000067721461023342500177700ustar00rootroot00000000000000from typing import Callable, Optional, Tuple, TypeVar, Union, cast from ..backends import NumpyOps from ..config import registry from ..model import Model from ..types import Array3d, ArrayXd, ListXd, Padded, Ragged NUMPY_OPS = NumpyOps() ArrayTXd = TypeVar("ArrayTXd", bound=ArrayXd) SeqT = TypeVar("SeqT", bound=Union[Padded, Ragged, ListXd, ArrayXd]) @registry.layers("with_array.v1") def with_array(layer: Model[ArrayTXd, ArrayTXd], pad: int = 0) -> Model[SeqT, SeqT]: """Transform sequence data into a contiguous array on the way into and out of a model. Handles a variety of sequence types: lists, padded and ragged. If the input is an array, it is passed through unchanged. """ model: Model[SeqT, SeqT] = Model( f"with_array({layer.name})", forward, init=init, layers=[layer], attrs={"pad": pad}, dims={name: layer.maybe_get_dim(name) for name in layer.dim_names}, ) return model def forward( model: Model[SeqT, SeqT], Xseq: SeqT, is_train: bool ) -> Tuple[SeqT, Callable]: if isinstance(Xseq, Ragged): return cast(Tuple[SeqT, Callable], _ragged_forward(model, Xseq, is_train)) elif isinstance(Xseq, Padded): return cast(Tuple[SeqT, Callable], _padded_forward(model, Xseq, is_train)) elif not isinstance(Xseq, (list, tuple)): return model.layers[0](Xseq, is_train) else: return cast(Tuple[SeqT, Callable], _list_forward(model, Xseq, is_train)) def init( model: Model[SeqT, SeqT], X: Optional[SeqT] = None, Y: Optional[SeqT] = None ) -> None: layer: Model[ArrayXd, ArrayXd] = model.layers[0] layer.initialize( X=_get_array(model, X) if X is not None else X, Y=_get_array(model, Y) if Y is not None else Y, ) for dim_name in layer.dim_names: value = layer.maybe_get_dim(dim_name) if value is not None: model.set_dim(dim_name, value) def _get_array(model, X: SeqT) -> ArrayXd: if isinstance(X, Ragged): return X.dataXd elif isinstance(X, Padded): return X.data elif not isinstance(X, (list, tuple)): return cast(ArrayXd, X) else: return model.ops.flatten(X) def _list_forward( model: Model[SeqT, SeqT], Xs: ListXd, is_train: bool ) -> Tuple[ListXd, Callable]: layer: Model[ArrayXd, ArrayXd] = model.layers[0] pad = model.attrs["pad"] lengths = NUMPY_OPS.asarray1i([len(seq) for seq in Xs]) Xf = layer.ops.flatten(Xs, pad=pad) Yf, get_dXf = layer(Xf, is_train) def backprop(dYs: ListXd) -> ListXd: dYf = layer.ops.flatten(dYs, pad=pad) dXf = get_dXf(dYf) return layer.ops.unflatten(dXf, lengths, pad=pad) return layer.ops.unflatten(Yf, lengths, pad=pad), backprop def _ragged_forward( model: Model[SeqT, SeqT], Xr: Ragged, is_train: bool ) -> Tuple[Ragged, Callable]: layer: Model[ArrayXd, ArrayXd] = model.layers[0] Y, get_dX = layer(Xr.dataXd, is_train) def backprop(dYr: Ragged) -> Ragged: return Ragged(get_dX(dYr.dataXd), dYr.lengths) return Ragged(Y, Xr.lengths), backprop def _padded_forward( model: Model[SeqT, SeqT], Xp: Padded, is_train: bool ) -> Tuple[Padded, Callable]: layer: Model[Array3d, Array3d] = model.layers[0] Y, get_dX = layer(Xp.data, is_train) def backprop(dYp: Padded) -> Padded: assert isinstance(dYp, Padded) dX = get_dX(dYp.data) return Padded(dX, dYp.size_at_t, dYp.lengths, dYp.indices) return Padded(Y, Xp.size_at_t, Xp.lengths, Xp.indices), backprop thinc-9.0.0/thinc/layers/with_array2d.py000066400000000000000000000100501461023342500201760ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar, Union, cast from ..backends import NumpyOps from ..config import registry from ..model import Model from ..types import Array2d, Floats2d, List2d, Padded, Ragged NUMPY_OPS = NumpyOps() ValT = TypeVar("ValT", bound=Array2d) SeqT = TypeVar("SeqT", bound=Union[Padded, Ragged, List2d, Array2d]) @registry.layers("with_array2d.v1") def with_array2d(layer: Model[ValT, ValT], pad: int = 0) -> Model[SeqT, SeqT]: """Transform sequence data into a contiguous 2d array on the way into and out of a model. Handles a variety of sequence types: lists, padded and ragged. If the input is a 2d array, it is passed through unchanged. """ return Model( f"with_array({layer.name})", forward, init=init, layers=[layer], attrs={"pad": pad}, dims={name: layer.maybe_get_dim(name) for name in layer.dim_names}, ) def forward( model: Model[SeqT, SeqT], Xseq: SeqT, is_train: bool ) -> Tuple[SeqT, Callable]: if isinstance(Xseq, Ragged): return cast(Tuple[SeqT, Callable], _ragged_forward(model, Xseq, is_train)) elif isinstance(Xseq, Padded): return cast(Tuple[SeqT, Callable], _padded_forward(model, Xseq, is_train)) elif not isinstance(Xseq, (list, tuple)): return model.layers[0](Xseq, is_train) else: return cast(Tuple[SeqT, Callable], _list_forward(model, Xseq, is_train)) return def init( model: Model[SeqT, SeqT], X: Optional[SeqT] = None, Y: Optional[SeqT] = None ) -> None: layer: Model[Array2d, Array2d] = model.layers[0] layer.initialize( X=_get_array(model, X) if X is not None else X, Y=_get_array(model, Y) if Y is not None else Y, ) for dim_name in layer.dim_names: value = layer.maybe_get_dim(dim_name) if value is not None: model.set_dim(dim_name, value) def _get_array(model, X: SeqT) -> Array2d: if isinstance(X, Ragged): return X.data elif isinstance(X, Padded): return model.ops.reshape2f( X.data, X.data.shape[0] * X.data.shape[1], X.data.shape[2] ) elif not isinstance(X, (list, tuple)): return cast(Array2d, X) else: return model.ops.flatten(X) def _list_forward( model: Model[SeqT, SeqT], Xs: List2d, is_train: bool ) -> Tuple[List2d, Callable]: layer: Model[Array2d, Array2d] = model.layers[0] pad = model.attrs["pad"] lengths = NUMPY_OPS.asarray1i([len(seq) for seq in Xs]) Xf = layer.ops.flatten(Xs, pad=pad) Yf, get_dXf = layer(Xf, is_train) def backprop(dYs: List2d) -> List2d: dYf = layer.ops.flatten(dYs, pad=pad) dXf = get_dXf(dYf) return layer.ops.unflatten(dXf, lengths, pad=pad) return layer.ops.unflatten(Yf, lengths, pad=pad), backprop def _ragged_forward( model: Model[SeqT, SeqT], Xr: Ragged, is_train: bool ) -> Tuple[Ragged, Callable]: layer: Model[Array2d, Array2d] = model.layers[0] Y, get_dX = layer(Xr.data, is_train) x_shape = Xr.dataXd.shape def backprop(dYr: Ragged) -> Ragged: return Ragged(get_dX(dYr.dataXd).reshape(x_shape), dYr.lengths) return Ragged(Y, Xr.lengths), backprop def _padded_forward( model: Model[SeqT, SeqT], Xp: Padded, is_train: bool ) -> Tuple[Padded, Callable]: layer: Model[Array2d, Array2d] = model.layers[0] X = model.ops.reshape2( Xp.data, Xp.data.shape[0] * Xp.data.shape[1], Xp.data.shape[2] ) Y2d, get_dX = layer(X, is_train) Y = model.ops.reshape3f( cast(Floats2d, Y2d), Xp.data.shape[0], Xp.data.shape[1], Y2d.shape[1] ) def backprop(dYp: Padded) -> Padded: assert isinstance(dYp, Padded) dY = model.ops.reshape2( dYp.data, dYp.data.shape[0] * dYp.data.shape[1], dYp.data.shape[2] ) dX2d = get_dX(dY) dX = model.ops.reshape3f( dX2d, dYp.data.shape[0], dYp.data.shape[1], dX2d.shape[1] ) return Padded(dX, dYp.size_at_t, dYp.lengths, dYp.indices) return Padded(Y, Xp.size_at_t, Xp.lengths, Xp.indices), backprop thinc-9.0.0/thinc/layers/with_cpu.py000066400000000000000000000026231461023342500174300ustar00rootroot00000000000000from typing import Any, Callable, Tuple import numpy from thinc.backends import Ops from ..config import registry from ..model import Model @registry.layers("with_cpu.v1") def with_cpu(layer: Model, ops: Ops) -> Model: layer.to_cpu() return Model( f"with_cpu({layer.name})", forward, layers=[layer], ops=ops, init=init, dims={name: layer.maybe_get_dim(name) for name in layer.dim_names}, ) def forward(model: Model, X: Any, is_train: bool) -> Tuple[Any, Callable]: cpu_outputs, backprop = model.layers[0].begin_update(_to_cpu(X)) gpu_outputs = _to_device(model.ops, cpu_outputs) def with_cpu_backprop(d_outputs): cpu_d_outputs = _to_cpu(d_outputs) return backprop(cpu_d_outputs) return gpu_outputs, with_cpu_backprop def init(model: Model, X: Any, Y: Any) -> None: model.layers[0].initialize(X, Y) def _to_cpu(X): if isinstance(X, numpy.ndarray): return X elif isinstance(X, tuple): return tuple([_to_cpu(x) for x in X]) elif isinstance(X, list): return [_to_cpu(x) for x in X] elif hasattr(X, "get"): return X.get() else: return X def _to_device(ops, X): if isinstance(X, tuple): return tuple([_to_device(ops, x) for x in X]) elif isinstance(X, list): return [_to_device(ops, x) for x in X] else: return ops.asarray(X) thinc-9.0.0/thinc/layers/with_debug.py000066400000000000000000000024651461023342500177330ustar00rootroot00000000000000from typing import Any, Callable, Optional, Tuple, TypeVar from ..model import Model _ModelT = TypeVar("_ModelT", bound=Model) do_nothing = lambda *args, **kwargs: None def with_debug( layer: _ModelT, name: Optional[str] = None, *, on_init: Callable[[Model, Any, Any], None] = do_nothing, on_forward: Callable[[Model, Any, bool], None] = do_nothing, on_backprop: Callable[[Any], None] = do_nothing, ) -> _ModelT: """Debugging layer that wraps any layer and allows executing callbacks during the forward pass, backward pass and initialization. The callbacks will receive the same arguments as the functions they're called in. """ name = layer.name if name is None else name orig_forward = layer._func orig_init = layer.init def forward(model: Model, X: Any, is_train: bool) -> Tuple[Any, Callable]: on_forward(model, X, is_train) layer_Y, layer_callback = orig_forward(layer, X, is_train=is_train) def backprop(dY: Any) -> Any: on_backprop(dY) return layer_callback(dY) return layer_Y, backprop def init(model: Model, X: Any, Y: Any) -> None: on_init(model, X, Y) if orig_init is not None: orig_init(layer, X, Y) layer.replace_callbacks(forward, init=init) return layer thinc-9.0.0/thinc/layers/with_flatten.py000066400000000000000000000032121461023342500202710ustar00rootroot00000000000000from typing import Any, Callable, List, Optional, Sequence, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import ArrayXd, ListXd ItemT = TypeVar("ItemT") InT = Sequence[Sequence[ItemT]] OutT = ListXd InnerInT = Sequence[ItemT] InnerOutT = ArrayXd @registry.layers("with_flatten.v1") def with_flatten(layer: Model[InnerInT[ItemT], InnerOutT]) -> Model[InT[ItemT], OutT]: return Model(f"with_flatten({layer.name})", forward, layers=[layer], init=init) def forward( model: Model[InT, OutT], Xnest: InT, is_train: bool ) -> Tuple[OutT, Callable]: layer: Model[InnerInT, InnerOutT] = model.layers[0] Xflat = _flatten(Xnest) Yflat, backprop_layer = layer(Xflat, is_train) # Get the split points. We want n-1 splits for n items. arr = layer.ops.asarray1i([len(x) for x in Xnest[:-1]]) splits = arr.cumsum() Ynest = layer.ops.xp.split(Yflat, splits, axis=0) def backprop(dYnest: OutT) -> InT: dYflat = model.ops.flatten(dYnest) # type: ignore[arg-type, var-annotated] # type ignore necessary for older versions of Mypy/Pydantic dXflat = backprop_layer(dYflat) dXnest = layer.ops.xp.split(dXflat, splits, axis=-1) return dXnest return Ynest, backprop def _flatten(nested: InT) -> InnerInT: flat: List = [] for item in nested: flat.extend(item) return cast(InT, flat) def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: model.layers[0].initialize( _flatten(X) if X is not None else None, model.layers[0].ops.xp.hstack(Y) if Y is not None else None, ) thinc-9.0.0/thinc/layers/with_flatten_v2.py000066400000000000000000000036411461023342500207060ustar00rootroot00000000000000from typing import Any, Callable, List, Optional, Sequence, Tuple, TypeVar, cast from ..config import registry from ..model import Model InItemT = TypeVar("InItemT") OutItemT = TypeVar("OutItemT") ItemT = TypeVar("ItemT") NestedT = List[List[ItemT]] FlatT = List[ItemT] @registry.layers("with_flatten.v2") def with_flatten_v2( layer: Model[FlatT[InItemT], FlatT[OutItemT]] ) -> Model[NestedT[InItemT], NestedT[OutItemT]]: return Model(f"with_flatten({layer.name})", forward, layers=[layer], init=init) def forward( model: Model[NestedT[InItemT], NestedT[OutItemT]], Xnest: NestedT[InItemT], is_train: bool, ) -> Tuple[NestedT[OutItemT], Callable]: layer: Model[FlatT[InItemT], FlatT[OutItemT]] = model.layers[0] Xflat, lens = _flatten(Xnest) Yflat, backprop_layer = layer(Xflat, is_train) Ynest = _unflatten(Yflat, lens) def backprop(dYnest: NestedT[InItemT]) -> NestedT[OutItemT]: dYflat, _ = _flatten(dYnest) # type: ignore[arg-type, var-annotated] # type ignore necessary for older versions of Mypy/Pydantic dXflat = backprop_layer(dYflat) dXnest = _unflatten(dXflat, lens) return dXnest return Ynest, backprop def _flatten(nested: NestedT[ItemT]) -> Tuple[FlatT[ItemT], List[int]]: flat: List = [] lens: List[int] = [] for item in nested: flat.extend(item) lens.append(len(item)) return cast(FlatT[ItemT], flat), lens def _unflatten(flat: FlatT[ItemT], lens: List[int]) -> NestedT[ItemT]: nested = [] for l in lens: nested.append(flat[:l]) flat = flat[l:] return nested def init( model: Model[NestedT[InItemT], NestedT[OutItemT]], X: Optional[NestedT[InItemT]] = None, Y: Optional[NestedT[OutItemT]] = None, ) -> None: model.layers[0].initialize( _flatten(X)[0] if X is not None else None, model.layers[0].ops.xp.hstack(Y) if Y is not None else None, ) thinc-9.0.0/thinc/layers/with_getitem.py000066400000000000000000000022171461023342500202760ustar00rootroot00000000000000from typing import Any, Callable, Optional, Tuple from ..config import registry from ..model import Model InT = Tuple[Any, ...] OutT = Tuple[Any, ...] @registry.layers("with_getitem.v1") def with_getitem(idx: int, layer: Model) -> Model[InT, OutT]: """Transform data on the way into and out of a layer, by plucking an item from a tuple. """ return Model( f"with_getitem({layer.name})", forward, init=init, layers=[layer], attrs={"idx": idx}, ) def forward( model: Model[InT, OutT], items: InT, is_train: bool ) -> Tuple[OutT, Callable]: idx = model.attrs["idx"] Y_i, backprop_item = model.layers[0](items[idx], is_train) def backprop(d_output: OutT) -> InT: dY_i = backprop_item(d_output[idx]) return d_output[:idx] + (dY_i,) + d_output[idx + 1 :] return items[:idx] + (Y_i,) + items[idx + 1 :], backprop def init( model: Model[InT, OutT], X: Optional[InT] = None, Y: Optional[OutT] = None ) -> None: idx = model.attrs["idx"] X_i = X[idx] if X is not None else X Y_i = Y[idx] if Y is not None else Y model.layers[0].initialize(X=X_i, Y=Y_i) thinc-9.0.0/thinc/layers/with_list.py000066400000000000000000000055151461023342500176170ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar, Union, cast from ..config import registry from ..model import Model from ..types import Array2d, Floats2d, Ints2d, List2d, Padded, Ragged SeqT = TypeVar("SeqT", Padded, Ragged, List2d, List[Floats2d], List[Ints2d]) @registry.layers("with_list.v1") def with_list(layer: Model[List2d, List2d]) -> Model[SeqT, SeqT]: return Model( f"with_list({layer.name})", forward, init=init, layers=[layer], dims={name: layer.maybe_get_dim(name) for name in layer.dim_names}, ) def forward( model: Model[SeqT, SeqT], Xseq: SeqT, is_train: bool ) -> Tuple[SeqT, Callable]: layer: Model[List2d, List2d] = model.layers[0] if isinstance(Xseq, Padded): return _padded_forward(layer, Xseq, is_train) elif isinstance(Xseq, Ragged): return _ragged_forward(layer, Xseq, is_train) else: return cast(Tuple[SeqT, Callable], layer(cast(List2d, Xseq), is_train)) def init( model: Model[SeqT, SeqT], X: Optional[SeqT] = None, Y: Optional[SeqT] = None ) -> None: model.layers[0].initialize( X=_get_list(model, X) if X is not None else None, Y=_get_list(model, Y) if Y is not None else None, ) def _get_list(model, seq): if isinstance(seq, Padded): return model.ops.padded2list(seq) elif isinstance(seq, Ragged): return model.ops.unflatten(seq.data, seq.lengths) else: return seq def _ragged_forward( layer: Model[List2d, List2d], Xr: Ragged, is_train: bool ) -> Tuple[Ragged, Callable]: # Assign these to locals, to keep code a bit shorter. unflatten = layer.ops.unflatten flatten = layer.ops.flatten # It's worth being a bit careful about memory here, as the activations # are potentially large on GPU. So we make nested function calls instead # of assigning to temporaries where possible, so memory can be reclaimed # sooner. Ys, get_dXs = layer(unflatten(Xr.data, Xr.lengths), is_train) def backprop(dYr: Ragged): return Ragged( flatten(get_dXs(unflatten(dYr.data, dYr.lengths))), dYr.lengths, ) return Ragged(flatten(Ys), Xr.lengths), backprop def _padded_forward( layer: Model[List2d, List2d], Xp: Padded, is_train: bool ) -> Tuple[Padded, Callable]: # Assign these to locals, to keep code a bit shorter. padded2list = layer.ops.padded2list list2padded = layer.ops.list2padded # It's worth being a bit careful about memory here, as the activations # are potentially large on GPU. So we make nested function calls instead # of assigning to temporaries where possible, so memory can be reclaimed # sooner. Ys, get_dXs = layer(padded2list(Xp), is_train) def backprop(dYp): return list2padded(get_dXs(padded2list(dYp))) return list2padded(Ys), backprop thinc-9.0.0/thinc/layers/with_nvtx_range.py000066400000000000000000000024141461023342500210120ustar00rootroot00000000000000from typing import Any, Callable, Optional, Tuple, TypeVar from ..model import Model from ..util import use_nvtx_range _ModelT = TypeVar("_ModelT", bound=Model) def with_nvtx_range( layer: _ModelT, name: Optional[str] = None, *, forward_color: int = -1, backprop_color: int = -1, ) -> _ModelT: """Wraps any layer and marks the forward and backprop phases as NVTX ranges for CUDA profiling. By default, the name of the layer is used as the name of the range, followed by the name of the pass. """ name = layer.name if name is None else name orig_forward = layer._func orig_init = layer.init def forward(model: Model, X: Any, is_train: bool) -> Tuple[Any, Callable]: with use_nvtx_range(f"{name} forward", forward_color): layer_Y, layer_callback = orig_forward(model, X, is_train=is_train) def backprop(dY: Any) -> Any: with use_nvtx_range(f"{name} backprop", backprop_color): return layer_callback(dY) return layer_Y, backprop def init(_model: Model, X: Any, Y: Any) -> Model: if orig_init is not None: return orig_init(layer, X, Y) else: return layer layer.replace_callbacks(forward, init=init) return layer thinc-9.0.0/thinc/layers/with_padded.py000066400000000000000000000113701461023342500200610ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar, Union, cast from ..config import registry from ..model import Model from ..types import Array2d, Floats3d, Ints1d, List2d, Padded, Ragged from ..util import is_xp_array PaddedData = Tuple[Floats3d, Ints1d, Ints1d, Ints1d] SeqT = TypeVar("SeqT", bound=Union[Padded, Ragged, List2d, Floats3d, PaddedData]) @registry.layers("with_padded.v1") def with_padded(layer: Model[Padded, Padded]) -> Model[SeqT, SeqT]: return Model( f"with_padded({layer.name})", forward, init=init, layers=[layer], dims={name: layer.maybe_get_dim(name) for name in layer.dim_names}, ) def forward( model: Model[SeqT, SeqT], Xseq: SeqT, is_train: bool ) -> Tuple[SeqT, Callable]: layer: Model[Padded, Padded] = model.layers[0] if isinstance(Xseq, Padded): return cast(Tuple[SeqT, Callable], layer(Xseq, is_train)) elif isinstance(Xseq, Ragged): return cast(Tuple[SeqT, Callable], _ragged_forward(layer, Xseq, is_train)) elif _is_padded_data(Xseq): return cast( Tuple[SeqT, Callable], _tuple_forward(layer, cast(PaddedData, Xseq), is_train), ) elif is_xp_array(Xseq): return cast( Tuple[SeqT, Callable], _array_forward(layer, cast(Floats3d, Xseq), is_train) ) else: return cast( Tuple[SeqT, Callable], _list_forward(layer, cast(List2d, Xseq), is_train) ) def init( model: Model[SeqT, SeqT], X: Optional[SeqT] = None, Y: Optional[SeqT] = None ) -> None: model.layers[0].initialize( X=_get_padded(model, X) if X is not None else None, Y=_get_padded(model, Y) if Y is not None else None, ) def _is_padded_data(seq: SeqT) -> bool: return isinstance(seq, tuple) and len(seq) == 4 and all(map(is_xp_array, seq)) def _get_padded(model: Model, seq: SeqT) -> Padded: if isinstance(seq, Padded): return seq elif isinstance(seq, Ragged): return model.ops.list2padded(model.ops.unflatten(seq.data, seq.lengths)) elif _is_padded_data(seq): return Padded(*seq) # type: ignore[misc] elif is_xp_array(seq): floats3d_seq = cast(Floats3d, seq) size_at_t = model.ops.asarray1i([floats3d_seq.shape[1]] * floats3d_seq.shape[0]) lengths = model.ops.asarray1i([floats3d_seq.shape[0]] * floats3d_seq.shape[1]) indices = model.ops.xp.arange(floats3d_seq.shape[1]) return Padded(floats3d_seq, size_at_t, lengths, indices) else: assert isinstance(seq, list), seq return model.ops.list2padded(seq) def _array_forward( layer: Model[Padded, Padded], X: Floats3d, is_train ) -> Tuple[Floats3d, Callable]: # Create bogus metadata for Padded. Xp = _get_padded(layer, X) Yp, get_dXp = layer(Xp, is_train) size_at_t = Xp.size_at_t lengths = Xp.lengths indices = Xp.indices def backprop(dY: Floats3d) -> Floats3d: dYp = Padded(dY, size_at_t, lengths, indices) dXp = get_dXp(dYp) return dXp.data return cast(Floats3d, Yp.data), backprop def _tuple_forward( layer: Model[Padded, Padded], X: PaddedData, is_train: bool ) -> Tuple[PaddedData, Callable]: Yp, get_dXp = layer(Padded(*X), is_train) def backprop(dY): dXp = get_dXp(Padded(*dY)) return (dXp.data, dXp.size_at_t, dXp.lengths, dXp.indices) return (cast(Floats3d, Yp.data), Yp.size_at_t, Yp.lengths, Yp.indices), backprop def _ragged_forward( layer: Model[Padded, Padded], Xr: Ragged, is_train: bool ) -> Tuple[Ragged, Callable]: # Assign these to locals, to keep code a bit shorter. list2padded = layer.ops.list2padded padded2list = layer.ops.padded2list unflatten = layer.ops.unflatten flatten = layer.ops.flatten # It's worth being a bit careful about memory here, as the activations # are potentially large on GPU. So we make nested function calls instead # of assigning to temporaries where possible, so memory can be reclaimed # sooner. Yp, get_dXp = layer(list2padded(unflatten(Xr.data, Xr.lengths)), is_train) def backprop(dYr: Ragged): flattened = flatten( padded2list(get_dXp(list2padded(unflatten(dYr.data, dYr.lengths)))), ) return Ragged(flattened, dYr.lengths) flattened = flatten(padded2list(Yp)) return Ragged(flattened, Xr.lengths), backprop def _list_forward( layer: Model[Padded, Padded], Xs: List2d, is_train: bool ) -> Tuple[List2d, Callable]: # Assign these to locals, to keep code a bit shorter. list2padded = layer.ops.list2padded padded2list = layer.ops.padded2list Yp, get_dXp = layer(list2padded(Xs), is_train) def backprop(dYs): return padded2list(get_dXp(list2padded(dYs))) return padded2list(Yp), backprop thinc-9.0.0/thinc/layers/with_ragged.py000066400000000000000000000105361461023342500200740ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar, Union, cast from ..backends import NumpyOps from ..config import registry from ..model import Model from ..types import Array2d, Ints1d, List2d, ListXd, Padded, Ragged NUMPY_OPS = NumpyOps() RaggedData = Tuple[Array2d, Ints1d] SeqT = TypeVar("SeqT", bound=Union[Padded, Ragged, ListXd, RaggedData]) @registry.layers("with_ragged.v1") def with_ragged(layer: Model[Ragged, Ragged]) -> Model[SeqT, SeqT]: return Model(f"with_ragged({layer.name})", forward, init=init, layers=[layer]) def forward( model: Model[SeqT, SeqT], Xseq: SeqT, is_train: bool ) -> Tuple[SeqT, Callable]: layer: Model[Ragged, Ragged] = model.layers[0] if isinstance(Xseq, Ragged): return cast(Tuple[SeqT, Callable], layer(Xseq, is_train)) elif isinstance(Xseq, Padded): return cast(Tuple[SeqT, Callable], _padded_forward(layer, Xseq, is_train)) elif _is_ragged_data(Xseq): return cast( Tuple[SeqT, Callable], _tuple_forward(layer, cast(RaggedData, Xseq), is_train), ) else: return cast( Tuple[SeqT, Callable], _list_forward(layer, cast(List, Xseq), is_train) ) def init( model: Model[SeqT, SeqT], X: Optional[SeqT] = None, Y: Optional[SeqT] = None, ) -> None: model.layers[0].initialize( X=_get_ragged(model, X) if X is not None else None, Y=_get_ragged(model, Y) if Y is not None else None, ) def _is_ragged_data(seq): return isinstance(seq, tuple) and len(seq) == 2 def _get_ragged(model: Model[SeqT, SeqT], seq: SeqT) -> Ragged: if isinstance(seq, Ragged): return seq elif isinstance(seq, Padded): lists = model.ops.padded2list(seq) lengths = model.ops.asarray1i([len(x) for x in lists]) k = model.ops.flatten(lists) return Ragged(model.ops.flatten(lists), lengths) elif _is_ragged_data(seq): return Ragged(*seq) # type: ignore[misc] else: list2d_seq = cast(List2d, seq) lengths = model.ops.asarray1i([len(x) for x in list2d_seq]) return Ragged(model.ops.flatten(list2d_seq), lengths) def _tuple_forward( layer: Model[Ragged, Ragged], X: RaggedData, is_train: bool ) -> Tuple[RaggedData, Callable]: Yr, get_dXr = layer(Ragged(*X), is_train) def backprop(dY: RaggedData) -> RaggedData: dXr = get_dXr(Ragged(*dY)) return (dXr.data, dXr.lengths) return (Yr.data, Yr.lengths), backprop def _padded_forward( layer: Model[Ragged, Ragged], Xp: Padded, is_train: bool ) -> Tuple[Padded, Callable]: # Assign these to locals, to keep code a bit shorter. list2padded = layer.ops.list2padded padded2list = layer.ops.padded2list unflatten = layer.ops.unflatten flatten = layer.ops.flatten # It's worth being a bit careful about memory here, as the activations # are potentially large on GPU. So we make nested function calls instead # of assigning to temporaries where possible, so memory can be reclaimed # sooner. Xs = padded2list(Xp) # Bit annoying here: padded is in a different order, so we need to make new # lengths. The lengths are unconditionally allocated in CPU memory, because # otherwire unflatten would move GPU allocations to the CPU again. For the # ragged arrays we let the layer's ops determine how lengths should be # stored to ensure that the array and lengths use the same type of memory. lengths = NUMPY_OPS.asarray1i([len(x) for x in Xs]) Yr, get_dXr = layer(Ragged(flatten(Xs), layer.ops.asarray1i(lengths)), is_train) def backprop(dYp: Padded): flattened = flatten(padded2list(dYp)) dXr = get_dXr(Ragged(flattened, lengths)) return list2padded(unflatten(dXr.data, lengths)) return ( list2padded(unflatten(Yr.data, Yr.lengths)), backprop, ) def _list_forward( layer: Model[Ragged, Ragged], Xs: List, is_train: bool ) -> Tuple[List, Callable]: # Assign these to locals, to keep code a bit shorter. flatten = layer.ops.flatten unflatten = layer.ops.unflatten lengths = [len(x) for x in Xs] Yr, get_dXr = layer(Ragged(flatten(Xs), layer.ops.asarray1i(lengths)), is_train) def backprop(dYs): flattened = flatten(dYs) return unflatten(get_dXr(Ragged(flattened, lengths)).data, lengths) return unflatten(Yr.data, Yr.lengths), backprop thinc-9.0.0/thinc/layers/with_reshape.py000066400000000000000000000033771461023342500202770ustar00rootroot00000000000000from typing import Callable, List, Optional, Tuple, TypeVar, cast from ..config import registry from ..model import Model from ..types import Array2d, Array3d InT = TypeVar("InT", bound=Array3d) OutT = TypeVar("OutT", bound=Array2d) @registry.layers("with_reshape.v1") def with_reshape(layer: Model[OutT, OutT]) -> Model[InT, InT]: """Reshape data on the way into and out from a layer.""" return Model( f"with_reshape({layer.name})", forward, init=init, layers=[layer], dims={"nO": None, "nI": None}, ) def forward(model: Model[InT, InT], X: InT, is_train: bool) -> Tuple[InT, Callable]: layer = model.layers[0] initial_shape = X.shape final_shape = list(initial_shape[:-1]) + [layer.get_dim("nO")] nB = X.shape[0] nT = X.shape[1] X2d = model.ops.reshape(X, (-1, X.shape[2])) Y2d, Y2d_backprop = layer(X2d, is_train=is_train) Y = model.ops.reshape3(Y2d, *final_shape) def backprop(dY: InT) -> InT: reshaped = model.ops.reshape2(dY, nB * nT, -1) return Y2d_backprop(model.ops.reshape3(reshaped, *initial_shape)) return cast(InT, Y), backprop def init( model: Model[InT, InT], X: Optional[Array3d] = None, Y: Optional[Array3d] = None ) -> None: layer = model.layers[0] if X is None and Y is None: layer.initialize() X2d: Optional[Array2d] = None Y2d: Optional[Array2d] = None if X is not None: X2d = cast(Array2d, model.ops.reshape(X, (-1, X.shape[-1]))) if Y is not None: Y2d = cast(Array2d, model.ops.reshape(Y, (-1, Y.shape[-1]))) layer.initialize(X=X2d, Y=Y2d) if layer.has_dim("nI"): model.set_dim("nI", layer.get_dim("nI")) if layer.has_dim("nO"): model.set_dim("nO", layer.get_dim("nO")) thinc-9.0.0/thinc/layers/with_signpost_interval.py000066400000000000000000000027471461023342500224220ustar00rootroot00000000000000from typing import Any, Callable, Optional, Tuple, TypeVar from ..compat import has_os_signpost, os_signpost from ..model import Model _ModelT = TypeVar("_ModelT", bound=Model) def with_signpost_interval( layer: _ModelT, signposter: "os_signpost.Signposter", name: Optional[str] = None, ) -> _ModelT: """Wraps any layer and marks the init, forward and backprop phases using signpost intervals for macOS Instruments profiling By default, the name of the layer is used as the name of the range, followed by the name of the pass. """ if not has_os_signpost: raise ValueError( "with_signpost_interval layer requires the 'os_signpost' package" ) name = layer.name if name is None else name orig_forward = layer._func orig_init = layer.init def forward(model: Model, X: Any, is_train: bool) -> Tuple[Any, Callable]: with signposter.use_interval(f"{name} forward"): layer_Y, layer_callback = orig_forward(model, X, is_train=is_train) def backprop(dY: Any) -> Any: with signposter.use_interval(f"{name} backprop"): return layer_callback(dY) return layer_Y, backprop def init(_model: Model, X: Any, Y: Any) -> Model: if orig_init is not None: with signposter.use_interval(f"{name} init"): return orig_init(layer, X, Y) else: return layer layer.replace_callbacks(forward, init=init) return layer thinc-9.0.0/thinc/loss.py000066400000000000000000000376641461023342500153040ustar00rootroot00000000000000from abc import abstractmethod from typing import ( Any, Dict, Generic, List, Optional, Sequence, Tuple, TypeVar, Union, cast, ) from .config import registry from .types import Floats2d, Ints1d from .util import get_array_module, to_categorical LossT = TypeVar("LossT") GradT = TypeVar("GradT") GuessT = TypeVar("GuessT") TruthT = TypeVar("TruthT") IntsOrFloats = Union[Ints1d, Floats2d] IntsOrFloatsOrStrs = Union[Ints1d, Floats2d, Sequence[int], Sequence[str]] class Loss(Generic[GuessT, TruthT, GradT, LossT]): # pragma: no cover """Base class for classes computing the loss / gradient. The class can be initialized with settings if needed. It provides get_loss and get_grad as separate methods to allow calculating them separately. It also provides a __call__ method that returns a tuple of both. """ def __init__(self, **kwargs: Any) -> None: ... def __call__(self, guesses: GuessT, truths: TruthT) -> Tuple[GradT, LossT]: return self.get_grad(guesses, truths), self.get_loss(guesses, truths) @abstractmethod def get_grad(self, guesses: GuessT, truths: TruthT) -> GradT: ... @abstractmethod def get_loss(self, guesses: GuessT, truths: TruthT) -> LossT: ... class CategoricalCrossentropy(Loss): names: Optional[Sequence[str]] missing_value: Optional[Union[str, int]] _name_to_i: Dict[str, int] def __init__( self, *, normalize: bool = True, names: Optional[Sequence[str]] = None, missing_value: Optional[Union[str, int]] = None, neg_prefix: Optional[str] = None, label_smoothing: float = 0.0, ): self.normalize = normalize self.names = names self.missing_value = missing_value self.neg_prefix = neg_prefix self.label_smoothing = label_smoothing if names is not None: self._name_to_i = {name: i for i, name in enumerate(names)} else: self._name_to_i = {} def convert_truths(self, truths, guesses: Floats2d) -> Tuple[Floats2d, Floats2d]: xp = get_array_module(guesses) missing = [] negatives_mask = None if self.names: negatives_mask = xp.ones((len(truths), len(self.names)), dtype="f") missing_value = self.missing_value # Convert list of ints or list of strings if isinstance(truths, list): truths = list(truths) if len(truths): if isinstance(truths[0], int): for i, value in enumerate(truths): if value == missing_value: missing.append(i) else: if self.names is None: msg = ( "Cannot calculate loss from list of strings without names. " "You can pass the names as a keyword argument when you " "create the loss object, " "e.g. CategoricalCrossentropy(names=['dog', 'cat'])" ) raise ValueError(msg) for i, value in enumerate(truths): if value == missing_value: truths[i] = self.names[0] missing.append(i) elif ( value and self.neg_prefix and value.startswith(self.neg_prefix) ): truths[i] = value[len(self.neg_prefix) :] neg_index = self._name_to_i[truths[i]] negatives_mask[i] = 0 # type: ignore negatives_mask[i][neg_index] = -1 # type: ignore truths = [self._name_to_i[name] for name in truths] truths = xp.asarray(truths, dtype="i") mask = _make_mask(guesses, missing) else: mask = _make_mask_by_value(truths, guesses, missing_value) if truths.ndim != guesses.ndim: # transform categorical values to one-hot encoding truths = to_categorical( cast(Ints1d, truths), n_classes=guesses.shape[-1], label_smoothing=self.label_smoothing, ) else: if self.label_smoothing: raise ValueError( "Label smoothing is only applied, when truths have type " "List[str], List[int] or Ints1d, but it seems like Floats2d " "was provided." ) # Transform negative annotations to a 0 for the negated value # + mask all other values for that row if negatives_mask is not None: truths *= negatives_mask truths[truths == -1] = 0 negatives_mask[negatives_mask == -1] = 1 mask *= negatives_mask return truths, mask def __call__( self, guesses: Floats2d, truths: IntsOrFloatsOrStrs ) -> Tuple[Floats2d, float]: d_truth = self.get_grad(guesses, truths) return (d_truth, self._get_loss_from_grad(d_truth)) def get_grad(self, guesses: Floats2d, truths: IntsOrFloatsOrStrs) -> Floats2d: target, mask = self.convert_truths(truths, guesses) xp = get_array_module(target) if guesses.shape != target.shape: # pragma: no cover err = f"Cannot calculate CategoricalCrossentropy loss: mismatched shapes: {guesses.shape} vs {target.shape}." raise ValueError(err) if xp.any(guesses > 1) or xp.any(guesses < 0): # pragma: no cover err = f"Cannot calculate CategoricalCrossentropy loss with guesses outside the [0,1] interval." raise ValueError(err) if xp.any(target > 1) or xp.any(target < 0): # pragma: no cover err = f"Cannot calculate CategoricalCrossentropy loss with truth values outside the [0,1] interval." raise ValueError(err) difference = guesses - target difference *= mask if self.normalize: difference = difference / guesses.shape[0] return difference def get_loss(self, guesses: Floats2d, truths: IntsOrFloatsOrStrs) -> float: d_truth = self.get_grad(guesses, truths) return self._get_loss_from_grad(d_truth) def _get_loss_from_grad(self, d_truth: Floats2d) -> float: # TODO: Add overload for axis=None case to sum return (d_truth**2).sum() # type: ignore @registry.losses("CategoricalCrossentropy.v1") def configure_CategoricalCrossentropy_v1( *, normalize: bool = True, names: Optional[Sequence[str]] = None, missing_value: Optional[Union[str, int]] = None, ) -> CategoricalCrossentropy: return CategoricalCrossentropy( normalize=normalize, names=names, missing_value=missing_value ) @registry.losses("CategoricalCrossentropy.v2") def configure_CategoricalCrossentropy_v2( *, normalize: bool = True, names: Optional[Sequence[str]] = None, missing_value: Optional[Union[str, int]] = None, neg_prefix: Optional[str] = None, ) -> CategoricalCrossentropy: return CategoricalCrossentropy( normalize=normalize, names=names, missing_value=missing_value, neg_prefix=neg_prefix, ) @registry.losses("CategoricalCrossentropy.v3") def configure_CategoricalCrossentropy_v3( *, normalize: bool = True, names: Optional[Sequence[str]] = None, missing_value: Optional[Union[str, int]] = None, neg_prefix: Optional[str] = None, label_smoothing: float = 0.0, ) -> CategoricalCrossentropy: return CategoricalCrossentropy( normalize=normalize, names=names, missing_value=missing_value, neg_prefix=neg_prefix, label_smoothing=label_smoothing, ) class SequenceCategoricalCrossentropy(Loss): def __init__( self, *, normalize: bool = True, names: Optional[Sequence[str]] = None, missing_value: Optional[Union[str, int]] = None, neg_prefix: Optional[str] = None, label_smoothing: float = 0.0, ): self.cc = CategoricalCrossentropy( normalize=False, names=names, missing_value=missing_value, neg_prefix=neg_prefix, label_smoothing=label_smoothing, ) self.normalize = normalize def __call__( self, guesses: Sequence[Floats2d], truths: Sequence[IntsOrFloatsOrStrs] ) -> Tuple[List[Floats2d], float]: grads = self.get_grad(guesses, truths) loss = self._get_loss_from_grad(grads) return grads, loss def get_grad( self, guesses: Sequence[Floats2d], truths: Sequence[IntsOrFloatsOrStrs] ) -> List[Floats2d]: err = "Cannot calculate SequenceCategoricalCrossentropy loss: guesses and truths must be same length" if len(guesses) != len(truths): # pragma: no cover raise ValueError(err) n = len(guesses) d_scores = [] for yh, y in zip(guesses, truths): d_yh = self.cc.get_grad(yh, y) if self.normalize: d_yh /= n d_scores.append(d_yh) return d_scores def get_loss( self, guesses: Sequence[Floats2d], truths: Sequence[IntsOrFloatsOrStrs] ) -> float: return self._get_loss_from_grad(self.get_grad(guesses, truths)) def _get_loss_from_grad(self, grads: Sequence[Floats2d]) -> float: loss = 0.0 for grad in grads: loss += self.cc._get_loss_from_grad(grad) return loss @registry.losses("SequenceCategoricalCrossentropy.v1") def configure_SequenceCategoricalCrossentropy_v1( *, normalize: bool = True, names: Optional[Sequence[str]] = None ) -> SequenceCategoricalCrossentropy: return SequenceCategoricalCrossentropy(normalize=normalize, names=names) @registry.losses("SequenceCategoricalCrossentropy.v2") def configure_SequenceCategoricalCrossentropy_v2( *, normalize: bool = True, names: Optional[Sequence[str]] = None, neg_prefix: Optional[str] = None, ) -> SequenceCategoricalCrossentropy: return SequenceCategoricalCrossentropy( normalize=normalize, names=names, neg_prefix=neg_prefix ) @registry.losses("SequenceCategoricalCrossentropy.v3") def configure_SequenceCategoricalCrossentropy_v3( *, normalize: bool = True, names: Optional[Sequence[str]] = None, missing_value: Optional[Union[str, int]] = None, neg_prefix: Optional[str] = None, label_smoothing: float = 0.0, ) -> SequenceCategoricalCrossentropy: return SequenceCategoricalCrossentropy( normalize=normalize, names=names, missing_value=missing_value, neg_prefix=neg_prefix, label_smoothing=label_smoothing, ) class L2Distance(Loss): def __init__(self, *, normalize: bool = True): self.normalize = normalize def __call__(self, guesses: Floats2d, truths: Floats2d) -> Tuple[Floats2d, float]: return self.get_grad(guesses, truths), self.get_loss(guesses, truths) def get_grad(self, guesses: Floats2d, truths: Floats2d) -> Floats2d: if guesses.shape != truths.shape: # pragma: no cover err = f"Cannot calculate L2 distance: mismatched shapes: {guesses.shape} vs {truths.shape}." raise ValueError(err) difference = guesses - truths if self.normalize: difference = difference / guesses.shape[0] return difference def get_loss(self, guesses: Floats2d, truths: Floats2d) -> float: if guesses.shape != truths.shape: # pragma: no cover err = f"Cannot calculate L2 distance: mismatched shapes: {guesses.shape} vs {truths.shape}." raise ValueError(err) d_truth = self.get_grad(guesses, truths) # TODO: Add overload for axis=None case to sum return (d_truth**2).sum() # type: ignore @registry.losses("L2Distance.v1") def configure_L2Distance(*, normalize: bool = True) -> L2Distance: return L2Distance(normalize=normalize) class CosineDistance(Loss): def __init__(self, *, normalize: bool = True, ignore_zeros: bool = False): self.normalize = normalize self.ignore_zeros = ignore_zeros def __call__(self, guesses: Floats2d, truths: Floats2d) -> Tuple[Floats2d, float]: return self.get_grad(guesses, truths), self.get_loss(guesses, truths) def get_similarity(self, guesses: Floats2d, truths: Floats2d) -> float: if guesses.shape != truths.shape: # pragma: no cover err = f"Cannot calculate cosine similarity: mismatched shapes: {guesses.shape} vs {truths.shape}." raise ValueError(err) xp = get_array_module(guesses) # Add a small constant to avoid 0 vectors yh = guesses + 1e-8 y = truths + 1e-8 norm_yh = xp.linalg.norm(yh, axis=1, keepdims=True) norm_y = xp.linalg.norm(y, axis=1, keepdims=True) mul_norms = norm_yh * norm_y cosine = (yh * y).sum(axis=1, keepdims=True) / mul_norms return cosine def get_grad(self, guesses: Floats2d, truths: Floats2d) -> Floats2d: if guesses.shape != truths.shape: # pragma: no cover err = f"Cannot calculate cosine similarity: mismatched shapes: {guesses.shape} vs {truths.shape}." raise ValueError(err) # Note: not using get_distance() here to avoid duplicating certain calculations xp = get_array_module(guesses) # Find the zero vectors if self.ignore_zeros: zero_indices = xp.abs(truths).sum(axis=1) == 0 # Add a small constant to avoid 0 vectors yh = guesses + 1e-8 y = truths + 1e-8 # https://math.stackexchange.com/questions/1923613/partial-derivative-of-cosinesimilarity norm_yh = xp.linalg.norm(yh, axis=1, keepdims=True) norm_y = xp.linalg.norm(y, axis=1, keepdims=True) mul_norms = norm_yh * norm_y cosine = (yh * y).sum(axis=1, keepdims=True) / mul_norms d_yh = (y / mul_norms) - (cosine * (yh / norm_yh**2)) if self.ignore_zeros: # If the target was a zero vector, don't count it in the loss. d_yh[zero_indices] = 0 if self.normalize: d_yh = d_yh / guesses.shape[0] return -d_yh def get_loss(self, guesses: Floats2d, truths: Floats2d) -> float: if guesses.shape != truths.shape: # pragma: no cover err = f"Cannot calculate cosine similarity: mismatched shapes: {guesses.shape} vs {truths.shape}." raise ValueError(err) xp = get_array_module(guesses) cosine = self.get_similarity(guesses, truths) losses = xp.abs(cosine - 1) if self.ignore_zeros: # If the target was a zero vector, don't count it in the loss. zero_indices = xp.abs(truths).sum(axis=1) == 0 losses[zero_indices] = 0 if self.normalize: losses = losses / guesses.shape[0] loss = losses.sum() return loss @registry.losses("CosineDistance.v1") def configure_CosineDistance( *, normalize: bool = True, ignore_zeros: bool = False ) -> CosineDistance: return CosineDistance(normalize=normalize, ignore_zeros=ignore_zeros) def _make_mask(guesses, missing) -> Floats2d: xp = get_array_module(guesses) mask = xp.ones(guesses.shape, dtype="f") mask[missing] = 0 return mask def _make_mask_by_value(truths, guesses, missing_value) -> Floats2d: xp = get_array_module(guesses) mask = xp.ones(guesses.shape, dtype="f") if missing_value is not None: if truths.ndim == 1: mask[truths == missing_value] = 0.0 else: # In 2D truths, labels are encoded as one-hot vectors, so we can get # the label indices using argmax. labels = xp.argmax(truths, axis=-1) mask[labels == missing_value] = 0.0 return mask __all__ = [ "SequenceCategoricalCrossentropy", "CategoricalCrossentropy", "L2Distance", "CosineDistance", ] thinc-9.0.0/thinc/model.py000066400000000000000000001041471461023342500154130ustar00rootroot00000000000000import contextlib import copy import functools import threading from contextvars import ContextVar from pathlib import Path from typing import ( Any, Callable, Dict, Generic, Iterable, Iterator, List, Optional, Sequence, Set, Tuple, TypeVar, Union, cast, ) import srsly from .backends import CupyOps, NumpyOps, Ops, ParamServer, get_current_ops from .optimizers import Optimizer # noqa: F401 from .shims import Shim from .types import FloatsXd from .util import ( DATA_VALIDATION, convert_recursive, is_xp_array, partial, validate_fwd_input_output, ) InT = TypeVar("InT") OutT = TypeVar("OutT") SelfT = TypeVar("SelfT", bound="Model") context_operators: ContextVar[dict] = ContextVar("context_operators", default={}) def empty_init(model: "Model", *args, **kwargs) -> "Model": return model class Model(Generic[InT, OutT]): """Class for implementing Thinc models and layers.""" global_id: int = 0 global_id_lock: threading.Lock = threading.Lock() _context_operators = context_operators name: str ops: Ops id: int _func: Callable init: Callable _params: ParamServer _dims: Dict[str, Optional[int]] _layers: List["Model"] _shims: List[Shim] _attrs: Dict[str, Any] _has_params: Dict[str, Optional[bool]] # This "locks" the class, so we get an error if you try to assign to # an unexpected variable. __slots__ = [ "name", "id", "ops", "_func", "init", "_params", "_dims", "_attrs", "_refs", "_layers", "_shims", "_has_params", ] def __init__( self, name: str, forward: Callable, *, init: Optional[Callable] = None, dims: Dict[str, Optional[int]] = {}, params: Dict[str, Optional[FloatsXd]] = {}, layers: Sequence["Model"] = [], shims: List[Shim] = [], attrs: Dict[str, Any] = {}, refs: Dict[str, Optional["Model"]] = {}, ops: Optional[Union[NumpyOps, CupyOps]] = None, ): """Initialize a new model.""" self.name = name if init is None: init = partial(empty_init, self) # Assign to callable attrs: https://github.com/python/mypy/issues/2427 setattr(self, "_func", forward) setattr(self, "init", init) self.ops = ops if ops is not None else get_current_ops() self._params = ParamServer() self._dims = dict(dims) self._attrs = dict(attrs) self._refs = dict(refs) self._layers = list(layers) self._shims = list(shims) # Take care to increment the base class here! It needs to be unique # across all models. with Model.global_id_lock: Model.global_id += 1 self.id = Model.global_id self._has_params = {} for name, value in params.items(): self._has_params[name] = None if value is not None: self.set_param(name, value) @property def layers(self) -> List["Model"]: """A list of child layers of the model. You can append to it to add layers but not reassign it. """ return self._layers @property def shims(self) -> List[Shim]: return self._shims @property def attrs(self) -> Dict[str, Any]: """A dict of the model's attrs. You can write to it to update attrs but not reassign it. """ return self._attrs @property def param_names(self) -> Tuple[str, ...]: """Get the names of registered parameter (including unset).""" return tuple(self._has_params.keys()) @property def grad_names(self) -> Tuple[str, ...]: """Get the names of parameters with registered gradients (including unset).""" return tuple([name for name in self.param_names if self.has_grad(name)]) @property def dim_names(self) -> Tuple[str, ...]: """Get the names of registered dimensions (including unset).""" return tuple(self._dims.keys()) @property def ref_names(self) -> Tuple[str, ...]: """Get the names of registered node references (including unset).""" return tuple(self._refs.keys()) @classmethod @contextlib.contextmanager def define_operators(cls, operators: Dict[str, Callable]): """Bind arbitrary binary functions to Python operators, for use in any `Model` instance. Can (and should) be used as a contextmanager. EXAMPLE: with Model.define_operators({">>": chain}): model = Relu(512) >> Relu(512) >> Softmax() """ token = cls._context_operators.set(dict(operators)) yield cls._context_operators.reset(token) def has_dim(self, name: str) -> Optional[bool]: """Check whether the model has a dimension of a given name. If the dimension is registered but the value is unset, returns None. """ if name not in self._dims: return False elif self._dims[name] is not None: return True else: return None def get_dim(self, name: str) -> int: """Retrieve the value of a dimension of the given name.""" if name not in self._dims: raise KeyError(f"Cannot get dimension '{name}' for model '{self.name}'") value = self._dims[name] if value is None: err = f"Cannot get dimension '{name}' for model '{self.name}': value unset" raise ValueError(err) else: return value def set_dim(self, name: str, value: int, *, force: bool = False) -> None: """Set a value for a dimension.""" if name not in self._dims: raise KeyError( f"Cannot set unknown dimension '{name}' for model '{self.name}'." ) old_value = self._dims[name] has_params = any(bool(y) for x, y in self._has_params.items()) invalid_change = (old_value is not None and old_value != value) and ( not force or force and has_params ) if invalid_change: err = f"Attempt to change dimension '{name}' for model '{self.name}' from {old_value} to {value}" raise ValueError(err) self._dims[name] = value def maybe_get_dim(self, name: str) -> Optional[int]: """Retrieve the value of a dimension of the given name, or None.""" return self.get_dim(name) if self.has_dim(name) else None def has_param(self, name: str) -> Optional[bool]: """Check whether the model has a weights parameter of the given name. Returns None if the parameter is registered but currently unset. """ if name not in self._has_params: return False elif self._has_params[name] is not None: return True else: return None def get_param(self, name: str) -> FloatsXd: """Retrieve a weights parameter by name.""" if name not in self._has_params: raise KeyError(f"Unknown param: '{name}' for model '{self.name}'.") if not self._params.has_param(self.id, name): raise KeyError( f"Parameter '{name}' for model '{self.name}' has not been allocated yet." ) return self._params.get_param(self.id, name) def maybe_get_param(self, name: str) -> Optional[FloatsXd]: """Retrieve a weights parameter by name, or None.""" return self.get_param(name) if self.has_param(name) else None def set_param(self, name: str, value: Optional[FloatsXd]) -> None: """Set a weights parameter's value.""" if value is None: self._has_params[name] = None else: self._params.set_param(self.id, name, value) self._has_params[name] = True def has_grad(self, name: str) -> bool: """Check whether the model has a non-zero gradient for a parameter.""" return self._params.has_grad(self.id, name) def get_grad(self, name: str) -> FloatsXd: """Get a gradient from the model.""" return self._params.get_grad(self.id, name) def set_grad(self, name: str, value: FloatsXd) -> None: """Set a gradient value for the model.""" self._params.set_grad(self.id, name, value) def maybe_get_grad(self, name: str) -> Optional[FloatsXd]: """Retrieve a gradient by name, or None.""" return self.get_grad(name) if self.has_grad(name) else None def inc_grad(self, name: str, value: FloatsXd) -> None: """Increment the gradient of a parameter by a value.""" self._params.inc_grad(self.id, name, value) def has_ref(self, name: str) -> Optional[bool]: """Check whether the model has a reference of a given name. If the reference is registered but the value is unset, returns None. """ if name not in self._refs: return False elif self._refs[name] is not None: return True else: return None def get_ref(self, name: str) -> "Model": """Retrieve the value of a reference of the given name.""" if name not in self._refs: raise KeyError(f"Cannot get reference '{name}' for model '{self.name}'.") value = self._refs[name] if value is None: err = f"Cannot get reference '{name}' for model '{self.name}': value unset." raise ValueError(err) else: return value def maybe_get_ref(self, name: str) -> Optional["Model"]: """Retrieve the value of a reference if it exists, or None.""" return self.get_ref(name) if self.has_ref(name) else None def set_ref(self, name: str, value: Optional["Model"]) -> None: """Set a value for a reference.""" if value is None: self._refs[name] = value elif value in self.walk(): self._refs[name] = value else: raise ValueError("Cannot add reference to node not in tree.") def __call__(self, X: InT, is_train: bool) -> Tuple[OutT, Callable]: """Call the model's `forward` function, returning the output and a callback to compute the gradients via backpropagation.""" return self._func(self, X, is_train=is_train) def initialize(self, X: Optional[InT] = None, Y: Optional[OutT] = None) -> "Model": """Finish initialization of the model, optionally providing a batch of example input and output data to perform shape inference.""" if DATA_VALIDATION.get(): validate_fwd_input_output(self.name, self._func, X, Y) if self.init is not None: self.init(self, X=X, Y=Y) return self def begin_update(self, X: InT) -> Tuple[OutT, Callable[[OutT], InT]]: """Run the model over a batch of data, returning the output and a callback to complete the backward pass. A tuple (Y, finish_update), where Y is a batch of output data, and finish_update is a callback that takes the gradient with respect to the output and an optimizer function, and returns the gradient with respect to the input. """ return self._func(self, X, is_train=True) def predict(self, X: InT) -> OutT: """Call the model's `forward` function with `is_train=False`, and return only the output, instead of the `(output, callback)` tuple. """ return self._func(self, X, is_train=False)[0] def finish_update(self, optimizer: Optimizer) -> None: """Update parameters with current gradients. The optimizer is called with each parameter and gradient of the model. """ for node in self.walk(): for shim in node.shims: shim.finish_update(optimizer) for node in self.walk(): for name in node.param_names: if node.has_grad(name): param, grad = optimizer( (node.id, name), node.get_param(name), node.get_grad(name) ) node.set_param(name, param) @contextlib.contextmanager def use_params(self, params: Dict[Tuple[int, str], FloatsXd]): """Context manager to temporarily set the model's parameters to specified values. The params are a dictionary keyed by model IDs, whose values are arrays of weight values. """ backup = {} for name in self.param_names: key = (self.id, name) if key in params: backup[name] = self.get_param(name) self.set_param(name, params[key]) with contextlib.ExitStack() as stack: for layer in self.layers: stack.enter_context(layer.use_params(params)) for shim in self.shims: stack.enter_context(shim.use_params(params)) yield if backup: for name, param in backup.items(): self.set_param(name, param) def walk(self, *, order: str = "bfs") -> Iterable["Model"]: """Iterate out layers of the model. Nodes are returned in breadth-first order by default. Other possible orders are "dfs_pre" (depth-first search in preorder) and "dfs_post" (depth-first search in postorder).""" if order == "bfs": return self._walk_bfs() elif order == "dfs_pre": return self._walk_dfs(post_order=False) elif order == "dfs_post": return self._walk_dfs(post_order=True) else: raise ValueError("Invalid order, must be one of: bfs, dfs_pre, dfs_post") def _walk_bfs(self) -> Iterable["Model"]: """Iterate out layers of the model, breadth-first.""" queue = [self] seen: Set[int] = set() for node in queue: if id(node) in seen: continue seen.add(id(node)) yield node queue.extend(node.layers) def _walk_dfs(self, post_order: bool = False) -> Iterable["Model"]: """Iterate out layers of the model, depth-first.""" seen: Dict[int, Iterator["Model"]] = dict() stack = [self] seen[id(self)] = iter(self.layers) if not post_order: yield self while stack: try: next_child = next(seen[id(stack[-1])]) if not id(next_child) in seen: if not post_order: yield next_child stack.append(next_child) seen[id(next_child)] = iter(next_child.layers) except StopIteration: if post_order: yield stack[-1] stack.pop() def remove_node(self, node: "Model") -> None: """Remove a node from all layers lists, and then update references. References that no longer point to a node within the tree will be set to `None`. For instance, let's say a node has its grandchild as a reference. If the child is removed, the grandchild reference will be left dangling, so will be set to None. """ for child in list(self.walk()): while node in child.layers: child.layers.remove(node) tree = set(self.walk()) for node in tree: for name in node.ref_names: ref = node.get_ref(name) if ref is not None and ref not in tree: node.set_ref(name, None) def replace_callbacks( self, forward: Callable, *, init: Optional[Callable] = None ) -> None: setattr(self, "_func", forward) setattr(self, "init", init) def replace_node(self, old: "Model", new: "Model") -> bool: """Replace a node anywhere it occurs within the model. Returns a boolean indicating whether the replacement was made.""" seen = False # We need to replace nodes in topological order of the transposed graph # to ensure that a node's dependencies are processed before the node. # This is equivalent to a post-order traversal of the original graph. for node in list(self.walk(order="dfs_post")): if node is old: seen = True else: node._layers = [ new if layer is old else layer for layer in node._layers ] for name in node.ref_names: if node.get_ref(name) is old: node.set_ref(name, new) return seen def get_gradients(self) -> Dict[Tuple[int, str], Tuple[FloatsXd, FloatsXd]]: """Get non-zero gradients of the model's parameters, as a dictionary keyed by the parameter ID. The values are (weights, gradients) tuples. """ gradients = {} for node in self.walk(): for name in node.grad_names: param = node.get_param(name) grad = node.get_grad(name) gradients[(node.id, name)] = (param, grad) return gradients def copy(self: SelfT) -> SelfT: """ Create a copy of the model, its attributes, and its parameters. Any child layers will also be deep-copied. The copy will receive a distinct `model.id` value. """ return self._copy() def _copy( self: SelfT, seen: Optional[Dict[int, Union["Model", Shim]]] = None ) -> SelfT: if seen is None: seen = {} params = {} for name in self.param_names: params[name] = self.get_param(name) if self.has_param(name) else None copied_layers: List[Model] = [] for layer in self.layers: if id(layer) in seen: copied_layers.append(cast(Model, seen[id(layer)])) else: copied_layer = layer._copy(seen) seen[id(layer)] = copied_layer copied_layers.append(copied_layer) copied_shims = [] for shim in self.shims: if id(shim) in seen: copied_shims.append(cast(Shim, seen[id(shim)])) else: copied_shim = shim.copy() seen[id(shim)] = copied_shim copied_shims.append(copied_shim) copied: Model[InT, OutT] = Model( self.name, self._func, init=self.init, params=copy.deepcopy(params), dims=copy.deepcopy(self._dims), attrs=copy.deepcopy(self._attrs), layers=copied_layers, shims=copied_shims, ) for name in self.grad_names: copied.set_grad(name, self.get_grad(name).copy()) return cast(SelfT, copied) def to_gpu(self, gpu_id: int) -> None: # pragma: no cover """Transfer the model to a given GPU device.""" import cupy.cuda.device with cupy.cuda.device.Device(gpu_id): self._to_ops(CupyOps()) def to_cpu(self) -> None: # pragma: no cover """Transfer the model to CPU.""" self._to_ops(NumpyOps()) def _to_ops(self, ops: Ops) -> None: # pragma: no cover """Common method for to_cpu/to_gpu.""" for node in self.walk(): node.ops = ops for name in node.param_names: if node.has_param(name): node.set_param(name, ops.asarray_f(node.get_param(name))) if node.has_grad(name): node.set_grad(name, ops.asarray_f(node.get_grad(name))) for shim in node.shims: shim.to_device(ops.device_type, ops.device_id) def to_bytes(self) -> bytes: """Serialize the model to a bytes representation. Models are usually serialized using msgpack, so you should be able to call msgpack.loads() on the data and get back a dictionary with the contents. Serialization should round-trip identically, i.e. the same bytes should result from loading and serializing a model. """ msg = self.to_dict() to_numpy_le = partial(self.ops.to_numpy, byte_order="<") msg = convert_recursive(is_xp_array, to_numpy_le, msg) return srsly.msgpack_dumps(msg) def to_disk(self, path: Union[Path, str]) -> None: """Serialize the model to disk. Most models will serialize to a single file, which should just be the bytes contents of model.to_bytes(). """ path = Path(path) if isinstance(path, str) else path with path.open("wb") as file_: file_.write(self.to_bytes()) def to_dict(self) -> Dict: """Serialize the model to a dict representation. Serialization should round-trip identically, i.e. the same dict should result from loading and serializing a model. """ # We separate out like this to make it easier to read the data in chunks. # The shims might have large weights, while the nodes data will be # small. The attrs are probably not very large, but could be. # The lists are aligned, and refer to the order of self.walk(). msg: Dict[str, List] = {"nodes": [], "attrs": [], "params": [], "shims": []} nodes = list(self.walk()) # Serialize references by their index into the flattened tree. # This is the main reason we can't accept out-of-tree references: # we'd have no way to serialize/deserialize them. node_to_i: Dict[int, Optional[int]] node_to_i = {node.id: i for i, node in enumerate(nodes)} for i, node in enumerate(nodes): refs: Dict[str, Optional[int]] = {} invalid_refs: List[str] = [] for name in node.ref_names: if not node.has_ref(name): refs[name] = None else: ref = node.get_ref(name) if ref.id in node_to_i: refs[name] = node_to_i[ref.id] else: invalid_refs.append(name) if invalid_refs: raise ValueError(f"Cannot get references: {invalid_refs}") dims = {} for dim in node.dim_names: dims[dim] = node.get_dim(dim) if node.has_dim(dim) else None msg["nodes"].append( {"index": i, "name": node.name, "dims": dims, "refs": refs} ) for node in nodes: attrs = {} for name, value in node.attrs.items(): try: attrs[name] = serialize_attr(value, value, name, node) except TypeError: continue msg["attrs"].append(attrs) for node in nodes: msg["shims"].append([shim.to_bytes() for shim in node.shims]) for node in nodes: params: Dict[str, Optional[FloatsXd]] = {} for name in node.param_names: if node.has_param(name): params[name] = cast(Optional[FloatsXd], node.get_param(name)) else: params[name] = None msg["params"].append(params) return msg def from_bytes(self, bytes_data: bytes) -> "Model": """Deserialize the model from a bytes representation. Models are usually serialized using msgpack, so you should be able to call msgpack.loads() on the data and get back a dictionary with the contents. Serialization should round-trip identically, i.e. the same bytes should result from loading and serializing a model. """ msg = srsly.msgpack_loads(bytes_data) msg = convert_recursive(is_xp_array, self.ops.asarray, msg) return self.from_dict(msg) def from_disk(self, path: Union[Path, str]) -> "Model": """Deserialize the model from disk. Most models will serialize to a single file, which should just be the bytes contents of model.to_bytes(). """ path = Path(path) if isinstance(path, str) else path with path.open("rb") as file_: bytes_data = file_.read() return self.from_bytes(bytes_data) def from_dict(self, msg: Dict) -> "Model": if "nodes" not in msg.keys(): # pragma: no cover err = "Trying to read a Model that was created with an incompatible version of Thinc" raise ValueError(err) nodes = list(self.walk()) if len(msg["nodes"]) != len(nodes): raise ValueError("Cannot deserialize model: mismatched structure") for i, node in enumerate(nodes): info = msg["nodes"][i] node.name = info["name"] for dim, value in info["dims"].items(): if value is not None: node.set_dim(dim, value) for ref, ref_index in info["refs"].items(): if ref_index is None: node.set_ref(ref, None) else: node.set_ref(ref, nodes[ref_index]) for attr, value in msg["attrs"][i].items(): default_value = node.attrs.get(attr) loaded_value = deserialize_attr(default_value, value, attr, node) node.attrs[attr] = loaded_value for param_name, value in msg["params"][i].items(): if value is not None: value = node.ops.asarray(value).copy() node.set_param(param_name, value) for i, shim_bytes in enumerate(msg["shims"][i]): node.shims[i].from_bytes(shim_bytes) return self def can_from_disk(self, path: Union[Path, str], *, strict: bool = True) -> bool: """Check whether serialized data on disk is compatible with the model. If 'strict', the function returns False if the model has an attribute already loaded that would be changed. """ path = Path(path) if isinstance(path, str) else path if path.is_dir() or not path.exists(): return False with path.open("rb") as file_: bytes_data = file_.read() return self.can_from_bytes(bytes_data, strict=strict) def can_from_bytes(self, bytes_data: bytes, *, strict: bool = True) -> bool: """Check whether the bytes data is compatible with the model. If 'strict', the function returns False if the model has an attribute already loaded that would be changed. """ try: msg = srsly.msgpack_loads(bytes_data) except ValueError: return False return self.can_from_dict(msg, strict=strict) def can_from_dict(self, msg: Dict, *, strict: bool = True) -> bool: """Check whether a dictionary is compatible with the model. If 'strict', the function returns False if the model has an attribute already loaded that would be changed. """ if "nodes" not in msg.keys(): return False nodes = list(self.walk()) if len(msg["nodes"]) != len(nodes): return False for i, node in enumerate(nodes): info = msg["nodes"][i] if strict and info["name"] != node.name: return False if len(msg["shims"][i]) != len(node.shims): # TODO: The shims should have a check for this too, but # for now we just check if the lengths match. return False for dim, value in info["dims"].items(): has_dim = node.has_dim(dim) if has_dim is False: return False elif has_dim and node.get_dim(dim) != value: return False for param_name, value in msg["params"][i].items(): has_param = node.has_param(param_name) if has_param is False: return False elif has_param and value is not None: param = node.get_param(param_name) if param.shape != value.shape: return False if strict: for attr, value in msg["attrs"][i].items(): if attr in node.attrs: try: serialized = serialize_attr( node.attrs[attr], node.attrs[attr], attr, node ) except TypeError: continue if serialized != value: return False return True def __add__(self, other: Any) -> "Model": """Apply the function bound to the '+' operator.""" if "+" not in self._context_operators.get(): raise TypeError("Undefined operator: +") return self._context_operators.get()["+"](self, other) def __sub__(self, other: Any) -> "Model": """Apply the function bound to the '-' operator.""" if "-" not in self._context_operators.get(): raise TypeError("Undefined operator: -") return self._context_operators.get()["-"](self, other) def __mul__(self, other: Any) -> "Model": """Apply the function bound to the '*' operator.""" if "*" not in self._context_operators.get(): raise TypeError("Undefined operator: *") return self._context_operators.get()["*"](self, other) def __matmul__(self, other: Any) -> "Model": """Apply the function bound to the '@' operator.""" if "@" not in self._context_operators.get(): raise TypeError("Undefined operator: @") return self._context_operators.get()["@"](self, other) def __div__(self, other: Any) -> "Model": # pragma: no cover """Apply the function bound to the '/' operator.""" if "/" not in self._context_operators.get(): raise TypeError("Undefined operator: /") return self._context_operators.get()["/"](self, other) def __truediv__(self, other: Any) -> "Model": """Apply the function bound to the '/' operator.""" if "/" not in self._context_operators.get(): raise TypeError("Undefined operator: /") return self._context_operators.get()["/"](self, other) def __floordiv__(self, other: Any) -> "Model": """Apply the function bound to the '//' operator.""" if "//" not in self._context_operators.get(): raise TypeError("Undefined operator: //") return self._context_operators.get()["//"](self, other) def __mod__(self, other: Any) -> "Model": """Apply the function bound to the '%' operator.""" if "%" not in self._context_operators.get(): raise TypeError("Undefined operator: %") return self._context_operators.get()["%"](self, other) def __pow__(self, other: Any, **kwargs) -> "Model": """Apply the function bound to the '**' operator.""" if "**" not in self._context_operators.get(): raise TypeError("Undefined operator: **") return self._context_operators.get()["**"](self, other) def __lshift__(self, other: Any) -> "Model": """Apply the function bound to the '<<' operator.""" if "<<" not in self._context_operators.get(): raise TypeError("Undefined operator: <<") return self._context_operators.get()["<<"](self, other) def __rshift__(self, other: Any) -> "Model": """Apply the function bound to the '>>' operator.""" if ">>" not in self._context_operators.get(): raise TypeError("Undefined operator: >>") return self._context_operators.get()[">>"](self, other) def __and__(self, other: Any) -> "Model": """Apply the function bound to the '&' operator.""" if "&" not in self._context_operators.get(): raise TypeError("Undefined operator: &") return self._context_operators.get()["&"](self, other) def __xor__(self, other: Any) -> "Model": """Apply the function bound to the '^' operator.""" if "^" not in self._context_operators.get(): raise TypeError("Undefined operator: ^") return self._context_operators.get()["^"](self, other) def __or__(self, other: Any) -> "Model": """Apply the function bound to the '|' operator.""" if "|" not in self._context_operators.get(): raise TypeError("Undefined operator: |") return self._context_operators.get()["|"](self, other) @functools.singledispatch def serialize_attr(_: Any, value: Any, name: str, model: Model) -> bytes: """Serialize an attribute value (defaults to msgpack). You can register custom serializers using the @serialize_attr.register decorator with the type to serialize, e.g.: @serialize_attr.register(MyCustomObject). """ return srsly.msgpack_dumps(value) @functools.singledispatch def deserialize_attr(_: Any, value: Any, name: str, model: Model) -> Any: """Deserialize an attribute value (defaults to msgpack). You can register custom deserializers using the @deserialize_attr.register decorator with the type to deserialize, e.g.: @deserialize_attr.register(MyCustomObject). """ return srsly.msgpack_loads(value) _ModelT = TypeVar("_ModelT", bound=Model) def change_attr_values(model: _ModelT, mapping: Dict[str, Dict[str, Any]]) -> _ModelT: """Walk over the model's nodes, changing the value of attributes using the provided mapping, which maps node names to attr names to attr values. """ for node in model.walk(): if node.name in mapping: attrs = mapping[node.name] for attr, value in attrs.items(): if attr in node.attrs: node.attrs[attr] = value return model def set_dropout_rate(model: _ModelT, drop: float, attrs=["dropout_rate"]) -> _ModelT: """Walk over the model's nodes, setting the dropout rate. You can specify one or more attribute names, by default it looks for ["dropout_rate"]. """ for node in model.walk(): for attr in attrs: if attr in node.attrs: node.attrs[attr] = drop return model def wrap_model_recursive(model: Model, wrapper: Callable[[Model], _ModelT]) -> _ModelT: """Recursively wrap a model and its submodules. The model is updated in-place.""" for node in list(model.walk()): model.replace_node(node, wrapper(node)) return wrapper(model) __all__ = [ "Model", "serialize_attr", "deserialize_attr", "change_attr_values", "set_dropout_rate", "wrap_model_recursive", ] thinc-9.0.0/thinc/mypy.py000066400000000000000000000263131461023342500153070ustar00rootroot00000000000000import itertools from typing import Dict, List from mypy.checker import TypeChecker from mypy.errorcodes import ErrorCode from mypy.errors import Errors from mypy.nodes import CallExpr, Decorator, Expression, FuncDef, MypyFile, NameExpr from mypy.options import Options from mypy.plugin import CheckerPluginInterface, FunctionContext, Plugin from mypy.subtypes import is_subtype from mypy.types import CallableType, Instance, Type, TypeVarType thinc_model_fullname = "thinc.model.Model" chained_out_fullname = "thinc.types.XY_YZ_OutT" intoin_outtoout_out_fullname = "thinc.types.XY_XY_OutT" def plugin(version: str): return ThincPlugin class ThincPlugin(Plugin): def __init__(self, options: Options) -> None: super().__init__(options) def get_function_hook(self, fullname: str): return function_hook def function_hook(ctx: FunctionContext) -> Type: try: return get_reducers_type(ctx) except AssertionError: # Add more function callbacks here return ctx.default_return_type def get_reducers_type(ctx: FunctionContext) -> Type: """ Determine a more specific model type for functions that combine models. This function operates on function *calls*. It analyzes each function call by looking at the function definition and the arguments passed as part of the function call, then determines a more specific return type for the function call. This method accepts a `FunctionContext` as part of the Mypy plugin interface. This function context provides easy access to: * `args`: List of "actual arguments" filling each "formal argument" of the called function. "Actual arguments" are those passed to the function as part of the function call. "Formal arguments" are the parameters defined by the function definition. The same actual argument may serve to fill multiple formal arguments. In some cases the relationship may even be ambiguous. For example, calling `range(*args)`, the actual argument `*args` may fill the `start`, `stop` or `step` formal arguments, depending on the length of the list. The `args` list is of length `num_formals`, with each element corresponding to a formal argument. Each value in the `args` list is a list of actual arguments which may fill the formal argument. For example, in the function call `range(*args, num)`, `num` may fill the `start`, `end` or `step` formal arguments depending on the length of `args`, so type-checking needs to consider all of these possibilities. * `arg_types`: Type annotation (or inferred type) of each argument. Like `args`, this value is a list of lists with an outer list entry for each formal argument and an inner list entry for each possible actual argument for the formal argument. * `arg_kinds`: "Kind" of argument passed to the function call. Argument kinds include positional, star (`*args`), named (`x=y`) and star2 (`**kwargs`) arguments (among others). Like `args`, this value is a list of lists. * `context`: AST node representing the function call with all available type information. Notable attributes include: * `args` and `arg_kinds`: Simple list of actual arguments, not mapped to formal arguments. * `callee`: AST node representing the function being called. Typically this is a `NameExpr`. To resolve this node to the function definition it references, accessing `callee.node` will usually return either a `FuncDef` or `Decorator` node. * etc. This function infers a more specific type for model-combining functions by making certain assumptions about how the function operates based on the order of its formal arguments and its return type. If the return type is `Model[InT, XY_YZ_OutT]`, the output of each argument is expected to be used as the input to the next argument. It's therefore necessary to check that the output type of each model is compatible with the input type of the following model. The combined model has the type `Model[InT, OutT]`, where `InT` is the input type of the first model and `OutT` is the output type of the last model. If the return type is `Model[InT, XY_XY_OutT]`, all model arguments receive input of the same type and are expected to produce output of the same type. It's therefore necessary to check that all models have the same input types and the same output types. The combined model has the type `Model[InT, OutT]`, where `InT` is the input type of all model arguments and `OutT` is the output type of all model arguments. Raises: AssertionError: Raised if a more specific model type couldn't be determined, indicating that the default general return type should be used. """ # Verify that we have a type-checking API and a default return type (presumably a # `thinc.model.Model` instance) assert isinstance(ctx.api, TypeChecker) assert isinstance(ctx.default_return_type, Instance) # Verify that we're inspecting a function call to a callable defined or decorated function assert isinstance(ctx.context, CallExpr) callee = ctx.context.callee assert isinstance(callee, NameExpr) callee_node = callee.node assert isinstance(callee_node, (FuncDef, Decorator)) callee_node_type = callee_node.type assert isinstance(callee_node_type, CallableType) # Verify that the callable returns a `thinc.model.Model` # TODO: Use `map_instance_to_supertype` to map subtypes to `Model` instances. # (figure out how to look up the `TypeInfo` for a class outside of the module being type-checked) callee_return_type = callee_node_type.ret_type assert isinstance(callee_return_type, Instance) assert callee_return_type.type.fullname == thinc_model_fullname assert callee_return_type.args assert len(callee_return_type.args) == 2 # Obtain the output type parameter of the `thinc.model.Model` return type # of the called API function out_type = callee_return_type.args[1] # Check if the `Model`'s output type parameter is one of the "special # type variables" defined to represent model composition (chaining) and # homogeneous reduction assert isinstance(out_type, TypeVarType) assert out_type.fullname if out_type.fullname not in {intoin_outtoout_out_fullname, chained_out_fullname}: return ctx.default_return_type # Extract type of each argument used to call the API function, making sure that they are also # `thinc.model.Model` instances args = list(itertools.chain(*ctx.args)) arg_types = [] for arg_type in itertools.chain(*ctx.arg_types): # TODO: Use `map_instance_to_supertype` to map subtypes to `Model` instances. assert isinstance(arg_type, Instance) assert arg_type.type.fullname == thinc_model_fullname assert len(arg_type.args) == 2 arg_types.append(arg_type) # Collect neighboring pairs of arguments and their types arg_pairs = list(zip(args[:-1], args[1:])) arg_types_pairs = list(zip(arg_types[:-1], arg_types[1:])) # Determine if passed models will be chained or if they all need to have # the same input and output type if out_type.fullname == chained_out_fullname: # Models will be chained, meaning that the output of each model will # be passed as the input to the next model # Verify that model inputs and outputs are compatible for (arg1, arg2), (type1, type2) in zip(arg_pairs, arg_types_pairs): assert isinstance(type1, Instance) assert isinstance(type2, Instance) assert type1.type.fullname == thinc_model_fullname assert type2.type.fullname == thinc_model_fullname check_chained( l1_arg=arg1, l1_type=type1, l2_arg=arg2, l2_type=type2, api=ctx.api ) # Generated model takes the first model's input and returns the last model's output return Instance( ctx.default_return_type.type, [arg_types[0].args[0], arg_types[-1].args[1]] ) elif out_type.fullname == intoin_outtoout_out_fullname: # Models must have the same input and output types # Verify that model inputs and outputs are compatible for (arg1, arg2), (type1, type2) in zip(arg_pairs, arg_types_pairs): assert isinstance(type1, Instance) assert isinstance(type2, Instance) assert type1.type.fullname == thinc_model_fullname assert type2.type.fullname == thinc_model_fullname check_intoin_outtoout( l1_arg=arg1, l1_type=type1, l2_arg=arg2, l2_type=type2, api=ctx.api ) # Generated model accepts and returns the same types as all passed models return Instance( ctx.default_return_type.type, [arg_types[0].args[0], arg_types[0].args[1]] ) # Make sure the default return type is returned if no branch was selected assert False, "Thinc mypy plugin error: it should return before this point" def check_chained( *, l1_arg: Expression, l1_type: Instance, l2_arg: Expression, l2_type: Instance, api: CheckerPluginInterface, ): if not is_subtype(l1_type.args[1], l2_type.args[0]): api.fail( f"Layer outputs type ({l1_type.args[1]}) but the next layer expects ({l2_type.args[0]}) as an input", l1_arg, code=error_layer_output, ) api.fail( f"Layer input type ({l2_type.args[0]}) is not compatible with output ({l1_type.args[1]}) from previous layer", l2_arg, code=error_layer_input, ) def check_intoin_outtoout( *, l1_arg: Expression, l1_type: Instance, l2_arg: Expression, l2_type: Instance, api: CheckerPluginInterface, ): if l1_type.args[0] != l2_type.args[0]: api.fail( f"Layer input ({l1_type.args[0]}) not compatible with next layer input ({l2_type.args[0]})", l1_arg, code=error_layer_input, ) api.fail( f"Layer input ({l2_type.args[0]}) not compatible with previous layer input ({l1_type.args[0]})", l2_arg, code=error_layer_input, ) if l1_type.args[1] != l2_type.args[1]: api.fail( f"Layer output ({l1_type.args[1]}) not compatible with next layer output ({l2_type.args[1]})", l1_arg, code=error_layer_output, ) api.fail( f"Layer output ({l2_type.args[1]}) not compatible with previous layer output ({l1_type.args[1]})", l2_arg, code=error_layer_output, ) error_layer_input = ErrorCode("layer-mismatch-input", "Invalid layer input", "Thinc") error_layer_output = ErrorCode("layer-mismatch-output", "Invalid layer output", "Thinc") class IntrospectChecker(TypeChecker): def __init__( self, errors: Errors, modules: Dict[str, MypyFile], options: Options, tree: MypyFile, path: str, plugin: Plugin, per_line_checking_time_ns: Dict[int, int], ): self._error_messages: List[str] = [] super().__init__( errors, modules, options, tree, path, plugin, per_line_checking_time_ns ) thinc-9.0.0/thinc/optimizers.py000066400000000000000000000343641461023342500165230ustar00rootroot00000000000000import itertools import math from collections import defaultdict from types import GeneratorType from typing import Any, Dict, List, Optional, Tuple, Union, cast from .backends import get_array_ops from .config import registry from .schedules import Schedule, constant from .types import FloatsXd, Generator KeyT = Tuple[int, str] ScheduleT = Union[float, List[float], Generator, Schedule] SGD_DEFAULTS: Dict[str, Union[float, bool, int]] = { "L2": 0.0, "L2_is_weight_decay": True, "grad_clip": 1.0, } ADAM_DEFAULTS: Dict[str, Union[float, bool, int]] = { "learn_rate": 0.001, "beta1": 0.9, "beta2": 0.999, "eps": 1e-08, "L2": SGD_DEFAULTS["L2"], "grad_clip": SGD_DEFAULTS["grad_clip"], "L2_is_weight_decay": True, } @registry.optimizers("RAdam.v1") def RAdam( learn_rate: ScheduleT = ADAM_DEFAULTS["learn_rate"], *, beta1: ScheduleT = ADAM_DEFAULTS["beta1"], beta2: ScheduleT = ADAM_DEFAULTS["beta2"], eps: ScheduleT = ADAM_DEFAULTS["eps"], L2: ScheduleT = ADAM_DEFAULTS["L2"], L2_is_weight_decay: bool = cast(bool, ADAM_DEFAULTS["L2_is_weight_decay"]), grad_clip: ScheduleT = ADAM_DEFAULTS["grad_clip"], use_averages: bool = True, ): return Optimizer( learn_rate, beta1=beta1, beta2=beta2, eps=eps, grad_clip=grad_clip, L2_is_weight_decay=L2_is_weight_decay, L2=L2, use_averages=use_averages, use_radam=True, ) @registry.optimizers("Adam.v1") def Adam( learn_rate: ScheduleT = ADAM_DEFAULTS["learn_rate"], *, L2: ScheduleT = ADAM_DEFAULTS["L2"], beta1: ScheduleT = ADAM_DEFAULTS["beta1"], beta2: ScheduleT = ADAM_DEFAULTS["beta2"], eps: ScheduleT = ADAM_DEFAULTS["eps"], grad_clip: ScheduleT = ADAM_DEFAULTS["grad_clip"], L2_is_weight_decay: bool = cast(bool, ADAM_DEFAULTS["L2_is_weight_decay"]), use_averages: bool = True, ): return Optimizer( learn_rate, L2=L2, beta1=beta1, beta2=beta2, eps=eps, grad_clip=grad_clip, L2_is_weight_decay=L2_is_weight_decay, use_averages=use_averages, use_radam=False, ) @registry.optimizers("SGD.v1") def SGD( learn_rate: ScheduleT, *, L2: ScheduleT = SGD_DEFAULTS["L2"], grad_clip: ScheduleT = SGD_DEFAULTS["grad_clip"], L2_is_weight_decay: bool = cast(bool, SGD_DEFAULTS["L2_is_weight_decay"]), use_averages: bool = True, ): return Optimizer( learn_rate, L2=L2, grad_clip=grad_clip, L2_is_weight_decay=L2_is_weight_decay, beta1=0.0, beta2=0.0, use_averages=use_averages, ) class Optimizer(object): """Do various flavours of stochastic gradient descent, with first and second order momentum. Currently support 'vanilla' SGD, Adam, and RAdam. """ mom1: Dict[KeyT, FloatsXd] mom2: Dict[KeyT, FloatsXd] averages: Optional[Dict[KeyT, FloatsXd]] schedules: Dict[str, Generator] nr_update: Dict[KeyT, int] last_seen: Dict[KeyT, int] grad_clip: Schedule learn_rate: Schedule b1: Schedule b2: Schedule eps: Schedule L2: Schedule use_radam: bool L2_is_weight_decay: bool _radam_buffer: List[List[Optional[FloatsXd]]] _step: int _last_score: Optional[Tuple[int, float]] # This "locks" the class, so we get an error if you try to assign to # an unexpected variable. __slots__ = [ "mom1", "mom2", "averages", "schedules", "nr_update", "last_seen", "grad_clip", "learn_rate", "b1", "b2", "eps", "L2", "use_radam", "L2_is_weight_decay", "_radam_buffer", "_step", "_last_score", ] def __init__( self, learn_rate: ScheduleT, *, L2: ScheduleT = ADAM_DEFAULTS["L2"], beta1: ScheduleT = ADAM_DEFAULTS["beta1"], beta2: ScheduleT = ADAM_DEFAULTS["beta2"], eps: ScheduleT = ADAM_DEFAULTS["eps"], grad_clip: ScheduleT = ADAM_DEFAULTS["grad_clip"], use_averages: bool = True, use_radam: bool = False, L2_is_weight_decay: bool = True, ): """ Initialize an optimizer. learn_rate (float): The initial learning rate. L2 (float): The L2 regularization term. beta1 (float): First-order momentum. beta2 (float): Second-order momentum. eps (float): Epsilon term for Adam etc. grad_clip (float): Gradient clipping. use_averages (bool): Whether to track moving averages of the parameters. use_radam (bool): Whether to use the RAdam optimizer. L2_is_weight_decay (bool): Whether to interpret the L2 parameter as a weight decay term, in the style of the AdamW optimizer. """ self._step = 0 self._last_score = None self.mom1 = {} self.mom2 = {} if use_averages: self.averages = {} else: self.averages = None self.nr_update = defaultdict(int) self.last_seen = defaultdict(int) self._set_attr_or_schedule("grad_clip", grad_clip) self._set_attr_or_schedule("learn_rate", learn_rate) self._set_attr_or_schedule("b1", beta1) self._set_attr_or_schedule("b2", beta2) self._set_attr_or_schedule("eps", eps) self._set_attr_or_schedule("L2", L2) self.use_radam = use_radam self.L2_is_weight_decay = L2_is_weight_decay self._radam_buffer = [[None, None, None] for _ in range(10)] def _set_attr_or_schedule(self, name, value): if isinstance(value, (float, bool, int)): setattr(self, name, constant(value)) elif isinstance(value, list): value = iter(value) setattr(self, name, _wrap_generator(name, value)) elif isinstance(value, GeneratorType): setattr(self, name, _wrap_generator(name, value)) elif isinstance(value, Schedule): setattr(self, name, value) else: err = f"Invalid schedule for '{name}' ({type(value)})" raise ValueError(err) def step_schedules(self): self._step += 1 @property def last_score(self) -> Optional[Tuple[int, float]]: return self._last_score @last_score.setter def last_score(self, score: float): self._last_score = (self._step, score) @property def step(self) -> int: return self._step def _schedule_args(self, key: KeyT) -> Dict[str, Any]: return { "key": key, "last_score": self.last_score, } def __call__( self, key: Tuple[int, str], weights: FloatsXd, gradient: FloatsXd, *, lr_scale: float = 1.0, ): """Call the optimizer with weights and a gradient. The key is the identifier for the parameter, usually the node ID and parameter name. """ if len(gradient) < 1: return weights, gradient ops = get_array_ops(weights) self.nr_update[key] += 1 nr_upd = self.nr_update[key] schedule_args = self._schedule_args(key) if self.L2(self.step, **schedule_args) != 0 and not self.L2_is_weight_decay: gradient += self.L2(self.step, **schedule_args) * weights if self.grad_clip(self.step, **schedule_args): gradient = ops.clip_gradient( gradient, self.grad_clip(self.step, **schedule_args), ) if self.use_radam: weights, gradient = self._radam( ops, weights, gradient, lr_scale, key, nr_upd ) elif ( self.b1(self.step, **schedule_args) > 0.0 and self.b2(self.step, **schedule_args) > 0.0 ): weights, gradient = self._adam( ops, weights, gradient, lr_scale, key, nr_upd ) elif self.b2(self.step, **schedule_args) > 0.0: # pragma: no cover raise NotImplementedError # TODO: error message else: weights -= lr_scale * self.learn_rate(self.step, **schedule_args) * gradient gradient *= 0 if self.L2(self.step, **schedule_args) != 0 and self.L2_is_weight_decay: weights -= ( lr_scale * self.learn_rate(self.step, **schedule_args) * self.L2(self.step, **schedule_args) * weights ) if self.averages is not None: if key not in self.averages: self.averages[key] = ops.alloc(weights.shape, dtype="float32") ops.update_averages(self.averages[key], weights, nr_upd) return weights, gradient def _radam(self, ops, weights, grad, lr_scale, key, nr_upd): if key not in self.mom1: self.mom1[key] = ops.alloc1f(weights.size) if key not in self.mom2: self.mom2[key] = ops.alloc1f(weights.size) weights_1D = ops.reshape1f(weights, weights.size) gradient_1D = ops.reshape1f(grad, grad.size) schedule_args = self._schedule_args(key) # While we port from the pytorch implementation, keep some of the same # naming state = { "step": self.nr_update[key], "exp_avg": self.mom1[key], "exp_avg_sq": self.mom2[key], } group = { "lr": self.learn_rate(self.step, **schedule_args), "betas": [ self.b1(self.step, **schedule_args), self.b2(self.step, **schedule_args), ], "eps": self.eps(self.step, **schedule_args), "weight_decay": 0.0, "buffer": self._radam_buffer, } degenerated_to_sgd = True exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"] beta1, beta2 = group["betas"] # exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad) exp_avg_sq *= beta2 exp_avg_sq += (1 - beta2) * (gradient_1D**2) # exp_avg.mul_(beta1).add_(1 - beta1, grad) exp_avg *= beta1 exp_avg += (1 - beta1) * gradient_1D state["step"] += 1 buffered = group["buffer"][int(state["step"] % 10)] if state["step"] == buffered[0]: N_sma, step_size = buffered[1], buffered[2] else: buffered[0] = state["step"] beta2_t = beta2 ** state["step"] N_sma_max = 2 / (1 - beta2) - 1 N_sma = N_sma_max - 2 * state["step"] * beta2_t / (1 - beta2_t) buffered[1] = N_sma # more conservative since it's an approximated value if N_sma >= 5: step_size = math.sqrt( (1 - beta2_t) * (N_sma - 4) / (N_sma_max - 4) * (N_sma - 2) / N_sma * N_sma_max / (N_sma_max - 2) ) / (1 - beta1 ** state["step"]) elif degenerated_to_sgd: step_size = 1.0 / (1 - beta1 ** state["step"]) else: step_size = -1 buffered[2] = step_size # more conservative since it's an approximated value if N_sma >= 5: if group["weight_decay"] != 0: weights_1D += -group["weight_decay"] * group["lr"] * weights_1D denom = ops.xp.sqrt(exp_avg_sq) + group["eps"] weights_1D += -step_size * group["lr"] * (exp_avg / denom) elif step_size > 0: if group["weight_decay"] != 0: weights_1D += -group["weight_decay"] * group["lr"] * weights_1D weights_1D += -step_size * group["lr"] * exp_avg return ( ops.reshape_f(weights_1D, weights.shape), ops.reshape_f(gradient_1D, grad.shape), ) def _adam(self, ops, weights, gradient, lr_scale, key, nr_upd): weights_1D = ops.reshape1f(weights, weights.size) gradient_1D = ops.reshape1f(gradient, gradient.size) schedule_args = self._schedule_args(key) if key not in self.mom1: self.mom1[key] = ops.alloc1f(weights.size) if key not in self.mom2: self.mom2[key] = ops.alloc1f(weights.size) mom1 = self.mom1[key] mom2 = self.mom2[key] b1 = self.b1(self.step, **schedule_args) b2 = self.b2(self.step, **schedule_args) fix1 = 1.0 - (b1**nr_upd) fix2 = 1.0 - (b2**nr_upd) lr = self.learn_rate(self.step, **schedule_args) * fix2**0.5 / fix1 eps = self.eps(self.step, **schedule_args) # needs to be 1D going into the adam function weights_1D, gradient_1D, mom1, mom2 = ops.adam( weights_1D, gradient_1D, mom1, mom2, b1, b2, eps, lr * lr_scale ) self.mom1[key] = mom1 self.mom2[key] = mom2 return ( ops.reshape_f(weights_1D, weights.shape), ops.reshape_f(gradient_1D, gradient.shape), ) def _wrap_generator(attr_name: str, generator: Generator) -> Schedule[Any]: try: peek = next(generator) except (StopIteration, TypeError) as e: err = f"Invalid schedule for '{attr_name}' ({type(generator)})\n{e}" raise ValueError(err) return Schedule( "wrap_generator", _wrap_generator_schedule, attrs={ "attr_name": attr_name, "last_step": -1, "last_value": peek, "generator": itertools.chain([peek], generator), }, ) def _wrap_generator_schedule(schedule: Schedule, step, **kwargs) -> float: attr_name = schedule.attrs["attr_name"] last_step = schedule.attrs["last_step"] last_value = schedule.attrs["last_value"] generator = schedule.attrs["generator"] if step < last_step: raise ValueError( f"'step' of the generator-based schedule for {attr_name} must not decrease" ) # Ensure that we have a value when we didn't step or when the # generator is exhausted. value = last_value for i in range(step - last_step): try: value = next(generator) except StopIteration: # schedule exhausted, use last value break schedule.attrs["last_step"] = step schedule.attrs["last_value"] = value return value __all__ = ["Adam", "RAdam", "SGD", "Optimizer", "ADAM_DEFAULTS", "SGD_DEFAULTS"] thinc-9.0.0/thinc/py.typed000066400000000000000000000000001461023342500154170ustar00rootroot00000000000000thinc-9.0.0/thinc/schedules.py000066400000000000000000000261161461023342500162710ustar00rootroot00000000000000"""Generators that provide different rates, schedules, decays or series.""" import itertools from dataclasses import dataclass from typing import Any, Callable, Dict, Generator, Generic, Optional, Tuple, TypeVar import numpy from .config import registry OutT = TypeVar("OutT") class Schedule(Generic[OutT]): """Class for implementing Thinc schedules.""" name: str _schedule: Callable _attrs: Dict[str, Any] __slots__ = ["name", "_schedule", "_attrs"] def __init__( self, name: str, schedule: Callable, *, attrs: Dict[str, Any] = {} ) -> None: """Initialize a new schedule. name (str): The name of the schedule type. schedule (Callable): The schedule function. """ self.name = name self._schedule = schedule self._attrs = dict(attrs) def __call__(self, step: int, **extra) -> OutT: """Compute the schedule for a given step.""" if step < 0: raise ValueError(f"Step must be non-negative, was: {step}") return self._schedule(self, step, **extra) @property def attrs(self): """Schedule attributes.""" return self._attrs def to_generator( self, start: int = 0, step_size=1, **extra ) -> Generator[OutT, None, None]: """Turn the schedule into a generator. start (int): The schedule initial step. step_size (int): The amount to increase the step for each generated value. **extra: Additional arguments that are passed to the schedule. RETURNS (Generator[OutT, None, None]): The generator. """ if start < 0: raise ValueError(f"Schedule start must be non-negative, was: {start}") if step_size < 0: raise ValueError(f"Step size must be non-negative, was: {step_size}") def generate(): for step in itertools.count(start, step_size): yield self(step, **extra) return generate() @registry.schedules("constant_then.v1") def constant_then(rate: OutT, steps: int, schedule: Schedule[OutT]) -> Schedule[OutT]: """Yield a constant rate for N steps, before starting a schedule.""" return Schedule( "constant_then", _constant_then_schedule, attrs={"rate": rate, "steps": steps, "schedule": schedule}, ) def _constant_then_schedule(schedule: Schedule, step: int, **kwargs) -> float: rate = schedule.attrs["rate"] steps = schedule.attrs["steps"] schedule = schedule.attrs["schedule"] if step < steps: return rate else: return schedule(step=step, **kwargs) @registry.schedules("constant.v1") def constant(rate: OutT) -> Schedule[OutT]: """Yield a constant rate.""" return Schedule("constant", _constant_schedule, attrs={"rate": rate}) def _constant_schedule(schedule: Schedule, step: int, **kwargs) -> float: rate = schedule.attrs["rate"] return rate @registry.schedules("decaying.v1") def decaying(base_rate: float, decay: float, *, t: float = 0.0) -> Schedule[float]: """Yield an infinite series of linearly decaying values, following the schedule: base_rate * 1 / (1 + decay * (t + step)) EXAMPLE: >>> learn_rates = decaying(0.001, 1e-4) >>> next(learn_rates) 0.001 >>> next(learn_rates) 0.00999 """ return Schedule( "decaying", _decaying_schedule, attrs={"base_rate": base_rate, "decay": decay, "t": t}, ) def _decaying_schedule(schedule: Schedule, step: int, **kwargs) -> float: base_rate = schedule.attrs["base_rate"] decay = schedule.attrs["decay"] t = schedule.attrs["t"] return base_rate * (1.0 / (1.0 + decay * (step + t))) @registry.schedules("compounding.v1") def compounding( start: float, stop: float, compound: float, *, t: float = 0.0 ) -> Schedule[float]: """Yield an infinite series of compounding values. Each time the generator is called, a value is produced by multiplying the previous value by the compound rate. EXAMPLE: >>> sizes = compounding(1.0, 10.0, 1.5) >>> assert next(sizes) == 1. >>> assert next(sizes) == 1 * 1.5 >>> assert next(sizes) == 1.5 * 1.5 """ return Schedule( "compounding", _compounding_schedule, attrs={"start": start, "stop": stop, "compound": compound, "t": t}, ) def _compounding_schedule(schedule: Schedule, step: int, **kwargs) -> float: start = schedule.attrs["start"] stop = schedule.attrs["stop"] compound = schedule.attrs["compound"] t = schedule.attrs["t"] return _clip(start * (compound ** (step + t)), start, stop) def _clip(value: float, start: float, stop: float) -> float: return max(value, stop) if (start > stop) else min(value, stop) @registry.schedules("plateau.v1") def plateau( max_patience: int, scale: float, schedule: Schedule[float] ) -> Schedule[float]: """Yields values from the wrapped schedule, exponentially scaled by the number of times optimization has plateaued. The caller must pass model evaluation scores through the last_score argument for the scaling to be adjusted. The last evaluation score is passed through the last_score argument as a tuple (last_score_step, last_score). This tuple indicates when a model was last evaluated (last_score_step) and with what score (last_score). max_patience (int): the number of evaluations without improvement when we consider the model to have plateaued. scale (float): scaling of the inner schedule (scale**n_plateaus * inner). schedule (Schedule[float]): the schedule to wrap. """ return Schedule( "plateau", _plateau_schedule, attrs={ "scale": scale, "max_patience": max_patience, "schedule": schedule, "state": _PlateauState( best_score=None, last_score_step=None, patience=0, n_plateaus=0 ), }, ) def _plateau_schedule( schedule: Schedule, step: int, *, last_score: Optional[Tuple[int, float]] = None, **kwargs, ) -> float: inner_schedule: Schedule[float] = schedule.attrs["schedule"] max_patience: int = schedule.attrs["max_patience"] scale: float = schedule.attrs["scale"] state: _PlateauState = schedule.attrs["state"] if last_score is None: return (scale**state.n_plateaus) * inner_schedule( step=step, last_score=last_score, **kwargs ) last_score_step, last_score_ = last_score if ( state.best_score is None or state.last_score_step is None or last_score_ > state.best_score ): state.best_score = last_score_ state.patience = 0 elif last_score_step < state.last_score_step: raise ValueError( f"Expected score with step >= {state.last_score_step}, was: {last_score_step}" ) elif last_score_step > state.last_score_step: # If the score didn't improve and we are not seeing the last # score again, we may be at a plateau, so increase patience. state.patience += 1 # If we are at the maximum patience, we consider the optimization # to have reached a plateau. if state.patience == max_patience: state.n_plateaus += 1 state.patience = 0 state.last_score_step = last_score_step return (scale**state.n_plateaus) * inner_schedule( step=step, last_score=last_score, **kwargs ) @dataclass class _PlateauState: """Plateau schedule state. best_score (Optional[float]): the best score so far, or None when no score has been observed. last_score_step (Optional[int]): the step of the last score that was observed. patience (int): the number of scores so far which do not improve over the best score (reset after reaching the maximum patience). n_plateaus (int): the number of times the maximum patience has been reached. """ best_score: Optional[float] last_score_step: Optional[int] patience: int n_plateaus: int # @dataclass(slots=True) is only supported in Python >= 3.10 __slots__ = ["best_score", "last_score_step", "patience", "n_plateaus"] @registry.schedules("slanted_triangular.v1") def slanted_triangular( max_rate: float, num_steps: int, *, cut_frac: float = 0.1, ratio: int = 32, t: float = 0.0, ) -> Schedule[float]: """Yield an infinite series of values according to Howard and Ruder's "slanted triangular learning rate" schedule. """ cut = int(num_steps * cut_frac) return Schedule( "slanted_triangular", _slanted_triangular_schedule, attrs={ "max_rate": max_rate, "cut": cut, "cut_frac": cut_frac, "ratio": ratio, "t": t, }, ) def _slanted_triangular_schedule(schedule: Schedule, step: int, **kwargs) -> float: max_rate = schedule.attrs["max_rate"] cut = schedule.attrs["cut"] cut_frac = schedule.attrs["cut_frac"] ratio = schedule.attrs["ratio"] t = schedule.attrs["t"] t_step = step + t + 1.0 if t_step < cut: p = t_step / cut else: p = 1 - ((t_step - cut) / (cut * (1 / cut_frac - 1))) return max_rate * (1 + p * (ratio - 1)) * (1 / ratio) @registry.schedules("warmup_linear.v1") def warmup_linear( initial_rate: float, warmup_steps: int, total_steps: int ) -> Schedule[float]: """Generate a series, starting from an initial rate, and then with a warmup period, and then a linear decline. Used for learning rates. """ return Schedule( "warmup_linear", _warmup_linear_schedule, attrs={ "initial_rate": initial_rate, "warmup_steps": warmup_steps, "total_steps": total_steps, }, ) def _warmup_linear_schedule(schedule: Schedule, step: int, **kwargs) -> float: initial_rate = schedule.attrs["initial_rate"] warmup_steps = schedule.attrs["warmup_steps"] total_steps = schedule.attrs["total_steps"] if step < warmup_steps: factor = step / max(1, warmup_steps) else: factor = max(0.0, (total_steps - step) / max(1.0, total_steps - warmup_steps)) return factor * initial_rate @registry.schedules("cyclic_triangular.v1") def cyclic_triangular(min_lr: float, max_lr: float, period: int) -> Schedule[float]: return Schedule( "cyclic_triangular", _cyclic_triangular_schedule, attrs={"min_lr": min_lr, "max_lr": max_lr, "period": period}, ) def _cyclic_triangular_schedule(schedule: Schedule, step: int, **kwargs) -> float: min_lr = schedule.attrs["min_lr"] max_lr = schedule.attrs["max_lr"] period = schedule.attrs["period"] it = step + 1 # https://towardsdatascience.com/adaptive-and-cyclical-learning-rates-using-pytorch-2bf904d18dee cycle = numpy.floor(1 + it / (2 * period)) x = numpy.abs(it / period - 2 * cycle + 1) relative = max(0, 1 - x) return min_lr + (max_lr - min_lr) * relative __all__ = [ "cyclic_triangular", "warmup_linear", "constant", "constant_then", "decaying", "warmup_linear", "slanted_triangular", "compounding", ] thinc-9.0.0/thinc/shims/000077500000000000000000000000001461023342500150555ustar00rootroot00000000000000thinc-9.0.0/thinc/shims/__init__.py000066400000000000000000000007161461023342500171720ustar00rootroot00000000000000from .mxnet import MXNetShim from .pytorch import PyTorchShim from .pytorch_grad_scaler import PyTorchGradScaler from .shim import Shim from .tensorflow import TensorFlowShim, keras_model_fns, maybe_handshake_model from .torchscript import TorchScriptShim # fmt: off __all__ = [ "MXNetShim", "PyTorchShim", "PyTorchGradScaler", "Shim", "TensorFlowShim", "TorchScriptShim", "maybe_handshake_model", "keras_model_fns", ] # fmt: on thinc-9.0.0/thinc/shims/mxnet.py000066400000000000000000000103331461023342500165620ustar00rootroot00000000000000# mypy: ignore-errors import copy from typing import Any, cast import srsly from ..compat import mxnet as mx from ..optimizers import Optimizer from ..types import ArgsKwargs, FloatsXd from ..util import ( convert_recursive, get_array_module, make_tempfile, mxnet2xp, xp2mxnet, ) from .shim import Shim class MXNetShim(Shim): """Interface between a MXNet model and a Thinc Model. This container is *not* a Thinc Model subclass itself. """ def __call__(self, inputs, is_train): if is_train: return self.begin_update(inputs) else: return self.predict(inputs), lambda a: ... def predict(self, inputs: ArgsKwargs) -> Any: """Pass inputs through to the underlying MXNet model, and return the output. No conversions are performed. The MXNet model is set into evaluation mode. """ mx.autograd.set_training(train_mode=False) with mx.autograd.pause(): outputs = self._model(*inputs.args, **inputs.kwargs) mx.autograd.set_training(train_mode=True) return outputs def begin_update(self, inputs: ArgsKwargs): """Pass the inputs through to the underlying MXNet model, keeping track of which items in the input are tensors requiring gradients. If the model returns a single value, it is converted into a one-element tuple. Return the outputs and a callback to backpropagate. """ mx.autograd.set_training(train_mode=True) mx.autograd.set_recording(True) output = self._model(*inputs.args, **inputs.kwargs) def backprop(grads): mx.autograd.set_recording(False) mx.autograd.backward(*grads.args, **grads.kwargs) return convert_recursive( lambda x: hasattr(x, "grad"), lambda x: x.grad, inputs ) return output, backprop def finish_update(self, optimizer: Optimizer): params = [] grads = [] shapes = [] ctx = mx.current_context() for key, value in self._model.collect_params().items(): grad = cast(FloatsXd, mxnet2xp(value.grad(ctx))) param = cast(FloatsXd, mxnet2xp(value.data(ctx))) params.append(param.ravel()) grads.append(grad.ravel()) shapes.append((param.size, param.shape)) if not params: return xp = get_array_module(params[0]) flat_params, flat_grads = optimizer( (self.id, "mxnet-shim"), xp.concatenate(params), xp.concatenate(grads) ) start = 0 for key, value in self._model.collect_params().items(): size, shape = shapes.pop(0) param = flat_params[start : start + size].reshape(shape) value.set_data(xp2mxnet(param)) value.zero_grad() start += size def copy(self, ctx: "mx.context.Context" = None): if ctx is None: ctx = mx.current_context() model_bytes = self.to_bytes() copied = copy.deepcopy(self) copied._model.initialize(ctx=ctx) copied.from_bytes(model_bytes) return copied def to_device(self, device_type: str, device_id: int): if device_type == "cpu": self._model = self.copy(mx.cpu()) elif device_type == "gpu": self._model = self.copy(mx.gpu()) else: msg = f"Unexpected device_type: {device_type}. Try 'cpu' or 'gpu'." raise ValueError(msg) def to_bytes(self): # MXNet doesn't implement save/load without a filename with make_tempfile("w+b") as temp: self._model.save_parameters(temp.name) temp.seek(0) weights_bytes = temp.read() msg = {"config": self.cfg, "state": weights_bytes} return srsly.msgpack_dumps(msg) def from_bytes(self, bytes_data): msg = srsly.msgpack_loads(bytes_data) self.cfg = msg["config"] self._load_params(msg["state"]) return self def _load_params(self, params): # MXNet doesn't implement save/load without a filename :( with make_tempfile("w+b") as temp: temp.write(params) self._model.load_parameters(temp.name, ctx=mx.current_context()) thinc-9.0.0/thinc/shims/pytorch.py000066400000000000000000000221741461023342500171250ustar00rootroot00000000000000import contextlib import itertools from io import BytesIO from typing import Any, Callable, Dict, Optional, cast import srsly from ..backends import CupyOps, context_pools, get_current_ops, set_gpu_allocator from ..compat import torch from ..optimizers import Optimizer from ..types import ArgsKwargs, FloatsXd from ..util import ( convert_recursive, get_torch_default_device, iterate_recursive, torch2xp, xp2torch, ) from .pytorch_grad_scaler import PyTorchGradScaler from .shim import Shim class PyTorchShim(Shim): """Interface between a PyTorch model and a Thinc Model. This container is *not* a Thinc Model subclass itself. mixed_precision: Enable mixed-precision. This changes whitelisted ops to run in half precision for better performance and lower memory use. grad_scaler: The gradient scaler to use for mixed-precision training. If this argument is set to "None" and mixed precision is enabled, a gradient scaler with the default configuration is used. device: The PyTorch device to run the model on. When this argument is set to "None", the default device for the currently active Thinc ops is used. serialize_model: Callback that receives the wrapped PyTorch model as its argument and returns a "bytes" representation of the same. The representation should contain all the necessary information to fully deserialize the model. deserialize_model: Callback that receives the default PyTorch model (passed to the constructor), the serialized "bytes" representation and a PyTorch device. It should return a fully deserialized model on the target device as its result. """ def __init__( self, model: Any, config=None, optimizer: Any = None, mixed_precision: bool = False, grad_scaler: Optional[PyTorchGradScaler] = None, device: Optional["torch.device"] = None, serialize_model: Optional[Callable[[Any], bytes]] = None, deserialize_model: Optional[Callable[[Any, bytes, "torch.device"], Any]] = None, ): super().__init__(model, config, optimizer) if device is None: device = get_torch_default_device() if model is not None: model.to(device) if grad_scaler is None: grad_scaler = PyTorchGradScaler(mixed_precision) grad_scaler.to_(device) self._grad_scaler = grad_scaler self._mixed_precision = mixed_precision self._serialize_model = ( serialize_model if serialize_model is not None else default_serialize_torch_model ) self._deserialize_model = ( deserialize_model if deserialize_model is not None else default_deserialize_torch_model ) if CupyOps.xp is not None and isinstance(get_current_ops(), CupyOps): pools = context_pools.get() if "pytorch" not in pools: from cupy import get_default_memory_pool set_gpu_allocator("pytorch") get_default_memory_pool().free_all_blocks() def __call__(self, inputs, is_train): if is_train: return self.begin_update(inputs) else: return self.predict(inputs), lambda a: ... @property def device(self): p = next(self._model.parameters(), None) if p is None: return get_torch_default_device() else: return p.device def predict(self, inputs: ArgsKwargs) -> Any: """Pass inputs through to the underlying PyTorch model, and return the output. No conversions are performed. The PyTorch model is set into evaluation mode. """ self._model.eval() with torch.no_grad(): with torch.cuda.amp.autocast(self._mixed_precision): outputs = self._model(*inputs.args, **inputs.kwargs) self._model.train() return outputs def begin_update(self, inputs: ArgsKwargs): """Pass the inputs through to the underlying PyTorch model, keeping track of which items in the input are tensors requiring gradients. If the model returns a single value, it is converted into a one-element tuple. Return the outputs and a callback to backpropagate. """ self._model.train() # Note: mixed-precision autocast must not be applied to backprop. with torch.cuda.amp.autocast(self._mixed_precision): output = self._model(*inputs.args, **inputs.kwargs) def backprop(grads): # Normally, gradient scaling is applied to the loss of a model. However, # since regular thinc layers do not use mixed-precision, we perform scaling # locally in this shim. Scaling the loss by a factor, scales the gradients # by the same factor (see the chain rule). Therefore, we scale the gradients # backprop'ed through the succeeding layer to get the same effect as loss # scaling. grads.kwargs["grad_tensors"] = self._grad_scaler.scale( grads.kwargs["grad_tensors"], inplace=True ) torch.autograd.backward(*grads.args, **grads.kwargs) # Unscale weights and check for overflows during backprop. grad_tensors = [] for torch_data in itertools.chain( self._model.parameters(), iterate_recursive(lambda x: hasattr(x, "grad"), inputs), ): if torch_data.grad is not None: grad_tensors.append(torch_data.grad) found_inf = self._grad_scaler.unscale(grad_tensors) # If there was an over/underflow, return zeroed-out gradients. if found_inf: grad_get = lambda x: x.grad.zero_() if x.grad is not None else x.grad else: grad_get = lambda x: x.grad return convert_recursive(lambda x: hasattr(x, "grad"), grad_get, inputs) return output, backprop def finish_update(self, optimizer: Optimizer): for name, torch_data in self._model.named_parameters(): if torch_data.grad is not None: if ( not self._grad_scaler.found_inf ): # Skip weight update if any gradient overflowed. param, grad = optimizer( (self.id, name), cast(FloatsXd, torch2xp(torch_data.data)), cast(FloatsXd, torch2xp(torch_data.grad)), ) torch_data.data = xp2torch( param, requires_grad=True, device=torch_data.device ) torch_data.grad.zero_() self._grad_scaler.update() @contextlib.contextmanager def use_params(self, params): key_prefix = f"pytorch_{self.id}_" state_dict = {} for k, v in params.items(): if hasattr(k, "startswith") and k.startswith(key_prefix): state_dict[k.replace(key_prefix, "")] = xp2torch(v, device=self.device) if state_dict: backup = {k: v.clone() for k, v in self._model.state_dict().items()} self._model.load_state_dict(state_dict) yield self._model.load_state_dict(backup) else: yield def to_device(self, device_type: str, device_id: int): # pragma: no cover if device_type == "cpu": self._model.cpu() elif device_type == "gpu": self._model.cuda(device_id) else: msg = f"Invalid device_type: {device_type}. Try 'cpu' or 'gpu'" raise ValueError(msg) def to_bytes(self): model_bytes = self._serialize_model(self._model) msg = {"config": self.cfg, "state": model_bytes} return srsly.msgpack_dumps(msg) def from_bytes(self, bytes_data): device = get_torch_default_device() msg = srsly.msgpack_loads(bytes_data) self.cfg = msg["config"] self._model = self._deserialize_model(self._model, msg["state"], device) self._grad_scaler.to_(device) return self def default_serialize_torch_model(model: Any) -> bytes: """Serializes the parameters of the wrapped PyTorch model to bytes. model: Wrapped PyTorch model. Returns: A `bytes` object that encapsulates the serialized model parameters. """ filelike = BytesIO() torch.save(model.state_dict(), filelike) filelike.seek(0) return filelike.getvalue() def default_deserialize_torch_model( model: Any, state_bytes: bytes, device: "torch.device" ) -> Any: """Deserializes the parameters of the wrapped PyTorch model and moves it to the specified device. model: Wrapped PyTorch model. state_bytes: Serialized parameters as a byte stream. device: PyTorch device to which the model is bound. Returns: The deserialized model. """ filelike = BytesIO(state_bytes) filelike.seek(0) model.load_state_dict(torch.load(filelike, map_location=device)) model.to(device) return model thinc-9.0.0/thinc/shims/pytorch_grad_scaler.py000066400000000000000000000136541461023342500214560ustar00rootroot00000000000000from typing import Dict, Iterable, List, Union, cast from ..compat import has_torch_amp, torch from ..util import is_torch_array class PyTorchGradScaler: """ Gradient scaler for the PyTorch shim. Gradients with small magnitudes are not representable in half-precision and will underflow to zero. A gradient scaler counters this issue by scaling up the loss before backpropagation, increasing the gradients by the same magnitude. A large enough scale will avoid that the gradients underflow. The gradients are unscaled in single precision after backpropagation, to provide the unscaled gradients to the optimizer. """ def __init__( self, enabled: bool = False, init_scale: float = 2.0**16, backoff_factor: float = 0.5, growth_factor: float = 2.0, growth_interval: int = 2000, ): """ Construct a gradient scaler for the PyTorch shim. enabled (bool): Sets whether the gradient scalar is enabled. If it is disabled, the methods of the grad scaler are no-ops. init_scale (float): The initial scale used to increase the gradient magnitude. backoff_factor (float): The scale will be multiplied by this factor if any of the gradients overflows. growth_factor (float): The scale will be multiplied by this factor when none of the gradients overflowed for "growth_interval" steps. growth_interval (int): When no overflows were found for this number of steps, the scale will be multiplied by "growth_factor". """ self._enabled = enabled self._growth_factor = growth_factor self._backoff_factor = backoff_factor self._growth_interval = growth_interval self._growth_tracker = torch.full((1,), 0, dtype=torch.int) self._scale = torch.full((1,), init_scale) self._found_inf = False def to_(self, device): self._growth_tracker = self._growth_tracker.to(device) self._scale = self._scale.to(device) def scale( self, tensors: Union["torch.Tensor", Iterable["torch.Tensor"]], inplace=False ) -> Union["torch.Tensor", List["torch.Tensor"]]: """Scale up the values in the given tensors.""" if not self._enabled: return cast("torch.Tensor", tensors) incorrect_type = ValueError( "Input to gradient scaling must be a Tensor or Iterable[Tensor]" ) # Cache per-device scales to avoid unnecessary d2d copies of the current scale. scale_per_device: Dict["torch.device", "torch.Tensor"] = dict() if is_torch_array(tensors): tensor = cast("torch.Tensor", tensors) return self._scale_tensor(tensor, scale_per_device, inplace) elif isinstance(tensors, Iterable): scaled_tensors = [] for tensor in tensors: if not is_torch_array(tensor): raise incorrect_type scaled_tensors.append( self._scale_tensor(tensor, scale_per_device, inplace) ) return scaled_tensors raise incorrect_type def _scale_tensor( self, tensor: "torch.Tensor", scale_per_device: Dict["torch.device", "torch.Tensor"], inplace: bool, ): if not has_torch_amp: raise ValueError( "Gradient scaling is not supported, requires capable GPU and torch>=1.9.0" ) if not tensor.is_cuda: msg = ( "Gradient scaling is only supported for CUDA tensors. " "If you are using PyTorch models, you can avoid this " "error by disabling mixed-precision support." ) raise ValueError(msg) device = tensor.device if device not in scale_per_device: scale_per_device[device] = self._scale.to(device=device) scale = scale_per_device[device] if inplace: return tensor.mul_(scale) else: return tensor * scale def _tensors_per_device(self, tensors): tensors_per_device = dict() for tensor in tensors: device_tensors = tensors_per_device.setdefault(tensor.device, []) device_tensors.append(tensor) return tensors_per_device @property def found_inf(self): return self._found_inf def unscale(self, tensors): """Unscale the given tensors. Returns True if any of the gradients were infinite.""" if not self._enabled: return False # Invert scale (in higher precision). inv_scale = self._scale.double().reciprocal().float() # Apply unscaling to tensors, per device. tensors_per_device = self._tensors_per_device(tensors) for device, device_tensors in tensors_per_device.items(): found_inf_device = torch.full((1,), 0.0, device=device) inv_scale_device = inv_scale.to(device=device) torch._amp_foreach_non_finite_check_and_unscale_( device_tensors, found_inf_device, inv_scale_device ) if bool(found_inf_device != 0): self._found_inf = True return self._found_inf def update(self): """ Update the scale factor and clear information about infinities. This method should be called after each optimization step. """ if not self._enabled: return found_inf_device = torch.full( (1,), 1.0 if self._found_inf else 0.0, device=self._scale.device ) torch._amp_update_scale_( self._scale, self._growth_tracker, found_inf_device, self._growth_factor, self._backoff_factor, self._growth_interval, ) # Clear infinity found status self._found_inf = False thinc-9.0.0/thinc/shims/shim.py000066400000000000000000000046621461023342500163770ustar00rootroot00000000000000import contextlib import copy import threading from pathlib import Path from typing import Any, Callable, Dict, Optional, Tuple, Union class Shim: # pragma: no cover """Define a basic interface for external models. Users can create subclasses of 'shim' to wrap external libraries. We provide shims for PyTorch. The Thinc Model class treats Shim objects as a sort of special type of sublayer: it knows they're not actual Thinc Model instances, but it also knows to talk to the shim instances when doing things like using transferring between devices, loading in parameters, optimization. It also knows Shim objects need to be serialized and deserialized with to/from bytes/disk, rather than expecting that they'll be msgpack-serializable. """ global_id: int = 0 global_id_lock: threading.Lock = threading.Lock() cfg: Dict _model: Any _optimizer: Optional[Any] def __init__(self, model: Any, config=None, optimizer: Any = None): with Shim.global_id_lock: Shim.global_id += 1 self.id = Shim.global_id self.cfg = dict(config) if config is not None else {} self._model = model self._optimizer = optimizer def __call__(self, inputs, is_train: bool) -> Tuple[Any, Callable[..., Any]]: raise NotImplementedError def predict(self, fwd_args: Any) -> Any: Y, backprop = self(fwd_args, is_train=False) return Y def begin_update(self, fwd_args: Any) -> Tuple[Any, Callable[..., Any]]: return self(fwd_args, is_train=True) def finish_update(self, optimizer): raise NotImplementedError @contextlib.contextmanager def use_params(self, params): yield def copy(self): return copy.deepcopy(self) def to_device(self, device_type: str, device_id: int): raise NotImplementedError def to_disk(self, path: Union[str, Path]): bytes_data = self.to_bytes() path = Path(path) if isinstance(path, str) else path with path.open("wb") as file_: file_.write(bytes_data) def from_disk(self, path: Union[str, Path]) -> "Shim": path = Path(path) if isinstance(path, str) else path with path.open("rb") as file_: bytes_data = file_.read() return self.from_bytes(bytes_data) def to_bytes(self): raise NotImplementedError def from_bytes(self, data) -> "Shim": raise NotImplementedError thinc-9.0.0/thinc/shims/tensorflow.py000066400000000000000000000245541461023342500176430ustar00rootroot00000000000000# mypy: ignore-errors import contextlib import copy from io import BytesIO from typing import Any, Dict, List, Optional import catalogue import numpy from ..backends import Ops, get_current_ops from ..compat import cupy, h5py from ..compat import tensorflow as tf from ..optimizers import Optimizer from ..types import ArgsKwargs, ArrayXd from ..util import get_array_module from .shim import Shim keras_model_fns = catalogue.create("thinc", "keras", entry_points=True) def maybe_handshake_model(keras_model): """Call the required predict/compile/build APIs to initialize a model if it is a subclass of tf.keras.Model. This is required to be able to call set_weights on subclassed layers.""" try: keras_model.get_config() return keras_model except (AttributeError, NotImplementedError): # Subclassed models don't implement get_config pass for prop_name in ["catalogue_name", "eg_x", "eg_y", "eg_shape"]: if not hasattr(keras_model, prop_name): raise ValueError( "Keras subclassed models are not whole-model serializable by " "TensorFlow. To work around this, you must decorate your keras " "model subclasses with the 'keras_subclass' decorator. The decorator " "requires a single X/Y input of fake-data that can be used to initialize " "your subclass model properly when loading the saved version." ) ops: Ops = get_current_ops() if ops.device_type == "cpu": device = "CPU" else: # pragma: no cover device = tf.test.gpu_device_name() compile_args = keras_model.eg_compile with tf.device(device): # Calling predict creates layers and weights for subclassed models keras_model.compile(**compile_args) keras_model.build(keras_model.eg_shape) keras_model.predict(keras_model.eg_x) # Made public in 2.2.x if hasattr(keras_model, "_make_train_function"): keras_model._make_train_function() else: keras_model.make_train_function() return keras_model class TensorFlowShim(Shim): """Interface between a TensorFlow model and a Thinc Model. This container is *not* a Thinc Model subclass itself. Reference for custom training: https://www.tensorflow.org/tutorials/customization/custom_training_walkthrough """ gradients: Optional[List["tf.Tensor"]] def __init__(self, model: Any, config=None, optimizer: Any = None): super().__init__(model, config, optimizer) self.gradients = None def __str__(self): lines: List[str] = [] def accumulate(line: str): lines.append(line) self._model.summary(print_fn=accumulate) return "\n".join(lines) def __call__(self, X: ArgsKwargs, is_train: bool): if is_train: return self.begin_update(X) else: return self.predict(X) def predict(self, X: ArgsKwargs): old_phase = tf.keras.backend.learning_phase() tf.keras.backend.set_learning_phase(0) Y = self._model(*X.args, **X.kwargs) tf.keras.backend.set_learning_phase(old_phase) return Y def begin_update(self, X: ArgsKwargs): tf.keras.backend.set_learning_phase(1) tape = tf.GradientTape() tape.__enter__() tape.watch(X.args) # watch the input layers output = self._model(*X.args, **X.kwargs) def backprop(d_output): # d_args[0] contains derivative of loss wrt output (d_loss/d_output) tape.__exit__(None, None, None) # We need to handle a tuple of inputs if len(X.args) == 1: wrt_tensors = [X.args[0]] # add the input layer also for d_loss/d_input else: wrt_tensors = list(X.args[0]) wrt_tensors.extend(self._model.trainable_variables) all_gradients = tape.gradient( output, wrt_tensors, output_gradients=d_output ) dX = all_gradients[: len(X.args)] opt_grads = all_gradients[1:] # Accumulate gradients if self.gradients is not None: assert len(opt_grads) == len(self.gradients), "gradients must match" variable: tf.Variable for variable, new_variable in zip(self.gradients, opt_grads): variable.assign_add(new_variable) else: # Create variables from the grads to allow accumulation self.gradients = [tf.Variable(f) for f in opt_grads] return ArgsKwargs(args=tuple(dX), kwargs={}) return output, backprop def finish_update(self, optimizer: Optimizer): if self.gradients is None: raise ValueError( "There are no gradients for optimization. Be sure to call begin_update" " before calling finish_update." ) assert len(self.gradients) == len(self._model.trainable_variables) grad: tf.Tensor variable: tf.Variable params = [] grads = [] shapes = [] for grad, variable in zip(self.gradients, self._model.trainable_variables): param = variable.numpy() grad = grad.numpy() shapes.append((param.size, param.shape)) params.append(param.ravel()) grads.append(grad.ravel()) xp = get_array_module(params[0]) flat_params, flat_grads = optimizer( (self.id, "tensorflow-shim"), xp.concatenate(params), xp.concatenate(grads) ) start = 0 for grad, variable in zip(self.gradients, self._model.trainable_variables): size, shape = shapes.pop(0) param = flat_params[start : start + size].reshape(shape) variable.assign(param) start += size self.gradients = None def _load_weights_from_state_dict( self, state_dict: Optional[Dict[str, ArrayXd]] = None ): if state_dict is None: state_dict = self._create_state_dict() for layer in self._model.layers: current_layer_weights = [] for weight in layer.weights: current_layer_weights.append(state_dict[weight.name]) layer.set_weights(current_layer_weights) # Create a state dict similar to PyTorch def _create_state_dict(self): # key as variable name and value as numpy arrays state_dict = {} for layer in self._model.layers: for weight in layer.weights: state_dict[weight.name] = weight.numpy() return state_dict @contextlib.contextmanager def use_params(self, params): key_prefix = f"tensorflow_{self.id}_" # state dict stores key as name and value as numpy array state_dict = {} for k, v in params.items(): if hasattr(k, "startswith") and k.startswith(key_prefix): if cupy is None: assert isinstance(v, numpy.ndarray) else: # pragma: no cover if isinstance(v, cupy.core.core.ndarray): v = cupy.asnumpy(v) assert isinstance(v, numpy.ndarray) state_dict[k.replace(key_prefix, "")] = v if state_dict: backup = self._create_state_dict() self._load_weights_from_state_dict(state_dict) yield self._load_weights_from_state_dict(backup) else: yield def _clone_model(self): """similar to tf.keras.models.clone_model() But the tf.keras.models.clone_model changes the names of tf.Variables. This method even preserves that """ model_json_config = self._model.to_json() tf.keras.backend.clear_session() self._model = tf.keras.models.model_from_json(model_json_config) self._load_weights_from_state_dict() def copy(self): model_json_config = self._model.to_json() self._model = None tf.keras.backend.clear_session() copied = copy.deepcopy(self) copied._model = tf.keras.models.model_from_json(model_json_config) copied._load_weights_from_state_dict() return copied def to_device(self, device_type: str, device_id: int): # pragma: no cover if device_type == "cpu": with tf.device("/CPU"): # pragma: no cover self._clone_model() elif device_type == "gpu": with tf.device("/GPU:{}".format(device_id)): self._clone_model() def to_bytes(self): filelike = BytesIO() try: with h5py.File(filelike, "w") as f: self._model.save(f, save_format="h5") return filelike.getvalue() except NotImplementedError: if not hasattr(self._model, "catalogue_name"): raise ValueError( "Couldn't serialize to h5, and model has no factory " "function for component serialization." ) # Check the factory function and throw ValueError if it doesn't exist keras_model_fns.get(self._model.catalogue_name) return self._model.catalogue_name, self._model.get_weights() def from_bytes(self, data): ops: Ops = get_current_ops() if ops.device_type == "cpu": device = "CPU" else: # pragma: no cover device = tf.test.gpu_device_name() # Plain bytes if isinstance(data, (str, bytes)): tf.keras.backend.clear_session() filelike = BytesIO(data) filelike.seek(0) with h5py.File(filelike, "r") as f: with tf.device(device): self._model = tf.keras.models.load_model(f) return # We only have to create the model if it doesn't already exist. catalogue_name, model_weights = data if self._model is None: model_fn = keras_model_fns.get(catalogue_name) tf.keras.backend.clear_session() with tf.device(device): if hasattr(self._model, "eg_args"): ak: ArgsKwargs = self._model.eg_args new_model = model_fn(*ak.args, **ak.kwargs) else: new_model = model_fn() self._model_initialized = maybe_handshake_model(new_model) self._model.set_weights(model_weights) thinc-9.0.0/thinc/shims/torchscript.py000066400000000000000000000046351461023342500200030ustar00rootroot00000000000000from io import BytesIO from typing import Any, Optional import srsly from ..compat import torch from ..util import get_torch_default_device from .pytorch import PyTorchShim from .pytorch_grad_scaler import PyTorchGradScaler class TorchScriptShim(PyTorchShim): """A Thinc shim that wraps a TorchScript module. model: The TorchScript module. A value of `None` is also possible to construct a shim to deserialize into. mixed_precision: Enable mixed-precision. This changes whitelisted ops to run in half precision for better performance and lower memory use. grad_scaler: The gradient scaler to use for mixed-precision training. If this argument is set to "None" and mixed precision is enabled, a gradient scaler with the default configuration is used. device: The PyTorch device to run the model on. When this argument is set to "None", the default device for the currently active Thinc ops is used. """ def __init__( self, model: Optional["torch.jit.ScriptModule"], config=None, optimizer: Any = None, mixed_precision: bool = False, grad_scaler: Optional[PyTorchGradScaler] = None, device: Optional["torch.device"] = None, ): if model is not None and not isinstance(model, torch.jit.ScriptModule): raise ValueError( "PyTorchScriptShim must be initialized with ScriptModule or None (for deserialization)" ) super().__init__(model, config, optimizer, mixed_precision, grad_scaler, device) def to_bytes(self): filelike = BytesIO() torch.jit.save(self._model, filelike) filelike.seek(0) model_bytes = filelike.getvalue() msg = {"config": self.cfg, "model": model_bytes} return srsly.msgpack_dumps(msg) def from_bytes(self, bytes_data): device = get_torch_default_device() msg = srsly.msgpack_loads(bytes_data) self.cfg = msg["config"] filelike = BytesIO(msg["model"]) filelike.seek(0) # As of Torch 2.0.0, loading TorchScript models directly to # an MPS device is not supported. map_location = torch.device("cpu") if device.type == "mps" else device self._model = torch.jit.load(filelike, map_location=map_location) self._model.to(device) self._grad_scaler.to_(device) return self thinc-9.0.0/thinc/tests/000077500000000000000000000000001461023342500150745ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/__init__.py000066400000000000000000000000001461023342500171730ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/backends/000077500000000000000000000000001461023342500166465ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/backends/__init__.py000066400000000000000000000000001461023342500207450ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/backends/_apple_blas/000077500000000000000000000000001461023342500211075ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/backends/_apple_blas/__init__.py000066400000000000000000000000001461023342500232060ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/backends/_apple_blas/test_gemm.py000066400000000000000000000046231461023342500234520ustar00rootroot00000000000000import numpy import pytest from thinc.compat import has_apple_ops try: import thinc.backends._accelerate as accelerate except: pass @pytest.mark.skipif(not has_apple_ops, reason="Apple ops not available") def test_basic_sgemm(): A = numpy.random.randn(5, 4).astype("f") B = numpy.random.randn(4, 7).astype("f") C = accelerate.gemm(A, B) assert C.shape == (A.shape[0], B.shape[1]) C_out = numpy.empty((5, 7), dtype="f") accelerate.gemm(A, B, out=C_out) numpy.testing.assert_allclose(C, C_out) @pytest.mark.skipif(not has_apple_ops, reason="Apple ops not available") def test_incorrect_output_size(): A = numpy.ndarray((5, 4), dtype="f") B = numpy.ndarray((4, 7), dtype="f") with pytest.raises(ValueError, match=r"Shape mismatch for output matrix"): accelerate.gemm(A, B, out=numpy.ndarray((3, 7), dtype="f")) with pytest.raises(ValueError, match=r"Shape mismatch for output matrix"): accelerate.gemm(A, B, out=numpy.ndarray((5, 3), dtype="f")) @pytest.mark.skipif(not has_apple_ops, reason="Apple ops not available") @pytest.mark.parametrize( "A_shape,B_shape,transA,transB", [ [(0, 0), (0, 0), False, False], [(0, 0), (0, 0), True, False], [(0, 0), (0, 0), False, True], [(0, 0), (0, 0), True, True], [(0, 5), (5, 0), False, False], [(5, 0), (5, 0), False, True], [(5, 0), (5, 0), True, False], ], ) def test_zero_size(A_shape, B_shape, transA, transB): A = numpy.ndarray(A_shape, dtype="f") B = numpy.ndarray(B_shape, dtype="f") if not transA and not transB: C = numpy.dot(A, B) elif transA: C = numpy.dot(A.T, B) elif transB: C = numpy.dot(A, B.T) else: C = numpy.dot(A.T, B.T) C_ = accelerate.gemm(A, B, trans1=transA, trans2=transB) assert C.shape == C_.shape @pytest.mark.skipif(not has_apple_ops, reason="Apple ops not available") @pytest.mark.parametrize( "A_shape,B_shape,transA,transB", [ [(4, 5), (4, 5), False, False], [(5, 4), (4, 5), True, False], [(4, 5), (5, 4), False, True], [(5, 4), (5, 4), True, True], ], ) def test_incorrect_shapes(A_shape, B_shape, transA, transB): A = numpy.ndarray(A_shape, dtype="f") B = numpy.ndarray(B_shape, dtype="f") with pytest.raises(ValueError, match=r"Shape mismatch"): accelerate.gemm(A, B, trans1=transA, trans2=transB) thinc-9.0.0/thinc/tests/backends/test_mem.py000066400000000000000000000005471461023342500210430ustar00rootroot00000000000000import numpy from thinc.backends._param_server import ParamServer def test_param_server_init(): array = numpy.zeros((5,), dtype="f") params = {("a", 1): array, ("b", 2): array} grads = {("a", 1): array, ("c", 3): array} ps = ParamServer(params, grads) assert ps.param_keys == (("a", 1), ("b", 2)) assert ps.grad_keys == (("a", 1),) thinc-9.0.0/thinc/tests/backends/test_mps_ops.py000066400000000000000000000006021461023342500217350ustar00rootroot00000000000000from thinc.api import NumpyOps, get_ops from thinc.compat import has_apple_ops def test_mps_ops_inherits_apple_ops(): ops = get_ops("mps") assert isinstance(ops, NumpyOps) if has_apple_ops: # We can't import AppleOps directly, because its' not # available on non-Darwin systems. assert "AppleOps" in [base.__name__ for base in type(ops).__bases__] thinc-9.0.0/thinc/tests/backends/test_ops.py000066400000000000000000001467351461023342500211000ustar00rootroot00000000000000import inspect import platform from typing import Tuple, cast import numpy import pytest from hypothesis import given, settings from hypothesis.strategies import composite, integers from numpy.testing import assert_allclose from packaging.version import Version from thinc.api import ( LSTM, CupyOps, NumpyOps, Ops, fix_random_seed, get_current_ops, get_ops, use_ops, ) from thinc.backends._custom_kernels import KERNELS, KERNELS_LIST, compile_mmh from thinc.compat import has_cupy_gpu, has_torch, torch_version from thinc.types import Floats2d from thinc.util import torch2xp, xp2torch from .. import strategies from ..strategies import arrays_BI, ndarrays_of_shape MAX_EXAMPLES = 10 VANILLA_OPS = Ops(numpy) # type:ignore NUMPY_OPS = NumpyOps() BLIS_OPS = NumpyOps(use_blis=True) CPU_OPS = [NUMPY_OPS, VANILLA_OPS] XP_OPS = [NUMPY_OPS] if has_cupy_gpu: XP_OPS.append(CupyOps()) ALL_OPS = XP_OPS + [VANILLA_OPS] FLOAT_TYPES = ["float32", "float64"] INT_TYPES = ["int32", "int64"] REDUCTIONS = ["reduce_first", "reduce_last", "reduce_max", "reduce_mean", "reduce_sum"] REDUCE_ZERO_LENGTH_RAISES = [ ("reduce_first", True), ("reduce_last", True), ("reduce_max", True), # From a mathematical perspective we'd want mean reduction to raise for # zero-length sequences, since floating point numbers are not a monoid # under averaging. However, floret relies on reduce_mean to return a # zero-vector in this case. ("reduce_mean", False), ("reduce_sum", False), ] def create_pytorch_funcs(): import math import torch def torch_relu(x): return torch.nn.functional.relu(x) def torch_relu_k(x): return torch.nn.functional.relu6(x) def torch_hard_sigmoid(x): return torch.clip(x * 0.2 + 0.5, 0, 1) def torch_hard_tanh(x): return torch.nn.functional.hardtanh(x) def torch_mish(x): return torch.nn.functional.mish(x) def torch_swish(x): return torch.nn.functional.silu(x) def torch_hard_swish(x): return x * torch_hard_sigmoid(x) def torch_hard_swish_mobilenet(x): return torch.nn.functional.hardswish(x) def torch_sigmoid(x): return torch.sigmoid(x) def torch_dish(x): return 0.5 * x * (x / (1 + x * x).sqrt() + 1) # https://github.com/huggingface/transformers/blob/master/src/transformers/activations.py#L37 def torch_gelu_approx(x): return ( 0.5 * x * ( 1.0 + torch.tanh( math.sqrt(2.0 / math.pi) * (x + 0.044715 * torch.pow(x, 3.0)) ) ) ) def torch_gelu(x): return torch.nn.functional.gelu(x) return [ ("relu", torch_relu), ("relu_k", torch_relu_k), ("hard_sigmoid", torch_hard_sigmoid), ("hard_tanh", torch_hard_tanh), ("mish", torch_mish), ("swish", torch_swish), ("hard_swish", torch_hard_swish), ("hard_swish_mobilenet", torch_hard_swish_mobilenet), ("dish", torch_dish), ("gelu_approx", torch_gelu_approx), ("gelu", torch_gelu), ("sigmoid", torch_sigmoid), ] if has_torch: TORCH_FUNCS = create_pytorch_funcs() else: TORCH_FUNCS = [] @pytest.mark.parametrize("op", [NumpyOps, CupyOps]) def test_ops_consistency(op): """Test that specific ops don't define any methods that are not on the Ops base class and that all ops methods define the exact same arguments.""" attrs = [m for m in dir(op) if not m.startswith("_")] for attr in attrs: assert hasattr(Ops, attr) method = getattr(op, attr) if hasattr(method, "__call__"): sig = inspect.signature(method) params = [p for p in sig.parameters][1:] base_sig = inspect.signature(getattr(Ops, attr)) base_params = [p for p in base_sig.parameters][1:] assert params == base_params, attr defaults = [p.default for p in sig.parameters.values()][1:] base_defaults = [p.default for p in base_sig.parameters.values()][1:] assert defaults == base_defaults, attr # If args are type annotated, their types should be the same annots = [p.annotation for p in sig.parameters.values()][1:] base_annots = [p.annotation for p in base_sig.parameters.values()][1:] for i, (p1, p2) in enumerate(zip(annots, base_annots)): if p1 != inspect.Parameter.empty and p2 != inspect.Parameter.empty: # Need to check string value to handle TypeVars etc. assert str(p1) == str(p2), attr @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.filterwarnings("ignore::RuntimeWarning") def test_adam_incorrect_inputs(ops): one = ops.xp.zeros(1, dtype="f") two = ops.xp.zeros(2, dtype="f") ops.adam(one, one, one, one, 0.0, 0.0, 0.0, 0.0) with pytest.raises(ValueError): ops.adam(two, one, one, one, 0.0, 0.0, 0.0, 0.0) with pytest.raises(ValueError): ops.adam(one, two, one, one, 0.0, 0.0, 0.0, 0.0) with pytest.raises(ValueError): ops.adam(one, one, two, one, 0.0, 0.0, 0.0, 0.0) with pytest.raises(ValueError): ops.adam(one, one, one, two, 0.0, 0.0, 0.0, 0.0) @pytest.mark.parametrize("ops", ALL_OPS) def test_alloc(ops): float_methods = (ops.alloc1f, ops.alloc2f, ops.alloc3f, ops.alloc4f) for i, method in enumerate(float_methods): shape = (1,) * (i + 1) arr = method(*shape) assert arr.dtype == numpy.float32 assert arr.ndim == len(shape) arr = ops.alloc_f(shape) assert arr.dtype == numpy.float32 assert arr.ndim == len(shape) int_methods = (ops.alloc1i, ops.alloc2i, ops.alloc3i, ops.alloc4i) for i, method in enumerate(int_methods): shape = (1,) * (i + 1) arr = method(*shape) assert arr.dtype == numpy.int32 assert arr.ndim == len(shape) arr = ops.alloc_i(shape) assert arr.dtype == numpy.int32 assert arr.ndim == len(shape) assert ops.alloc(1).ndim == 1 @pytest.mark.parametrize("ops", XP_OPS) def test_hash_gives_distinct_keys(ops): ids = ops.alloc1f(5, dtype="uint64") keys = ops.hash(ids, 0) assert keys.shape == (5, 4) assert keys.dtype == "uint32" for i in range(len(ids)): for j in range(keys.shape[1]): assert keys[i, j] != 0 @pytest.mark.parametrize("ops", XP_OPS) def test_get_dropout_empty(ops): shape = (2, 2) drop = 0.0 mask = ops.get_dropout_mask(shape, drop) if drop <= 0.0: assert mask[mask == 1.0].all() else: assert mask[mask != 1.0].all() @pytest.mark.parametrize("ops", XP_OPS) def test_get_dropout_not_empty(ops): shape = (200, 200) drop = 0.5 mask = ops.get_dropout_mask(shape, drop) assert (mask > 1.0).any() assert (mask == 0.0).any() assert mask.shape == shape @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @pytest.mark.parametrize("index_dtype", ["int32", "uint32"]) def test_gather_add(ops, dtype, index_dtype): table = ops.xp.arange(12, dtype=dtype).reshape(4, 3) indices = ops.xp.array([[0, 2], [3, 1], [0, 1]], dtype=index_dtype) gathered = ops.gather_add(table, indices) ops.xp.testing.assert_allclose( gathered, [[6.0, 8.0, 10.0], [12.0, 14.0, 16.0], [3.0, 5.0, 7.0]] ) @pytest.mark.parametrize("ops", XP_OPS) @given(table=strategies.arrays_BI()) def test_gather_add_against_numpy(ops, table): table = ops.asarray(table) indices = ops.xp.arange(100, dtype="i").reshape(25, 4) % table.shape[0] ops.xp.testing.assert_allclose( ops.gather_add(table, indices), table[indices].sum(1), atol=1e-5, ) @pytest.mark.parametrize("ops", ALL_OPS) def test_gather_add_oob_raises(ops): table = ops.xp.arange(12, dtype="f").reshape(4, 3) indices = ops.xp.array([[0, 2], [3, 1], [5, 1]], dtype="i") with pytest.raises(IndexError): ops.gather_add(table, indices) @pytest.mark.parametrize("ops", CPU_OPS) def test_seq2col_window_one_small(ops): seq = ops.asarray([[1.0], [3.0], [4.0], [5]], dtype="float32") cols = ops.seq2col(seq, 1) if hasattr(cols, "get"): cols = cols.get() assert_allclose(cols[0], [0.0, 1.0, 3.0]) assert_allclose(cols[1], [1.0, 3.0, 4.0]) assert_allclose(cols[2], [3.0, 4.0, 5.0]) assert_allclose(cols[3], [4.0, 5.0, 0.0]) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BOP()) def test_maxout(ops, dtype, X): X = ops.asarray(X, dtype=dtype) expected_best = X.max(axis=-1).astype(dtype) predicted_best, which = ops.maxout(X) assert predicted_best.dtype == dtype ops.xp.testing.assert_allclose( expected_best, predicted_best, rtol=0.001, atol=0.001 ) # Can't compare 'which' directly, as sort order might be different. # So, instead we use 'which' to extract elements from X and then # check the result against the expected output. ops.xp.testing.assert_allclose( ops.xp.take_along_axis(X, ops.xp.expand_dims(which, -1), axis=-1), ops.xp.expand_dims(expected_best, -1), atol=1e-10, ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_maxout(ops, dtype): dX = ops.backprop_maxout( ops.asarray2f([[1.0, 2.0], [3.0, 4.0]], dtype=dtype), ops.asarray2i([[1, 0], [2, 1]]), 3, ) assert dX.dtype == dtype ops.xp.testing.assert_allclose( dX, [[[0.0, 1.0, 0.0], [2.0, 0.0, 0.0]], [[0.0, 0.0, 3.0], [0.0, 4.0, 0.0]]], ) with pytest.raises(IndexError): ops.backprop_maxout( ops.asarray2f([[1.0, 2.0], [3.0, 4.0]]), ops.asarray2i([[1, 0], [3, 1]]), 3 ) @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_seq2col_window_one(ops, X): X = ops.asarray(X) base_ops = Ops() base_ops.xp = ops.xp baseX = base_ops.alloc(X.shape) + X target = base_ops.seq2col(base_ops.asarray(baseX), nW=1) predicted = ops.seq2col(X, nW=1) ops.xp.testing.assert_allclose(target, predicted, atol=0.001, rtol=0.001) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_seq2col_lengths_all_zero(ops, dtype): # Empty batch ops.xp.testing.assert_allclose( ops.alloc((0, 0), dtype=dtype), ops.seq2col( ops.alloc((0, 0), dtype=dtype), 1, lengths=ops.xp.zeros((0,), dtype="int32") ), ) ops.xp.testing.assert_allclose( ops.alloc((0, 0), dtype=dtype), ops.backprop_seq2col( ops.alloc((0, 0), dtype=dtype), 1, lengths=ops.xp.zeros((0,), dtype="int32") ), ) # Zero-length sequence ops.xp.testing.assert_allclose( ops.alloc((0, 0), dtype=dtype), ops.seq2col(ops.alloc((0, 0), dtype=dtype), 1, lengths=ops.asarray1i([0])), ) ops.xp.testing.assert_allclose( ops.alloc((0, 0), dtype=dtype), ops.backprop_seq2col( ops.alloc((0, 0), dtype=dtype), 1, lengths=ops.asarray1i([0]) ), ) # Multiple zero-length sequences ops.xp.testing.assert_allclose( ops.alloc((0, 0), dtype=dtype), ops.seq2col(ops.alloc((0, 0), dtype=dtype), 1, lengths=ops.asarray1i([0, 0])), ) ops.xp.testing.assert_allclose( ops.alloc((0, 0), dtype=dtype), ops.backprop_seq2col( ops.alloc((0, 0), dtype=dtype), 1, lengths=ops.asarray1i([0, 0]) ), ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_seq2col_lengths_zero_first_last(ops, dtype): cols_check = ops.asarray2f( [ [0, 0, 0, 1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9, 10, 11, 12], [7, 8, 9, 10, 11, 12, 13, 14, 15], [10, 11, 12, 13, 14, 15, 0, 0, 0], ], dtype=dtype, ) grad_check = ops.asarray2f( [[2, 4, 6], [12, 15, 18], [21, 24, 27], [30, 33, 36], [26, 28, 30]], dtype=dtype ) # Initial zero-length sequence ops.xp.testing.assert_allclose( cols_check, ops.seq2col( ops.xp.arange(1.0, 16.0, dtype=dtype).reshape(5, 3), 1, lengths=ops.asarray1i([0, 5]), ), ) ops.xp.testing.assert_allclose( grad_check, ops.backprop_seq2col( cols_check, 1, lengths=ops.asarray1i([0, 5]), ), ) # Final zero-length sequence. ops.xp.testing.assert_allclose( cols_check, ops.seq2col( ops.xp.arange(1.0, 16.0, dtype=dtype).reshape(5, 3), 1, lengths=ops.asarray1i([5, 0]), ), ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_seq2col_lengths_zero_between(ops, dtype): cols_check = ops.asarray2f( [ [0, 0, 0, 1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9, 10, 11, 12], [7, 8, 9, 10, 11, 12, 13, 14, 15], [10, 11, 12, 13, 14, 15, 0, 0, 0], [0, 0, 0, 16, 17, 18, 19, 20, 21], [16, 17, 18, 19, 20, 21, 0, 0, 0], ], dtype=dtype, ) grad_check = ops.asarray2f( [ [2, 4, 6], [12, 15, 18], [21, 24, 27], [30, 33, 36], [26, 28, 30], [32, 34, 36], [38, 40, 42], ], dtype=dtype, ) # Zero-length between. ops.xp.testing.assert_allclose( cols_check, ops.seq2col( ops.xp.arange(1.0, 22.0, dtype=dtype).reshape(7, 3), 1, lengths=ops.asarray1i([5, 0, 2]), ), ) ops.xp.testing.assert_allclose( grad_check, ops.backprop_seq2col( cols_check, 1, lengths=ops.asarray1i([5, 0, 2]), ), ) # Zero-length between twice. ops.xp.testing.assert_allclose( cols_check, ops.seq2col( ops.xp.arange(1.0, 22.0, dtype=dtype).reshape(7, 3), 1, lengths=ops.asarray1i([5, 0, 0, 2]), ), ) ops.xp.testing.assert_allclose( grad_check, ops.backprop_seq2col( cols_check, 1, lengths=ops.asarray1i([5, 0, 0, 2]), ), ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_seq2col_window_one_lengths(ops, dtype): X = ops.xp.arange(1.0, 16.0, dtype=dtype).reshape(5, 3) lengths = ops.asarray1i([1, 3, 1]) cols = ops.seq2col(X, 1, lengths=lengths) ops.xp.testing.assert_allclose( ops.asarray2f( [ [0, 0, 0, 1, 2, 3, 0, 0, 0], [0, 0, 0, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9, 10, 11, 12], [7, 8, 9, 10, 11, 12, 0, 0, 0], [0, 0, 0, 13, 14, 15, 0, 0, 0], ], dtype=dtype, ), cols, ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_seq2col_window_two_lengths(ops, dtype): X = ops.xp.arange(1.0, 16.0, dtype=dtype).reshape(5, 3) lengths = ops.asarray1i([1, 3, 1]) cols = ops.seq2col(X, 2, lengths=lengths) ops.xp.testing.assert_allclose( ops.asarray2f( [ [0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12], [0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0], [4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 13, 14, 15, 0, 0, 0, 0, 0, 0], ], dtype=dtype, ), cols, ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_seq2col_window_one_small(ops, dtype): cols = ops.asarray( [[0.0, 0.0, 0.0], [-1.0, 0.0, 1.0], [2.0, 0.0, 0.0]], dtype=dtype ) expected = [[-1.0], [2.0], [1.0]] seq = ops.backprop_seq2col(cols, 1) if not isinstance(seq, numpy.ndarray): seq = seq.get() assert_allclose(seq, expected, atol=0.001, rtol=0.001) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_backprop_seq2col_window_one(ops, dtype, X): if X.shape[1] % 3: return None X = ops.asarray(X, dtype=dtype) if ops.xp.abs(X).max() >= 30: return None base_ops = Ops() base_ops.xp = ops.xp target = base_ops.backprop_seq2col(X, nW=1) predicted = ops.backprop_seq2col(X, nW=1) for row in range(target.shape[0]): diff = target[row].sum() - predicted[row].sum() if diff < -0.1 or diff > 0.1: print(row, diff) print(target[row]) print(predicted[row]) ops.xp.testing.assert_allclose(target, predicted, atol=0.001, rtol=0.001) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_seq2col_window_one_lengths(ops, dtype): d_y = ops.xp.arange(0.1, 4.6, step=0.1, dtype=dtype).reshape(5, 9) lengths = ops.asarray1i([1, 3, 1]) d_seqs = ops.backprop_seq2col(d_y, 1, lengths=lengths) ops.xp.testing.assert_allclose( ops.asarray2f( [ [0.4, 0.5, 0.6], [3.2, 3.4, 3.6], [6.6, 6.9, 7.2], [5.6, 5.8, 6.0], [4.0, 4.1, 4.2], ], dtype=dtype, ), d_seqs, atol=1e-6, ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_seq2col_window_two(ops, dtype): seq = ops.asarray([[1.0], [2.0], [3.0], [4]], dtype=dtype) cols = ops.seq2col(seq, 2) if not isinstance(cols, numpy.ndarray): cols = cols.get() assert_allclose(cols[0], [0.0, 0.0, 1.0, 2.0, 3.0]) assert_allclose(cols[1], [0.0, 1.0, 2.0, 3.0, 4.0]) assert_allclose(cols[2], [1.0, 2.0, 3.0, 4.0, 0.0]) assert_allclose(cols[3], [2.0, 3.0, 4.0, 0.0, 0.0]) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_seq2col_window_two_lengths(ops, dtype): d_y = ops.xp.arange(0.1, 7.6, step=0.1, dtype=dtype).reshape(5, 15) lengths = ops.asarray1i([1, 3, 1]) d_seqs = ops.backprop_seq2col(d_y, 2, lengths=lengths) ops.xp.testing.assert_allclose( ops.asarray2f( [ [0.7, 0.8, 0.9], [10.2, 10.5, 10.8], [11.1, 11.4, 11.7], [12.0, 12.3, 12.6], [6.7, 6.8, 6.9], ], dtype=dtype, ), d_seqs, ) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_seq2col_window_two(ops, dtype): cols = ops.asarray( [ [0.0, 0.0, 1.0, 2.0, 3.0], [0.0, 1.0, 2.0, 3.0, 4.0], [1.0, 2.0, 3.0, 4.0, 0.0], [2.0, 3.0, 4.0, 0.0, 0.0], ], dtype=dtype, ) # We're summing the values that each row # was used as a feature. So row 0 had a # gradient of 1 in row 0, 1 in row 2, and # 1 in row 3. expected = ops.asarray( [ [1 + 1 + 1.0 + 0.0], [2.0 + 2.0 + 2.0 + 2.0], [3.0 + 3.0 + 3.0 + 3.0], [0.0 + 4.0 + 4.0 + 4.0], ], dtype=dtype, ) seq = ops.backprop_seq2col(cols, 2) ops.xp.testing.assert_allclose(seq, expected, atol=0.001, rtol=0.001) @pytest.mark.skipif(not has_cupy_gpu, reason="needs GPU/CuPy") @pytest.mark.parametrize("nW", [1, 2]) def test_large_seq2col_gpu_against_cpu(nW): cupy_ops = CupyOps() numpy_ops = NumpyOps() # Use array with a large enough batch to require multiple # CUDA grids. batch_size = 128 * 128 * 2 # threads per block * blocks * 2 X = numpy_ops.xp.random.randn(batch_size * 2).astype("float32").reshape(-1, 2) X_gpu = cupy_ops.asarray2f(X) # Use somewhat interesting sequence lengths. lengths = numpy_ops.asarray1i([1, 4, 2, 1] * (batch_size // 8)) lengths_gpu = cupy_ops.asarray1i(lengths) cols = numpy_ops.seq2col(X, nW=nW, lengths=lengths) cols_gpu = cupy_ops.seq2col(X_gpu, nW=nW, lengths=lengths_gpu) assert_allclose(cols, cols_gpu.get()) @pytest.mark.skipif(not has_cupy_gpu, reason="needs GPU/CuPy") @pytest.mark.parametrize("nW", [1, 2]) def test_large_backprop_seq2col_gpu_against_cpu(nW): cupy_ops = CupyOps() numpy_ops = NumpyOps() # Use array with a large enough batch to require multiple # CUDA grids. batch_size = 128 * 128 * 2 # threads per block * blocks * 2 nF = 2 * nW + 1 d_cols = ( numpy_ops.xp.random.randn(batch_size * nF).astype("float32").reshape(-1, nF) ) d_cols_gpu = cupy_ops.asarray2f(d_cols) # Use somewhat interesting sequence lengths. lengths = numpy_ops.asarray1i([1, 4, 2, 1] * (batch_size // 8)) lengths_gpu = cupy_ops.asarray1i(lengths) d_seqs = numpy_ops.backprop_seq2col(d_cols, nW=nW, lengths=lengths) d_seqs_gpu = cupy_ops.backprop_seq2col(d_cols_gpu, nW=nW, lengths=lengths_gpu) assert_allclose(d_seqs, d_seqs_gpu.get()) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_backprop_reduce_sum(ops, dtype, X): X = ops.asarray(X, dtype=dtype) if ops.xp.abs(X).max() >= 5: return None lengths = ops.asarray([3] * len(X), dtype="i") out = ops.backprop_reduce_sum(X, lengths) assert out.dtype == dtype assert out.shape == (sum(lengths), X.shape[1]) start = 0 for i, length in enumerate(lengths): ops.xp.testing.assert_allclose( out[start : start + length].sum(axis=0), X[i] * length, rtol=0.01, atol=0.01 ) start += length @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_softmax_sums_to_one(ops, X): y = ops.softmax(ops.asarray(X)) for row in y: assert 0.99999 <= row.sum() <= 1.0001 @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_softmax_works_inplace(ops, X): X = ops.asarray(X) X = ops.softmax(X, inplace=True) for row in X: assert 0.99999 <= row.sum() <= 1.00001 def torch_softmax_with_temperature( X: Floats2d, dY: Floats2d, temperature: float ) -> Tuple[Floats2d, Floats2d]: import torch Xt = xp2torch(X, requires_grad=True) dYt = xp2torch(dY) Xt_temp = Xt / temperature Yt = torch.nn.functional.softmax(Xt_temp, dim=-1) Yt.backward(dYt) return cast(Floats2d, torch2xp(Yt)), cast( Floats2d, torch2xp(cast(torch.Tensor, Xt.grad)) ) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("temperature", [0.5, 1.0, 2.0]) def test_softmax_temperature(ops, temperature): X = ops.xp.arange(-10, 10, 0.2, dtype="f").reshape(10, 10) dY = ops.xp.eye(10, dtype="f") Y = ops.softmax(X, temperature=temperature) dX = ops.backprop_softmax(Y, dY, temperature=temperature) Yt, dXt = torch_softmax_with_temperature(X, dY, temperature) ops.xp.testing.assert_allclose(Y, Yt, atol=1e-6) ops.xp.testing.assert_allclose(dX, dXt, atol=1e-6) @pytest.mark.parametrize("cpu_ops", [*CPU_OPS, BLIS_OPS]) def test_gemm_computes_correctly(cpu_ops): W = numpy.zeros((3, 2), dtype="f") X = numpy.zeros((4, 2), dtype="f") W += numpy.random.uniform(size=W.size).reshape(W.shape) X += numpy.random.uniform(size=X.size).reshape(X.shape) Y = cpu_ops.gemm(X, W, trans2=True) expected = numpy.dot(X, W.T) assert_allclose(expected, Y, atol=1e-4, rtol=1e-4) W = numpy.zeros((2, 3), dtype="f") X = numpy.zeros((2, 4), dtype="f") W += numpy.random.uniform(size=W.size).reshape(W.shape) X += numpy.random.uniform(size=X.size).reshape(X.shape) Y = cpu_ops.gemm(X, W, trans1=True) expected = numpy.dot(X.T, W) assert_allclose(expected, Y, atol=1e-4, rtol=1e-4) cpu_ops.gemm(X, W, trans1=True, out=Y) @pytest.mark.parametrize("cpu_ops", [*CPU_OPS, BLIS_OPS]) def test_gemm_out_used(cpu_ops): a = b = numpy.zeros((2, 2), dtype="f") c = numpy.ones((2, 2), dtype="f") cpu_ops.gemm(a, b, out=c) assert numpy.array_equal(c, numpy.zeros((2, 2))) @pytest.mark.parametrize("cpu_ops", CPU_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_flatten_unflatten_roundtrip(cpu_ops, X): flat = cpu_ops.flatten([x for x in X]) assert flat.ndim == 1 unflat = cpu_ops.unflatten(flat, [len(x) for x in X]) assert_allclose(X, unflat) flat2 = cpu_ops.flatten([x for x in X], pad=1, dtype="f") assert len(flat2) > len(flat) unflat2 = cpu_ops.unflatten(flat2, [len(x) for x in X], pad=1) assert_allclose(X, unflat2) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES + INT_TYPES) def test_pad(ops, dtype): X = [ops.xp.arange(1, 3, dtype=dtype), ops.xp.arange(1, 5, dtype=dtype)] ops.xp.testing.assert_allclose(ops.pad(X), [[1, 2, 0, 0], [1, 2, 3, 4]]) ops.xp.testing.assert_allclose( ops.pad(X, round_to=8), [[1, 2, 0, 0, 0, 0, 0, 0], [1, 2, 3, 4, 0, 0, 0, 0]] ) X = [ ops.xp.arange(1, 5, dtype=dtype).reshape(2, 2), ops.xp.arange(1, 9, dtype=dtype).reshape(4, 2), ] ops.xp.testing.assert_allclose( ops.pad(X), [ [[1, 2], [3, 4], [0, 0], [0, 0]], [[1, 2], [3, 4], [5, 6], [7, 8]], ], ) ops.xp.testing.assert_allclose( ops.pad(X, round_to=5), [ [[1, 2], [3, 4], [0, 0], [0, 0], [0, 0]], [[1, 2], [3, 4], [5, 6], [7, 8], [0, 0]], ], ) with pytest.raises(ValueError, match=r"Rounding for padding must at least be 1"): ops.pad(X, round_to=0) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_reduce_sum(ops, dtype): X = ops.asarray2f( [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [1.0, 2.0], [3.0, 4.0]], dtype=dtype ) lengths = ops.asarray1i([3, 2]) ops.xp.testing.assert_allclose( ops.reduce_sum(X, lengths), [[9.0, 12.0], [4.0, 6.0]] ) # Zero-length array lengths = ops.asarray1i([3, 0, 2]) ops.xp.testing.assert_allclose( ops.reduce_sum(X, lengths), [[9.0, 12.0], [0.0, 0.0], [4.0, 6.0]] ) with pytest.raises(IndexError): ops.reduce_sum(X, ops.xp.array([5, 5, 5, 5], dtype="i")) with pytest.raises(ValueError): ops.reduce_sum(X, ops.xp.array([-1, 10, 5, 5], dtype="i")) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_fails_with_incorrect_length(ops, dtype): with pytest.raises(ValueError, match=r"lengths must be"): ops.backprop_reduce_sum( ops.xp.arange(1, 7, dtype=dtype).reshape(2, 3), ops.xp.array([-1, 2], dtype="int32"), ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_reduce_first(ops, dtype): X = ops.asarray2f( [[1.0, 6.0], [2.0, 7.0], [3.0, 8.0], [4.0, 9.0], [5.0, 10.0]], dtype=dtype ) lengths = ops.asarray1i([3, 2]) Y, starts_ends = ops.reduce_first(X, lengths) ops.xp.testing.assert_array_equal(starts_ends, ops.asarray1i([0, 3, 5])) ops.xp.testing.assert_allclose(Y, [[1.0, 6.0], [4.0, 9.0]]) lengths = ops.asarray1i([3, 0, 2]) with pytest.raises(ValueError, match=r"all sequence lengths must be > 0"): ops.reduce_last(X, lengths) lengths = ops.asarray1i([3, 2, 1]) with pytest.raises(IndexError, match=r"lengths must sum up to the number of rows"): ops.reduce_last(X, lengths) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_reduce_first(ops, dtype): dY = ops.asarray2f([[1.0, 3.0], [2.0, 4.0]], dtype=dtype) starts_ends = ops.asarray1i([0, 3, 5]) dX = ops.backprop_reduce_first(dY, starts_ends) ops.xp.testing.assert_allclose( dX, [[1.0, 3.0], [0.0, 0.0], [0.0, 0.0], [2.0, 4.0], [0.0, 0.0]] ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_reduce_last(ops, dtype): X = ops.asarray2f( [[1.0, 6.0], [2.0, 7.0], [3.0, 8.0], [4.0, 9.0], [5.0, 10.0]], dtype=dtype ) lengths = ops.asarray1i([3, 2]) Y, lasts = ops.reduce_last(X, lengths) ops.xp.testing.assert_array_equal(lasts, ops.asarray1i([2, 4])) ops.xp.testing.assert_allclose(Y, [[3.0, 8.0], [5.0, 10.0]]) lengths = ops.asarray1i([3, 0, 2]) with pytest.raises(ValueError, match=r"all sequence lengths must be > 0"): ops.reduce_last(X, lengths) lengths = ops.asarray1i([3, 2, 1]) with pytest.raises(IndexError, match=r"lengths must sum up to the number of rows"): ops.reduce_last(X, lengths) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_reduce_last(ops, dtype): dY = ops.asarray2f([[1.0, 3.0], [2.0, 4.0]], dtype=dtype) lasts = ops.asarray1i([2, 4]) dX = ops.backprop_reduce_last(dY, lasts) ops.xp.testing.assert_allclose( dX, [[0.0, 0.0], [0.0, 0.0], [1.0, 3.0], [0.0, 0.0], [2.0, 4.0]] ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_reduce_max_sm(ops, dtype): X = ops.xp.zeros((6, 3), dtype=dtype) X += ops.xp.random.uniform(-1, 1, X.shape) lengths = ops.xp.array([2, 2, 2], dtype="i") maxes, which = ops.reduce_max(X, lengths) assert maxes.dtype == dtype assert ops.xp.all(which >= 0) assert ops.xp.all(which < X.shape[0]) start = 0 for i, length in enumerate(lengths): truth = X[start : start + length].max(axis=0) ops.xp.testing.assert_allclose(maxes[i], truth) start += length @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_reduce_max(ops, dtype): m = ops.xp.zeros((19, 5), dtype=dtype) m += ops.xp.random.uniform(-1, 1, m.shape) lengths = ops.xp.array([5, 5, 3, 6], dtype="i") # m[4, 0] = 1 # m[0, 1] = 2 # m[1, 3] = 3 maxes, which = ops.reduce_max(m, lengths) assert maxes.dtype == dtype assert ops.xp.all(which >= 0) assert ops.xp.all(which < m.shape[0]) start = 0 for i, length in enumerate(lengths): truth = m[start : start + length].max(axis=0) ops.xp.testing.assert_allclose(maxes[i], truth) start += length with pytest.raises(IndexError): ops.reduce_max(m, ops.xp.array([5, 5, 5, 5], dtype="i")) with pytest.raises(ValueError): ops.reduce_max(m, ops.xp.array([-1, 10, 5, 5], dtype="i")) with pytest.raises(ValueError): ops.reduce_max(m, ops.xp.array([5, 5, 0, 3, 6], dtype="i")) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_reduce_max(ops, dtype): dX = ops.backprop_reduce_max( ops.xp.arange(1, 7, dtype=dtype).reshape(2, 3), ops.xp.array([[2, 1, 0], [1, 0, 1]]).astype("int32"), ops.xp.array([3, 2], dtype="int32"), ) assert dX.dtype == dtype ops.xp.testing.assert_allclose( dX, [ [0.0, 0.0, 3.0], [0.0, 2.0, 0.0], [1.0, 0.0, 0.0], [0.0, 5.0, 0.0], [4.0, 0.0, 6.0], ], ) with pytest.raises(IndexError): ops.backprop_reduce_max( ops.xp.arange(1, 7, dtype="f").reshape(2, 3), ops.xp.array([[2, 3, 0], [1, 0, 1]]).astype("int32"), ops.xp.array([3, 2], dtype="int32"), ) with pytest.raises(ValueError): ops.backprop_reduce_max( ops.xp.arange(1, 7, dtype=dtype).reshape(2, 3), ops.xp.array([[2, 1, 0], [1, 0, 1]]).astype("int32"), ops.xp.array([-3, 2], dtype="int32"), ) with pytest.raises(ValueError): ops.backprop_reduce_max( ops.xp.arange(1, 7, dtype=dtype).reshape(2, 3), ops.xp.array([[2, 1, 0], [1, 0, 1], [1, 0, 1]]).astype("int32"), ops.xp.array([3, 0, 2], dtype="int32"), ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_reduce_mean(ops, dtype): X = ops.asarray2f( [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [1.0, 2.0], [3.0, 4.0]], dtype=dtype ) lengths = ops.asarray1i([3, 2]) ops.xp.testing.assert_allclose( ops.reduce_mean(X, lengths), [[3.0, 4.0], [2.0, 3.0]] ) # Zero-length array lengths = ops.asarray1i([3, 0, 2]) ops.xp.testing.assert_allclose( ops.reduce_mean(X, lengths), [[3.0, 4.0], [0.0, 0.0], [2.0, 3.0]] ) # Zero-length array last. X = ops.asarray2f([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=dtype) lengths = ops.asarray1i([3, 0]) ops.xp.testing.assert_allclose( ops.reduce_mean(X, lengths), [[3.0, 4.0], [0.0, 0.0]] ) with pytest.raises(IndexError): ops.reduce_mean(X, ops.xp.array([3, 3], dtype="i")) with pytest.raises(ValueError): ops.reduce_mean(X, ops.xp.array([-1, 5], dtype="i")) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) def test_backprop_reduce_mean(ops, dtype): dX = ops.backprop_reduce_mean( ops.xp.arange(1, 7, dtype=dtype).reshape(2, 3), ops.xp.array([4, 2], dtype="int32"), ) assert dX.dtype == dtype ops.xp.testing.assert_allclose( dX, [ [0.25, 0.5, 0.75], [0.25, 0.5, 0.75], [0.25, 0.5, 0.75], [0.25, 0.5, 0.75], [2.0, 2.5, 3.0], [2.0, 2.5, 3.0], ], ) with pytest.raises(ValueError, match=r"lengths must be"): ops.backprop_reduce_mean( ops.xp.arange(1, 7, dtype=dtype).reshape(2, 3), ops.xp.array([-1, 2], dtype="int32"), ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @pytest.mark.parametrize("reduction", REDUCTIONS) def test_reduce_empty_batch(ops, dtype, reduction): func = getattr(ops, reduction) backprop_func = getattr(ops, f"backprop_{reduction}") lengths = ops.asarray1i([]) Y = func(ops.alloc((0, 10), dtype=dtype), lengths) if reduction == "reduce_max": Y, which = Y dX = backprop_func(Y, which, lengths) elif isinstance(Y, tuple): Y, extra = Y dX = backprop_func(Y, extra) else: dX = backprop_func(Y, lengths) assert Y.shape == (0, 10) assert dX.shape == (0, 10) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @pytest.mark.parametrize("reduction", REDUCTIONS) def test_reduce_empty_hidden(ops, dtype, reduction): func = getattr(ops, reduction) backprop_func = getattr(ops, f"backprop_{reduction}") lengths = ops.asarray1i([2, 3]) Y = func(ops.alloc((5, 0), dtype=dtype), lengths) if reduction == "reduce_max": Y, which = Y dX = backprop_func(Y, which, lengths) elif isinstance(Y, tuple): Y, extra = Y dX = backprop_func(Y, extra) else: dX = backprop_func(Y, lengths) assert Y.shape == (2, 0) assert dX.shape == (5, 0) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @pytest.mark.parametrize("reduction_raises", REDUCE_ZERO_LENGTH_RAISES) def test_reduce_zero_seq_length(ops, dtype, reduction_raises): reduction_str, raises = reduction_raises reduction = getattr(ops, reduction_str) X = ops.asarray2f( [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [1.0, 2.0], [3.0, 4.0]], dtype=dtype ) lengths = ops.asarray1i([3, 0, 2]) if raises: with pytest.raises(ValueError): reduction(X, lengths) else: # All non-raising reductions have zero as their identity element. ops.xp.testing.assert_allclose(reduction(X, lengths)[1], [0.0, 0.0]) @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_mish(ops, X): X = ops.asarray(X) Y = ops.mish(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize("dtype", FLOAT_TYPES) @pytest.mark.parametrize( "op", [ "backprop_clipped_linear", "backprop_dish", "backprop_gelu", "backprop_gelu_approx", "backprop_hard_sigmoid", "backprop_hard_swish", "backprop_hard_swish_mobilenet", "backprop_hard_tanh", "backprop_mish", "backprop_relu", "backprop_relu_k", "backprop_softmax", "backprop_swish", ], ) def test_eltwise_backprop_rejects_incorrect_shapes(ops, dtype, op): backprop = getattr(ops, op) positional_args = [ p for p in inspect.signature(backprop).parameters.values() if p.default == inspect.Parameter.empty ] if len(positional_args) == 3: with pytest.raises(ValueError): backprop( ops.xp.zeros(10, dtype=dtype), ops.xp.zeros(5, dtype=dtype), ops.xp.zeros(10, dtype=dtype), ) with pytest.raises(ValueError): backprop( ops.xp.zeros(10, dtype=dtype), ops.xp.zeros(10, dtype=dtype), ops.xp.zeros(5, dtype=dtype), ) else: with pytest.raises(ValueError): backprop( ops.xp.arange(-10, 10, dtype=dtype), ops.xp.arange(5, -5, -1, dtype=dtype), ) @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_relu_k(ops, X): X = ops.asarray(X) Y = ops.relu_k(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() assert (Y >= 0).sum() == Y.size assert (Y <= 6.0).sum() == Y.size @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_swish(ops, X): X = ops.asarray(X) Y = ops.swish(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_hard_sigmoid(ops, X): X = ops.asarray(X) Y = ops.hard_sigmoid(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() assert (Y >= 0).sum() == Y.size assert (Y <= 1.0).sum() == Y.size @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_hard_tanh(ops, X): X = ops.asarray(X) Y = ops.hard_tanh(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() assert (Y >= -1.0).sum() == Y.size assert (Y <= 1.0).sum() == Y.size @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_hard_swish(ops, X): X = ops.asarray(X) Y = ops.hard_swish(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_hard_swish_mobilenet(ops, X): X = ops.asarray(X) Y = ops.hard_swish_mobilenet(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_gelu_approx(ops, X): X = ops.asarray(X) Y = ops.gelu_approx(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_dish(ops, X): X = ops.asarray(X) Y = ops.dish(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_gelu(ops, X): X = ops.asarray(X) Y = ops.gelu(X) assert Y.shape == X.shape assert not ops.xp.isnan(Y).any() @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(X=strategies.arrays_BI()) def test_backprop_mish(ops, X): X = ops.asarray(X) # Test zero gradients result in 0 dX zeros = ops.alloc(X.shape) dX = ops.backprop_mish(zeros, X) assert dX.shape == X.shape assert (dX == 0).all() def get_lstm_args(depth, dirs, nO, batch_size, nI, draw=None): if dirs == 1: n_params = (nO * 4) * nI + nO * 4 + nO * 4 * nO + nO * 4 for _ in range(1, depth): n_params += nO * 4 * nO + nO * 4 + nO * 4 * nO + nO * 4 else: n_params = (nO * 2) * nI + nO * 2 + nO * 2 * (nO // 2) + nO * 2 for _ in range(1, depth): n_params += nO * 2 * nO + nO * 2 + nO * 2 * (nO // 2) + nO * 2 n_params *= 2 lstm = LSTM(nO, nI, depth=depth, bi=dirs >= 2).initialize() assert lstm.get_param("LSTM").size == n_params if draw: params = draw(ndarrays_of_shape(n_params)) # For some reason this is crashing hypothesis? # size_at_t = draw(ndarrays_of_shape(shape=(batch_size,), lo=1, dtype="int32")) size_at_t = numpy.ones(shape=(batch_size,), dtype="int32") X = draw(ndarrays_of_shape((int(size_at_t.sum()), nI))) else: params = numpy.ones((n_params,), dtype="f") size_at_t = numpy.ones(shape=(batch_size,), dtype="int32") X = numpy.zeros(((int(size_at_t.sum()), nI))) H0 = numpy.zeros((depth, dirs, nO // dirs)) C0 = numpy.zeros((depth, dirs, nO // dirs)) return (params, H0, C0, X, size_at_t) @composite def draw_lstm_args(draw): depth = draw(integers(1, 4)) dirs = draw(integers(1, 2)) nO = draw(integers(1, 16)) * dirs batch_size = draw(integers(1, 6)) nI = draw(integers(1, 16)) return get_lstm_args(depth, dirs, nO, batch_size, nI, draw=draw) @pytest.mark.parametrize("ops", XP_OPS) @pytest.mark.parametrize( "depth,dirs,nO,batch_size,nI", [ (1, 1, 1, 1, 1), (1, 1, 2, 1, 1), (1, 1, 2, 1, 2), (2, 1, 1, 1, 1), (2, 1, 2, 2, 2), (1, 2, 2, 1, 1), (2, 2, 2, 2, 2), ], ) def test_lstm_forward_training(ops, depth, dirs, nO, batch_size, nI): reference_ops = Ops() params, H0, C0, X, size_at_t = get_lstm_args(depth, dirs, nO, batch_size, nI) reference = reference_ops.lstm_forward_training(params, H0, C0, X, size_at_t) Y, fwd_state = ops.lstm_forward_training(params, H0, C0, X, size_at_t) assert_allclose(fwd_state[2], reference[1][2], atol=1e-4, rtol=1e-3) assert_allclose(fwd_state[1], reference[1][1], atol=1e-4, rtol=1e-3) assert_allclose(Y, reference[0], atol=1e-4, rtol=1e-3) @pytest.mark.skipif(platform.machine() == "aarch64", reason="Flaky, skip temporarily") @pytest.mark.parametrize("ops", XP_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(args=draw_lstm_args()) def test_lstm_forward_training_fuzz(ops, args): params, H0, C0, X, size_at_t = args reference_ops = Ops() reference = reference_ops.lstm_forward_training(params, H0, C0, X, size_at_t) Y, fwd_state = ops.lstm_forward_training(params, H0, C0, X, size_at_t) assert_allclose(fwd_state[2], reference[1][2], atol=1e-4, rtol=1e-3) assert_allclose(fwd_state[1], reference[1][1], atol=1e-4, rtol=1e-3) assert_allclose(Y, reference[0], atol=1e-4, rtol=1e-3) def test_get_ops(): assert isinstance(get_ops("numpy"), NumpyOps) assert isinstance(get_ops("cupy"), CupyOps) # If Apple ops are available, "cpu" should return AppleOps or # NumpyOps otherwise. try: from thinc.backends.apple_ops import AppleOps assert isinstance(get_ops("cpu"), AppleOps) except ImportError: assert isinstance(get_ops("cpu"), NumpyOps) # If BigEndian ops are available, "cpu" should return BigEndianOps or # NumpyOps otherwise. try: from thinc_bigendian_ops import BigEndianOps assert isinstance(get_ops("cpu"), BigEndianOps) except ImportError: assert isinstance(get_ops("cpu"), NumpyOps) with pytest.raises(ValueError): get_ops("blah") ops = Ops(numpy) assert ops.xp == numpy def test_use_ops(): class_ops = get_current_ops() with use_ops("numpy"): new_ops = get_current_ops() assert new_ops.name == "numpy" with use_ops("cupy"): new_ops = get_current_ops() assert new_ops.name == "cupy" new_ops = get_current_ops() assert class_ops.name == new_ops.name def test_minibatch(): fix_random_seed(0) ops = get_current_ops() items = [1, 2, 3, 4, 5, 6] batches = ops.minibatch(3, items) assert list(batches) == [[1, 2, 3], [4, 5, 6]] batches = ops.minibatch((i for i in (3, 2, 1)), items) assert list(batches) == [[1, 2, 3], [4, 5], [6]] batches = list(ops.minibatch(3, numpy.asarray(items))) assert isinstance(batches[0], numpy.ndarray) assert numpy.array_equal(batches[0], numpy.asarray([1, 2, 3])) assert numpy.array_equal(batches[1], numpy.asarray([4, 5, 6])) batches = list(ops.minibatch((i for i in (3, 2, 1)), items, shuffle=True)) assert batches != [[1, 2, 3], [4, 5], [6]] assert len(batches[0]) == 3 assert len(batches[1]) == 2 assert len(batches[2]) == 1 with pytest.raises(ValueError): ops.minibatch(10, (i for i in range(100))) with pytest.raises(ValueError): ops.minibatch(10, True) def test_multibatch(): fix_random_seed(0) ops = get_current_ops() arr1 = numpy.asarray([1, 2, 3, 4]) arr2 = numpy.asarray([5, 6, 7, 8]) batches = list(ops.multibatch(2, arr1, arr2)) assert numpy.concatenate(batches).tolist() == [[1, 2], [5, 6], [3, 4], [7, 8]] batches = list(ops.multibatch(2, arr1, arr2, shuffle=True)) assert len(batches) == 2 assert len(batches[0]) == 2 assert len(batches[1]) == 2 batches = list(ops.multibatch(2, [1, 2, 3, 4], [5, 6, 7, 8])) assert batches == [[[1, 2], [5, 6]], [[3, 4], [7, 8]]] with pytest.raises(ValueError): ops.multibatch(10, (i for i in range(100)), (i for i in range(100))) with pytest.raises(ValueError): ops.multibatch(10, arr1, (i for i in range(100)), arr2) def test_ngrams(): ops = get_current_ops() arr1 = numpy.asarray([1, 2, 3, 4, 5], dtype=numpy.uint64) for n in range(1, 10): assert len(ops.ngrams(n, arr1)) == max(0, arr1.shape[0] - (n - 1)) assert len(ops.ngrams(-1, arr1)) == 0 assert len(ops.ngrams(arr1.shape[0] + 1, arr1)) == 0 @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.skipif(torch_version < Version("1.9.0"), reason="needs PyTorch 1.9.0") @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("dtype", ["float32", "float64"]) @pytest.mark.parametrize("torch_func", TORCH_FUNCS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given( x=strategies.floats(min_value=-30, max_value=30), dY=strategies.floats(min_value=-1, max_value=1), ) def test_compare_activations_to_torch(ops, dtype, x, dY, torch_func): import torch func_name, pytorch_func = torch_func forward = getattr(ops, func_name) backward = getattr(ops, "backprop_" + func_name) # The tolerance of isclose is set to 1e-06 instead of # the default 1e-08 due to the GELU x_thinc = ops.asarray([x], dtype=dtype) x_torch = xp2torch(x_thinc, requires_grad=True) y = pytorch_func(x_torch) y_thinc = forward(x_thinc) y.backward() assert x_thinc.dtype == y_thinc.dtype assert y_thinc is not x_thinc y_think_inplace = forward(x_thinc, inplace=True) assert y_think_inplace is x_thinc assert ops.xp.isclose(y_thinc, y_think_inplace, atol=1e-06) assert ops.xp.isclose(y_thinc, y.detach(), atol=1e-05) x_thinc = ops.asarray([x], dtype=dtype) dY_thinc = ops.asarray([dY], dtype=dtype) dY_thinc_inplace = dY_thinc.copy() s = inspect.signature(backward) params = {p for p in s.parameters if p in ["dY", "X", "Y"]} if params == {"dY", "X", "Y"}: dx_thinc = backward(dY_thinc, Y=y_thinc, X=x_thinc) assert dx_thinc.dtype == x_thinc.dtype assert dx_thinc is not dY_thinc dx_thinc_inplace = backward( dY=dY_thinc_inplace, Y=y_thinc, X=x_thinc, inplace=True ) assert dx_thinc_inplace is dY_thinc_inplace assert ops.xp.isclose(dx_thinc, dx_thinc_inplace) assert ops.xp.isclose(x_torch.grad.item() * dY, float(dx_thinc), atol=1e-06) elif params == {"Y", "dY"}: dx_thinc = backward(dY_thinc, Y=y_thinc) assert dx_thinc.dtype == x_thinc.dtype assert ops.xp.isclose( dx_thinc, backward(dY=dY_thinc_inplace, Y=y_thinc, inplace=True), ) assert ops.xp.isclose(x_torch.grad.item() * dY, float(dx_thinc), atol=1e-06) elif params == {"dY", "X"}: dx_thinc = backward(dY_thinc, X=x_thinc) assert dx_thinc.dtype == x_thinc.dtype assert ops.xp.isclose( dx_thinc, backward(dY=dY_thinc_inplace, X=x_thinc, inplace=True) ) assert ops.xp.isclose( x_torch.grad.item() * dY, float(backward(dY_thinc, X=x_thinc)), atol=1e-06 ) else: raise NotImplementedError( f"No PyTorch comparison implemented for parameter set: {params}" ) @pytest.mark.parametrize("ops", ALL_OPS) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(x=strategies.floats(min_value=-10, max_value=10)) def test_clipped_linear(ops, x): x_thinc = ops.xp.asarray([x]) assert ops.xp.isclose(ops.clipped_linear(x_thinc, max_val=6.0), ops.relu_k(x_thinc)) assert ops.xp.isclose( ops.backprop_clipped_linear(ops.asarray1f([1.0]), x_thinc, max_val=6.0), ops.backprop_relu_k(ops.asarray1f([1.0]), x_thinc), ) assert ops.xp.isclose( ops.clipped_linear(x_thinc, slope=0.2, offset=0.5), ops.hard_sigmoid(x_thinc) ) assert ops.xp.isclose( ops.backprop_clipped_linear( ops.asarray1f([1.0]), x_thinc, slope=0.2, offset=0.5 ), ops.backprop_hard_sigmoid(ops.asarray1f([1.0]), x_thinc), ) @pytest.mark.parametrize("ops", ALL_OPS) @pytest.mark.parametrize("byte_order", (">", "<", "=", "|")) @settings(max_examples=MAX_EXAMPLES, deadline=None) @given(x=strategies.floats(min_value=-10, max_value=10)) def test_to_numpy_byteorder(ops, byte_order, x): x = ops.xp.asarray([x]) y = ops.to_numpy(x, byte_order=byte_order) assert numpy.array_equal(ops.to_numpy(x), ops.to_numpy(y)) if byte_order in (">", "<"): # hack from: https://stackoverflow.com/a/49740663 assert y.dtype.newbyteorder("S").newbyteorder("S").byteorder == byte_order else: assert x.dtype.byteorder == y.dtype.byteorder @pytest.mark.skipif(not has_cupy_gpu, reason="needs GPU/CuPy") def test_custom_kernel_compilation(): for kernel_name in KERNELS_LIST: compiled_kernel = KERNELS.get_function(kernel_name) assert compiled_kernel is not None assert compile_mmh() is not None @pytest.mark.parametrize("ops", ALL_OPS) def test_asarray_from_list_uint64(ops): # list contains int values both above and below int64.max uint64_list = [16, 11648197037703959513] assert uint64_list == list(ops.asarray(uint64_list, dtype="uint64")) thinc-9.0.0/thinc/tests/conftest.py000066400000000000000000000042411461023342500172740ustar00rootroot00000000000000import pytest from hypothesis import settings # Functionally disable deadline settings for tests # to prevent spurious test failures in CI builds. settings.register_profile("no_deadlines", deadline=2 * 60 * 1000) # in ms settings.load_profile("no_deadlines") def pytest_sessionstart(session): # If Tensorflow is installed, attempt to enable memory growth # to prevent it from allocating all of the GPU's free memory # to its internal memory pool(s). try: import tensorflow as tf physical_devices = tf.config.list_physical_devices("GPU") for device in physical_devices: try: tf.config.experimental.set_memory_growth(device, True) except: # Invalid device or cannot modify virtual devices once initialized. print(f"failed to enable Tensorflow memory growth on {device}") except ImportError: pass def pytest_addoption(parser): try: parser.addoption("--slow", action="store_true", help="include slow tests") # Options are already added, e.g. if conftest is copied in a build pipeline # and runs twice except ValueError: pass def pytest_runtest_setup(item): def getopt(opt): # When using 'pytest --pyargs thinc' to test an installed copy of # thinc, pytest skips running our pytest_addoption() hook. Later, when # we call getoption(), pytest raises an error, because it doesn't # recognize the option we're asking about. To avoid this, we need to # pass a default value. We default to False, i.e., we act like all the # options weren't given. return item.config.getoption(f"--{opt}", False) for opt in ["slow"]: if opt in item.keywords and not getopt(opt): pytest.skip(f"need --{opt} option to run") @pytest.fixture() def pathy_fixture(): pytest.importorskip("pathy") import shutil import tempfile from pathy import Pathy, use_fs temp_folder = tempfile.mkdtemp(prefix="thinc-pathy") use_fs(temp_folder) root = Pathy("gs://test-bucket") root.mkdir(exist_ok=True) yield root use_fs(False) shutil.rmtree(temp_folder) thinc-9.0.0/thinc/tests/enable_mxnet.py000066400000000000000000000001341461023342500201050ustar00rootroot00000000000000from thinc.compat import enable_mxnet try: enable_mxnet() except ImportError: pass thinc-9.0.0/thinc/tests/enable_tensorflow.py000066400000000000000000000001461461023342500211570ustar00rootroot00000000000000from thinc.compat import enable_tensorflow try: enable_tensorflow() except ImportError: pass thinc-9.0.0/thinc/tests/layers/000077500000000000000000000000001461023342500163735ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/layers/__init__.py000066400000000000000000000000001461023342500204720ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/layers/test_basic_tagger.py000066400000000000000000000045761461023342500224320ustar00rootroot00000000000000import random import pytest from thinc.api import ( Adam, HashEmbed, Model, Relu, Softmax, chain, expand_window, strings2arrays, with_array, ) @pytest.fixture(scope="module") def ancora(): pytest.importorskip("ml_datasets") import ml_datasets return ml_datasets.ud_ancora_pos_tags() def create_embed_relu_relu_softmax(depth, width, vector_length): with Model.define_operators({">>": chain}): model = strings2arrays() >> with_array( HashEmbed(width, vector_length, column=0) >> expand_window(window_size=1) >> Relu(width, width * 3) >> Relu(width, width) >> Softmax(17, width) ) return model @pytest.fixture(params=[create_embed_relu_relu_softmax]) def create_model(request): return request.param def evaluate_tagger(model, dev_X, dev_Y, batch_size): correct = 0.0 total = 0.0 for i in range(0, len(dev_X), batch_size): Yh = model.predict(dev_X[i : i + batch_size]) Y = dev_Y[i : i + batch_size] for j in range(len(Yh)): correct += (Yh[j].argmax(axis=1) == Y[j].argmax(axis=1)).sum() total += Yh[j].shape[0] return correct / total def get_shuffled_batches(Xs, Ys, batch_size): zipped = list(zip(Xs, Ys)) random.shuffle(zipped) for i in range(0, len(zipped), batch_size): batch_X, batch_Y = zip(*zipped[i : i + batch_size]) yield list(batch_X), list(batch_Y) @pytest.mark.parametrize( ("depth", "width", "vector_width", "nb_epoch"), [(2, 32, 16, 5)] ) def test_small_end_to_end(depth, width, vector_width, nb_epoch, create_model, ancora): (train_X, train_Y), (dev_X, dev_Y) = ancora batch_size = 8 model = create_model(depth, width, vector_width).initialize() optimizer = Adam(0.001) losses = [] scores = [] for _ in range(nb_epoch): losses.append(0.0) for X, Y in get_shuffled_batches(train_X, train_Y, batch_size): Yh, backprop = model.begin_update(X) d_loss = [] for i in range(len(Yh)): d_loss.append(Yh[i] - Y[i]) losses[-1] += ((Yh[i] - Y[i]) ** 2).sum() backprop(d_loss) model.finish_update(optimizer) scores.append(evaluate_tagger(model, dev_X, dev_Y, batch_size)) assert losses[-1] < losses[0] assert scores[-1] > scores[0] thinc-9.0.0/thinc/tests/layers/test_combinators.py000066400000000000000000000172241461023342500223320ustar00rootroot00000000000000import numpy import pytest from numpy.testing import assert_allclose from thinc.api import ( Dropout, Linear, Model, NumpyOps, add, clone, concatenate, map_list, noop, ) from thinc.layers import chain, tuplify @pytest.fixture(params=[1, 2, 9]) def nB(request): return request.param @pytest.fixture(params=[1, 6]) def nI(request): return request.param @pytest.fixture(params=[1, 5, 3]) def nH(request): return request.param @pytest.fixture(params=[1, 2, 7, 9]) def nO(request): return request.param @pytest.fixture def model1(nH, nI): return Linear(nH, nI) @pytest.fixture def model2(nO, nH): return Linear(nO, nH) @pytest.fixture def model3(nO): return Linear(nO, nO) def test_tuplify_zero(): with pytest.raises(TypeError): tuplify() def test_tuplify_one(model1): with pytest.raises(TypeError): tuplify(model1) def test_tuplify_two(model1, model2): model = tuplify(model1, model2) assert len(model.layers) == 2 def test_tuplify_operator_two(model1, model2): with Model.define_operators({"&": tuplify}): model = model1 & model2 assert len(model.layers) == 2 def test_tuplify_dulicates_input(): model = tuplify(noop(), noop()) ones = numpy.ones([10]) out = model.predict(ones) assert out == (ones, ones) def test_tuplify_initialize(nI, nO): linear = Linear(nO) model = tuplify(linear, linear) ones = numpy.ones((1, nI), dtype="float") model.initialize(X=ones) def test_tuplify_three(model1, model2, model3): model = tuplify(model1, model2, model3) assert len(model.layers) == 3 def test_tuplify_operator_three(model1, model2, model3): # Previously we 'flattened' these nested calls. We might opt to do so # again, especially for the operators. with Model.define_operators({"&": tuplify}): model = model1 & model2 & model3 assert len(model.layers) == 2 assert len(model.layers[0].layers) == 2 def test_chain_zero(): with pytest.raises(TypeError): chain() def test_chain_one(model1): with pytest.raises(TypeError): chain(model1) def test_chain_two(model1, model2): model = chain(model1, model2) assert len(model.layers) == 2 def test_chain_operator_two(model1, model2): with Model.define_operators({">>": chain}): model = model1 >> model2 assert len(model.layers) == 2 def test_chain_three(model1, model2, model3): model = chain(model1, model2, model3) assert len(model.layers) == 3 def test_chain_operator_three(model1, model2, model3): # Previously we 'flattened' these nested calls. We might opt to do so # again, especially for the operators. with Model.define_operators({">>": chain}): model = model1 >> model2 >> model3 assert len(model.layers) == 2 assert len(model.layers[0].layers) == 2 def test_chain_right_branch(model1, model2, model3): # Previously we 'flattened' these nested calls. We might opt to do so # again, especially for the operators. merge1 = chain(model1, model2) merge2 = chain(merge1, model3) assert len(merge1.layers) == 2 assert len(merge2.layers) == 2 @pytest.mark.parametrize("ops", [NumpyOps(), NumpyOps(use_blis=True)]) def test_chain(ops): data = numpy.asarray([[1, 2, 3, 4]], dtype="f") model = chain(Linear(1), Dropout(), Linear(1)) model.ops = ops model.initialize(data, data) Y, backprop = model(data, is_train=True) backprop(Y) # Layers with and without nO/nI model = chain(Linear(1), Dropout(), Linear(1, 1)) model.initialize(data, data) # Setting dim on model model = chain(Linear(1), Dropout(), Linear(1)) model.set_dim("nO", 1) model.initialize(data, None) model = chain(Linear(1, 1), Dropout(), Linear(1, 1)) model.set_dim("nI", 1) model.initialize(None, data) # Not enough arguments with pytest.raises(TypeError): chain(Linear()) with pytest.raises(TypeError): chain() def test_concatenate_one(model1): model = concatenate(model1) assert isinstance(model, Model) def test_concatenate_two(model1, model2): model = concatenate(model1, model2) assert len(model.layers) == 2 def test_concatenate_operator_two(model1, model2): with Model.define_operators({"|": concatenate}): model = model1 | model2 assert len(model.layers) == 2 def test_concatenate_three(model1, model2, model3): model = concatenate(model1, model2, model3) assert len(model.layers) == 3 def test_concatenate_operator_three(model1, model2, model3): with Model.define_operators({"|": concatenate}): model = model1 | model2 | model3 assert len(model.layers) == 3 def test_clone_changes_predictions(nH, nI): model1 = Linear(nH) model = clone(model1, 10) ones = numpy.ones((10, nI), dtype="f") model.initialize(X=ones) output_from_cloned = model.predict(ones) output_from_orig = model1.predict(ones) assert output_from_cloned.sum() != output_from_orig.sum() def test_clone_gives_distinct_ids(nH, nI): model = clone(Linear(nH), 5) assert len(model.layers) == 5 seen_ids = set() for node in model.walk(): assert node.id not in seen_ids seen_ids.add(node.id) assert len(seen_ids) == 6 def test_clone_noop(): model = clone(Linear(), 0) assert len(model.layers) == 0 assert model.name == "noop" def test_concatenate_noop(): model = concatenate() assert len(model.layers) == 0 assert model.name == "noop" def test_noop(): data = numpy.asarray([1, 2, 3], dtype="f") model = noop(Linear(), Linear()) model.initialize(data, data) Y, backprop = model(data, is_train=True) assert numpy.array_equal(Y, data) dX = backprop(Y) assert numpy.array_equal(dX, data) def test_add(): data = numpy.asarray([[1, 2, 3, 4]], dtype="f") model = add(Linear(), Linear()) model.initialize(data, data) Y, backprop = model(data, is_train=True) Y2 = sum(layer.predict(data) for layer in model.layers) assert numpy.array_equal(Y, Y2) dX = backprop(Y) assert dX.shape == data.shape # Test that nesting works model2 = add(model, Linear()) assert len(model2.layers) == 3 model.initialize(data, data) Y = model2.predict(data) Y2 = sum(layer.predict(data) for layer in model2.layers) assert numpy.array_equal(Y, Y2) def test_add_edge_cases(): data = numpy.asarray([[1, 2, 3, 4]], dtype="f") with pytest.raises(TypeError): add() model = add(Linear(), Linear()) model._layers = [] Y, backprop = model(data, is_train=True) assert numpy.array_equal(data, Y) dX = backprop(Y) assert numpy.array_equal(dX, data) def test_concatenate(): data = numpy.asarray([[1, 2, 3], [4, 5, 6]], dtype="f") model = concatenate(Linear(), Linear()) model.initialize(data, data) Y, backprop = model(data, is_train=True) assert Y.shape[1] == sum([layer.predict(data).shape[1] for layer in model.layers]) dX = backprop(Y) assert dX.shape == data.shape def test_map_list(): nI = 4 nO = 9 Xs = [numpy.zeros((6, nI), dtype="f"), numpy.ones((3, nI), dtype="f")] Y_shapes = [(x.shape[0], nO) for x in Xs] model = map_list(Linear()) model.initialize(X=Xs, Y=[numpy.zeros(shape, dtype="f") for shape in Y_shapes]) Ys, backprop = model(Xs, is_train=True) assert isinstance(Ys, list) assert len(Ys) == len(Xs) layer = model.layers[0] for X, Y in zip(Xs, Ys): assert_allclose(layer.predict(X), Y) dXs = backprop(Ys) assert isinstance(dXs, list) assert len(dXs) == len(Xs) assert dXs[0].shape == Xs[0].shape assert dXs[1].shape == Xs[1].shape thinc-9.0.0/thinc/tests/layers/test_feed_forward.py000066400000000000000000000125011461023342500224320ustar00rootroot00000000000000from functools import partial import numpy import pytest from numpy.testing import assert_allclose from thinc.api import Linear, NumpyOps, Relu, chain @pytest.fixture(params=[1, 2, 9]) def nB(request): return request.param @pytest.fixture(params=[1, 6]) def nI(request): return request.param @pytest.fixture(params=[1, 5, 3]) def nH(request): return request.param @pytest.fixture(params=[1, 2, 7, 9]) def nO(request): return request.param @pytest.fixture def model1(nH, nI): model = Relu(nH, nI).initialize() return model @pytest.fixture def model2(nO, nH): model = Linear(nO, nH).initialize() return model @pytest.fixture def input_data(nB, nI): return numpy.ones((nB, nI), dtype="f") + 1.0 @pytest.fixture def gradient_data(nB, nO): return numpy.zeros((nB, nO), dtype="f") - 1.0 @pytest.fixture def model(model1, model2): return chain(model1, model2).initialize() def get_expected_predict(input_data, Ws, bs): numpy_ops = NumpyOps() X = input_data for i, (W, b) in enumerate(zip(Ws, bs)): X = numpy_ops.asarray(X) if i > 0: X *= X > 0 X = numpy.tensordot(X, W, axes=[[1], [1]]) + b return X def numeric_gradient(predict, weights, epsilon=1e-4): out1 = predict(weights + epsilon) out2 = predict(weights - epsilon) return (out1 - out2) / (2 * epsilon) def test_models_have_shape(model1, model2, nI, nH, nO): assert model1.get_param("W").shape == (nH, nI) assert model1.get_param("b").shape == (nH,) assert model2.get_param("W").shape == (nO, nH) assert model2.get_param("b").shape == (nO,) def test_model_shape(model, model1, model2, nI, nH, nO): assert model.get_dim("nI") == model1.get_dim("nI") assert model.get_dim("nO") == model2.get_dim("nO") def test_infer_output_shape(): model = Relu(dropout=0.2) X = model.ops.alloc2f(4, 5) Y = model.ops.alloc2f(4, 2) assert model.has_dim("nI") is None assert model.has_dim("nO") is None model.initialize(X=X, Y=Y) assert model.get_dim("nI") == 5 assert model.get_dim("nO") == 2 def test_predict_and_begin_update_match(model, model1, model2, input_data): model = chain(model1, model2) via_predict = model.predict(input_data) via_update, _ = model.begin_update(input_data) assert_allclose(via_predict, via_update) expected = get_expected_predict( input_data, [model1.get_param("W"), model2.get_param("W")], [model1.get_param("b"), model2.get_param("b")], ) assert_allclose(via_update, expected, atol=1e-2, rtol=1e-4) def test_init_functions_are_called(): init_was_called = {} def register_init(name, model, X=None, Y=None): init_was_called[name] = True layer1 = Linear(5) layer2 = Linear(5) layer3 = Linear(5) layer1.init = partial(register_init, "one") layer2.init = partial(register_init, "two") layer3.init = partial(register_init, "three") # This is the nesting we'll get from operators. model = chain(layer1, chain(layer2, layer3)) assert not init_was_called model.initialize() assert init_was_called["one"] assert init_was_called["two"] assert init_was_called["three"] class GradientSpy(object): def __init__(self): self.weights = None self.d_weights = None def __call__(self, weights, grad): self.weights = weights self.d_weights = grad # I don't know how to get this working properly after the refactor. It's a numeric # gradient check. I suspect the test is the problem, not the code. @pytest.mark.skip # This is the actual definition -- it's just annoying to see tonnes of skips. # def test_gradient(model, input_data, nB, nH, nI, nO): def test_gradient(): truth = numpy.zeros((nB, nO), dtype="float32") truth[0] = 1.0 guess, backprop = model.begin_update(input_data) backprop(guess - truth) for layer in model.layers: for name in layer.param_names: agrad = layer.get_grad(name).ravel() # Should have grads for all params. predict = get_predict(layer, name, input_data) ngrad = get_numeric_gradient(predict, agrad.size, truth) assert_allclose(agrad, ngrad, atol=0.2, rtol=0.2) def get_predict(layer, param_name, inputs): """Helper for gradient check. To do the numeric gradient check, we have to be able to wiggle one value in a parameter, and check the prediction before and after. So we need to get a callback that gives an output given a change to one weight. """ def predict(i, epsilon): param = layer.get_param(param_name) shape = param.shape param = param.ravel() param[i] += epsilon layer.set_param(param_name, param.reshape(shape)) outputs = layer.predict(inputs) param[i] -= epsilon layer.set_param(param_name, param.reshape(shape)) return outputs.reshape(shape) return predict def get_numeric_gradient(predict, n, target): gradient = numpy.zeros(n) for i in range(n): out1 = predict(i, 1e-4) out2 = predict(i, -1e-4) err1 = _get_loss(out1, target) err2 = _get_loss(out2, target) gradient[i] = (err1 - err2) / (2 * 1e-4) print("NGrad", i, err1, err2) return gradient def _get_loss(truth, guess): return numpy.sum(numpy.sum(0.5 * numpy.square(truth - guess), 1)) thinc-9.0.0/thinc/tests/layers/test_hash_embed.py000066400000000000000000000010251461023342500220610ustar00rootroot00000000000000import numpy from thinc.api import HashEmbed def test_init(): model = HashEmbed(64, 1000).initialize() assert model.get_dim("nV") == 1000 assert model.get_dim("nO") == 64 assert model.get_param("E").shape == (1000, 64) def test_seed_changes_bucket(): model1 = HashEmbed(64, 1000, seed=2).initialize() model2 = HashEmbed(64, 1000, seed=1).initialize() arr = numpy.ones((1,), dtype="uint64") vector1 = model1.predict(arr) vector2 = model2.predict(arr) assert vector1.sum() != vector2.sum() thinc-9.0.0/thinc/tests/layers/test_layers_api.py000066400000000000000000000233661461023342500221460ustar00rootroot00000000000000from typing import List, Optional import numpy import pytest import srsly from numpy.testing import assert_almost_equal from thinc.api import Dropout, Model, NumpyOps, registry, with_padded from thinc.backends import NumpyOps from thinc.compat import has_torch from thinc.types import Array2d, Floats2d, FloatsXd, Padded, Ragged, Shape from thinc.util import data_validation, get_width OPS = NumpyOps() class NoDropoutOps(NumpyOps): def get_dropout_mask(self, shape: Shape, drop: Optional[float]) -> FloatsXd: if drop is None or drop <= 0: return self.xp.ones(shape, dtype="f") else: raise ValueError("During prediction, dropout should not be applied") array1d = OPS.xp.asarray([1, 2, 3], dtype="f") array1dint = OPS.xp.asarray([1, 2, 3], dtype="i") array2d = OPS.xp.asarray([[4, 2, 3, 4], [1, 5, 3, 1], [9, 8, 5, 7]], dtype="f") array2dint = OPS.xp.asarray([[1, 2, 3], [4, 5, 6]], dtype="i") array3d = OPS.xp.zeros((3, 3, 3), dtype="f") ragged = Ragged(array2d, OPS.xp.asarray([2, 1], dtype="i")) padded = Padded( array3d, array1d, OPS.asarray1i([1, 2, 3, 4]), OPS.asarray1i([1, 2, 3, 4]) ) width = array2d.shape[1] vectors = numpy.zeros((array2dint.max(), 1), dtype="f") def assert_data_match(Y, out_data): assert type(Y) == type(out_data) if isinstance(out_data, OPS.xp.ndarray): assert isinstance(Y, OPS.xp.ndarray) assert out_data.ndim == Y.ndim elif isinstance(out_data, Ragged): assert isinstance(Y, Ragged) assert out_data.data.ndim == Y.data.ndim assert out_data.lengths.ndim == Y.lengths.ndim elif isinstance(out_data, Padded): assert isinstance(Y, Padded) assert out_data.data.ndim == Y.data.ndim assert out_data.size_at_t.ndim == Y.size_at_t.ndim assert len(out_data.lengths) == len(Y.lengths) assert len(out_data.indices) == len(Y.indices) elif isinstance(out_data, (list, tuple)): assert isinstance(Y, (list, tuple)) assert all(isinstance(x, numpy.ndarray) for x in Y) else: pytest.fail(f"wrong output of {type(Y)}: {Y}") TEST_CASES_SUMMABLE = [ # Array to array ("Dish.v1", {}, array2d, array2d), ("Dish.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("Dropout.v1", {}, array2d, array2d), ("LayerNorm.v1", {}, array2d, array2d), ("Linear.v1", {}, array2d, array2d), ("Logistic.v1", {}, array2d, array2d), ("Maxout.v1", {}, array2d, array2d), ("Maxout.v1", {"normalize": True, "dropout": 0.2}, array2d, array2d), ("Maxout.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("Mish.v1", {}, array2d, array2d), ("Mish.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("Mish.v1", {"normalize": True, "dropout": 0.2}, array2d, array2d), ("Relu.v1", {}, array2d, array2d), ("Relu.v1", {"normalize": True, "dropout": 0.2}, array2d, array2d), ("Sigmoid.v1", {}, array2d, array2d), ("Sigmoid.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("ClippedLinear.v1", {}, array2d, array2d), ("ClippedLinear.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("ReluK.v1", {}, array2d, array2d), ("ReluK.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("HardSigmoid.v1", {}, array2d, array2d), ("HardSigmoid.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("HardTanh.v1", {}, array2d, array2d), ("HardTanh.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("HardSwish.v1", {}, array2d, array2d), ("HardSwish.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("HardSwishMobilenet.v1", {}, array2d, array2d), ("HardSwishMobilenet.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("Swish.v1", {}, array2d, array2d), ("Swish.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("Gelu.v1", {}, array2d, array2d), ("Gelu.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("sigmoid_activation.v1", {}, array2d, array2d), ("softmax_activation.v1", {}, array2d, array2d), ("Softmax.v1", {}, array2d, array2d), ("Softmax.v1", {"nO": 4, "nI": 4}, array2d, array2d), ("Softmax.v2", {}, array2d, array2d), ("Softmax.v2", {"nO": 4, "nI": 4}, array2d, array2d), # fmt: off # List to list ("LSTM.v1", {"bi": False}, [array2d, array2d], [array2d, array2d]), pytest.param("PyTorchLSTM.v1", {"bi": False, "nO": width, "nI": width}, [array2d, array2d], [array2d, array2d], marks=pytest.mark.skipif(not has_torch, reason="needs PyTorch")), # fmt: on ] TEST_CASES = [ *TEST_CASES_SUMMABLE, pytest.param( "PyTorchLSTM.v1", {"bi": True, "nO": width * 2, "nI": width}, [array2d, array2d], [array2d, array2d], marks=pytest.mark.skipif(not has_torch, reason="needs PyTorch"), ), ("LSTM.v1", {"bi": True}, [array2d, array2d], [array2d, array2d]), # Ragged to array ("reduce_max.v1", {}, ragged, array2d), ("reduce_mean.v1", {}, ragged, array2d), ("reduce_sum.v1", {}, ragged, array2d), # fmt: off # Other ("expand_window.v1", {}, array2d, array2d), ("expand_window.v1", {}, ragged, ragged), ("Embed.v1", {"nO": 4, "nV": int(array2dint.max() + 1), "column": 0, "dropout": 0.2}, array2dint, array2d), ("Embed.v1", {"nO": 4, "nV": int(array1dint.max() + 1)}, array1dint, array2d), ("HashEmbed.v1", {"nO": 1, "nV": int(array2dint.max()), "column": 0, "dropout": 0.2}, array2dint, array2d), ("HashEmbed.v1", {"nO": 1, "nV": 2}, array1dint, array2d), ("MultiSoftmax.v1", {"nOs": (1, 3)}, array2d, array2d), # ("CauchySimilarity.v1", {}, (array2d, array2d), array1d), ("ParametricAttention.v1", {}, ragged, ragged), ("ParametricAttention.v2", {}, ragged, ragged), ("ParametricAttention.v2", {"key_transform": {"@layers": "Gelu.v1"}}, ragged, ragged), ("SparseLinear.v1", {}, (numpy.asarray([1, 2, 3], dtype="uint64"), array1d, numpy.asarray([1, 1], dtype="i")), array2d), ("SparseLinear.v2", {}, (numpy.asarray([1, 2, 3], dtype="uint64"), array1d, numpy.asarray([1, 1], dtype="i")), array2d), ("remap_ids.v1", {"dtype": "f"}, ["a", 1, 5.0], array2dint), ("remap_ids.v2", {"mapping_table": {}, "column": 1}, numpy.array([[1, 2, 3], [4, 5, 6]]).T, array2dint), ("premap_ids.v1", {"mapping_table": {}, "column": 1}, numpy.array([[1, 2, 3], [4, 5, 6]]).T, array2dint), # fmt: on ] @pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES) def test_layers_from_config(name, kwargs, in_data, out_data): cfg = {"@layers": name, **kwargs} filled_cfg = registry.fill({"config": cfg}) assert srsly.is_json_serializable(filled_cfg) model = registry.resolve({"config": cfg})["config"] if "LSTM" in name: model = with_padded(model) valid = True with data_validation(valid): model.initialize(in_data, out_data) Y, backprop = model(in_data, is_train=True) if model.has_dim("nO"): assert get_width(Y) == model.get_dim("nO") assert_data_match(Y, out_data) dX = backprop(Y) assert_data_match(dX, in_data) # Test that during predictions, no dropout is applied model._to_ops(NoDropoutOps()) model.predict(in_data) @pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES_SUMMABLE) def test_layers_with_residual(name, kwargs, in_data, out_data): cfg = {"@layers": "residual.v1", "layer": {"@layers": name, **kwargs}} model = registry.resolve({"config": cfg})["config"] if "LSTM" in name: model = with_padded(model) model.initialize(in_data, out_data) Y, backprop = model(in_data, is_train=True) assert_data_match(Y, out_data) dX = backprop(Y) assert_data_match(dX, in_data) @pytest.mark.parametrize("data", [array2d, ragged, padded, [array2d, array2d]]) def test_dropout(data): model = Dropout(0.2) model.initialize(data, data) Y, backprop = model(data, is_train=False) assert_data_match(Y, data) dX = backprop(Y) assert_data_match(dX, data) @pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES) def test_layers_batching_all(name, kwargs, in_data, out_data): cfg = {"@layers": name, **kwargs} model = registry.resolve({"config": cfg})["config"] if "expand_window" in name: return if "LSTM" in name: model = with_padded(model) util_batch_unbatch_list(model, in_data, out_data) else: if isinstance(in_data, OPS.xp.ndarray) and in_data.ndim == 2: if isinstance(out_data, OPS.xp.ndarray) and out_data.ndim == 2: util_batch_unbatch_array(model, in_data, out_data) if isinstance(in_data, Ragged): if isinstance(out_data, OPS.xp.ndarray) and out_data.ndim == 2: util_batch_unbatch_ragged(model, in_data, out_data) def util_batch_unbatch_array( model: Model[Floats2d, Array2d], in_data: Floats2d, out_data: Array2d ): unbatched = [model.ops.reshape2f(a, 1, -1) for a in in_data] with data_validation(True): model.initialize(in_data, out_data) Y_batched = model.predict(in_data).tolist() Y_not_batched = [model.predict(u)[0].tolist() for u in unbatched] assert_almost_equal(Y_batched, Y_not_batched, decimal=4) def util_batch_unbatch_list( model: Model[List[Array2d], List[Array2d]], in_data: List[Array2d], out_data: List[Array2d], ): with data_validation(True): model.initialize(in_data, out_data) Y_batched = model.predict(in_data) Y_not_batched = [model.predict([u])[0] for u in in_data] assert_almost_equal(Y_batched, Y_not_batched, decimal=4) # type: ignore def util_batch_unbatch_ragged( model: Model[Ragged, Array2d], in_data: Ragged, out_data: Array2d ): with data_validation(True): model.initialize(in_data, out_data) Y_batched = model.predict(in_data) Y_not_batched = [model.predict(in_data[i])[0] for i in range(len(in_data))] assert_almost_equal(Y_batched, Y_not_batched, decimal=4) # type: ignore thinc-9.0.0/thinc/tests/layers/test_linear.py000066400000000000000000000162561461023342500212700ustar00rootroot00000000000000import numpy import pytest from hypothesis import given, settings from mock import MagicMock from numpy.testing import assert_allclose from thinc.api import SGD, Dropout, Linear, chain from ..strategies import arrays_OI_O_BI from ..util import get_model, get_shape @pytest.fixture def model(): model = Linear() return model def test_linear_default_name(model): assert model.name == "linear" def test_linear_dimensions_on_data(): X = MagicMock(shape=(5, 10), spec=numpy.ndarray) X.ndim = 2 X.dtype = "float32" y = MagicMock(shape=(8,), spec=numpy.ndarray) y.ndim = 2 y.dtype = "float32" y.max = MagicMock() model = Linear() model.initialize(X, y) assert model.get_dim("nI") is not None y.max.assert_called_with() @given(arrays_OI_O_BI(max_batch=8, max_out=8, max_in=8)) def test_begin_update_matches_predict(W_b_input): model = get_model(W_b_input) nr_batch, nr_out, nr_in = get_shape(W_b_input) W, b, input_ = W_b_input fwd_via_begin_update, finish_update = model.begin_update(input_) fwd_via_predict_batch = model.predict(input_) assert_allclose(fwd_via_begin_update, fwd_via_predict_batch) @given(arrays_OI_O_BI(max_batch=8, max_out=8, max_in=8)) def test_finish_update_calls_optimizer_with_weights(W_b_input): model = get_model(W_b_input) nr_batch, nr_out, nr_in = get_shape(W_b_input) W, b, input_ = W_b_input output, finish_update = model.begin_update(input_) seen_keys = set() def sgd(key, data, gradient, **kwargs): seen_keys.add(key) assert data.shape == gradient.shape return data, gradient grad_BO = numpy.ones((nr_batch, nr_out), dtype="f") grad_BI = finish_update(grad_BO) # noqa: F841 model.finish_update(sgd) for name in model.param_names: assert (model.id, name) in seen_keys @settings(max_examples=100) @given(arrays_OI_O_BI(max_batch=8, max_out=8, max_in=8)) def test_predict_small(W_b_input): W, b, input_ = W_b_input nr_out, nr_in = W.shape model = Linear(nr_out, nr_in) model.set_param("W", W) model.set_param("b", b) einsummed = numpy.einsum( "oi,bi->bo", numpy.asarray(W, dtype="float64"), numpy.asarray(input_, dtype="float64"), optimize=False, ) expected_output = einsummed + b predicted_output = model.predict(input_) assert_allclose(predicted_output, expected_output, rtol=0.01, atol=0.01) @given(arrays_OI_O_BI(max_batch=20, max_out=30, max_in=30)) @settings(deadline=None) def test_predict_extensive(W_b_input): W, b, input_ = W_b_input nr_out, nr_in = W.shape model = Linear(nr_out, nr_in) model.set_param("W", W) model.set_param("b", b) einsummed = numpy.einsum( "bi,oi->bo", numpy.asarray(input_, dtype="float32"), numpy.asarray(W, dtype="float32"), optimize=False, ) expected_output = einsummed + b predicted_output = model.predict(input_) assert_allclose(predicted_output, expected_output, rtol=1e-04, atol=0.0001) @given(arrays_OI_O_BI(max_batch=8, max_out=8, max_in=8)) def test_dropout_gives_zero_activations(W_b_input): model = chain(get_model(W_b_input), Dropout(1.0)) nr_batch, nr_out, nr_in = get_shape(W_b_input) W, b, input_ = W_b_input fwd_dropped, _ = model.begin_update(input_) assert all(val == 0.0 for val in fwd_dropped.flatten()) @given(arrays_OI_O_BI(max_batch=8, max_out=8, max_in=8)) def test_dropout_gives_zero_gradients(W_b_input): model = chain(get_model(W_b_input), Dropout(1.0)) nr_batch, nr_out, nr_in = get_shape(W_b_input) W, b, input_ = W_b_input for node in model.walk(): if node.name == "dropout": node.attrs["dropout_rate"] = 1.0 fwd_dropped, finish_update = model.begin_update(input_) grad_BO = numpy.ones((nr_batch, nr_out), dtype="f") grad_BI = finish_update(grad_BO) assert all(val == 0.0 for val in grad_BI.flatten()) @pytest.fixture def model2(): model = Linear(2, 2).initialize() return model def test_init(model2): assert model2.get_dim("nO") == 2 assert model2.get_dim("nI") == 2 assert model2.get_param("W") is not None assert model2.get_param("b") is not None def test_predict_bias(model2): input_ = model2.ops.alloc2f(1, model2.get_dim("nI")) target_scores = model2.ops.alloc2f(1, model2.get_dim("nI")) scores = model2.predict(input_) assert_allclose(scores[0], target_scores[0]) # Set bias for class 0 model2.get_param("b")[0] = 2.0 target_scores[0, 0] = 2.0 scores = model2.predict(input_) assert_allclose(scores, target_scores) # Set bias for class 1 model2.get_param("b")[1] = 5.0 target_scores[0, 1] = 5.0 scores = model2.predict(input_) assert_allclose(scores, target_scores) @pytest.mark.parametrize( "X,expected", [ (numpy.asarray([0.0, 0.0], dtype="f"), [0.0, 0.0]), (numpy.asarray([1.0, 0.0], dtype="f"), [1.0, 0.0]), (numpy.asarray([0.0, 1.0], dtype="f"), [0.0, 1.0]), (numpy.asarray([1.0, 1.0], dtype="f"), [1.0, 1.0]), ], ) def test_predict_weights(X, expected): W = numpy.asarray([1.0, 0.0, 0.0, 1.0], dtype="f").reshape((2, 2)) bias = numpy.asarray([0.0, 0.0], dtype="f") model = Linear(W.shape[0], W.shape[1]) model.set_param("W", W) model.set_param("b", bias) scores = model.predict(X.reshape((1, -1))) assert_allclose(scores.ravel(), expected) def test_update(): W = numpy.asarray([1.0, 0.0, 0.0, 1.0], dtype="f").reshape((2, 2)) bias = numpy.asarray([0.0, 0.0], dtype="f") model = Linear(2, 2) model.set_param("W", W) model.set_param("b", bias) sgd = SGD(1.0, L2=0.0, grad_clip=0.0) sgd.averages = None ff = numpy.asarray([[0.0, 0.0]], dtype="f") tf = numpy.asarray([[1.0, 0.0]], dtype="f") ft = numpy.asarray([[0.0, 1.0]], dtype="f") # noqa: F841 tt = numpy.asarray([[1.0, 1.0]], dtype="f") # noqa: F841 # ff, i.e. 0, 0 scores, backprop = model.begin_update(ff) assert_allclose(scores[0, 0], scores[0, 1]) # Tell it the answer was 'f' gradient = numpy.asarray([[-1.0, 0.0]], dtype="f") backprop(gradient) for key, (param, d_param) in model.get_gradients().items(): param, d_param = sgd(key, param, d_param) model.set_param(key[1], param) model.set_grad(key[1], d_param) b = model.get_param("b") W = model.get_param("W") assert b[0] == 1.0 assert b[1] == 0.0 # Unchanged -- input was zeros, so can't get gradient for weights. assert W[0, 0] == 1.0 assert W[0, 1] == 0.0 assert W[1, 0] == 0.0 assert W[1, 1] == 1.0 # tf, i.e. 1, 0 scores, finish_update = model.begin_update(tf) # Tell it the answer was 'T' gradient = numpy.asarray([[0.0, -1.0]], dtype="f") finish_update(gradient) for key, (W, dW) in model.get_gradients().items(): sgd(key, W, dW) b = model.get_param("b") W = model.get_param("W") assert b[0] == 1.0 assert b[1] == 1.0 # Gradient for weights should have been outer(gradient, input) # so outer([0, -1.], [1., 0.]) # = [[0., 0.], [-1., 0.]] assert W[0, 0] == 1.0 - 0.0 assert W[0, 1] == 0.0 - 0.0 assert W[1, 0] == 0.0 - -1.0 assert W[1, 1] == 1.0 - 0.0 thinc-9.0.0/thinc/tests/layers/test_lstm.py000066400000000000000000000130221461023342500207610ustar00rootroot00000000000000import timeit import numpy import pytest from thinc.api import LSTM, NumpyOps, Ops, PyTorchLSTM, fix_random_seed, with_padded from thinc.compat import has_torch @pytest.fixture(params=[1, 6]) def nI(request): return request.param @pytest.fixture(params=[1, 2, 7, 9]) def nO(request): return request.param def test_list2padded(): ops = NumpyOps() seqs = [numpy.zeros((5, 4)), numpy.zeros((8, 4)), numpy.zeros((2, 4))] padded = ops.list2padded(seqs) arr = padded.data size_at_t = padded.size_at_t assert arr.shape == (8, 3, 4) assert size_at_t[0] == 3 assert size_at_t[1] == 3 assert size_at_t[2] == 2 assert size_at_t[3] == 2 assert size_at_t[4] == 2 assert size_at_t[5] == 1 assert size_at_t[6] == 1 assert size_at_t[7] == 1 unpadded = ops.padded2list(padded) assert unpadded[0].shape == (5, 4) assert unpadded[1].shape == (8, 4) assert unpadded[2].shape == (2, 4) @pytest.mark.parametrize("ops", [Ops(), NumpyOps()]) @pytest.mark.parametrize("nO,nI", [(1, 2), (2, 2), (100, 200), (9, 6)]) def test_LSTM_init_with_sizes(ops, nO, nI): model = with_padded(LSTM(nO, nI, depth=1)).initialize() for node in model.walk(): model.ops = ops # Check no unallocated params. assert node.has_param("LSTM") is not None assert node.has_param("HC0") is not None for node in model.walk(): # Check param sizes. if node.has_param("LSTM"): params = node.get_param("LSTM") assert params.shape == ( ((nO * 4 * nI)) + (nO * 4) + (nO * 4 * nO + nO * 4), ) if node.has_param("HC0"): params = node.get_param("HC0") assert params.shape == (2, 1, 1, nO) @pytest.mark.parametrize("ops", [Ops(), NumpyOps()]) def test_LSTM_fwd_bwd_shapes_simple(ops, nO, nI): nO = 1 nI = 2 X = numpy.asarray([[0.1, 0.1], [-0.1, -0.1], [1.0, 1.0]], dtype="f") model = with_padded(LSTM(nO, nI)).initialize(X=[X]) for node in model.walk(): node.ops = ops ys, backprop_ys = model([X], is_train=True) dXs = backprop_ys(ys) assert numpy.vstack(dXs).shape == numpy.vstack([X]).shape @pytest.mark.parametrize("ops", [Ops(), NumpyOps()]) @pytest.mark.parametrize( "nO,nI,depth,bi,lengths", [ (1, 1, 1, False, [1]), (12, 32, 1, False, [3, 1]), (2, 2, 1, True, [2, 5, 7]), (2, 2, 2, False, [7, 2, 4]), (2, 2, 2, True, [1]), (32, 16, 1, True, [5, 1, 10, 2]), (32, 16, 2, True, [3, 3, 5]), (32, 16, 3, True, [9, 2, 4]), ], ) def test_BiLSTM_fwd_bwd_shapes(ops, nO, nI, depth, bi, lengths): Xs = [numpy.ones((length, nI), dtype="f") for length in lengths] model = with_padded(LSTM(nO, nI, depth=depth, bi=bi)).initialize(X=Xs) for node in model.walk(): node.ops = ops ys, backprop_ys = model(Xs, is_train=True) dXs = backprop_ys(ys) assert numpy.vstack(dXs).shape == numpy.vstack(Xs).shape def test_LSTM_learns(): fix_random_seed(0) nO = 2 nI = 2 def sgd(key, weights, gradient): weights -= 0.001 * gradient return weights, gradient * 0 model = with_padded(LSTM(nO, nI)) X = [[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]] Y = [[0.2, 0.2], [0.3, 0.3], [0.4, 0.4]] X = [model.ops.asarray(x, dtype="f").reshape((1, -1)) for x in X] Y = [model.ops.asarray(y, dtype="f").reshape((1, -1)) for y in Y] model = model.initialize(X, Y) Yhs, bp_Yhs = model.begin_update(X) loss1 = sum([((yh - y) ** 2).sum() for yh, y in zip(Yhs, Y)]) Yhs, bp_Yhs = model.begin_update(X) dYhs = [yh - y for yh, y in zip(Yhs, Y)] dXs = bp_Yhs(dYhs) model.finish_update(sgd) Yhs, bp_Yhs = model.begin_update(X) dYhs = [yh - y for yh, y in zip(Yhs, Y)] dXs = bp_Yhs(dYhs) # noqa: F841 loss2 = sum([((yh - y) ** 2).sum() for yh, y in zip(Yhs, Y)]) assert loss1 > loss2, (loss1, loss2) @pytest.mark.skip def test_benchmark_LSTM_fwd(): nO = 128 nI = 128 n_batch = 1000 batch_size = 30 seq_len = 30 lengths = numpy.random.normal(scale=10, loc=30, size=n_batch * batch_size) lengths = numpy.maximum(lengths, 1) batches = [] uniform_lengths = False model = with_padded(LSTM(nO, nI)).initialize() for batch_lengths in model.ops.minibatch(batch_size, lengths): batch_lengths = list(batch_lengths) if uniform_lengths: seq_len = max(batch_lengths) batch = [ numpy.asarray( numpy.random.uniform(0.0, 1.0, (int(seq_len), nI)), dtype="f" ) for _ in batch_lengths ] else: batch = [ numpy.asarray( numpy.random.uniform(0.0, 1.0, (int(seq_len), nI)), dtype="f" ) for seq_len in batch_lengths ] batches.append(batch) start = timeit.default_timer() for Xs in batches: ys, bp_ys = model.begin_update(list(Xs)) # _ = bp_ys(ys) end = timeit.default_timer() n_samples = n_batch * batch_size print( "--- %i samples in %s seconds (%f samples/s, %.7f s/sample) ---" % (n_samples, end - start, n_samples / (end - start), (end - start) / n_samples) ) def test_lstm_init(): model = with_padded(LSTM(2, 2, bi=True)).initialize() model.initialize() @pytest.mark.skipif(not has_torch, reason="needs PyTorch") def test_pytorch_lstm_init(): model = with_padded(PyTorchLSTM(2, 2, depth=0)).initialize() assert model.name == "with_padded(noop)" thinc-9.0.0/thinc/tests/layers/test_mappers.py000066400000000000000000000031621461023342500214550ustar00rootroot00000000000000import numpy import pytest from thinc.layers import premap_ids, remap_ids, remap_ids_v2 @pytest.fixture def keys(): return numpy.array([4, 2, 6, 1, 8, 7, 9, 3, 30]) @pytest.fixture def mapper(keys): return {int(k): int(v) for v, k in enumerate(keys)} def test_premap(keys, mapper): premap = premap_ids(mapper, default=99) values, _ = premap(keys, False) numpy.testing.assert_equal(values.squeeze(), numpy.asarray(range(len(keys)))) def test_remap(keys, mapper): remap = remap_ids(mapper, default=99) values, _ = remap(keys, False) numpy.testing.assert_equal(values.squeeze(), numpy.asarray(range(len(keys)))) def test_remap_v2(keys, mapper): remap = remap_ids_v2(mapper, default=99) values, _ = remap(keys, False) numpy.testing.assert_equal(values.squeeze(), numpy.asarray(range(len(keys)))) def test_remap_premap_eq(keys, mapper): remap = remap_ids(mapper, default=99) remap_v2 = remap_ids_v2(mapper, default=99) premap = premap_ids(mapper, default=99) values1, _ = remap(keys, False) values2, _ = remap_v2(keys, False) values3, _ = premap(keys, False) numpy.testing.assert_equal(values1, values2) numpy.testing.assert_equal(values2, values3) def test_column(keys, mapper): idx = numpy.zeros((len(keys), 4), dtype="int") idx[:, 3] = keys remap_v2 = remap_ids_v2(mapper, column=3) premap = premap_ids(mapper, column=3) numpy.testing.assert_equal( remap_v2(idx, False)[0].squeeze(), numpy.asarray(range(len(keys))) ) numpy.testing.assert_equal( premap(idx, False)[0].squeeze(), numpy.asarray(range(len(keys))) ) thinc-9.0.0/thinc/tests/layers/test_mnist.py000066400000000000000000000071251461023342500211430ustar00rootroot00000000000000import pytest from thinc.api import ( Adam, PyTorchWrapper, Relu, Softmax, TensorFlowWrapper, chain, clone, get_current_ops, ) from thinc.compat import has_tensorflow, has_torch @pytest.fixture(scope="module") def mnist(limit=5000): pytest.importorskip("ml_datasets") import ml_datasets (train_X, train_Y), (dev_X, dev_Y) = ml_datasets.mnist() return (train_X[:limit], train_Y[:limit]), (dev_X[:limit], dev_Y[:limit]) def create_relu_softmax(width, dropout, nI, nO): return chain(clone(Relu(nO=width, dropout=dropout), 2), Softmax(10, width)) def create_wrapped_pytorch(width, dropout, nI, nO): import torch import torch.nn import torch.nn.functional as F class PyTorchModel(torch.nn.Module): def __init__(self, width, nO, nI, dropout): super(PyTorchModel, self).__init__() self.dropout1 = torch.nn.Dropout2d(dropout) self.dropout2 = torch.nn.Dropout2d(dropout) self.fc1 = torch.nn.Linear(nI, width) self.fc2 = torch.nn.Linear(width, nO) def forward(self, x): x = F.relu(x) x = self.dropout1(x) x = self.fc1(x) x = F.relu(x) x = self.dropout2(x) x = self.fc2(x) output = F.log_softmax(x, dim=1) return output return PyTorchWrapper(PyTorchModel(width, nO, nI, dropout)) def create_wrapped_tensorflow(width, dropout, nI, nO): from tensorflow.keras.layers import Dense, Dropout from tensorflow.keras.models import Sequential tf_model = Sequential() tf_model.add(Dense(width, activation="relu", input_shape=(nI,))) tf_model.add(Dropout(dropout)) tf_model.add(Dense(width, activation="relu")) tf_model.add(Dropout(dropout)) tf_model.add(Dense(nO, activation=None)) return TensorFlowWrapper(tf_model) @pytest.fixture( # fmt: off params=[ create_relu_softmax, pytest.param(create_wrapped_pytorch, marks=pytest.mark.skipif(not has_torch, reason="needs PyTorch")), pytest.param(create_wrapped_tensorflow, marks=pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow")) ] # fmt: on ) def create_model(request): return request.param @pytest.mark.slow @pytest.mark.parametrize(("width", "nb_epoch", "min_score"), [(32, 20, 0.8)]) def test_small_end_to_end(width, nb_epoch, min_score, create_model, mnist): batch_size = 128 dropout = 0.2 (train_X, train_Y), (dev_X, dev_Y) = mnist model = create_model(width, dropout, nI=train_X.shape[1], nO=train_Y.shape[1]) model.initialize(X=train_X[:5], Y=train_Y[:5]) optimizer = Adam(0.001) losses = [] scores = [] ops = get_current_ops() for i in range(nb_epoch): for X, Y in model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True): Yh, backprop = model.begin_update(X) # Ensure that the tensor is type-compatible with the current backend. Yh = ops.asarray(Yh) backprop(Yh - Y) model.finish_update(optimizer) losses.append(((Yh - Y) ** 2).sum()) correct = 0 total = 0 for X, Y in model.ops.multibatch(batch_size, dev_X, dev_Y): Yh = model.predict(X) Yh = ops.asarray(Yh) correct += (Yh.argmax(axis=1) == Y.argmax(axis=1)).sum() total += Yh.shape[0] score = correct / total scores.append(score) assert losses[-1] < losses[0], losses if scores[0] < 1.0: assert scores[-1] > scores[0], scores assert any([score > min_score for score in scores]), scores thinc-9.0.0/thinc/tests/layers/test_mxnet_wrapper.py000066400000000000000000000142241461023342500227020ustar00rootroot00000000000000from typing import cast import numpy import pytest from thinc.api import ( Adam, ArgsKwargs, Model, MXNetWrapper, Ops, get_current_ops, mxnet2xp, xp2mxnet, ) from thinc.compat import has_cupy_gpu, has_mxnet from thinc.types import Array1d, Array2d, IntsXd from thinc.util import to_categorical from ..util import check_input_converters, make_tempdir @pytest.fixture def n_hidden() -> int: return 12 @pytest.fixture def input_size() -> int: return 784 @pytest.fixture def n_classes() -> int: return 10 @pytest.fixture def answer() -> int: return 1 @pytest.fixture def X(input_size: int) -> Array2d: ops: Ops = get_current_ops() return cast(Array2d, ops.alloc(shape=(1, input_size))) @pytest.fixture def Y(answer: int, n_classes: int) -> Array2d: ops: Ops = get_current_ops() return cast( Array2d, to_categorical(cast(IntsXd, ops.asarray([answer])), n_classes=n_classes), ) @pytest.fixture def mx_model(n_hidden: int, input_size: int, X: Array2d): import mxnet as mx mx_model = mx.gluon.nn.Sequential() mx_model.add( mx.gluon.nn.Dense(n_hidden), mx.gluon.nn.LayerNorm(), mx.gluon.nn.Dense(n_hidden, activation="relu"), mx.gluon.nn.LayerNorm(), mx.gluon.nn.Dense(10, activation="softrelu"), ) mx_model.initialize() return mx_model @pytest.fixture def model(mx_model) -> Model[Array2d, Array2d]: return MXNetWrapper(mx_model) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_roundtrip_conversion(): import mxnet as mx xp_tensor = numpy.zeros((2, 3), dtype="f") mx_tensor = xp2mxnet(xp_tensor) assert isinstance(mx_tensor, mx.nd.NDArray) new_xp_tensor = mxnet2xp(mx_tensor) assert numpy.array_equal(xp_tensor, new_xp_tensor) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_gluon_sequential(): import mxnet as mx mx_model = mx.gluon.nn.Sequential() mx_model.add(mx.gluon.nn.Dense(12)) wrapped = MXNetWrapper(mx_model) assert isinstance(wrapped, Model) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_built_model( model: Model[Array2d, Array2d], X: Array2d, Y: Array1d ): # built models are validated more and can perform useful operations: assert model.predict(X) is not None # They can de/serialized assert model.from_bytes(model.to_bytes()) is not None @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_predict(model: Model[Array2d, Array2d], X: Array2d): model.predict(X) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_train_overfits( model: Model[Array2d, Array2d], X: Array2d, Y: Array1d, answer: int ): optimizer = Adam() for i in range(100): guesses, backprop = model(X, is_train=True) d_guesses = (guesses - Y) / guesses.shape[0] backprop(d_guesses) model.finish_update(optimizer) predicted = model.predict(X).argmax() assert predicted == answer @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_can_copy_model(model: Model[Array2d, Array2d], X: Array2d): model.predict(X) copy: Model[Array2d, Array2d] = model.copy() assert copy is not None @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_to_bytes(model: Model[Array2d, Array2d], X: Array2d): model.predict(X) # And can be serialized model_bytes = model.to_bytes() assert model_bytes is not None model.from_bytes(model_bytes) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_to_from_disk(model: Model[Array2d, Array2d], X: Array2d): model.predict(X) with make_tempdir() as tmp_path: model_file = tmp_path / "model.bytes" model.to_disk(model_file) another_model = model.from_disk(model_file) assert another_model is not None @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_from_bytes(model: Model[Array2d, Array2d], X: Array2d): model.predict(X) model_bytes = model.to_bytes() another_model = model.from_bytes(model_bytes) assert another_model is not None @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_to_cpu(mx_model, X: Array2d): model = MXNetWrapper(mx_model) model.predict(X) model.to_cpu() @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") @pytest.mark.skipif(not has_cupy_gpu, reason="needs GPU/cupy") def test_mxnet_wrapper_to_gpu(model: Model[Array2d, Array2d], X: Array2d): model.predict(X) model.to_gpu(0) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") @pytest.mark.parametrize( "data,n_args,kwargs_keys", [ # fmt: off (numpy.zeros((2, 3), dtype="f"), 1, []), ([numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")], 2, []), ((numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")), 2, []), ({"a": numpy.zeros((2, 3), dtype="f"), "b": numpy.zeros((2, 3), dtype="f")}, 0, ["a", "b"]), (ArgsKwargs((numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")), {"c": numpy.zeros((2, 3), dtype="f")}), 2, ["c"]), # fmt: on ], ) def test_mxnet_wrapper_convert_inputs(data, n_args, kwargs_keys): import mxnet as mx mx_model = mx.gluon.nn.Sequential() mx_model.add(mx.gluon.nn.Dense(12)) mx_model.initialize() model = MXNetWrapper(mx_model) convert_inputs = model.attrs["convert_inputs"] Y, backprop = convert_inputs(model, data, is_train=True) check_input_converters(Y, backprop, data, n_args, kwargs_keys, mx.nd.NDArray) @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_thinc_model_subclass(mx_model): class CustomModel(Model): def fn(self) -> int: return 1337 model = MXNetWrapper(mx_model, model_class=CustomModel) assert isinstance(model, CustomModel) assert model.fn() == 1337 @pytest.mark.skipif(not has_mxnet, reason="needs MXNet") def test_mxnet_wrapper_thinc_set_model_name(mx_model): model = MXNetWrapper(mx_model, model_name="cool") assert model.name == "cool" thinc-9.0.0/thinc/tests/layers/test_parametric_attention_v2.py000066400000000000000000000004351461023342500246310ustar00rootroot00000000000000from thinc.layers.gelu import Gelu from thinc.layers.parametricattention_v2 import ( KEY_TRANSFORM_REF, ParametricAttention_v2, ) def test_key_transform_used(): attn = ParametricAttention_v2(key_transform=Gelu()) assert attn.get_ref(KEY_TRANSFORM_REF).name == "gelu" thinc-9.0.0/thinc/tests/layers/test_pytorch_wrapper.py000066400000000000000000000154471461023342500232470ustar00rootroot00000000000000import numpy import pytest from thinc.api import ( SGD, ArgsKwargs, CupyOps, Linear, MPSOps, NumpyOps, PyTorchWrapper, PyTorchWrapper_v2, PyTorchWrapper_v3, Relu, chain, get_current_ops, torch2xp, use_ops, xp2torch, ) from thinc.backends import context_pools from thinc.compat import has_cupy_gpu, has_torch, has_torch_amp, has_torch_mps_gpu from thinc.layers.pytorchwrapper import PyTorchWrapper_v3 from thinc.shims.pytorch import ( default_deserialize_torch_model, default_serialize_torch_model, ) from thinc.shims.pytorch_grad_scaler import PyTorchGradScaler from thinc.util import get_torch_default_device from ..util import check_input_converters, make_tempdir XP_OPS = [NumpyOps()] if has_cupy_gpu: XP_OPS.append(CupyOps()) if has_torch_mps_gpu: XP_OPS.append(MPSOps()) if has_torch_amp: TORCH_MIXED_PRECISION = [False, True] else: TORCH_MIXED_PRECISION = [False] XP_OPS_MIXED = [ (ops, mixed) for ops in XP_OPS for mixed in TORCH_MIXED_PRECISION if not mixed or isinstance(ops, CupyOps) ] def check_learns_zero_output(model, sgd, X, Y): """Check we can learn to output a zero vector""" Yh, get_dX = model.begin_update(X) dYh = (Yh - Y) / Yh.shape[0] dX = get_dX(dYh) model.finish_update(sgd) prev = numpy.abs(Yh.sum()) for i in range(100): Yh, get_dX = model.begin_update(X) total = numpy.abs(Yh.sum()) dX = get_dX(Yh - Y) # noqa: F841 model.finish_update(sgd) assert total < prev @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize("nN,nI,nO", [(2, 3, 4)]) def test_pytorch_unwrapped(nN, nI, nO): model = Linear(nO, nI).initialize() X = numpy.zeros((nN, nI), dtype="f") X += numpy.random.uniform(size=X.size).reshape(X.shape) sgd = SGD(0.01) Y = numpy.zeros((nN, nO), dtype="f") check_learns_zero_output(model, sgd, X, Y) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize("nN,nI,nO", [(2, 3, 4)]) def test_pytorch_wrapper(nN, nI, nO): import torch.nn model = PyTorchWrapper(torch.nn.Linear(nI, nO)).initialize() sgd = SGD(0.001) X = numpy.zeros((nN, nI), dtype="f") X += numpy.random.uniform(size=X.size).reshape(X.shape) Y = numpy.zeros((nN, nO), dtype="f") Yh, get_dX = model.begin_update(X) assert isinstance(Yh, numpy.ndarray) assert Yh.shape == (nN, nO) dYh = (Yh - Y) / Yh.shape[0] dX = get_dX(dYh) model.finish_update(sgd) assert dX.shape == (nN, nI) check_learns_zero_output(model, sgd, X, Y) assert isinstance(model.predict(X), numpy.ndarray) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize("ops_mixed", XP_OPS_MIXED) @pytest.mark.parametrize("nN,nI,nO", [(2, 3, 4)]) def test_pytorch_wrapper_thinc_input(ops_mixed, nN, nI, nO): import torch.nn ops, mixed_precision = ops_mixed with use_ops(ops.name): ops = get_current_ops() pytorch_layer = torch.nn.Linear(nO, nO) # Initialize with large weights to trigger overflow of FP16 in # mixed-precision training. torch.nn.init.uniform_(pytorch_layer.weight, 9.0, 11.0) device = get_torch_default_device() model = chain( Relu(), PyTorchWrapper_v2( pytorch_layer.to(device), mixed_precision=mixed_precision, grad_scaler=PyTorchGradScaler( enabled=mixed_precision, init_scale=2.0**16 ), ).initialize(), ) # pytorch allocator is set in PyTorchShim if isinstance(ops, CupyOps): assert "pytorch" in context_pools.get() sgd = SGD(0.001) X = ops.xp.zeros((nN, nI), dtype="f") X += ops.xp.random.uniform(size=X.size).reshape(X.shape) Y = ops.xp.zeros((nN, nO), dtype="f") model.initialize(X, Y) Yh, get_dX = model.begin_update(X) assert isinstance(Yh, ops.xp.ndarray) assert Yh.shape == (nN, nO) dYh = (Yh - Y) / Yh.shape[0] dX = get_dX(dYh) model.finish_update(sgd) assert dX.shape == (nN, nI) check_learns_zero_output(model, sgd, X, Y) assert isinstance(model.predict(X), ops.xp.ndarray) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") def test_pytorch_roundtrip_conversion(): import torch xp_tensor = numpy.zeros((2, 3), dtype="f") torch_tensor = xp2torch(xp_tensor) assert isinstance(torch_tensor, torch.Tensor) new_xp_tensor = torch2xp(torch_tensor) assert numpy.array_equal(xp_tensor, new_xp_tensor) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") def test_pytorch_wrapper_roundtrip(): import torch.nn model = PyTorchWrapper(torch.nn.Linear(2, 3)) model_bytes = model.to_bytes() PyTorchWrapper(torch.nn.Linear(2, 3)).from_bytes(model_bytes) with make_tempdir() as path: model_path = path / "model" model.to_disk(model_path) new_model = PyTorchWrapper(torch.nn.Linear(2, 3)).from_bytes(model_bytes) new_model.from_disk(model_path) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize( "data,n_args,kwargs_keys", [ # fmt: off (numpy.zeros((2, 3), dtype="f"), 1, []), ([numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")], 2, []), ((numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")), 2, []), ({"a": numpy.zeros((2, 3), dtype="f"), "b": numpy.zeros((2, 3), dtype="f")}, 0, ["a", "b"]), (ArgsKwargs((numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")), {"c": numpy.zeros((2, 3), dtype="f")}), 2, ["c"]), # fmt: on ], ) def test_pytorch_convert_inputs(data, n_args, kwargs_keys): import torch.nn model = PyTorchWrapper(torch.nn.Linear(3, 4)) convert_inputs = model.attrs["convert_inputs"] Y, backprop = convert_inputs(model, data, is_train=True) check_input_converters(Y, backprop, data, n_args, kwargs_keys, torch.Tensor) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") def test_pytorch_wrapper_custom_serde(): import torch.nn def serialize(model): return default_serialize_torch_model(model) def deserialize(model, state_bytes, device): return default_deserialize_torch_model(model, state_bytes, device) def get_model(): return PyTorchWrapper_v3( torch.nn.Linear(2, 3), serialize_model=serialize, deserialize_model=deserialize, ) model = get_model() model_bytes = model.to_bytes() get_model().from_bytes(model_bytes) with make_tempdir() as path: model_path = path / "model" model.to_disk(model_path) new_model = get_model().from_bytes(model_bytes) new_model.from_disk(model_path) thinc-9.0.0/thinc/tests/layers/test_reduce.py000066400000000000000000000071571461023342500212650ustar00rootroot00000000000000import numpy import pytest from thinc.api import reduce_first, reduce_last, reduce_max, reduce_mean, reduce_sum from thinc.types import Ragged @pytest.fixture def Xs(): seqs = [numpy.zeros((10, 8), dtype="f"), numpy.zeros((4, 8), dtype="f")] for x in seqs: x[0] = 1 x[1] = 2 # so max != first x[-1] = -1 return seqs def test_init_reduce_first(): model = reduce_first() def test_init_reduce_last(): model = reduce_last() def test_init_reduce_mean(): model = reduce_mean() def test_init_reduce_max(): model = reduce_max() def test_init_reduce_sum(): model = reduce_sum() def test_reduce_first(Xs): model = reduce_first() lengths = model.ops.asarray([x.shape[0] for x in Xs], dtype="i") X = Ragged(model.ops.flatten(Xs), lengths) Y, backprop = model(X, is_train=True) assert isinstance(Y, numpy.ndarray) assert Y.shape == (len(Xs), Xs[0].shape[1]) assert Y.dtype == Xs[0].dtype assert list(Y[0]) == list(Xs[0][0]) assert list(Y[1]) == list(Xs[1][0]) dX = backprop(Y) assert dX.dataXd.shape == X.dataXd.shape def test_reduce_last(Xs): model = reduce_last() lengths = model.ops.asarray([x.shape[0] for x in Xs], dtype="i") X = Ragged(model.ops.flatten(Xs), lengths) Y, backprop = model(X, is_train=True) assert isinstance(Y, numpy.ndarray) assert Y.shape == (len(Xs), Xs[0].shape[1]) assert Y.dtype == Xs[0].dtype assert list(Y[0]) == list(Xs[0][-1]) assert list(Y[1]) == list(Xs[1][-1]) dX = backprop(Y) assert dX.dataXd.shape == X.dataXd.shape def test_reduce_max(Xs): model = reduce_max() lengths = model.ops.asarray([x.shape[0] for x in Xs], dtype="i") X = Ragged(model.ops.flatten(Xs), lengths) Y, backprop = model(X, is_train=True) assert isinstance(Y, numpy.ndarray) assert Y.shape == (len(Xs), Xs[0].shape[1]) assert Y.dtype == Xs[0].dtype assert list(Y[0]) == list(Xs[0][1]) assert list(Y[1]) == list(Xs[1][1]) dX = backprop(Y) assert dX.dataXd.shape == X.dataXd.shape def test_reduce_mean(Xs): Xs = [x * 1000 for x in Xs] # use large numbers for numeric stability model = reduce_mean() lengths = model.ops.asarray([x.shape[0] for x in Xs], dtype="i") X = Ragged(model.ops.flatten(Xs), lengths) Y, backprop = model(X, is_train=True) assert isinstance(Y, numpy.ndarray) assert Y.shape == (len(Xs), Xs[0].shape[1]) assert Y.dtype == Xs[0].dtype assert numpy.all(Y[0] == Y[0][0]) # all values in row should be equal assert Y[0][0] == Xs[0].mean() assert numpy.all(Y[1] == Y[1][0]) assert Y[1][0] == Xs[1].mean() dX = backprop(Y) assert dX.dataXd.shape == X.dataXd.shape def test_reduce_sum(Xs): model = reduce_sum() lengths = model.ops.asarray([x.shape[0] for x in Xs], dtype="i") X = Ragged(model.ops.flatten(Xs), lengths) Y, backprop = model(X, is_train=True) assert isinstance(Y, numpy.ndarray) assert Y.shape == (len(Xs), Xs[0].shape[1]) assert Y.dtype == Xs[0].dtype assert Y[0][0] == Xs[0][:, 0].sum() assert numpy.all(Y[0] == Y[0][0]) assert Y[1][-1] == Xs[1][:, 0].sum() assert numpy.all(Y[1] == Y[1][0]) dX = backprop(Y) assert dX.dataXd.shape == X.dataXd.shape def test_size_mismatch(Xs): for reduce in [reduce_first, reduce_last, reduce_max, reduce_mean, reduce_sum]: model = reduce() lengths = model.ops.asarray([x.shape[0] for x in Xs], dtype="i") X = Ragged(model.ops.flatten(Xs), lengths) Y, backprop = model(X, is_train=True) Y_bad = Y[:-1] with pytest.raises(ValueError): backprop(Y_bad) thinc-9.0.0/thinc/tests/layers/test_resizable.py000066400000000000000000000015521461023342500217670ustar00rootroot00000000000000from functools import partial import pytest from thinc.api import Linear, resizable from thinc.layers.resizable import resize_linear_weighted, resize_model @pytest.fixture def model(): output_layer = Linear(nO=None, nI=None) fill_defaults = {"b": 0, "W": 0} model = resizable( output_layer, resize_layer=partial(resize_linear_weighted, fill_defaults=fill_defaults), ) return model def test_resizable_linear_default_name(model): assert model.name == "resizable(linear)" def test_resize_model(model): """Test that resizing the model doesn't cause an exception.""" resize_model(model, new_nO=10) resize_model(model, new_nO=11) model.set_dim("nO", 0, force=True) resize_model(model, new_nO=10) model.set_dim("nI", 10, force=True) model.set_dim("nO", 0, force=True) resize_model(model, new_nO=10) thinc-9.0.0/thinc/tests/layers/test_shim.py000066400000000000000000000016611461023342500207500ustar00rootroot00000000000000from typing import List from thinc.shims.shim import Shim from ..util import make_tempdir class MockShim(Shim): def __init__(self, data: List[int]): super().__init__(None, config=None, optimizer=None) self.data = data def to_bytes(self): return bytes(self.data) def from_bytes(self, data: bytes) -> "MockShim": return MockShim(data=list(data)) def test_shim_can_roundtrip_with_path(): with make_tempdir() as path: shim_path = path / "cool_shim.data" shim = MockShim([1, 2, 3]) shim.to_disk(shim_path) copy_shim = shim.from_disk(shim_path) assert copy_shim.to_bytes() == shim.to_bytes() def test_shim_can_roundtrip_with_path_subclass(pathy_fixture): shim_path = pathy_fixture / "cool_shim.data" shim = MockShim([1, 2, 3]) shim.to_disk(shim_path) copy_shim = shim.from_disk(shim_path) assert copy_shim.to_bytes() == shim.to_bytes() thinc-9.0.0/thinc/tests/layers/test_softmax.py000066400000000000000000000054651461023342500214770ustar00rootroot00000000000000from typing import Tuple, cast import numpy import pytest from numpy.testing import assert_allclose from thinc.api import Model, NumpyOps, Softmax_v2 from thinc.types import Floats2d, Ints1d from thinc.util import has_torch, torch2xp, xp2torch OPS = NumpyOps() inputs = OPS.xp.asarray([[4, 2, 3, 4], [1, 5, 3, 1], [9, 8, 5, 7]], dtype="f") outputs = OPS.xp.asarray( [ [0.39948627, 0.05406459, 0.14696279, 0.39948627], [0.01562812, 0.8532666, 0.11547707, 0.01562812], [0.657233, 0.24178252, 0.01203764, 0.08894681], ], dtype="f", ) def test_unnormalized_softmax_backprop(): model = Softmax_v2(normalize_outputs=False) model.initialize(inputs, outputs) _, backprop = model(inputs, is_train=False) with pytest.raises(ValueError, match="backprop is not supported"): backprop(OPS.xp.zeros_like(outputs)) # Backprop should not fail when training. _, backprop = model(inputs, is_train=True) dX = backprop(OPS.xp.zeros_like(outputs)) assert OPS.xp.all(dX == 0.0) def torch_softmax_with_temperature( model: Model, X: Floats2d, targets: Ints1d ) -> Tuple[Floats2d, Floats2d]: import torch Wt = xp2torch(model.get_param("W")) bt = xp2torch(model.get_param("b")) temperature = model.attrs["softmax_temperature"] Xt = xp2torch(X, requires_grad=True) Yt_gold = xp2torch(targets).long() XWbt = (Xt @ Wt) + bt XWbt_temp = XWbt / temperature loss = torch.nn.CrossEntropyLoss() output = loss(XWbt_temp, Yt_gold) output.backward() return cast( Floats2d, torch2xp(torch.nn.functional.softmax(XWbt_temp, dim=-1)) ), cast(Floats2d, torch2xp(cast(torch.Tensor, Xt.grad))) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize("temperature", [0.5, 1.0, 2.0]) def test_softmax_temperature(temperature): model = Softmax_v2( temperature=temperature, init_W=lambda ops, shape: ops.xp.eye(shape[1], dtype="f"), init_b=lambda ops, shape: ops.xp.zeros(shape, dtype="f"), ) X = OPS.xp.arange(-1, 1, 0.2, dtype="f").reshape(1, 10) targets = OPS.asarray1i([4]) Y_gold = OPS.xp.eye(10, dtype="f")[targets] model.initialize(X, Y_gold) Yt, dXt = torch_softmax_with_temperature(model, X, targets) Y, backprop = model(X, is_train=True) dX = backprop(Y - Y_gold) assert_allclose(Y, Yt, atol=1e-4) assert_allclose(dX, dXt, atol=1e-4) def test_reject_incorrect_temperature(): with pytest.raises(ValueError, match=r"softmax temperature.*zero"): Softmax_v2(normalize_outputs=False, temperature=0.0) model = Softmax_v2(normalize_outputs=False) model.attrs["softmax_temperature"] = 0.0 model.initialize(inputs, outputs) with pytest.raises(ValueError, match=r"softmax temperature.*zero"): model(inputs, is_train=False) thinc-9.0.0/thinc/tests/layers/test_sparse_linear.py000066400000000000000000000043631461023342500226410ustar00rootroot00000000000000import math import numpy import pytest from thinc.api import SGD, SparseLinear, SparseLinear_v2, to_categorical @pytest.fixture def instances(): lengths = numpy.asarray([5, 4], dtype="int32") keys = numpy.arange(9, dtype="uint64") values = numpy.ones(9, dtype="float32") X = (keys, values, lengths) y = numpy.asarray([0, 2], dtype="int32") return X, to_categorical(y, n_classes=3) @pytest.fixture def sgd(): return SGD(0.001) def test_basic(instances, sgd): X, y = instances nr_class = 3 model = SparseLinear(nr_class).initialize() yh, backprop = model.begin_update(X) loss1 = ((yh - y) ** 2).sum() backprop(yh - y) model.finish_update(sgd) yh, backprop = model.begin_update(X) loss2 = ((yh - y) ** 2).sum() assert loss2 < loss1 def test_init(): model = SparseLinear(3).initialize() keys = numpy.ones((5,), dtype="uint64") values = numpy.ones((5,), dtype="f") lengths = numpy.zeros((2,), dtype="int32") lengths[0] = 3 lengths[1] = 2 scores, backprop = model.begin_update((keys, values, lengths)) assert scores.shape == (2, 3) d_feats = backprop(scores) assert len(d_feats) == 3 def test_distribution(): n_class = 10 length = 2**18 model = SparseLinear_v2(nO=n_class, length=length).initialize() ii64 = numpy.iinfo(numpy.uint64) lengths = numpy.zeros((2,), dtype="int32") for p_nonzero in range(1, 12): # Clear gradients from the previous iterarion. model.set_grad("W", 0.0) n = 2**p_nonzero keys = numpy.random.randint(ii64.min, ii64.max, size=(n,), dtype=numpy.uint64) values = numpy.ones((n,), dtype="f") lengths[0] = n // 2 lengths[1] = n // 2 # Probability that a bit is set (2 because we use 2 hashes). p_nonzero = 1 - math.exp(-2 * n / length) Y, backprop = model.begin_update((keys, values, lengths)) backprop(numpy.ones_like(Y)) # Check that for each class we have the expected rate of non-zeros. dW = model.get_grad("W").reshape(n_class, -1) nonzero_empirical = numpy.count_nonzero(dW, axis=1) / dW.shape[1] numpy.testing.assert_allclose( nonzero_empirical, p_nonzero, rtol=1e-4, atol=1e-4 ) thinc-9.0.0/thinc/tests/layers/test_tensorflow_wrapper.py000066400000000000000000000314671461023342500237610ustar00rootroot00000000000000import numpy import pytest from thinc.api import ( Adam, ArgsKwargs, Linear, Model, TensorFlowWrapper, get_current_ops, keras_subclass, tensorflow2xp, xp2tensorflow, ) from thinc.compat import has_cupy_gpu, has_tensorflow from thinc.util import to_categorical from ..util import check_input_converters, make_tempdir @pytest.fixture def n_hidden(): return 12 @pytest.fixture def input_size(): return 784 @pytest.fixture def n_classes(): return 10 @pytest.fixture def answer(): return 1 @pytest.fixture def X(input_size): ops = get_current_ops() return ops.alloc(shape=(1, input_size)) @pytest.fixture def Y(answer, n_classes): ops = get_current_ops() return to_categorical(ops.asarray1i([answer]), n_classes=n_classes) @pytest.fixture def tf_model(n_hidden, input_size): import tensorflow as tf tf_model = tf.keras.Sequential( [ tf.keras.layers.Dense(n_hidden, input_shape=(input_size,)), tf.keras.layers.LayerNormalization(), tf.keras.layers.Dense(n_hidden, activation="relu"), tf.keras.layers.LayerNormalization(), tf.keras.layers.Dense(10, activation="softmax"), ] ) return tf_model @pytest.fixture def model(tf_model): return TensorFlowWrapper(tf_model) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_roundtrip_conversion(): import tensorflow as tf ops = get_current_ops() xp_tensor = ops.alloc2f(2, 3, zeros=True) tf_tensor = xp2tensorflow(xp_tensor) assert isinstance(tf_tensor, tf.Tensor) new_xp_tensor = tensorflow2xp(tf_tensor, ops=ops) assert ops.xp.array_equal(xp_tensor, new_xp_tensor) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_construction_requires_keras_model(): import tensorflow as tf keras_model = tf.keras.Sequential([tf.keras.layers.Dense(12, input_shape=(12,))]) assert isinstance(TensorFlowWrapper(keras_model), Model) with pytest.raises(ValueError): TensorFlowWrapper(Linear(2, 3)) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_built_model(model, X, Y): # built models are validated more and can perform useful operations: assert model.predict(X) is not None # Can print a keras summary assert str(model.shims[0]) != "" # They can de/serialized assert model.from_bytes(model.to_bytes()) is not None @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_predict(model, X): model.predict(X) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_train_overfits(model, X, Y, answer): optimizer = Adam() ops = get_current_ops() for i in range(100): guesses, backprop = model(X, is_train=True) # Ensure that the tensor is type-compatible with the current backend. guesses = ops.asarray(guesses) d_guesses = (guesses - Y) / guesses.shape[0] backprop(d_guesses) model.finish_update(optimizer) predicted = model.predict(X).argmax() assert predicted == answer @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_accumulate_gradients(model, X, Y, answer): import tensorflow as tf optimizer = Adam() gradients = [] ops = get_current_ops() for i in range(3): guesses, backprop = model(X, is_train=True) # Ensure that the tensor is type-compatible with the current backend. guesses = ops.asarray(guesses) d_guesses = (guesses - Y) / guesses.shape[0] backprop(d_guesses) shim_grads = [tf.identity(var) for var in model.shims[0].gradients] gradients.append(shim_grads) # Apply the gradients model.finish_update(optimizer) assert model.shims[0].gradients is None # Compare prev/next pairs and ensure their gradients have changed for i in range(len(gradients)): # Skip the first one if i == 0: continue found_diff = False curr_grads = gradients[i] prev_grads = gradients[i - 1] for curr, prev in zip(curr_grads, prev_grads): if (prev != curr).numpy().any(): found_diff = True assert found_diff is True @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_serialize_model_subclass( X, Y, input_size, n_classes, answer ): import tensorflow as tf input_shape = (1, input_size) ops = get_current_ops() @keras_subclass( "foo.v1", X=ops.alloc2f(*input_shape), Y=to_categorical(ops.asarray1i([1]), n_classes=n_classes), input_shape=input_shape, ) class CustomKerasModel(tf.keras.Model): def __init__(self, **kwargs): super(CustomKerasModel, self).__init__(**kwargs) self.in_dense = tf.keras.layers.Dense( 12, name="in_dense", input_shape=input_shape ) self.out_dense = tf.keras.layers.Dense( n_classes, name="out_dense", activation="softmax" ) def call(self, inputs) -> tf.Tensor: x = self.in_dense(inputs) return self.out_dense(x) model = TensorFlowWrapper(CustomKerasModel()) # Train the model to predict the right single answer optimizer = Adam() for i in range(50): guesses, backprop = model(X, is_train=True) # Ensure that the tensor is type-compatible with the current backend. guesses = ops.asarray(guesses) d_guesses = (guesses - Y) / guesses.shape[0] backprop(d_guesses) model.finish_update(optimizer) predicted = model.predict(X).argmax() assert predicted == answer # Save then Load the model from bytes model.from_bytes(model.to_bytes()) # The from_bytes model gets the same answer assert model.predict(X).argmax() == answer @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_keras_subclass_decorator_compile_args(): import tensorflow as tf class UndecoratedModel(tf.keras.Model): def call(self, inputs): return inputs # Can't wrap an undecorated keras subclass model with pytest.raises(ValueError): TensorFlowWrapper(UndecoratedModel()) @keras_subclass( "TestModel", X=numpy.array([0.0, 0.0]), Y=numpy.array([0.5]), input_shape=(2,), compile_args={"loss": "binary_crossentropy"}, ) class TestModel(tf.keras.Model): def call(self, inputs): return inputs model = TensorFlowWrapper(TestModel()) model = model.from_bytes(model.to_bytes()) assert model.shims[0]._model.loss == "binary_crossentropy" assert isinstance(model, Model) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_keras_subclass_decorator(): import tensorflow as tf class UndecoratedModel(tf.keras.Model): def call(self, inputs): return inputs # Can't wrap an undecorated keras subclass model with pytest.raises(ValueError): TensorFlowWrapper(UndecoratedModel()) @keras_subclass( "TestModel", X=numpy.array([0.0, 0.0]), Y=numpy.array([0.5]), input_shape=(2,) ) class TestModel(tf.keras.Model): def call(self, inputs): return inputs # Can wrap an decorated keras subclass model assert isinstance(TensorFlowWrapper(TestModel()), Model) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_keras_subclass_decorator_capture_args_kwargs( X, Y, input_size, n_classes, answer ): import tensorflow as tf @keras_subclass( "TestModel", X=numpy.array([0.0, 0.0]), Y=numpy.array([0.5]), input_shape=(2,) ) class TestModel(tf.keras.Model): def __init__(self, custom=False, **kwargs): super().__init__(self) # This is to force the mode to pass the captured arguments # or fail. assert custom is True assert kwargs.get("other", None) is not None def call(self, inputs): return inputs # Can wrap an decorated keras subclass model model = TensorFlowWrapper(TestModel(True, other=1337)) assert hasattr(model.shims[0]._model, "eg_args") args_kwargs = model.shims[0]._model.eg_args assert True in args_kwargs.args assert "other" in args_kwargs.kwargs # Raises an error if the args/kwargs is not serializable obj = {} obj["key"] = obj with pytest.raises(ValueError): TensorFlowWrapper(TestModel(True, other=obj)) # Provides the same arguments when copying a capture model model = model.from_bytes(model.to_bytes()) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_can_copy_model(model): copy = model.copy() assert copy is not None @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_print_summary(model, X): summary = str(model.shims[0]) # Summary includes the layers of our model assert "layer_normalization" in summary assert "dense" in summary # And counts of params assert "Total params" in summary assert "Trainable params" in summary assert "Non-trainable params" in summary @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_to_bytes(model, X): # And can be serialized model_bytes = model.to_bytes() assert model_bytes is not None model.from_bytes(model_bytes) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_to_from_disk(model, X, Y, answer): with make_tempdir() as tmp_path: model_file = tmp_path / "model.h5" model.to_disk(model_file) another_model = model.from_disk(model_file) assert another_model is not None @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_from_bytes(model, X): model.predict(X) model_bytes = model.to_bytes() another_model = model.from_bytes(model_bytes) assert another_model is not None @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_use_params(model, X, Y, answer): optimizer = Adam() ops = get_current_ops() with model.use_params(optimizer.averages): assert model.predict(X).argmax() is not None for i in range(10): guesses, backprop = model.begin_update(X) # Ensure that the tensor is type-compatible with the current backend. guesses = ops.asarray(guesses) d_guesses = (guesses - Y) / guesses.shape[0] backprop(d_guesses) model.finish_update(optimizer) with model.use_params(optimizer.averages): predicted = model.predict(X).argmax() assert predicted == answer @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_to_cpu(tf_model): model = TensorFlowWrapper(tf_model) model.to_cpu() @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") @pytest.mark.skipif(not has_cupy_gpu, reason="needs GPU/cupy") def test_tensorflow_wrapper_to_gpu(model, X): model.to_gpu(0) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") @pytest.mark.parametrize( "data,n_args,kwargs_keys", [ # fmt: off (numpy.zeros((2, 3), dtype="f"), 1, []), ([numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")], 2, []), ((numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")), 2, []), ({"a": numpy.zeros((2, 3), dtype="f"), "b": numpy.zeros((2, 3), dtype="f")}, 0, ["a", "b"]), (ArgsKwargs((numpy.zeros((2, 3), dtype="f"), numpy.zeros((2, 3), dtype="f")), {"c": numpy.zeros((2, 3), dtype="f")}), 2, ["c"]), # fmt: on ], ) def test_tensorflow_wrapper_convert_inputs(data, n_args, kwargs_keys): import tensorflow as tf keras_model = tf.keras.Sequential([tf.keras.layers.Dense(12, input_shape=(12,))]) model = TensorFlowWrapper(keras_model) convert_inputs = model.attrs["convert_inputs"] Y, backprop = convert_inputs(model, data, is_train=True) check_input_converters(Y, backprop, data, n_args, kwargs_keys, tf.Tensor) @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_thinc_model_subclass(tf_model): class CustomModel(Model): def fn(self): return 1337 model = TensorFlowWrapper(tf_model, model_class=CustomModel) assert isinstance(model, CustomModel) assert model.fn() == 1337 @pytest.mark.skipif(not has_tensorflow, reason="needs TensorFlow") def test_tensorflow_wrapper_thinc_set_model_name(tf_model): model = TensorFlowWrapper(tf_model, model_name="cool") assert model.name == "cool" thinc-9.0.0/thinc/tests/layers/test_torchscriptwrapper.py000066400000000000000000000014461461023342500237560ustar00rootroot00000000000000import numpy import pytest from thinc.api import ( PyTorchWrapper_v2, TorchScriptWrapper_v1, pytorch_to_torchscript_wrapper, ) from thinc.compat import has_torch, torch @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.parametrize("nN,nI,nO", [(2, 3, 4)]) def test_pytorch_script(nN, nI, nO): model = PyTorchWrapper_v2(torch.nn.Linear(nI, nO)).initialize() script_model = pytorch_to_torchscript_wrapper(model) X = numpy.random.randn(nN, nI).astype("f") Y = model.predict(X) Y_script = script_model.predict(X) numpy.testing.assert_allclose(Y, Y_script) serialized = script_model.to_bytes() script_model2 = TorchScriptWrapper_v1() script_model2.from_bytes(serialized) numpy.testing.assert_allclose(Y, script_model2.predict(X)) thinc-9.0.0/thinc/tests/layers/test_transforms.py000066400000000000000000000036701461023342500222100ustar00rootroot00000000000000import numpy import pytest from thinc.api import NumpyOps, Ragged, registry, strings2arrays from ..util import get_data_checker @pytest.fixture(params=[[], [(10, 2)], [(5, 3), (1, 3)], [(2, 3), (0, 3), (1, 3)]]) def shapes(request): return request.param @pytest.fixture def ops(): return NumpyOps() @pytest.fixture def list_data(shapes): return [numpy.zeros(shape, dtype="f") for shape in shapes] @pytest.fixture def ragged_data(ops, list_data): lengths = numpy.array([len(x) for x in list_data], dtype="i") if not list_data: return Ragged(ops.alloc2f(0, 0), lengths) else: return Ragged(ops.flatten(list_data), lengths) @pytest.fixture def padded_data(ops, list_data): return ops.list2padded(list_data) @pytest.fixture def array_data(ragged_data): return ragged_data.data def check_transform(transform, in_data, out_data): model = registry.resolve({"config": {"@layers": transform}})["config"] input_checker = get_data_checker(in_data) output_checker = get_data_checker(out_data) model.initialize(in_data, out_data) Y, backprop = model(in_data, is_train=True) output_checker(Y, out_data) dX = backprop(Y) input_checker(dX, in_data) def test_list2array(list_data, array_data): check_transform("list2array.v1", list_data, array_data) def test_list2ragged(list_data, ragged_data): check_transform("list2ragged.v1", list_data, ragged_data) def test_list2padded(list_data, padded_data): check_transform("list2padded.v1", list_data, padded_data) def test_ragged2list(ragged_data, list_data): check_transform("ragged2list.v1", ragged_data, list_data) def test_padded2list(padded_data, list_data): check_transform("padded2list.v1", padded_data, list_data) def test_strings2arrays(): strings = ["hello", "world"] model = strings2arrays() Y, backprop = model.begin_update(strings) assert len(Y) == len(strings) assert backprop([]) == [] thinc-9.0.0/thinc/tests/layers/test_uniqued.py000066400000000000000000000043141461023342500214600ustar00rootroot00000000000000import numpy import pytest from hypothesis import given, settings from hypothesis.strategies import composite, integers, lists from numpy.testing import assert_allclose from thinc.layers import Embed from thinc.layers.uniqued import uniqued ROWS = 10 # This test uses a newer hypothesis feature than the skanky flatmap-style # I used previously. This is much nicer, although it still takes some getting # used to. The key feature is this composite decorator. It injects a function, # 'draw'. @composite def lists_of_integers(draw, columns=2, lo=0, hi=ROWS - 1): # We call draw to get example values, which we can manipulate. # Here we get a list of integers, where each member of the list # should be between a min and max value. int_list = draw(lists(integers(min_value=lo, max_value=hi))) # Now we can use this int list to make an array, and it'll be the arrays # that our functions receive. # We trim the list, so we're of length divisible by columns. int_list = int_list[len(int_list) % columns :] # And make the array and reshape it. array = numpy.array(int_list, dtype="uint64") return array.reshape((-1, columns)) @pytest.fixture(scope="module") def model(nO=128): return Embed(nO, ROWS, column=0).initialize() def test_uniqued_calls_init(): calls = [] embed = Embed(5, 5, column=0) embed.init = lambda *args, **kwargs: calls.append(True) embed.initialize() assert calls == [True] uembed = uniqued(embed) uembed.initialize() assert calls == [True, True] @given(X=lists_of_integers(lo=0, hi=ROWS - 1)) @settings(deadline=None) def test_uniqued_doesnt_change_result(model, X): umodel = uniqued(model, column=model.attrs["column"]).initialize() Y, bp_Y = model(X, is_train=True) Yu, bp_Yu = umodel(X, is_train=True) assert_allclose(Y, Yu) dX = bp_Y(Y) dXu = bp_Yu(Yu) assert_allclose(dX, dXu) if X.size: pass # TODO: This test is a problem, because we exceed the embedding table. # Fix it with a better cap. # Check that different inputs do give different results # Z, bp_Z = model(X + 1, is_train=True) # with pytest.raises(AssertionError): # assert_allclose(Y, Z) thinc-9.0.0/thinc/tests/layers/test_with_debug.py000066400000000000000000000014421461023342500221260ustar00rootroot00000000000000from mock import MagicMock from thinc.api import Linear, with_debug def test_with_debug(): on_init = MagicMock() on_forward = MagicMock() on_backprop = MagicMock() model = with_debug( Linear(), on_init=on_init, on_forward=on_forward, on_backprop=on_backprop ) on_init.assert_not_called() on_forward.assert_not_called() on_backprop.assert_not_called() X = model.ops.alloc2f(1, 1) Y = model.ops.alloc2f(1, 1) model.initialize(X=X, Y=Y) on_init.assert_called_once_with(model, X, Y) on_forward.assert_not_called() on_backprop.assert_not_called() Yh, backprop = model(X, is_train=True) on_forward.assert_called_once_with(model, X, True) on_backprop.assert_not_called() backprop(Y) on_backprop.assert_called_once_with(Y) thinc-9.0.0/thinc/tests/layers/test_with_flatten.py000066400000000000000000000015471461023342500225030ustar00rootroot00000000000000from typing import List from thinc.api import Model, with_flatten_v2 INPUT = [[1, 2, 3], [4, 5], [], [6, 7, 8]] INPUT_FLAT = [1, 2, 3, 4, 5, 6, 7, 8] OUTPUT = [[2, 3, 4], [5, 6], [], [7, 8, 9]] BACKPROP_OUTPUT = [[3, 4, 5], [6, 7], [], [8, 9, 10]] def _memoize_input() -> Model[List[int], List[int]]: return Model(name="memoize_input", forward=_memoize_input_forward) def _memoize_input_forward( model: Model[List[int], List[int]], X: List[int], is_train: bool ): model.attrs["last_input"] = X def backprop(dY: List[int]): return [v + 2 for v in dY] return [v + 1 for v in X], backprop def test_with_flatten(): model = with_flatten_v2(_memoize_input()) Y, backprop = model(INPUT, is_train=True) assert Y == OUTPUT assert model.layers[0].attrs["last_input"] == INPUT_FLAT assert backprop(INPUT) == BACKPROP_OUTPUT thinc-9.0.0/thinc/tests/layers/test_with_transforms.py000066400000000000000000000236711461023342500232460ustar00rootroot00000000000000import numpy import numpy.testing import pytest from thinc.api import ( Linear, Model, NumpyOps, noop, with_array, with_array2d, with_getitem, with_list, with_padded, with_ragged, ) from thinc.types import Padded, Ragged from ..util import get_data_checker @pytest.fixture(params=[[], [(10, 2)], [(5, 3), (1, 3)], [(2, 3), (0, 3), (1, 3)]]) def shapes(request): return request.param @pytest.fixture def ops(): return NumpyOps() @pytest.fixture def list_input(shapes): data = [numpy.zeros(shape, dtype="f") for shape in shapes] for i, x in enumerate(data): # Give values that make it easy to see where rows or columns mismatch. x += i * 100 x += numpy.arange(x.shape[0]).reshape((-1, 1)) * 10 x += numpy.arange(x.shape[1]).reshape((1, -1)) return data @pytest.fixture def ragged_input(ops, list_input): lengths = numpy.array([len(x) for x in list_input], dtype="i") if not list_input: return Ragged(ops.alloc2f(0, 0), lengths) else: return Ragged(ops.flatten(list_input), lengths) @pytest.fixture def padded_input(ops, list_input): return ops.list2padded(list_input) @pytest.fixture def array_input(ragged_input): return ragged_input.data @pytest.fixture def padded_data_input(padded_input): x = padded_input return (x.data, x.size_at_t, x.lengths, x.indices) @pytest.fixture def ragged_data_input(ragged_input): return (ragged_input.data, ragged_input.lengths) @pytest.fixture def noop_models(): return [ with_padded(noop()), with_array(noop()), with_array2d(noop()), with_list(noop()), with_ragged(noop()), ] # As an example operation, lets just trim the last dimension. That # should catch stuff that confuses the input and output. def get_array_model(): def _trim_array_forward(model, X, is_train): def backprop(dY): return model.ops.alloc2f(dY.shape[0], dY.shape[1] + 1) return X[:, :-1], backprop return with_array2d(Model("trimarray", _trim_array_forward)) def get_list_model(): def _trim_list_forward(model, Xs, is_train): def backprop(dYs): dXs = [] for dY in dYs: dXs.append(model.ops.alloc2f(dY.shape[0], dY.shape[1] + 1)) return dXs Ys = [X[:, :-1] for X in Xs] return Ys, backprop return with_list(Model("trimlist", _trim_list_forward)) def get_padded_model(): def _trim_padded_forward(model, Xp, is_train): def backprop(dYp): dY = dYp.data dX = model.ops.alloc3f(dY.shape[0], dY.shape[1], dY.shape[2] + 1) return Padded(dX, dYp.size_at_t, dYp.lengths, dYp.indices) assert isinstance(Xp, Padded) X = Xp.data X = X.reshape((X.shape[0] * X.shape[1], X.shape[2])) X = X[:, :-1] X = X.reshape((Xp.data.shape[0], Xp.data.shape[1], X.shape[1])) return Padded(X, Xp.size_at_t, Xp.lengths, Xp.indices), backprop return with_padded(Model("trimpadded", _trim_padded_forward)) def get_ragged_model(): def _trim_ragged_forward(model, Xr, is_train): def backprop(dYr): dY = dYr.data dX = model.ops.alloc2f(dY.shape[0], dY.shape[1] + 1) return Ragged(dX, dYr.lengths) return Ragged(Xr.data[:, :-1], Xr.lengths), backprop return with_ragged(Model("trimragged", _trim_ragged_forward)) def check_initialize(model, inputs): # Just check that these run and don't hit errors. I guess we should add a # spy and check that model.layers[0].initialize gets called, but shrug? model.initialize() model.initialize(X=inputs) model.initialize(X=inputs, Y=model.predict(inputs)) def check_transform_produces_correct_output_type_forward(model, inputs, checker): # It's pretty redundant to check these three assertions, so if the tests # get slow this could be removed. I think it should be fine though? outputs = model.predict(inputs) assert checker(inputs, outputs) outputs, _ = model(inputs, is_train=True) assert checker(inputs, outputs) outputs, _ = model(inputs, is_train=False) assert checker(inputs, outputs) def check_transform_produces_correct_output_type_backward(model, inputs, checker): # It's pretty redundant to check these three assertions, so if the tests # get slow this could be removed. I think it should be fine though? outputs, backprop = model.begin_update(inputs) d_inputs = backprop(outputs) assert checker(inputs, d_inputs) def check_transform_doesnt_change_noop_values(model, inputs, d_outputs): # Check that if we're wrapping a noop() layer in the transform, we don't # change the output values. outputs, backprop = model.begin_update(inputs) d_inputs = backprop(d_outputs) if isinstance(outputs, list): for i in range(len(outputs)): numpy.testing.assert_equal(inputs[i], outputs[i]) numpy.testing.assert_equal(d_outputs[i], d_inputs[i]) elif isinstance(outputs, numpy.ndarray): numpy.testing.assert_equal(inputs, outputs) numpy.testing.assert_equal(d_outputs, d_inputs) elif isinstance(outputs, Ragged): numpy.testing.assert_equal(inputs.data, outputs.data) numpy.testing.assert_equal(d_outputs.data, d_inputs.data) elif isinstance(outputs, Padded): numpy.testing.assert_equal(inputs.data, outputs.data) numpy.testing.assert_equal(d_inputs.data, d_inputs.data) def test_noop_transforms(noop_models, ragged_input, padded_input, list_input): # Make distinct backprop values, # to check that the gradients get passed correctly d_ragged = Ragged(ragged_input.data + 1, ragged_input.lengths) d_padded = padded_input.copy() d_padded.data += 1 d_list = [dx + 1 for dx in list_input] for model in noop_models: print(model.name) check_transform_doesnt_change_noop_values(model, padded_input, d_padded) check_transform_doesnt_change_noop_values(model, list_input, d_list) check_transform_doesnt_change_noop_values(model, ragged_input, d_ragged) def test_with_array_initialize(ragged_input, padded_input, list_input, array_input): for inputs in (ragged_input, padded_input, list_input, array_input): check_initialize(get_array_model(), inputs) def test_with_padded_initialize( ragged_input, padded_input, list_input, padded_data_input ): for inputs in (ragged_input, padded_input, list_input, padded_data_input): check_initialize(get_padded_model(), inputs) def test_with_list_initialize(ragged_input, padded_input, list_input): for inputs in (ragged_input, padded_input, list_input): check_initialize(get_list_model(), inputs) def test_with_ragged_initialize( ragged_input, padded_input, list_input, ragged_data_input ): for inputs in (ragged_input, padded_input, list_input, ragged_data_input): check_initialize(get_ragged_model(), inputs) def test_with_array_forward(ragged_input, padded_input, list_input, array_input): for inputs in (ragged_input, padded_input, list_input, array_input): checker = get_data_checker(inputs) model = get_array_model() check_transform_produces_correct_output_type_forward(model, inputs, checker) def test_with_list_forward(ragged_input, padded_input, list_input): for inputs in (ragged_input, padded_input, list_input): checker = get_data_checker(inputs) model = get_list_model() check_transform_produces_correct_output_type_forward(model, inputs, checker) def test_with_padded_forward(ragged_input, padded_input, list_input, padded_data_input): for inputs in (ragged_input, padded_input, list_input, padded_data_input): checker = get_data_checker(inputs) model = get_padded_model() check_transform_produces_correct_output_type_forward(model, inputs, checker) def test_with_ragged_forward(ragged_input, padded_input, list_input, ragged_data_input): for inputs in (ragged_input, padded_input, list_input, ragged_data_input): checker = get_data_checker(inputs) model = get_ragged_model() check_transform_produces_correct_output_type_forward(model, inputs, checker) def test_with_array_backward(ragged_input, padded_input, list_input, array_input): for inputs in (ragged_input, padded_input, list_input, array_input): checker = get_data_checker(inputs) model = get_array_model() check_transform_produces_correct_output_type_backward(model, inputs, checker) def test_with_list_backward(ragged_input, padded_input, list_input): for inputs in (ragged_input, padded_input, list_input): checker = get_data_checker(inputs) model = get_list_model() check_transform_produces_correct_output_type_backward(model, inputs, checker) def test_with_ragged_backward( ragged_input, padded_input, list_input, ragged_data_input ): for inputs in (ragged_input, padded_input, list_input, ragged_data_input): checker = get_data_checker(inputs) model = get_ragged_model() check_transform_produces_correct_output_type_backward(model, inputs, checker) def test_with_padded_backward( ragged_input, padded_input, list_input, padded_data_input ): for inputs in (ragged_input, padded_input, list_input, padded_data_input): checker = get_data_checker(inputs) model = get_padded_model() check_transform_produces_correct_output_type_backward(model, inputs, checker) def test_with_getitem(): data = ( numpy.asarray([[1, 2, 3, 4]], dtype="f"), numpy.asarray([[5, 6, 7, 8]], dtype="f"), ) model = with_getitem(1, Linear()) model.initialize(data, data) Y, backprop = model.begin_update(data) assert len(Y) == len(data) assert numpy.array_equal(Y[0], data[0]) # the other item stayed the same assert not numpy.array_equal(Y[1], data[1]) dX = backprop(Y) assert numpy.array_equal(dX[0], data[0]) assert not numpy.array_equal(dX[1], data[1]) thinc-9.0.0/thinc/tests/model/000077500000000000000000000000001461023342500161745ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/model/__init__.py000066400000000000000000000000001461023342500202730ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/model/test_model.py000066400000000000000000000467161461023342500207230ustar00rootroot00000000000000import threading import time from collections import Counter import numpy import pytest from thinc.api import ( Adam, CupyOps, Dropout, Linear, Model, Relu, Shim, Softmax, chain, change_attr_values, concatenate, set_dropout_rate, use_ops, with_debug, wrap_model_recursive, ) from thinc.compat import has_cupy_gpu from ..util import make_tempdir @pytest.fixture def model_with_no_args(): return Linear() def create_model(name): return Model(name, lambda X: (X, lambda dY: dY)) def test_model_defaults_to_cpu(model_with_no_args): assert not isinstance(model_with_no_args.ops, CupyOps) def test_models_get_different_ids(model_with_no_args): model1 = Linear() model2 = Linear() assert model1.id != model2.id def test_model_init(): class MyShim(Shim): name = "testshim" model_a = create_model("a") model = Model( "test", lambda X: (X, lambda dY: dY), dims={"nI": 10, "nO": None}, params={"W": numpy.zeros((10,)), "b": None}, refs={"a": model_a, "b": None}, attrs={"foo": "bar"}, shims=[MyShim(None)], layers=[model_a, model_a], ) assert model.has_param("W") assert model.get_param("W").shape == (10,) assert model.has_param("b") is None with pytest.raises(KeyError): model.get_param("b") with pytest.raises(KeyError): model.get_param("X") model.set_param("X", numpy.zeros((10,))) assert model.has_param("X") assert model.get_param("X").shape == (10,) with model.use_params({(model.id, "X"): numpy.ones((10,))}): assert numpy.array_equal(model.get_param("X"), numpy.ones((10,))) assert numpy.array_equal(model.get_param("X"), numpy.zeros((10,))) assert not model.has_grad("W") assert not model.has_grad("xyz") with pytest.raises(KeyError): model.get_grad("b") model.set_param("W", model.ops.alloc1f(10)) model.set_grad("W", model.ops.alloc1f(10)) with pytest.raises(ValueError): model.inc_grad("W", numpy.zeros((5, 0))) assert model.has_dim("nI") assert model.get_dim("nI") == 10 with pytest.raises(KeyError): model.get_dim("xyz") with pytest.raises(ValueError): model.get_dim("nO") assert model.has_ref("a") assert model.get_ref("a").name == "a" assert not model.has_ref("xyz") with pytest.raises(KeyError): model.get_ref("xyz") assert model.has_ref("b") is None with pytest.raises(ValueError): model.get_ref("b") model.set_ref("c", model_a) assert model.has_ref("c") assert model.get_ref("c").name == "a" with pytest.raises(ValueError): model.set_ref("c", create_model("c")) assert "foo" in model.attrs assert "bar" not in model.attrs assert model.attrs["foo"] == "bar" with pytest.raises(KeyError): model.attrs["bar"] model.attrs["bar"] = "baz" model_copy = model.copy() assert model_copy.name == "test" def test_model_set_dim(): class MyShim(Shim): name = "testshim" model_a = create_model("a") model = Model( "test", lambda X: (X, lambda dY: dY), dims={"nI": 5, "nO": None}, params={"W": None, "b": None}, refs={"a": model_a, "b": None}, attrs={"foo": "bar"}, shims=[MyShim(None)], layers=[model_a, model_a], ) with pytest.raises(ValueError): model.set_dim("nI", 10) # force can be used before any parameters are set model.set_dim("nI", 10, force=True) model.set_param("W", model.ops.alloc1f(10)) model.set_grad("W", model.ops.alloc1f(10)) assert model.has_dim("nI") assert model.get_dim("nI") == 10 with pytest.raises(KeyError): model.set_dim("xyz", 20) with pytest.raises(ValueError): model.set_dim("nI", 20) # force can't be used after any parameter is set with pytest.raises(ValueError): model.set_dim("nI", 20, force=True) def test_param_names(): model = create_model("tmp") assert model.param_names == tuple() model.set_param("param1", None) assert model.param_names == ("param1",) model.set_param("param2", None) assert model.param_names == ("param1", "param2") def test_grad_names(): model = create_model("tmp") assert model.grad_names == tuple() model.set_param("param1", model.ops.alloc2f(4, 4)) model.set_grad("param1", model.ops.alloc2f(4, 4) + 1) assert model.grad_names == ("param1",) def test_dim_names(): model = Linear(5, 3) assert model.dim_names == ("nO", "nI") def test_model_set_reference(): parent = create_model("parent") child = create_model("child") grandchild = create_model("child") parent.layers.append(child) assert parent.ref_names == tuple() parent.set_ref("kid", child) assert parent.ref_names == ("kid",) assert parent.get_ref("kid") is child child.layers.append(grandchild) with pytest.raises(KeyError): parent.get_ref("grandkid") parent.set_ref("grandkid", grandchild) assert parent.get_ref("grandkid") is grandchild parent.remove_node(grandchild) assert grandchild not in child.layers assert not parent.has_ref("grandkind") def test_maybe_methods(): model = Linear(5) assert model.maybe_get_dim("nI") is None model.set_dim("nI", 4) assert model.maybe_get_dim("nI") == 4 assert model.maybe_get_ref("boo") is None assert model.maybe_get_param("W") is None model.initialize() assert model.maybe_get_param("W") is not None def test_model_can_save_to_disk(model_with_no_args): with make_tempdir() as path: model_with_no_args.to_disk(path / "thinc_model") def test_model_can_load_from_disk(model_with_no_args): with make_tempdir() as path: model_with_no_args.to_disk(path / "thinc_model") m2 = model_with_no_args.from_disk(path / "thinc_model") assert model_with_no_args.to_bytes() == m2.to_bytes() def test_model_can_roundtrip_with_path_subclass(model_with_no_args, pathy_fixture): path = pathy_fixture / "thinc_model" model_with_no_args.to_disk(path) m2 = model_with_no_args.from_disk(path) assert model_with_no_args.to_bytes() == m2.to_bytes() def test_change_attr_values(model_with_no_args): model = model_with_no_args model.name = "target" model.attrs["has_var"] = False change_attr_values(model, {"target": {"has_var": True, "error": True}}) assert model.attrs["has_var"] is True assert "error" not in model.attrs def test_set_dropout(): model = Dropout() assert model.attrs["dropout_rate"] == 0.0 set_dropout_rate(model, 0.2) assert model.attrs["dropout_rate"] == 0.2 def test_set_dropout_2(model_with_no_args): model = model_with_no_args model.name = "dropout" model.attrs["dropout_rate"] = 0.0 set_dropout_rate(model, 0.2) assert model.attrs["dropout_rate"] == 0.2 def test_bind_plus(): with Model.define_operators({"+": lambda a, b: (a.name, b.name)}): m = create_model(name="a") + create_model(name="b") assert m == ("a", "b") def test_plus_chain(): with Model.define_operators({"+": lambda a, b: a}): m = ( create_model(name="a") + create_model(name="b") + create_model(name="c") + create_model(name="d") ) assert m.name == "a" def test_overload_operators_in_subthread(): """Test we can create a model in a child thread with overloaded operators.""" # Worker1 will start and run, while worker 2 sleeps after Model.define_operators. # Without thread-safety, worker2 will find that its operator definitions # have been removed, causing an error. worker1 = threading.Thread(target=_overload_plus, args=("+", 0)) worker2 = threading.Thread(target=_overload_plus, args=("*", 1)) worker2.start() worker1.start() worker1.join() worker2.join() worker1 = threading.Thread(target=_overload_plus, args=("+", 1)) worker2 = threading.Thread(target=_overload_plus, args=("*", 0)) worker2.start() worker1.start() worker1.join() worker2.join() def _overload_plus(operator, sleep): m1 = create_model(name="a") m2 = create_model(name="b") with Model.define_operators({operator: lambda a, b: a.name + b.name}): time.sleep(sleep) if operator == "+": value = m1 + m2 else: value = m1 * m2 assert value == "ab" assert Model._context_operators.get() == {} def test_nested_operator_contexts(): m1 = create_model(name="a") m2 = create_model(name="b") assert Model._context_operators.get() == {} with Model.define_operators({"+": lambda a, b: a.name + b.name}): value = m1 + m2 with pytest.raises(TypeError): value = m1 * m2 with Model.define_operators({"*": lambda a, b: a.name + b.name}): with pytest.raises(TypeError): value = m1 + m2 value = m1 * m2 with Model.define_operators({"-": lambda a, b: a.name + b.name}): with pytest.raises(TypeError): value = m1 + m2 value = m1 - m2 with pytest.raises(TypeError): value = m1 + m2 value = m1 * m2 value = m1 + m2 with pytest.raises(TypeError): value = m1 * m2 assert value == "ab" assert Model._context_operators.get() == {} @pytest.mark.parametrize("op", "+ - * @ / // % ** << >> & ^ |".split()) def test_all_operators(op): m1 = Linear() m2 = Linear() with Model.define_operators({op: lambda a, b: a.name + b.name}): if op == "+": value = m1 + m2 else: with pytest.raises(TypeError): value = m1 + m2 if op == "-": value = m1 - m2 else: with pytest.raises(TypeError): value = m1 - m2 if op == "*": value = m1 * m2 else: with pytest.raises(TypeError): value = m1 * m2 if op == "@": value = m1.__matmul__(m2) # Be kind to Python 2... else: with pytest.raises(TypeError): value = m1.__matmul__(m2) if op == "/": value = m1 / m2 else: with pytest.raises(TypeError): value = m1 / m2 if op == "//": value = m1 // m2 else: with pytest.raises(TypeError): value = m1 // m2 if op == "^": value = m1 ^ m2 else: with pytest.raises(TypeError): value = m1 ^ m2 if op == "%": value = m1 % m2 else: with pytest.raises(TypeError): value = m1 % m2 if op == "**": value = m1**m2 else: with pytest.raises(TypeError): value = m1**m2 if op == "<<": value = m1 << m2 else: with pytest.raises(TypeError): value = m1 << m2 if op == ">>": value = m1 >> m2 else: with pytest.raises(TypeError): value = m1 >> m2 if op == "&": value = m1 & m2 else: with pytest.raises(TypeError): value = m1 & m2 if op == "^": value = m1 ^ m2 else: with pytest.raises(TypeError): value = m1 ^ m2 if op == "|": value = m1 | m2 else: with pytest.raises(TypeError): value = m1 | m2 # noqa: F841 assert Model._context_operators.get() == {} def test_unique_id_multithreading(): """Create a bunch of threads and assert they all get unique IDs""" list_of_ids = [] def get_model_id(id_list, index): id_list.append(create_model(name=f"worker{index}").id) counter = 0 while len(list_of_ids) < 1000: workers = [] for i in range(50): w = threading.Thread(target=get_model_id, args=(list_of_ids, counter)) workers.append(w) counter += 1 for w in workers: w.start() for w in workers: w.join() assert len(list_of_ids) == len(list(set(list_of_ids))) @pytest.mark.skipif(not has_cupy_gpu, reason="needs CuPy GPU") def test_model_gpu(): pytest.importorskip("ml_datasets") import ml_datasets with use_ops("cupy"): n_hidden = 32 dropout = 0.2 (train_X, train_Y), (dev_X, dev_Y) = ml_datasets.mnist() model = chain( Relu(nO=n_hidden, dropout=dropout), Relu(nO=n_hidden, dropout=dropout), Softmax(), ) # make sure the data is on the right device train_X = model.ops.asarray(train_X) train_Y = model.ops.asarray(train_Y) dev_X = model.ops.asarray(dev_X) dev_Y = model.ops.asarray(dev_Y) model.initialize(X=train_X[:5], Y=train_Y[:5]) optimizer = Adam(0.001) batch_size = 128 for i in range(2): batches = model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True) for X, Y in batches: Yh, backprop = model.begin_update(X) backprop(Yh - Y) model.finish_update(optimizer) # Evaluate and print progress correct = 0 total = 0 for X, Y in model.ops.multibatch(batch_size, dev_X, dev_Y): Yh = model.predict(X) correct += (Yh.argmax(axis=1) == Y.argmax(axis=1)).sum() total += Yh.shape[0] def test_replace_node(): relu1 = Relu(5) relu2 = Relu(5) relu_chain = chain(relu1, relu2) relu1_debug = with_debug(relu1) debug = Model( "test", lambda X: (X, lambda dY: dY), layers=[relu1, relu2, relu1, relu_chain], refs={"relu1": relu1, "relu2": relu2, "relu3": relu1}, ) debug.replace_node(relu1, relu1_debug) assert debug.layers[0] == relu1_debug assert debug.layers[1] == relu2 assert debug.layers[2] == relu1_debug assert debug.get_ref("relu1") == relu1_debug assert debug.get_ref("relu2") == relu2 assert debug.get_ref("relu3") == relu1_debug # Check that nodes are replaced recursively assert debug.layers[3] == relu_chain assert debug.layers[3].layers[0] == relu1_debug assert debug.layers[3].layers[1] == relu2 def test_replace_node_with_indirect_node_ref(): # a # / \ # x b[y=y] # | | # y x # | # y def dummy_model(name, layers): return Model(name, lambda model, X, is_train: ..., layers=layers) y = dummy_model("y", []) x = dummy_model("x", [y]) y_debug = with_debug(y) b = dummy_model("b", [x]) b.set_ref("y", y) a = chain(x, b) a.name = "a" a.replace_node(y, y_debug) assert a.layers[0].layers[0] == y_debug assert a.layers[1].layers[0].layers[0] == y_debug assert a.layers[1].get_ref("y") == y_debug def test_with_debug(): pytest.importorskip("ml_datasets") import ml_datasets (train_X, train_Y), (dev_X, dev_Y) = ml_datasets.mnist() counts = Counter() def on_init(*_): counts["init"] += 1 def on_forward(*_): counts["forward"] += 1 def on_backprop(*_): counts["backprop"] += 1 relu = Relu() relu2 = with_debug( Relu(), on_init=on_init, on_forward=on_forward, on_backprop=on_backprop ) chained = chain(relu, relu2, relu2) chained.initialize(X=train_X[:5], Y=train_Y[:5]) _, backprop = chained(X=train_X[:5], is_train=False) # Not real loss gradients, but we don't care for testing. backprop(train_Y[:5]) # Four times forward, because initialization also applies forward for # validation. assert counts == {"init": 2, "forward": 4, "backprop": 2} def test_recursive_wrap(): def dummy_model(name, layers): return Model(name, lambda model, X, is_train: ..., layers=layers) # Check: # # * Recursion: chain -> relu # * Multiple sublayers: chain -> [relu, relu] relu = Relu(5) chained = chain(relu, relu) chained_debug = wrap_model_recursive( chained, lambda model: dummy_model(f"dummy({model.name})", [model]) ) assert chained_debug.name == "dummy(relu>>relu)" assert chained_debug.layers[0] is chained assert chained_debug.layers[0].layers[0].name == "dummy(relu)" assert chained_debug.layers[0].layers[0].layers[0] is relu assert chained_debug.layers[0].layers[1].name == "dummy(relu)" assert chained_debug.layers[0].layers[1].layers[0] is relu def test_recursive_double_wrap(): def dummy_model(name, layers): return Model(name, lambda model, X, is_train: ..., layers=layers) relu = Relu(5) chained = chain(relu, relu) concat = concatenate(chained, chained, relu) concat_wrapped = wrap_model_recursive( concat, lambda model: dummy_model(f"dummy({model.name})", [model]) ) n_debug = 0 for model in concat_wrapped.walk(): if model.name.startswith("dummy"): n_debug += 1 # There should be 3 unique dummy wrappers: # * Around concatenate. # * Around chain. # * Around relu. assert n_debug == 3 assert concat_wrapped.layers[0].layers[0].layers[0].layers[0].name == "dummy(relu)" assert concat_wrapped.layers[0].layers[0].layers[0].layers[1].name == "dummy(relu)" assert concat_wrapped.layers[0].layers[1].layers[0].layers[0].name == "dummy(relu)" assert concat_wrapped.layers[0].layers[1].layers[0].layers[1].name == "dummy(relu)" assert concat_wrapped.layers[0].layers[2].name == "dummy(relu)" def test_wrap_non_child_references(): relu = Relu(5) relu2 = Relu(5) chained = chain(relu, relu) chained2 = chain(relu2, chained) chained2.set_ref("relu", relu) # Fails in case non-child references cannot be set. wrap_model_recursive(chained2, with_debug) def test_walk_dfs(): relu = Relu(5) relu2 = Relu(5) inner_chain = chain(relu, relu2) chained = chain(inner_chain, inner_chain) assert list(chained.walk(order="dfs_pre")) == [chained, inner_chain, relu, relu2] assert list(chained.walk(order="dfs_post")) == [ relu, relu2, inner_chain, chained, ] def test_walk_bfs_post_order_fails(): relu = Relu(5) with pytest.raises(ValueError, match="Invalid order"): relu.walk(order="dfs_post_order") def test_model_copy_with_loop(): class MyShim(Shim): name = "testshim" def to_bytes(self): return test_replace_node_with_indirect_node_ref def from_bytes(self, bytes): pass model_a = create_model("a") working_shim = MyShim(None) layer = Model( "test", lambda X: (X, lambda dY: dY), dims={"nI": 5, "nO": 5}, params={"W": numpy.zeros((10,)), "b": None}, refs={"a": model_a, "b": None}, attrs={"foo": "bar"}, shims=[working_shim], layers=[model_a, model_a], ) layer2 = Model( "test2", lambda X: (X, lambda dY: dY), dims={"nI": 5, "nO": 5}, params={"W": numpy.zeros((10,)), "b": None}, refs={"a": model_a, "b": None}, attrs={"foo": "bar"}, shims=[working_shim], layers=[model_a, model_a], ) relu = Relu(5) model = chain(layer, relu, layer, layer2) model2 = model.copy() model.from_dict(model2.to_dict()) assert model2.name == "test>>relu>>test>>test2" assert model2.layers[0] == model2.layers[2] assert id(model2.layers[0].shims[0]) == id(model2.layers[3].shims[0]) thinc-9.0.0/thinc/tests/model/test_validation.py000066400000000000000000000025521461023342500217430ustar00rootroot00000000000000import pytest from thinc.api import ( ParametricAttention, Relu, Softmax, chain, list2ragged, reduce_max, reduce_sum, with_ragged, ) from thinc.util import DataValidationError, data_validation def test_validation(): model = chain(Relu(10), Relu(10), with_ragged(reduce_max()), Softmax()) with data_validation(True): with pytest.raises(DataValidationError): model.initialize(X=model.ops.alloc2f(1, 10), Y=model.ops.alloc2f(1, 10)) with pytest.raises(DataValidationError): model.initialize(X=model.ops.alloc3f(1, 10, 1), Y=model.ops.alloc2f(1, 10)) with pytest.raises(DataValidationError): model.initialize(X=[model.ops.alloc2f(1, 10)], Y=model.ops.alloc2f(1, 10)) def test_validation_complex(): good_model = chain(list2ragged(), reduce_sum(), Relu(12, dropout=0.5), Relu(1)) X = [good_model.ops.xp.zeros((4, 75), dtype="f")] Y = good_model.ops.xp.zeros((1,), dtype="f") good_model.initialize(X, Y) good_model.predict(X) bad_model = chain( list2ragged(), reduce_sum(), Relu(12, dropout=0.5), # ERROR: Why can't I attach a Relu to an attention layer? ParametricAttention(12), Relu(1), ) with data_validation(True): with pytest.raises(DataValidationError): bad_model.initialize(X, Y) thinc-9.0.0/thinc/tests/mypy/000077500000000000000000000000001461023342500160725ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/mypy/__init__.py000066400000000000000000000000001461023342500201710ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/mypy/configs/000077500000000000000000000000001461023342500175225ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/mypy/configs/mypy-default.ini000066400000000000000000000003031461023342500226370ustar00rootroot00000000000000[mypy] follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True # disallow_any_generics = True check_untyped_defs = True disallow_untyped_defs = True thinc-9.0.0/thinc/tests/mypy/configs/mypy-plugin.ini000066400000000000000000000003311461023342500225120ustar00rootroot00000000000000[mypy] plugins = thinc.mypy follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True # disallow_any_generics = True check_untyped_defs = True disallow_untyped_defs = True thinc-9.0.0/thinc/tests/mypy/modules/000077500000000000000000000000001461023342500175425ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/mypy/modules/__init__.py000066400000000000000000000000001461023342500216410ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/mypy/modules/fail_no_plugin.py000066400000000000000000000002471461023342500231040ustar00rootroot00000000000000from thinc.api import Relu, Softmax, add, chain, reduce_max bad_model = chain(Relu(10), reduce_max(), Softmax()) bad_model2 = add(Relu(10), reduce_max(), Softmax()) thinc-9.0.0/thinc/tests/mypy/modules/fail_plugin.py000066400000000000000000000010651461023342500224070ustar00rootroot00000000000000from thinc.api import Relu, Softmax, add, chain, concatenate, reduce_max bad_model = chain(Relu(10), reduce_max(), Softmax()) bad_model2 = add(Relu(10), reduce_max(), Softmax()) bad_model_only_plugin = chain( Relu(10), Relu(10), Relu(10), Relu(10), reduce_max(), Softmax() ) bad_model_only_plugin2 = add( Relu(10), Relu(10), Relu(10), Relu(10), reduce_max(), Softmax() ) reveal_type(bad_model_only_plugin2) bad_model_only_plugin3 = concatenate( Relu(10), Relu(10), Relu(10), Relu(10), reduce_max(), Softmax() ) reveal_type(bad_model_only_plugin3) thinc-9.0.0/thinc/tests/mypy/modules/success_no_plugin.py000066400000000000000000000006541461023342500236430ustar00rootroot00000000000000from thinc.api import Relu, Softmax, add, chain, reduce_max good_model = chain(Relu(10), Relu(10), Softmax()) reveal_type(good_model) good_model2 = add(Relu(10), Relu(10), Softmax()) reveal_type(good_model2) bad_model_undetected = chain(Relu(10), Relu(10), reduce_max(), Softmax()) reveal_type(bad_model_undetected) bad_model_undetected2 = add(Relu(10), Relu(10), reduce_max(), Softmax()) reveal_type(bad_model_undetected2) thinc-9.0.0/thinc/tests/mypy/modules/success_plugin.py000066400000000000000000000014771461023342500231530ustar00rootroot00000000000000from typing import Any, TypeVar from thinc.api import Model, Relu, Softmax, add, chain, reduce_max good_model = chain(Relu(10), Relu(10), Softmax()) reveal_type(good_model) good_model2 = add(Relu(10), Relu(10), Softmax()) reveal_type(good_model2) bad_model_undetected = chain(Relu(10), Relu(10), Relu(10), Relu(10), Softmax()) reveal_type(bad_model_undetected) bad_model_undetected2 = add(Relu(10), Relu(10), Relu(10), Relu(10), Softmax()) reveal_type(bad_model_undetected2) def forward() -> None: pass OtherType = TypeVar("OtherType") def other_function( layer1: Model, layer2: Model, *layers: Model ) -> Model[Any, OtherType]: return Model("some_model", forward) non_combinator_model = other_function( Model("x", forward), Model("y", forward), Model("z", forward) ) reveal_type(non_combinator_model) thinc-9.0.0/thinc/tests/mypy/outputs/000077500000000000000000000000001461023342500176155ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/mypy/outputs/fail-no-plugin.txt000066400000000000000000000001611461023342500231750ustar00rootroot000000000000003: error: Cannot infer type argument 2 of "chain" [misc] 5: error: Cannot infer type argument 1 of "add" [misc]thinc-9.0.0/thinc/tests/mypy/outputs/fail-plugin.txt000066400000000000000000000045601461023342500225720ustar00rootroot000000000000003: error: Cannot infer type argument 2 of "chain" [misc] 3: error: Layer outputs type (thinc.types.Floats2d) but the next layer expects (thinc.types.Ragged) as an input [layer-mismatch-output] 3: error: Layer input type (thinc.types.Ragged) is not compatible with output (thinc.types.Floats2d) from previous layer [layer-mismatch-input] 5: error: Cannot infer type argument 1 of "add" [misc] 5: error: Layer input (thinc.types.Floats2d) not compatible with next layer input (thinc.types.Ragged) [layer-mismatch-input] 5: error: Layer input (thinc.types.Ragged) not compatible with previous layer input (thinc.types.Floats2d) [layer-mismatch-input] 5: error: Layer input (thinc.types.Ragged) not compatible with next layer input (thinc.types.Floats2d) [layer-mismatch-input] 5: error: Layer input (thinc.types.Floats2d) not compatible with previous layer input (thinc.types.Ragged) [layer-mismatch-input] 8: error: Layer outputs type (thinc.types.Floats2d) but the next layer expects (thinc.types.Ragged) as an input [layer-mismatch-output] 8: error: Layer input type (thinc.types.Ragged) is not compatible with output (thinc.types.Floats2d) from previous layer [layer-mismatch-input] 12: error: Layer input (thinc.types.Floats2d) not compatible with next layer input (thinc.types.Ragged) [layer-mismatch-input] 12: error: Layer input (thinc.types.Ragged) not compatible with previous layer input (thinc.types.Floats2d) [layer-mismatch-input] 12: error: Layer input (thinc.types.Ragged) not compatible with next layer input (thinc.types.Floats2d) [layer-mismatch-input] 12: error: Layer input (thinc.types.Floats2d) not compatible with previous layer input (thinc.types.Ragged) [layer-mismatch-input] 14: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, thinc.types.Floats2d]" 17: error: Layer input (thinc.types.Floats2d) not compatible with next layer input (thinc.types.Ragged) [layer-mismatch-input] 17: error: Layer input (thinc.types.Ragged) not compatible with previous layer input (thinc.types.Floats2d) [layer-mismatch-input] 17: error: Layer input (thinc.types.Ragged) not compatible with next layer input (thinc.types.Floats2d) [layer-mismatch-input] 17: error: Layer input (thinc.types.Floats2d) not compatible with previous layer input (thinc.types.Ragged) [layer-mismatch-input] 20: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, thinc.types.Floats2d]" thinc-9.0.0/thinc/tests/mypy/outputs/success-no-plugin.txt000066400000000000000000000011001461023342500237240ustar00rootroot000000000000003: error: Need type annotation for "good_model" [var-annotated] 4: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, Any]" 6: error: Need type annotation for "good_model2" [var-annotated] 7: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, Any]" 9: error: Need type annotation for "bad_model_undetected" [var-annotated] 10: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, Any]" 12: error: Need type annotation for "bad_model_undetected2" [var-annotated] 13: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, Any]"thinc-9.0.0/thinc/tests/mypy/outputs/success-plugin.txt000066400000000000000000000007561461023342500233320ustar00rootroot000000000000006: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, thinc.types.Floats2d]" 9: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, thinc.types.Floats2d]" 12: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, thinc.types.Floats2d]" 15: note: Revealed type is "thinc.model.Model[thinc.types.Floats2d, thinc.types.Floats2d]" 31: error: Need type annotation for "non_combinator_model" [var-annotated] 34: note: Revealed type is "thinc.model.Model[Any, Any]"thinc-9.0.0/thinc/tests/mypy/test_mypy.py000066400000000000000000000060001461023342500204750ustar00rootroot00000000000000import os import re import shutil import sys from pathlib import Path import pytest mypy = pytest.importorskip("mypy") # You can change the following variable to True during development to overwrite expected output with generated output GENERATE = False cases = [ ("mypy-plugin.ini", "success_plugin.py", "success-plugin.txt"), ("mypy-plugin.ini", "fail_plugin.py", "fail-plugin.txt"), ("mypy-default.ini", "success_no_plugin.py", "success-no-plugin.txt"), ("mypy-default.ini", "fail_no_plugin.py", "fail-no-plugin.txt"), ] @pytest.mark.skipif( mypy.__file__.endswith(".py"), reason="Non-compiled mypy is too slow" ) @pytest.mark.parametrize("config_filename,python_filename,output_filename", cases) def test_mypy_results( config_filename, python_filename, output_filename, tmpdir, monkeypatch ): from mypy import api as mypy_api os.chdir(tmpdir) root_dir = Path(__file__).parent thinc_root_dir = Path(__file__).parent.parent.parent.parent if "--pyargs" not in sys.argv: monkeypatch.setenv("MYPYPATH", str(thinc_root_dir)) tmpdir_path = Path(tmpdir) full_config_path: Path = root_dir / f"configs/{config_filename}" full_module_path: Path = root_dir / f"modules/{python_filename}" full_output_path: Path = root_dir / f"outputs/{output_filename}" full_tmp_config_path: Path = tmpdir_path / config_filename full_tmp_module_path: Path = tmpdir_path / python_filename shutil.copy(str(full_config_path), tmpdir) shutil.copy(str(full_module_path), tmpdir) expected_out = "" expected_err = "" expected_returncode = 1 expected_out = full_output_path.read_text() # Specifying a different cache dir for each configuration dramatically speeds up subsequent execution # It also prevents cache-invalidation-related bugs in the tests cache_dir = tmpdir_path / f".mypy_cache/test-{config_filename[:-4]}" command = [ str(full_tmp_module_path), "--config-file", str(full_tmp_config_path), "--cache-dir", str(cache_dir), "--show-error-codes", ] print( f"\nExecuting: mypy {' '.join(command)}" ) # makes it easier to debug as necessary actual_result = mypy_api.run(command) actual_out, actual_err, actual_returncode = actual_result # Need to strip filenames due to differences in formatting by OS actual_out = "\n".join( [".py:".join(line.split(".py:")[1:]) for line in actual_out.split("\n") if line] ).strip() actual_out = re.sub(r"\n\s*\n", r"\n", actual_out) if GENERATE and output_filename is not None: full_output_path.write_text(actual_out) else: assert actual_out.strip() == expected_out.strip(), actual_out assert actual_err == expected_err assert actual_returncode == expected_returncode @pytest.mark.skipif( mypy.__file__.endswith(".py"), reason="Non-compiled mypy is too slow" ) def test_generation_is_disabled(): """ Makes sure we don't accidentally leave generation on """ assert not GENERATE thinc-9.0.0/thinc/tests/regression/000077500000000000000000000000001461023342500172545ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/regression/__init__.py000066400000000000000000000000001461023342500213530ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/regression/issue519/000077500000000000000000000000001461023342500206435ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/regression/issue519/__init__.py000066400000000000000000000000001461023342500227420ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/regression/issue519/program.py000066400000000000000000000007401461023342500226650ustar00rootroot00000000000000from thinc.api import Relu, Softmax, chain, concatenate from thinc.model import Model from thinc.types import Floats2d n_hidden = 32 dropout = 0.2 model1: Model[Floats2d, Floats2d] = chain( Relu(nO=n_hidden, dropout=dropout), Relu(nO=n_hidden, dropout=dropout), Softmax() ) model2: Model[Floats2d, Floats2d] = chain( Relu(nO=n_hidden, dropout=dropout), Relu(nO=n_hidden, dropout=dropout), Softmax() ) model3: Model[Floats2d, Floats2d] = concatenate(*[model1, model2]) thinc-9.0.0/thinc/tests/regression/issue519/test_issue519.py000066400000000000000000000014611461023342500236450ustar00rootroot00000000000000import subprocess import sys try: import importlib.resources as importlib_resources except ImportError: import importlib_resources # type: ignore import pytest @pytest.mark.slow def test_issue519(): """ Test ability of Thinc mypy plugin to handle variadic arguments. This test can take up to 45 seconds, and is thus marked as slow. """ # Determine the name of the parent module (which contains the test program) parent_module_name = __name__[: __name__.rfind(".")] # Load test program that calls a Thinc API with variadic arguments program_text = importlib_resources.read_text(parent_module_name, "program.py") # Ask Mypy to type-check the loaded program text subprocess.run( [sys.executable, "-m", "mypy", "--command", program_text], check=True ) thinc-9.0.0/thinc/tests/regression/test_issue208.py000066400000000000000000000005101461023342500222430ustar00rootroot00000000000000from thinc.api import Linear, chain def test_issue208(): """Test issue that was caused by trying to flatten nested chains.""" layer1 = Linear(nO=9, nI=3) layer2 = Linear(nO=12, nI=9) layer3 = Linear(nO=5, nI=12) model = chain(layer1, chain(layer2, layer3)).initialize() assert model.get_dim("nO") == 5 thinc-9.0.0/thinc/tests/regression/test_issue564.py000066400000000000000000000010101461023342500222440ustar00rootroot00000000000000import pytest from thinc.api import CupyOps from thinc.compat import has_torch, has_torch_cuda_gpu @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.skipif(not has_torch_cuda_gpu, reason="needs a GPU") def test_issue564(): import torch if CupyOps.xp is not None: ops = CupyOps() t = torch.zeros((10, 2)).cuda() a = ops.asarray(t) assert a.shape == t.shape ops.xp.testing.assert_allclose( a, ops.alloc2f(10, 2), ) thinc-9.0.0/thinc/tests/shims/000077500000000000000000000000001461023342500162175ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/shims/__init__.py000066400000000000000000000000001461023342500203160ustar00rootroot00000000000000thinc-9.0.0/thinc/tests/shims/test_pytorch_grad_scaler.py000066400000000000000000000064251461023342500236550ustar00rootroot00000000000000import pytest from hypothesis import given, settings from hypothesis.strategies import lists, one_of, tuples from thinc.api import PyTorchGradScaler from thinc.compat import has_torch, has_torch_amp, has_torch_cuda_gpu, torch from thinc.util import is_torch_array from ..strategies import ndarrays def tensors(): return ndarrays().map(lambda a: torch.tensor(a).cuda()) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.skipif(not has_torch_cuda_gpu, reason="needs a GPU") @pytest.mark.skipif( not has_torch_amp, reason="requires PyTorch with mixed-precision support" ) @given(X=one_of(tensors(), lists(tensors()), tuples(tensors()))) @settings(deadline=None) def test_scale_random_inputs(X): import torch device_id = torch.cuda.current_device() scaler = PyTorchGradScaler(enabled=True) scaler.to_(device_id) if is_torch_array(X): assert torch.allclose(scaler.scale(X), X * 2.0**16) else: scaled1 = scaler.scale(X) scaled2 = [t * 2.0**16 for t in X] for t1, t2 in zip(scaled1, scaled2): assert torch.allclose(t1, t2) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.skipif(not has_torch_cuda_gpu, reason="needs a GPU") @pytest.mark.skipif( not has_torch_amp, reason="requires PyTorch with mixed-precision support" ) def test_grad_scaler(): import torch device_id = torch.cuda.current_device() scaler = PyTorchGradScaler(enabled=True) scaler.to_(device_id) # Test that scaling works as expected. t = torch.tensor([1.0], device=device_id) assert scaler.scale([torch.tensor([1.0], device=device_id)]) == [ torch.tensor([2.0**16], device=device_id) ] assert scaler.scale(torch.tensor([1.0], device=device_id)) == torch.tensor( [2.0**16], device=device_id ) with pytest.raises(ValueError): scaler.scale("bogus") with pytest.raises(ValueError): scaler.scale(42) # Test infinity detection. g = [ torch.tensor([2.0**16], device=device_id), torch.tensor([float("Inf")], device=device_id), ] # Check that infinity was found. assert scaler.unscale(g) # Check whether unscale was successful. assert g[0] == torch.tensor([1.0]).cuda() scaler.update() # Since infinity was found, the scale should be halved from 2**16 # to 2**15 for the next step. assert scaler.scale([torch.tensor([1.0], device=device_id)]) == [ torch.tensor([2.0**15], device=device_id) ] @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.skipif( has_torch_amp, reason="needs PyTorch without gradient scaling support" ) def test_raises_on_old_pytorch(): import torch scaler = PyTorchGradScaler(enabled=True) with pytest.raises(ValueError, match=r"not supported.*1.9.0"): scaler.scale([torch.tensor([1.0], device="cpu")]) @pytest.mark.skipif(not has_torch, reason="needs PyTorch") @pytest.mark.skipif( not has_torch_amp, reason="needs PyTorch with gradient scaling support" ) def test_raises_with_cpu_tensor(): import torch scaler = PyTorchGradScaler(enabled=True) with pytest.raises( ValueError, match=r"Gradient scaling is only supported for CUDA tensors." ): scaler.scale([torch.tensor([1.0], device="cpu")]) thinc-9.0.0/thinc/tests/strategies.py000066400000000000000000000070031461023342500176200ustar00rootroot00000000000000import numpy from hypothesis.extra.numpy import arrays from hypothesis.strategies import floats, integers, just, tuples from thinc.api import Linear, NumpyOps def get_ops(): return NumpyOps() def get_model(W_values, b_values): model = Linear(W_values.shape[0], W_values.shape[1], ops=NumpyOps()) model.initialize() model.set_param("W", W_values) model.set_param("b", b_values) return model def get_output(input_, W_values, b_values): return numpy.einsum("oi,bi->bo", W_values, input_) + b_values def get_input(nr_batch, nr_in): ops = NumpyOps() return ops.alloc2f(nr_batch, nr_in) def lengths(lo=1, hi=10): return integers(min_value=lo, max_value=hi) def shapes(min_rows=1, max_rows=100, min_cols=1, max_cols=100): return tuples(lengths(lo=min_rows, hi=max_rows), lengths(lo=min_cols, hi=max_cols)) def ndarrays_of_shape(shape, lo=-10.0, hi=10.0, dtype="float32", width=32): if dtype.startswith("float"): return arrays( dtype, shape=shape, elements=floats(min_value=lo, max_value=hi, width=width) ) else: return arrays(dtype, shape=shape, elements=integers(min_value=lo, max_value=hi)) def ndarrays(min_len=0, max_len=10, min_val=-10.0, max_val=10.0): return lengths(lo=1, hi=2).flatmap( lambda n: ndarrays_of_shape(n, lo=min_val, hi=max_val) ) def arrays_BI(min_B=1, max_B=10, min_I=1, max_I=100): shapes = tuples(lengths(lo=min_B, hi=max_B), lengths(lo=min_I, hi=max_I)) return shapes.flatmap(ndarrays_of_shape) def arrays_BOP(min_B=1, max_B=10, min_O=1, max_O=100, min_P=1, max_P=5): shapes = tuples( lengths(lo=min_B, hi=max_B), lengths(lo=min_O, hi=max_O), lengths(lo=min_P, hi=max_P), ) return shapes.flatmap(ndarrays_of_shape) def arrays_BOP_BO(min_B=1, max_B=10, min_O=1, max_O=100, min_P=1, max_P=5): shapes = tuples( lengths(lo=min_B, hi=max_B), lengths(lo=min_O, hi=max_O), lengths(lo=min_P, hi=max_P), ) return shapes.flatmap( lambda BOP: tuples(ndarrays_of_shape(BOP), ndarrays_of_shape(BOP[:-1])) ) def arrays_BI_BO(min_B=1, max_B=10, min_I=1, max_I=100, min_O=1, max_O=100): shapes = tuples( lengths(lo=min_B, hi=max_B), lengths(lo=min_I, hi=max_I), lengths(lo=min_O, hi=max_O), ) return shapes.flatmap( lambda BIO: tuples( ndarrays_of_shape((BIO[0], BIO[1])), ndarrays_of_shape((BIO[0], BIO[2])) ) ) def arrays_OI_O_BI( min_batch=1, max_batch=16, min_out=1, max_out=16, min_in=1, max_in=16 ): shapes = tuples( lengths(lo=min_batch, hi=max_batch), lengths(lo=min_in, hi=max_out), lengths(lo=min_in, hi=max_in), ) def W_b_inputs(shape): batch_size, nr_out, nr_in = shape W = ndarrays_of_shape((nr_out, nr_in)) b = ndarrays_of_shape((nr_out,)) input_ = ndarrays_of_shape((batch_size, nr_in)) return tuples(W, b, input_) return shapes.flatmap(W_b_inputs) def arrays_OPFI_BI_lengths(max_B=5, max_P=3, max_F=5, max_I=8): shapes = tuples( lengths(hi=max_B), lengths(hi=max_P), lengths(hi=max_F), lengths(hi=max_I), arrays("int32", shape=(5,), elements=integers(min_value=1, max_value=10)), ) strat = shapes.flatmap( lambda opfi_lengths: tuples( ndarrays_of_shape(opfi_lengths[:-1]), ndarrays_of_shape((sum(opfi_lengths[-1]), opfi_lengths[-2])), just(opfi_lengths[-1]), ) ) return strat thinc-9.0.0/thinc/tests/test_config.py000066400000000000000000000133111461023342500177510ustar00rootroot00000000000000import inspect import pickle from types import GeneratorType from typing import Any, Callable, Dict, Iterable, List, Optional, Union import catalogue import numpy import pytest try: from pydantic.v1 import BaseModel, PositiveInt, StrictBool, StrictFloat, constr except ImportError: from pydantic import BaseModel, PositiveInt, StrictBool, StrictFloat, constr # type: ignore import thinc.config from thinc.api import Config, Model, NumpyOps, RAdam from thinc.config import ConfigValidationError from thinc.types import Generator, Ragged from thinc.util import partial from .util import make_tempdir EXAMPLE_CONFIG = """ [optimizer] @optimizers = "Adam.v1" beta1 = 0.9 beta2 = 0.999 use_averages = true [optimizer.learn_rate] @schedules = "warmup_linear.v1" initial_rate = 0.1 warmup_steps = 10000 total_steps = 100000 [pipeline] [pipeline.parser] name = "parser" factory = "parser" [pipeline.parser.model] @layers = "spacy.ParserModel.v1" hidden_depth = 1 hidden_width = 64 token_vector_width = 128 [pipeline.parser.model.tok2vec] @layers = "Tok2Vec.v1" width = ${pipeline.parser.model:token_vector_width} [pipeline.parser.model.tok2vec.embed] @layers = "spacy.MultiFeatureHashEmbed.v1" width = ${pipeline.parser.model.tok2vec:width} [pipeline.parser.model.tok2vec.embed.hidden] @layers = "MLP.v1" depth = 1 pieces = 3 layer_norm = true outputs = ${pipeline.parser.model.tok2vec.embed:width} [pipeline.parser.model.tok2vec.encode] @layers = "spacy.MaxoutWindowEncoder.v1" depth = 4 pieces = 3 window_size = 1 [pipeline.parser.model.lower] @layers = "spacy.ParserLower.v1" [pipeline.parser.model.upper] @layers = "thinc.Linear.v1" """ OPTIMIZER_CFG = """ [optimizer] @optimizers = "Adam.v1" beta1 = 0.9 beta2 = 0.999 use_averages = true [optimizer.learn_rate] @schedules = "warmup_linear.v1" initial_rate = 0.1 warmup_steps = 10000 total_steps = 100000 """ class my_registry(thinc.config.registry): cats = catalogue.create("thinc", "tests", "cats", entry_points=False) class HelloIntsSchema(BaseModel): hello: int world: int class Config: extra = "forbid" class DefaultsSchema(BaseModel): required: int optional: str = "default value" class Config: extra = "forbid" class ComplexSchema(BaseModel): outer_req: int outer_opt: str = "default value" level2_req: HelloIntsSchema level2_opt: DefaultsSchema = DefaultsSchema(required=1) @my_registry.cats.register("catsie.v1") def catsie_v1(evil: StrictBool, cute: bool = True) -> str: if evil: return "scratch!" else: return "meow" @my_registry.cats.register("catsie.v2") def catsie_v2(evil: StrictBool, cute: bool = True, cute_level: int = 1) -> str: if evil: return "scratch!" else: if cute_level > 2: return "meow <3" return "meow" good_catsie = {"@cats": "catsie.v1", "evil": False, "cute": True} ok_catsie = {"@cats": "catsie.v1", "evil": False, "cute": False} bad_catsie = {"@cats": "catsie.v1", "evil": True, "cute": True} worst_catsie = {"@cats": "catsie.v1", "evil": True, "cute": False} def test_make_config_positional_args_dicts(): cfg = { "hyper_params": {"n_hidden": 512, "dropout": 0.2, "learn_rate": 0.001}, "model": { "@layers": "chain.v1", "*": { "relu1": {"@layers": "Relu.v1", "nO": 512, "dropout": 0.2}, "relu2": {"@layers": "Relu.v1", "nO": 512, "dropout": 0.2}, "softmax": {"@layers": "Softmax.v1"}, }, }, "optimizer": {"@optimizers": "Adam.v1", "learn_rate": 0.001}, } resolved = my_registry.resolve(cfg) model = resolved["model"] X = numpy.ones((784, 1), dtype="f") model.initialize(X=X, Y=numpy.zeros((784, 1), dtype="f")) model.begin_update(X) model.finish_update(resolved["optimizer"]) def test_objects_from_config(): config = { "optimizer": { "@optimizers": "my_cool_optimizer.v1", "beta1": 0.2, "learn_rate": { "@schedules": "my_cool_repetitive_schedule.v1", "base_rate": 0.001, "repeat": 4, }, } } @thinc.registry.optimizers.register("my_cool_optimizer.v1") def make_my_optimizer(learn_rate: List[float], beta1: float): return RAdam(learn_rate, beta1=beta1) @thinc.registry.schedules("my_cool_repetitive_schedule.v1") def decaying(base_rate: float, repeat: int) -> List[float]: return repeat * [base_rate] optimizer = my_registry.resolve(config)["optimizer"] assert optimizer.b1(step=optimizer._step, key=(0, "")) == 0.2 assert optimizer.learn_rate(step=optimizer._step, key=(0, "")) == 0.001 def test_handle_generic_model_type(): """Test that validation can handle checks against arbitrary generic types in function argument annotations.""" @my_registry.layers("my_transform.v1") def my_transform(model: Model[int, int]): model.name = "transformed_model" return model cfg = {"@layers": "my_transform.v1", "model": {"@layers": "Linear.v1"}} model = my_registry.resolve({"test": cfg})["test"] assert isinstance(model, Model) assert model.name == "transformed_model" def test_arg_order_is_preserved(): str_cfg = """ [model] [model.chain] @layers = "chain.v1" [model.chain.*.hashembed] @layers = "HashEmbed.v1" nO = 8 nV = 8 [model.chain.*.expand_window] @layers = "expand_window.v1" window_size = 1 """ cfg = Config().from_str(str_cfg) resolved = my_registry.resolve(cfg) model = resolved["model"]["chain"] # Fails when arguments are sorted, because expand_window # is sorted before hashembed. assert model.name == "hashembed>>expand_window" thinc-9.0.0/thinc/tests/test_examples.py000066400000000000000000000033251461023342500203260ustar00rootroot00000000000000import os from pathlib import Path import pytest @pytest.fixture def test_files(nb_file): pytest.importorskip("nbconvert") pytest.importorskip("nbformat") import nbconvert import nbformat from nbconvert.preprocessors import ExecutePreprocessor if not Path(nb_file).exists(): return kernel_name = os.environ.get("NOTEBOOK_KERNEL", "python3") with open(nb_file) as f: nb = nbformat.read(f, as_version=4) proc = ExecutePreprocessor(timeout=600, kernel_name=kernel_name) proc.allow_errors = True proc.preprocess(nb, {"metadata": {"path": "/"}}) cells_with_outputs = [c for c in nb.cells if "outputs" in c] for cell in cells_with_outputs: for output in cell["outputs"]: if output.output_type == "error": for l in output.traceback: print(l) raise Exception(f"{output.ename}: {output.evalue}") @pytest.mark.parametrize( "nb_file", ( "examples/01_intro_model_definition_methods.ipynb", "examples/05_benchmarking_layers.ipynb", ), ) def test_ipython_notebooks(test_files: None): ... @pytest.mark.skip(reason="these notebooks need special software or hardware") @pytest.mark.parametrize( "nb_file", ( "examples/00_intro_to_thinc.ipynb", "examples/02_transformers_tagger_bert.ipynb", "examples/03_pos_tagger_basic_cnn.ipynb", "examples/03_textcat_basic_neural_bow.ipynb", "examples/04_configure_gpu_memory.ipynb", "examples/04_parallel_training_ray.ipynb", "examples/05_visualizing_models.ipynb", "examples/06_predicting_like_terms.ipynb", ), ) def test_ipython_notebooks_slow(test_files: None): ... thinc-9.0.0/thinc/tests/test_import__all__.py000066400000000000000000000034101461023342500213020ustar00rootroot00000000000000import ast import importlib from collections import namedtuple from typing import List, Tuple import pytest _Import = namedtuple("_Import", ["module", "name", "alias"]) def get_imports(path: str) -> Tuple[_Import, ...]: """Parse Python file at path, retrieve import statements. Adapted from https://stackoverflow.com/a/9049549. path (str): Path to Python file. RETURNS (Tuple[_Import]): All imports found in file at path. """ with open(path) as fh: root = ast.parse(fh.read(), path) imports: List[_Import] = [] for node in ast.walk(root): if isinstance(node, ast.Import): module: List[str] = [] elif isinstance(node, ast.ImportFrom) and node.module: module = node.module.split(".") else: continue assert isinstance(node, (ast.Import, ast.ImportFrom)) imports.extend( [_Import(module, n.name.split("."), n.asname) for n in node.names] ) return tuple(imports) @pytest.mark.parametrize("module_name", ["thinc.api", "thinc.shims", "thinc.layers"]) def test_import_reexport_equivalency(module_name: str): """Tests whether a module's __all__ is equivalent to its imports. This assumes that this module is supposed to re-export all imported values. module_name (str): Module to load. """ mod = importlib.import_module(module_name) assert set(mod.__all__) == { k for k in set(n for i in get_imports(str(mod.__file__)) for n in i.name) if ( # Ignore all values prefixed with _, as we expect those not to be re-exported. # However, __version__ should be reexported in thinc/__init__.py. (not k.startswith("_") or module_name == "thinc" and k == "__version__") ) } thinc-9.0.0/thinc/tests/test_indexing.py000066400000000000000000000035501461023342500203150ustar00rootroot00000000000000import numpy import pytest from numpy.testing import assert_allclose from thinc.types import Pairs, Ragged @pytest.fixture def ragged(): data = numpy.zeros((20, 4), dtype="f") lengths = numpy.array([4, 2, 8, 1, 4], dtype="i") data[0] = 0 data[1] = 1 data[2] = 2 data[3] = 3 data[4] = 4 data[5] = 5 return Ragged(data, lengths) def test_ragged_empty(): data = numpy.zeros((0, 4), dtype="f") lengths = numpy.array([], dtype="i") ragged = Ragged(data, lengths) assert_allclose(ragged[0:0].data, ragged.data) assert_allclose(ragged[0:0].lengths, ragged.lengths) assert_allclose(ragged[0:2].data, ragged.data) assert_allclose(ragged[0:2].lengths, ragged.lengths) assert_allclose(ragged[1:2].data, ragged.data) assert_allclose(ragged[1:2].lengths, ragged.lengths) def test_ragged_starts_ends(ragged): starts = ragged._get_starts() ends = ragged._get_ends() assert list(starts) == [0, 4, 6, 14, 15] assert list(ends) == [4, 6, 14, 15, 19] def test_ragged_simple_index(ragged, i=1): r = ragged[i] assert_allclose(r.data, ragged.data[4:6]) assert_allclose(r.lengths, ragged.lengths[i : i + 1]) def test_ragged_slice_index(ragged, start=0, end=2): r = ragged[start:end] size = ragged.lengths[start:end].sum() assert r.data.shape == (size, r.data.shape[1]) assert_allclose(r.lengths, ragged.lengths[start:end]) def test_ragged_array_index(ragged): arr = numpy.array([2, 1, 4], dtype="i") r = ragged[arr] assert r.data.shape[0] == ragged.lengths[arr].sum() def test_pairs_arrays(): one = numpy.zeros((128, 45), dtype="f") two = numpy.zeros((128, 12), dtype="f") pairs = Pairs(one, two) assert pairs[:2].one.shape == (2, 45) assert pairs[0].two.shape == (12,) assert pairs[-1:].one.shape == (1, 45) assert pairs[-1:].two.shape == (1, 12) thinc-9.0.0/thinc/tests/test_initializers.py000066400000000000000000000017341461023342500212200ustar00rootroot00000000000000import numpy import pytest from thinc import registry from thinc.api import ( NumpyOps, glorot_uniform_init, normal_init, uniform_init, zero_init, ) @pytest.mark.parametrize( "init_func", [glorot_uniform_init, zero_init, uniform_init, normal_init] ) def test_initializer_func_setup(init_func): ops = NumpyOps() data = numpy.ndarray([1, 2, 3, 4], dtype="f") result = init_func(ops, data.shape) assert not numpy.array_equal(data, result) @pytest.mark.parametrize( "name,kwargs", [ ("glorot_uniform_init.v1", {}), ("zero_init.v1", {}), ("uniform_init.v1", {"lo": -0.5, "hi": 0.5}), ("normal_init.v1", {"mean": 0.1}), ], ) def test_initializer_from_config(name, kwargs): """Test that initializers are loaded and configured correctly from registry (as partials).""" cfg = {"test": {"@initializers": name, **kwargs}} func = registry.resolve(cfg)["test"] func(NumpyOps(), (1, 2, 3, 4)) thinc-9.0.0/thinc/tests/test_loss.py000066400000000000000000000274631461023342500175010ustar00rootroot00000000000000import numpy import pytest from thinc import registry from thinc.api import ( CategoricalCrossentropy, CosineDistance, L2Distance, SequenceCategoricalCrossentropy, ) # some simple arrays scores0 = numpy.zeros((3, 3), dtype="f") labels0 = numpy.asarray([0, 1, 1], dtype="i") # a few more diverse ones to test realistic values guesses1 = numpy.asarray([[0.1, 0.5, 0.6], [0.4, 0.6, 0.3], [1, 1, 1], [0, 0, 0]]) labels1 = numpy.asarray([2, 1, 0, 2]) labels1_full = numpy.asarray([[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 1]]) labels1_strings = ["C", "B", "A", "C"] guesses2 = numpy.asarray([[0.2, 0.3, 0.0]]) labels2 = numpy.asarray([1]) labels2_strings = ["B"] eps = 0.0001 def test_loss(): d_scores = CategoricalCrossentropy().get_grad(scores0, labels0) assert d_scores.dtype == "float32" assert d_scores.shape == scores0.shape d_scores = SequenceCategoricalCrossentropy().get_grad([scores0], [labels0]) assert d_scores[0].dtype == "float32" assert d_scores[0].shape == scores0.shape assert SequenceCategoricalCrossentropy().get_grad([], []) == [] @pytest.mark.parametrize( "dist", [CategoricalCrossentropy(), CosineDistance(ignore_zeros=True), L2Distance()] ) @pytest.mark.parametrize("vect", [scores0, guesses1, guesses2]) def test_equality(dist, vect): assert int(dist.get_grad(vect, vect)[0][0]) == pytest.approx(0, eps) assert dist.get_loss(vect, vect) == pytest.approx(0, eps) @pytest.mark.parametrize( "guesses, labels", [(guesses1, labels1), (guesses1, labels1_full)] ) def test_categorical_crossentropy(guesses, labels): d_scores = CategoricalCrossentropy(normalize=True).get_grad(guesses, labels) assert d_scores.shape == guesses.shape # The normalization divides the difference (e.g. 0.4) by the number of vectors (4) assert d_scores[1][0] == pytest.approx(0.1, eps) assert d_scores[1][1] == pytest.approx(-0.1, eps) # The third vector predicted all labels, but only the first one was correct assert d_scores[2][0] == pytest.approx(0, eps) assert d_scores[2][1] == pytest.approx(0.25, eps) assert d_scores[2][2] == pytest.approx(0.25, eps) # The fourth vector predicted no labels but should have predicted the last one assert d_scores[3][0] == pytest.approx(0, eps) assert d_scores[3][1] == pytest.approx(0, eps) assert d_scores[3][2] == pytest.approx(-0.25, eps) loss = CategoricalCrossentropy(normalize=True).get_loss(guesses, labels) assert loss == pytest.approx(0.239375, eps) def test_crossentropy_incorrect_scores_targets(): labels = numpy.asarray([2]) guesses_neg = numpy.asarray([[-0.1, 0.5, 0.6]]) with pytest.raises(ValueError, match=r"Cannot calculate.*guesses"): CategoricalCrossentropy(normalize=True).get_grad(guesses_neg, labels) guesses_larger_than_one = numpy.asarray([[1.1, 0.5, 0.6]]) with pytest.raises(ValueError, match=r"Cannot calculate.*guesses"): CategoricalCrossentropy(normalize=True).get_grad( guesses_larger_than_one, labels ) guesses_ok = numpy.asarray([[0.1, 0.4, 0.5]]) targets_neg = numpy.asarray([[-0.1, 0.5, 0.6]]) with pytest.raises(ValueError, match=r"Cannot calculate.*truth"): CategoricalCrossentropy(normalize=True).get_grad(guesses_ok, targets_neg) targets_larger_than_one = numpy.asarray([[2.0, 0.5, 0.6]]) with pytest.raises(ValueError, match=r"Cannot calculate.*truth"): CategoricalCrossentropy(normalize=True).get_grad( guesses_ok, targets_larger_than_one ) @pytest.mark.parametrize( "guesses, labels", [(guesses1, [2, 1, 0, 2])], ) def test_categorical_crossentropy_int_list_missing(guesses, labels): d_scores = CategoricalCrossentropy(normalize=True, missing_value=0).get_grad( guesses, labels ) assert d_scores.shape == guesses.shape # The normalization divides the difference (e.g. 0.4) by the number of vectors (4) assert d_scores[1][0] == pytest.approx(0.1, eps) assert d_scores[1][1] == pytest.approx(-0.1, eps) # Label 0 is masked, because it represents the missing value assert d_scores[2][0] == 0.0 assert d_scores[2][1] == 0.0 assert d_scores[2][2] == 0.0 # The fourth vector predicted no labels but should have predicted the last one assert d_scores[3][0] == pytest.approx(0, eps) assert d_scores[3][1] == pytest.approx(0, eps) assert d_scores[3][2] == pytest.approx(-0.25, eps) loss = CategoricalCrossentropy(normalize=True, missing_value=0).get_loss( guesses, labels ) assert loss == pytest.approx(0.114375, eps) @pytest.mark.parametrize( "guesses, labels", [(guesses1, labels1), (guesses1, labels1_full)] ) def test_categorical_crossentropy_missing(guesses, labels): d_scores = CategoricalCrossentropy(normalize=True, missing_value=0).get_grad( guesses, labels ) assert d_scores.shape == guesses.shape # The normalization divides the difference (e.g. 0.4) by the number of vectors (4) assert d_scores[1][0] == pytest.approx(0.1, eps) assert d_scores[1][1] == pytest.approx(-0.1, eps) # Label 0 is masked, because it represents the missing value assert d_scores[2][0] == 0.0 assert d_scores[2][1] == 0.0 assert d_scores[2][2] == 0.0 # The fourth vector predicted no labels but should have predicted the last one assert d_scores[3][0] == pytest.approx(0, eps) assert d_scores[3][1] == pytest.approx(0, eps) assert d_scores[3][2] == pytest.approx(-0.25, eps) loss = CategoricalCrossentropy(normalize=True, missing_value=0).get_loss( guesses, labels ) assert loss == pytest.approx(0.114375, eps) @pytest.mark.parametrize( "guesses, labels, names", [ ([guesses1, guesses2], [labels1, labels2], []), ([guesses1, guesses2], [labels1_full, labels2], []), ([guesses1, guesses2], [labels1_strings, labels2_strings], ["A", "B", "C"]), ], ) def test_sequence_categorical_crossentropy(guesses, labels, names): d_scores = SequenceCategoricalCrossentropy(normalize=False, names=names).get_grad( guesses, labels ) d_scores1 = d_scores[0] d_scores2 = d_scores[1] assert d_scores1.shape == guesses1.shape assert d_scores2.shape == guesses2.shape assert d_scores1[1][0] == pytest.approx(0.4, eps) assert d_scores1[1][1] == pytest.approx(-0.4, eps) # The normalization divides the difference (e.g. 0.4) by the number of seqs d_scores = SequenceCategoricalCrossentropy(normalize=True, names=names).get_grad( guesses, labels ) d_scores1 = d_scores[0] d_scores2 = d_scores[1] assert d_scores1[1][0] == pytest.approx(0.2, eps) assert d_scores1[1][1] == pytest.approx(-0.2, eps) # The third vector predicted all labels, but only the first one was correct assert d_scores1[2][0] == pytest.approx(0, eps) assert d_scores1[2][1] == pytest.approx(0.5, eps) assert d_scores1[2][2] == pytest.approx(0.5, eps) # The fourth vector predicted no labels but should have predicted the last one assert d_scores1[3][0] == pytest.approx(0, eps) assert d_scores1[3][1] == pytest.approx(0, eps) assert d_scores1[3][2] == pytest.approx(-0.5, eps) # Test the second batch assert d_scores2[0][0] == pytest.approx(0.1, eps) assert d_scores2[0][1] == pytest.approx(-0.35, eps) loss = SequenceCategoricalCrossentropy(normalize=True, names=names).get_loss( guesses, labels ) assert loss == pytest.approx(1.09, eps) @pytest.mark.parametrize( "guesses, labels, names", [ ([guesses1], [["A", "!A", "", "!C"]], ["A", "B", "C"]), ], ) def test_sequence_categorical_missing_negative(guesses, labels, names): d_scores = SequenceCategoricalCrossentropy( normalize=False, names=names, neg_prefix="!", missing_value="" ).get_grad(guesses, labels) d_scores0 = d_scores[0] # [0.1, 0.5, 0.6] should be A assert d_scores0[0][0] == pytest.approx(-0.9, eps) assert d_scores0[0][1] == pytest.approx(0.5, eps) assert d_scores0[0][2] == pytest.approx(0.6, eps) # [0.4, 0.6, 0.3] should NOT be A assert d_scores0[1][0] == pytest.approx(0.4, eps) assert d_scores0[1][1] == pytest.approx(0.0, eps) assert d_scores0[1][2] == pytest.approx(0.0, eps) # [1, 1, 1] has missing gold label assert d_scores0[2][0] == pytest.approx(0.0, eps) assert d_scores0[2][1] == pytest.approx(0.0, eps) assert d_scores0[2][2] == pytest.approx(0.0, eps) # [0.0, 0.0, 0.0] should NOT be C assert d_scores0[3][0] == pytest.approx(0.0, eps) assert d_scores0[3][1] == pytest.approx(0.0, eps) assert d_scores0[3][2] == pytest.approx(0.0, eps) def test_L2(): # L2 loss = 2ยฒ+4ยฒ=20 (or normalized: 1ยฒ+2ยฒ=5) vec1 = numpy.asarray([[1, 2], [8, 9]]) vec2 = numpy.asarray([[1, 2], [10, 5]]) d_vecs = L2Distance().get_grad(vec1, vec2) assert d_vecs.shape == vec1.shape numpy.testing.assert_allclose( d_vecs[0], numpy.zeros(d_vecs[0].shape), rtol=eps, atol=eps ) loss_not_normalized = L2Distance(normalize=False).get_loss(vec1, vec2) assert loss_not_normalized == pytest.approx(20, eps) loss_normalized = L2Distance(normalize=True).get_loss(vec1, vec2) assert loss_normalized == pytest.approx(5, eps) def test_cosine_orthogonal(): # These are orthogonal, i.e. loss is 1 vec1 = numpy.asarray([[0, 2], [0, 5]]) vec2 = numpy.asarray([[8, 0], [7, 0]]) d_vecs = CosineDistance(normalize=True).get_grad(vec1, vec2) assert d_vecs.shape == vec1.shape assert d_vecs[0][0] < 0 assert d_vecs[0][1] > 0 assert d_vecs[1][0] < 0 assert d_vecs[1][1] > 0 loss_not_normalized = CosineDistance(normalize=False).get_loss(vec1, vec2) assert loss_not_normalized == pytest.approx(2, eps) loss_normalized = CosineDistance(normalize=True).get_loss(vec1, vec2) assert loss_normalized == pytest.approx(1, eps) def test_cosine_equal(): # These 3 vectors are equal when measured with Cosine similarity, i.e. loss is 0 vec1 = numpy.asarray([[1, 2], [8, 9], [3, 3]]) vec2 = numpy.asarray([[1, 2], [80, 90], [300, 300]]) d_vec1 = CosineDistance().get_grad(vec1, vec2) assert d_vec1.shape == vec1.shape numpy.testing.assert_allclose(d_vec1, numpy.zeros(d_vec1.shape), rtol=eps, atol=eps) loss_not_normalized = CosineDistance(normalize=False).get_loss(vec1, vec2) assert loss_not_normalized == pytest.approx(0, eps) loss_normalized = CosineDistance(normalize=True).get_loss(vec1, vec2) assert loss_normalized == pytest.approx(0, eps) def test_cosine_unmatched(): vec1 = numpy.asarray([[1, 2, 3]]) vec2 = numpy.asarray([[1, 2]]) with pytest.raises(ValueError): CosineDistance().get_grad(vec1, vec2) @pytest.mark.parametrize( "name,kwargs,args", [ ("CategoricalCrossentropy.v1", {}, (scores0, labels0)), ("SequenceCategoricalCrossentropy.v1", {}, ([scores0], [labels0])), ("CategoricalCrossentropy.v2", {"neg_prefix": "!"}, (scores0, labels0)), ("CategoricalCrossentropy.v3", {"neg_prefix": "!"}, (scores0, labels0)), ( "SequenceCategoricalCrossentropy.v2", {"neg_prefix": "!"}, ([scores0], [labels0]), ), ( "SequenceCategoricalCrossentropy.v3", {"neg_prefix": "!"}, ([scores0], [labels0]), ), ("L2Distance.v1", {}, (scores0, scores0)), ( "CosineDistance.v1", {"normalize": True, "ignore_zeros": True}, (scores0, scores0), ), ], ) def test_loss_from_config(name, kwargs, args): """Test that losses are loaded and configured correctly from registry (as partials).""" cfg = {"test": {"@losses": name, **kwargs}} func = registry.resolve(cfg)["test"] loss = func.get_grad(*args) if isinstance(loss, (list, tuple)): loss = loss[0] assert loss.ndim == 2 func.get_loss(*args) func(*args) thinc-9.0.0/thinc/tests/test_optimizers.py000066400000000000000000000116051461023342500207150ustar00rootroot00000000000000import numpy import pytest from thinc.api import Optimizer, registry from thinc.optimizers import KeyT, _wrap_generator STUB_KEY: KeyT = (0, "") def _test_schedule_valid(): while True: yield 0.456 def _test_schedule_invalid(): yield from [] @pytest.fixture( params=[ (lambda: 0.123, 0.123, 0.123, 0.123), (lambda: _test_schedule_valid(), 0.456, 0.456, 0.456), (lambda: (i for i in [0.2, 0.1, 0.4, 0.5, 0.6, 0.7, 0.8]), 0.2, 0.1, 0.4), (lambda: (i for i in [0.333, 0.666]), 0.333, 0.666, 0.666), (lambda: [0.9, 0.8, 0.7], 0.9, 0.8, 0.7), (lambda: [0.0, 0.123], 0.0, 0.123, 0.123), ], scope="function", ) def schedule_valid(request): # Use lambda to prevent iterator from being consumed by first test r_func, r1, r2, r3 = request.param return r_func(), r1, r2, r3 @pytest.fixture( params=[ (lambda: 0.123, 0.123, 0.123, 0.123), (lambda: (i for i in [0.2, 0.1, 0.4, 0.5, 0.6, 0.7, 0.8]), 0.2, 0.1, 0.4), (lambda: (i for i in [0.333, 0.666]), 0.333, 0.666, 0.666), (lambda: [0.9, 0.8, 0.7], 0.9, 0.8, 0.7), (lambda: [0.0, 0.123], 0.0, 0.123, 0.123), ], scope="function", ) def schedule_config_valid(request): # Use lambda to prevent iterator from being consumed by first test r_func, r1, r2, r3 = request.param return r_func(), r1, r2, r3 @pytest.fixture( params=[ (lambda: "hello"), (lambda: _test_schedule_invalid()), (lambda: (_ for _ in [])), (lambda: []), ], scope="function", ) def schedule_invalid(request): # Use lambda to prevent iterator from being consumed by first test r_func = request.param return r_func() @pytest.mark.parametrize("name", ["RAdam.v1", "Adam.v1", "SGD.v1"]) def test_optimizers_from_config(name): learn_rate = 0.123 cfg = {"@optimizers": name, "learn_rate": learn_rate} optimizer = registry.resolve({"config": cfg})["config"] assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == learn_rate def test_optimizer_schedules_from_config(schedule_config_valid): lr, lr_next1, lr_next2, lr_next3 = schedule_config_valid cfg = {"@optimizers": "Adam.v1", "learn_rate": lr} optimizer = registry.resolve({"cfg": cfg})["cfg"] assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == lr_next1 optimizer.step_schedules() assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == lr_next2 optimizer.step_schedules() assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == lr_next3 optimizer.learn_rate = lambda *, step, key: 1.0 assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == 1.0 def test_optimizer_schedules_valid(schedule_valid): lr, lr_next1, lr_next2, lr_next3 = schedule_valid optimizer = Optimizer(learn_rate=lr) assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == lr_next1 optimizer.step_schedules() assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == lr_next2 optimizer.step_schedules() assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == lr_next3 optimizer.learn_rate = lambda *, step, key: 1.0 assert optimizer.learn_rate(step=optimizer._step, key=STUB_KEY) == 1.0 def test_optimizer_schedules_invalid(schedule_invalid): with pytest.raises(ValueError): Optimizer(learn_rate=schedule_invalid) def test_optimizer_init(): optimizer = Optimizer( learn_rate=0.123, use_averages=False, use_radam=True, L2=0.1, L2_is_weight_decay=False, ) _, gradient = optimizer((0, "x"), numpy.zeros((1, 2)), numpy.zeros(0)) assert numpy.array_equal(gradient, numpy.zeros(0)) W = numpy.asarray([1.0, 0.0, 0.0, 1.0], dtype="f").reshape((4,)) dW = numpy.asarray([[-1.0, 0.0, 0.0, 1.0]], dtype="f").reshape((4,)) optimizer((0, "x"), W, dW) optimizer = Optimizer(learn_rate=0.123, beta1=0.1, beta2=0.1) optimizer((1, "x"), W, dW) def test_optimizer_last_score(): optimizer = Optimizer( learn_rate=0.123, ) assert optimizer.last_score is None optimizer.last_score = 1.0 assert optimizer.last_score == (0, 1.0) optimizer.step_schedules() optimizer.step_schedules() assert optimizer.last_score == (0, 1.0) optimizer.last_score = 2.0 assert optimizer.last_score == (2, 2.0) def test_generator_schedule(): s = _wrap_generator("test", iter([0.0, 1.0, 2.0, 3.0])) assert s(step=0, key=STUB_KEY, last_score=None) == 0.0 assert s(step=0, key=STUB_KEY, last_score=None) == 0.0 assert s(step=1, key=STUB_KEY, last_score=None) == 1.0 assert s(step=1, key=STUB_KEY, last_score=None) == 1.0 assert s(step=3, key=STUB_KEY, last_score=None) == 3.0 assert s(step=10, key=STUB_KEY, last_score=None) == 3.0 with pytest.raises(ValueError, match=r"must not decrease"): s(step=1, key=STUB_KEY, last_score=None) thinc-9.0.0/thinc/tests/test_schedules.py000066400000000000000000000066171461023342500204760ustar00rootroot00000000000000from itertools import islice import pytest from thinc.api import ( compounding, constant, constant_then, cyclic_triangular, decaying, slanted_triangular, warmup_linear, ) from thinc.schedules import plateau def test_decaying_rate(): rates = decaying(0.001, 1e-4) rate = rates(step=0) assert rate == 0.001 next_rate = rates(step=1) assert next_rate < rate assert next_rate > 0 assert next_rate > rates(step=2) rates_offset = decaying(0.001, 1e-4, t=1.0) assert rates(step=1) == rates_offset(step=0) assert rates(step=2) == rates_offset(step=1) def test_compounding_rate(): rates = compounding(1, 16, 1.01) rate0 = rates(step=0) assert rate0 == 1.0 rate1 = rates(step=1) rate2 = rates(step=2) rate3 = rates(step=3) assert rate3 > rate2 > rate1 > rate0 assert (rate3 - rate2) > (rate2 - rate1) > (rate1 - rate0) rates_offset = compounding(1, 16, 1.01, t=1.0) assert rates(step=1) == rates_offset(step=0) assert rates(step=2) == rates_offset(step=1) def test_slanted_triangular_rate(): rates = slanted_triangular(1.0, 20.0, ratio=10) rate0 = rates(step=0) assert rate0 < 1.0 rate1 = rates(step=1) assert rate1 > rate0 rate2 = rates(step=2) assert rate2 < rate1 rate3 = rates(step=3) assert rate0 < rate3 < rate2 rates_offset = slanted_triangular(1.0, 20.0, ratio=10, t=1.0) assert rates(step=1) == rates_offset(step=0) assert rates(step=2) == rates_offset(step=1) def test_constant_then_schedule(): rates = constant_then(1.0, 2, constant(100)) assert rates(step=0) == 1.0 assert rates(step=1) == 1.0 assert rates(step=2) == 100 assert rates(step=3) == 100 def test_constant(): rates = constant(123) assert rates(step=0, key=(0, "")) == 123 assert rates(step=0, key=(0, "")) == 123 def test_warmup_linear(): rates = warmup_linear(1.0, 2, 10) expected = [0.0, 0.5, 1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125, 0.0] for i in range(11): assert rates(step=i, key=(0, "")) == expected[i] def test_cyclic_triangular(): rates = cyclic_triangular(0.1, 1.0, 2) expected = [0.55, 1.0, 0.55, 0.1, 0.55, 1.0, 0.55, 0.1, 0.55, 1.0] for i in range(10): assert rates(step=i, key=(0, "")) == expected[i] def test_plateau(): schedule = plateau(2, 0.5, constant(1.0)) assert schedule(step=0, last_score=None) == 1.0 assert schedule(step=1, last_score=(1, 1.0)) == 1.0 # patience == 0 assert schedule(step=2, last_score=(2, 1.0)) == 1.0 # patience == 1 assert schedule(step=3, last_score=None) == 1.0 # patience == 1 assert schedule(step=4, last_score=(4, 1.0)) == 0.5 # patience == 2, reset assert schedule(step=5, last_score=(4, 1.0)) == 0.5 # patience == 0 assert schedule(step=6, last_score=(6, 0.9)) == 0.5 # patience == 1 assert schedule(step=7, last_score=(7, 2.0)) == 0.5 # patience == 0 assert schedule(step=8, last_score=(8, 1.0)) == 0.5 # patience == 1 assert schedule(step=9, last_score=(9, 2.0)) == 0.25 # patience == 2, reset with pytest.raises(ValueError, match=r"Expected score with step"): schedule(step=1, last_score=(1, 1.0)) == 1.0 def test_to_generator(): rates = warmup_linear(1.0, 2, 10) expected = [0.0, 0.5, 1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125, 0.0] assert list(islice(rates.to_generator(), len(expected))) == expected thinc-9.0.0/thinc/tests/test_serialize.py000066400000000000000000000152041461023342500204760ustar00rootroot00000000000000import pytest import srsly from thinc.api import ( Linear, Maxout, Model, Shim, chain, deserialize_attr, serialize_attr, with_array, ) @pytest.fixture def linear(): return Linear(5, 3) class SerializableAttr: value = "foo" def to_bytes(self): return self.value.encode("utf8") def from_bytes(self, data): self.value = f"{data.decode('utf8')} from bytes" return self class SerializableShim(Shim): name = "testshim" value = "shimdata" def to_bytes(self): return self.value.encode("utf8") def from_bytes(self, data): self.value = f"{data.decode('utf8')} from bytes" return self def test_pickle_with_flatten(linear): Xs = [linear.ops.alloc2f(2, 3), linear.ops.alloc2f(4, 3)] model = with_array(linear).initialize() pickled = srsly.pickle_dumps(model) loaded = srsly.pickle_loads(pickled) Ys = loaded.predict(Xs) assert len(Ys) == 2 assert Ys[0].shape == (Xs[0].shape[0], linear.get_dim("nO")) assert Ys[1].shape == (Xs[1].shape[0], linear.get_dim("nO")) def test_simple_model_roundtrip_bytes(): model = Maxout(5, 10, nP=2).initialize() b = model.get_param("b") b += 1 data = model.to_bytes() b = model.get_param("b") b -= 1 model = model.from_bytes(data) assert model.get_param("b")[0, 0] == 1 def test_simple_model_roundtrip_bytes_length(): """Ensure that serialization of non-initialized weight matrices goes fine""" model1 = Maxout(5, 10, nP=2) model2 = Maxout(5, 10, nP=2) data1 = model1.to_bytes() model2 = model2.from_bytes(data1) data2 = model2.to_bytes() assert data1 == data2 assert len(data1) == len(data2) def test_simple_model_roundtrip_bytes_serializable_attrs(): fwd = lambda model, X, is_train: (X, lambda dY: dY) attr = SerializableAttr() assert attr.value == "foo" assert attr.to_bytes() == b"foo" model = Model("test", fwd, attrs={"test": attr}) model.initialize() @serialize_attr.register(SerializableAttr) def serialize_attr_custom(_, value, name, model): return value.to_bytes() @deserialize_attr.register(SerializableAttr) def deserialize_attr_custom(_, value, name, model): return SerializableAttr().from_bytes(value) model_bytes = model.to_bytes() model = model.from_bytes(model_bytes) assert "test" in model.attrs assert model.attrs["test"].value == "foo from bytes" def test_multi_model_roundtrip_bytes(): model = chain(Maxout(5, 10, nP=2), Maxout(2, 3)).initialize() b = model.layers[0].get_param("b") b += 1 b = model.layers[1].get_param("b") b += 2 data = model.to_bytes() b = model.layers[0].get_param("b") b -= 1 b = model.layers[1].get_param("b") b -= 2 model = model.from_bytes(data) assert model.layers[0].get_param("b")[0, 0] == 1 assert model.layers[1].get_param("b")[0, 0] == 2 def test_multi_model_load_missing_dims(): model = chain(Maxout(5, 10, nP=2), Maxout(2, 3)).initialize() b = model.layers[0].get_param("b") b += 1 b = model.layers[1].get_param("b") b += 2 data = model.to_bytes() model2 = chain(Maxout(5, nP=None), Maxout(nP=None)) model2 = model2.from_bytes(data) assert model2.layers[0].get_param("b")[0, 0] == 1 assert model2.layers[1].get_param("b")[0, 0] == 2 def test_serialize_model_shims_roundtrip_bytes(): fwd = lambda model, X, is_train: (X, lambda dY: dY) test_shim = SerializableShim(None) shim_model = Model("shimmodel", fwd, shims=[test_shim]) model = chain(Linear(2, 3), shim_model, Maxout(2, 3)) model.initialize() assert model.layers[1].shims[0].value == "shimdata" model_bytes = model.to_bytes() with pytest.raises(ValueError): Linear(2, 3).from_bytes(model_bytes) test_shim = SerializableShim(None) shim_model = Model("shimmodel", fwd, shims=[test_shim]) new_model = chain(Linear(2, 3), shim_model, Maxout(2, 3)).from_bytes(model_bytes) assert new_model.layers[1].shims[0].value == "shimdata from bytes" def test_serialize_refs_roundtrip_bytes(): fwd = lambda model, X, is_train: (X, lambda dY: dY) model_a = Model("a", fwd) model = Model("test", fwd, refs={"a": model_a, "b": None}).initialize() with pytest.raises(ValueError): # ref not in nodes model.to_bytes() model = Model("test", fwd, refs={"a": model_a, "b": None}, layers=[model_a]) assert model.ref_names == ("a", "b") model_bytes = model.to_bytes() with pytest.raises(ValueError): Model("test", fwd).from_bytes(model_bytes) new_model = Model("test", fwd, layers=[model_a]) new_model.from_bytes(model_bytes) assert new_model.ref_names == ("a", "b") def test_serialize_attrs(): fwd = lambda model, X, is_train: (X, lambda dY: dY) attrs = {"test": "foo"} model1 = Model("test", fwd, attrs=attrs).initialize() bytes_attr = serialize_attr(model1.attrs["test"], attrs["test"], "test", model1) assert bytes_attr == srsly.msgpack_dumps("foo") model2 = Model("test", fwd, attrs={"test": ""}) result = deserialize_attr(model2.attrs["test"], bytes_attr, "test", model2) assert result == "foo" # Test objects with custom serialization functions @serialize_attr.register(SerializableAttr) def serialize_attr_custom(_, value, name, model): return value.to_bytes() @deserialize_attr.register(SerializableAttr) def deserialize_attr_custom(_, value, name, model): return SerializableAttr().from_bytes(value) attrs = {"test": SerializableAttr()} model3 = Model("test", fwd, attrs=attrs) bytes_attr = serialize_attr(model3.attrs["test"], attrs["test"], "test", model3) assert bytes_attr == b"foo" model4 = Model("test", fwd, attrs=attrs) assert model4.attrs["test"].value == "foo" result = deserialize_attr(model4.attrs["test"], bytes_attr, "test", model4) assert result.value == "foo from bytes" def test_simple_model_can_from_dict(): model = Maxout(5, 10, nP=2).initialize() model_dict = model.to_dict() assert model.can_from_dict(model_dict) # Test check without initialize assert Maxout(5, 10, nP=2).can_from_dict(model_dict) # Test not-strict check assert not Maxout(10, 5, nP=2).can_from_dict(model_dict) assert Maxout(5, nP=2).can_from_dict(model_dict) def test_multi_model_can_from_dict(): model = chain(Maxout(5, 10, nP=2), Maxout(2, 3)).initialize() model_dict = model.to_dict() assert model.can_from_dict(model_dict) assert chain(Maxout(5, 10, nP=2), Maxout(2, 3)).can_from_dict(model_dict) resized = chain(Maxout(5, 10, nP=3), Maxout(2, 3)) assert not resized.can_from_dict(model_dict) thinc-9.0.0/thinc/tests/test_types.py000066400000000000000000000030271461023342500176530ustar00rootroot00000000000000import numpy import pytest from thinc.types import ( Floats1d, Floats2d, Floats3d, Floats4d, Ints1d, Ints2d, Ints3d, Ints4d, ) try: from pydantic.v1 import ValidationError, create_model except ImportError: from pydantic import ValidationError, create_model # type: ignore from thinc.types import ( Floats1d, Floats2d, Floats3d, Floats4d, Ints1d, Ints2d, Ints3d, Ints4d, ) @pytest.mark.parametrize( "arr,arr_type", [ (numpy.zeros(0, dtype=numpy.float32), Floats1d), (numpy.zeros((0, 0), dtype=numpy.float32), Floats2d), (numpy.zeros((0, 0, 0), dtype=numpy.float32), Floats3d), (numpy.zeros((0, 0, 0, 0), dtype=numpy.float32), Floats4d), (numpy.zeros(0, dtype=numpy.int32), Ints1d), (numpy.zeros((0, 0), dtype=numpy.int32), Ints2d), (numpy.zeros((0, 0, 0), dtype=numpy.int32), Ints3d), (numpy.zeros((0, 0, 0, 0), dtype=numpy.int32), Ints4d), ], ) def test_array_validation_valid(arr, arr_type): test_model = create_model("TestModel", arr=(arr_type, ...)) result = test_model(arr=arr) assert numpy.array_equal(arr, result.arr) @pytest.mark.parametrize( "arr,arr_type", [ (numpy.zeros((0, 0), dtype=numpy.float32), Floats1d), (numpy.zeros((0, 0), dtype=numpy.float32), Ints2d), ], ) def test_array_validation_invalid(arr, arr_type): test_model = create_model("TestModel", arr=(arr_type, ...)) with pytest.raises(ValidationError): test_model(arr=arr) thinc-9.0.0/thinc/tests/test_util.py000066400000000000000000000130171461023342500174640ustar00rootroot00000000000000import numpy import pytest from hypothesis import given from thinc.api import Padded, Ragged, get_width from thinc.types import ArgsKwargs from thinc.util import ( convert_recursive, get_array_module, is_cupy_array, is_numpy_array, to_categorical, ) from . import strategies ALL_XP = [numpy] try: import cupy ALL_XP.append(cupy) except ImportError: pass @pytest.mark.parametrize( "obj,width", [ (numpy.zeros((1, 2, 3, 4)), 4), (numpy.array(1), 0), (numpy.array([1, 2]), 3), ([numpy.zeros((1, 2)), numpy.zeros((1))], 2), (Ragged(numpy.zeros((1, 2)), numpy.zeros(1)), 2), # type:ignore ( Padded( numpy.zeros((2, 1, 2)), # type:ignore numpy.zeros(2), # type:ignore numpy.array([1, 0]), # type:ignore numpy.array([0, 1]), # type:ignore ), 2, ), ([], 0), ], ) def test_get_width(obj, width): assert get_width(obj) == width @pytest.mark.parametrize("obj", [1234, "foo", {"a": numpy.array(0)}]) def test_get_width_fail(obj): with pytest.raises(ValueError): get_width(obj) @pytest.mark.parametrize("xp", ALL_XP) def test_array_module_cpu_gpu_helpers(xp): error = ( "Only numpy and cupy arrays are supported" ", but found instead. If " "get_array_module module wasn't called " "directly, this might indicate a bug in Thinc." ) with pytest.raises(ValueError, match=error): get_array_module(0) zeros = xp.zeros((1, 2)) xp_ = get_array_module(zeros) assert xp_ == xp if xp == numpy: assert is_numpy_array(zeros) assert not is_numpy_array((1, 2)) else: assert is_cupy_array(zeros) assert not is_cupy_array((1, 2)) @given( label_smoothing=strategies.floats(min_value=0.0, max_value=0.5, exclude_max=True) ) def test_to_categorical(label_smoothing): # Test without n_classes one_hot = to_categorical(numpy.asarray([1, 2], dtype="i")) assert one_hot.shape == (2, 3) # From keras # https://github.com/keras-team/keras/blob/master/tests/keras/utils/np_utils_test.py nc = 5 shapes = [(1,), (3,), (4, 3), (5, 4, 3), (3, 1), (3, 2, 1)] expected_shapes = [ (1, nc), (3, nc), (4, 3, nc), (5, 4, 3, nc), (3, 1, nc), (3, 2, 1, nc), ] labels = [numpy.random.randint(0, nc, shape) for shape in shapes] one_hots = [to_categorical(label, nc) for label in labels] smooths = [ to_categorical(label, nc, label_smoothing=label_smoothing) for label in labels ] for i in range(len(expected_shapes)): label = labels[i] one_hot = one_hots[i] expected_shape = expected_shapes[i] smooth = smooths[i] assert one_hot.shape == expected_shape assert smooth.shape == expected_shape assert numpy.array_equal(one_hot, one_hot.astype(bool)) assert numpy.all(one_hot.sum(axis=-1) == 1) assert numpy.all(numpy.argmax(one_hot, -1).reshape(label.shape) == label) assert numpy.all(smooth.argmax(axis=-1) == one_hot.argmax(axis=-1)) assert numpy.all(numpy.isclose(numpy.sum(smooth, axis=-1), 1.0)) assert numpy.isclose(numpy.max(smooth), 1 - label_smoothing) assert numpy.isclose( numpy.min(smooth), label_smoothing / (smooth.shape[-1] - 1) ) # At least one class is required without label smoothing. numpy.testing.assert_allclose( to_categorical(numpy.asarray([0, 0, 0]), 1), [[1.0], [1.0], [1.0]] ) numpy.testing.assert_allclose( to_categorical(numpy.asarray([0, 0, 0])), [[1.0], [1.0], [1.0]] ) with pytest.raises(ValueError, match=r"n_classes should be at least 1"): to_categorical(numpy.asarray([0, 0, 0]), 0) # At least two classes are required with label smoothing. numpy.testing.assert_allclose( to_categorical(numpy.asarray([0, 1, 0]), 2, label_smoothing=0.01), [[0.99, 0.01], [0.01, 0.99], [0.99, 0.01]], ) numpy.testing.assert_allclose( to_categorical(numpy.asarray([0, 1, 0]), label_smoothing=0.01), [[0.99, 0.01], [0.01, 0.99], [0.99, 0.01]], ) with pytest.raises( ValueError, match=r"n_classes should be greater than 1.*label smoothing.*but 1" ): to_categorical(numpy.asarray([0, 1, 0]), 1, label_smoothing=0.01), with pytest.raises( ValueError, match=r"n_classes should be greater than 1.*label smoothing.*but 1" ): to_categorical(numpy.asarray([0, 0, 0]), label_smoothing=0.01), with pytest.raises(ValueError, match=r"label_smoothing parameter"): to_categorical(numpy.asarray([0, 1, 2, 3, 4]), label_smoothing=0.8) with pytest.raises(ValueError, match=r"label_smoothing parameter"): to_categorical(numpy.asarray([0, 1, 2, 3, 4]), label_smoothing=0.88) def test_convert_recursive(): is_match = lambda obj: obj == "foo" convert_item = lambda obj: obj.upper() obj = { "a": {("b", "foo"): {"c": "foo", "d": ["foo", {"e": "foo", "f": (1, "foo")}]}} } result = convert_recursive(is_match, convert_item, obj) assert result["a"][("b", "FOO")]["c"] == "FOO" assert result["a"][("b", "FOO")]["d"] == ["FOO", {"e": "FOO", "f": (1, "FOO")}] obj = {"a": ArgsKwargs(("foo", [{"b": "foo"}]), {"a": ["x", "foo"]})} result = convert_recursive(is_match, convert_item, obj) assert result["a"].args == ("FOO", [{"b": "FOO"}]) assert result["a"].kwargs == {"a": ["x", "FOO"]} thinc-9.0.0/thinc/tests/util.py000066400000000000000000000070201461023342500164220ustar00rootroot00000000000000import contextlib import shutil import tempfile from pathlib import Path import numpy import pytest from thinc.api import ArgsKwargs, Linear, Padded, Ragged from thinc.util import has_cupy, is_cupy_array, is_numpy_array @contextlib.contextmanager def make_tempdir(): d = Path(tempfile.mkdtemp()) yield d shutil.rmtree(str(d)) def get_model(W_b_input, cls=Linear): W, b, input_ = W_b_input nr_out, nr_in = W.shape model = cls(nr_out, nr_in) model.set_param("W", W) model.set_param("b", b) model.initialize() return model def get_shape(W_b_input): W, b, input_ = W_b_input return input_.shape[0], W.shape[0], W.shape[1] def get_data_checker(inputs): if isinstance(inputs, Ragged): return assert_raggeds_match elif isinstance(inputs, Padded): return assert_paddeds_match elif isinstance(inputs, list): return assert_lists_match elif isinstance(inputs, tuple) and len(inputs) == 4: return assert_padded_data_match elif isinstance(inputs, tuple) and len(inputs) == 2: return assert_ragged_data_match else: return assert_arrays_match def assert_arrays_match(X, Y): assert X.dtype == Y.dtype # Transformations are allowed to change last dimension, but not batch size. assert X.shape[0] == Y.shape[0] return True def assert_lists_match(X, Y): assert isinstance(X, list) assert isinstance(Y, list) assert len(X) == len(Y) for x, y in zip(X, Y): assert_arrays_match(x, y) return True def assert_raggeds_match(X, Y): assert isinstance(X, Ragged) assert isinstance(Y, Ragged) assert_arrays_match(X.lengths, Y.lengths) assert_arrays_match(X.data, Y.data) return True def assert_paddeds_match(X, Y): assert isinstance(X, Padded) assert isinstance(Y, Padded) assert_arrays_match(X.size_at_t, Y.size_at_t) assert assert_arrays_match(X.lengths, Y.lengths) assert assert_arrays_match(X.indices, Y.indices) assert X.data.dtype == Y.data.dtype assert X.data.shape[1] == Y.data.shape[1] assert X.data.shape[0] == Y.data.shape[0] return True def assert_padded_data_match(X, Y): return assert_paddeds_match(Padded(*X), Padded(*Y)) def assert_ragged_data_match(X, Y): return assert_raggeds_match(Ragged(*X), Ragged(*Y)) def check_input_converters(Y, backprop, data, n_args, kwargs_keys, type_): assert isinstance(Y, ArgsKwargs) assert len(Y.args) == n_args assert list(Y.kwargs.keys()) == kwargs_keys assert all(isinstance(arg, type_) for arg in Y.args) assert all(isinstance(arg, type_) for arg in Y.kwargs.values()) dX = backprop(Y) def is_supported_backend_array(arr): return is_cupy_array(arr) or is_numpy_array(arr) input_type = type(data) if not isinstance(data, list) else tuple assert isinstance(dX, input_type) or is_supported_backend_array(dX) if isinstance(data, dict): assert list(dX.keys()) == kwargs_keys assert all(is_supported_backend_array(arr) for arr in dX.values()) elif isinstance(data, (list, tuple)): assert isinstance(dX, tuple) assert all(is_supported_backend_array(arr) for arr in dX) elif isinstance(data, ArgsKwargs): assert len(dX.args) == n_args assert list(dX.kwargs.keys()) == kwargs_keys assert all(is_supported_backend_array(arg) for arg in dX.args) assert all(is_supported_backend_array(arg) for arg in dX.kwargs.values()) elif not isinstance(data, numpy.ndarray): pytest.fail(f"Bad data type: {dX}") thinc-9.0.0/thinc/types.py000066400000000000000000001353101461023342500154530ustar00rootroot00000000000000import sys from abc import abstractmethod from dataclasses import dataclass from typing import ( Any, Callable, Container, Dict, Generic, Iterable, Iterator, List, Optional, Sequence, Sized, Tuple, TypeVar, Union, cast, overload, ) import numpy from .compat import cupy, has_cupy if has_cupy: get_array_module = cupy.get_array_module else: get_array_module = lambda obj: numpy # Use typing_extensions for Python versions < 3.8 if sys.version_info < (3, 8): from typing_extensions import Literal, Protocol else: from typing import Literal, Protocol # noqa: F401 # fmt: off XY_YZ_OutT = TypeVar("XY_YZ_OutT") XY_XY_OutT = TypeVar("XY_XY_OutT") DeviceTypes = Literal["cpu", "gpu", "tpu"] Batchable = Union["Pairs", "Ragged", "Padded", "ArrayXd", List, Tuple] Xp = Union["numpy", "cupy"] # type: ignore Shape = Tuple[int, ...] DTypes = Literal["f", "i", "float16", "float32", "float64", "int32", "int64", "uint32", "uint64"] DTypesFloat = Literal["f", "float32", "float16", "float64"] DTypesInt = Literal["i", "int32", "int64", "uint32", "uint64"] Array1d = Union["Floats1d", "Ints1d"] Array2d = Union["Floats2d", "Ints2d"] Array3d = Union["Floats3d", "Ints3d"] Array4d = Union["Floats4d", "Ints4d"] FloatsXd = Union["Floats1d", "Floats2d", "Floats3d", "Floats4d"] IntsXd = Union["Ints1d", "Ints2d", "Ints3d", "Ints4d"] ArrayXd = Union[FloatsXd, IntsXd] List1d = Union[List["Floats1d"], List["Ints1d"]] List2d = Union[List["Floats2d"], List["Ints2d"]] List3d = Union[List["Floats3d"], List["Ints3d"]] List4d = Union[List["Floats4d"], List["Ints4d"]] ListXd = Union[List1d, List2d, List3d, List4d] ArrayT = TypeVar("ArrayT") SelfT = TypeVar("SelfT") Array1dT = TypeVar("Array1dT", bound="Array1d") FloatsXdT = TypeVar("FloatsXdT", "Floats1d", "Floats2d", "Floats3d", "Floats4d") # These all behave the same as far as indexing is concerned Slicish = Union[slice, List[int], "ArrayXd"] _1_KeyScalar = int _1_Key1d = Slicish _1_AllKeys = Union[_1_KeyScalar, _1_Key1d] _F1_AllReturns = Union[float, "Floats1d"] _I1_AllReturns = Union[int, "Ints1d"] _2_KeyScalar = Tuple[int, int] _2_Key1d = Union[int, Tuple[Slicish, int], Tuple[int, Slicish]] _2_Key2d = Union[Tuple[Slicish, Slicish], Slicish] _2_AllKeys = Union[_2_KeyScalar, _2_Key1d, _2_Key2d] _F2_AllReturns = Union[float, "Floats1d", "Floats2d"] _I2_AllReturns = Union[int, "Ints1d", "Ints2d"] _3_KeyScalar = Tuple[int, int, int] _3_Key1d = Union[Tuple[int, int], Tuple[int, int, Slicish], Tuple[int, Slicish, int], Tuple[Slicish, int, int]] _3_Key2d = Union[int, Tuple[int, Slicish], Tuple[Slicish, int], Tuple[int, Slicish, Slicish], Tuple[Slicish, int, Slicish], Tuple[Slicish, Slicish, int]] _3_Key3d = Union[Slicish, Tuple[Slicish, Slicish], Tuple[Slicish, Slicish, Slicish]] _3_AllKeys = Union[_3_KeyScalar, _3_Key1d, _3_Key2d, _3_Key3d] _F3_AllReturns = Union[float, "Floats1d", "Floats2d", "Floats3d"] _I3_AllReturns = Union[int, "Ints1d", "Ints2d", "Ints3d"] _4_KeyScalar = Tuple[int, int, int, int] _4_Key1d = Union[Tuple[int, int, int], Tuple[int, int, int, Slicish], Tuple[int, int, Slicish, int], Tuple[int, Slicish, int, int], Tuple[Slicish, int, int, int]] _4_Key2d = Union[Tuple[int, int], Tuple[int, int, Slicish], Tuple[int, Slicish, int], Tuple[Slicish, int, int], Tuple[int, int, Slicish, Slicish], Tuple[int, Slicish, int, Slicish], Tuple[int, Slicish, Slicish, int], Tuple[Slicish, int, int, Slicish], Tuple[Slicish, int, Slicish, int], Tuple[Slicish, Slicish, int, int]] _4_Key3d = Union[int, Tuple[int, Slicish], Tuple[Slicish, int], Tuple[int, Slicish, Slicish], Tuple[Slicish, int, Slicish], Tuple[Slicish, Slicish, int], Tuple[int, Slicish, Slicish, Slicish], Tuple[Slicish, int, Slicish, Slicish], Tuple[Slicish, Slicish, int, Slicish], Tuple[Slicish, Slicish, Slicish, int]] _4_Key4d = Union[Slicish, Tuple[Slicish, Slicish], Tuple[Slicish, Slicish, Slicish], Tuple[Slicish, Slicish, Slicish, Slicish]] _4_AllKeys = Union[_4_KeyScalar, _4_Key1d, _4_Key2d, _4_Key3d, _4_Key4d] _F4_AllReturns = Union[float, "Floats1d", "Floats2d", "Floats3d", "Floats4d"] _I4_AllReturns = Union[int, "Ints1d", "Ints2d", "Ints3d", "Ints4d"] # Typedefs for the reduction methods. Tru = Literal[True] Fal = Literal[False] OneAx = Union[int, Tuple[int]] TwoAx = Tuple[int, int] ThreeAx = Tuple[int, int, int] FourAx = Tuple[int, int, int, int] _1_AllAx = Optional[OneAx] _2_AllAx = Union[Optional[TwoAx], OneAx] _3_AllAx = Union[Optional[ThreeAx], TwoAx, OneAx] _4_AllAx = Union[Optional[FourAx], ThreeAx, TwoAx, OneAx] _1F_ReduceResults = Union[float, "Floats1d"] _2F_ReduceResults = Union[float, "Floats1d", "Floats2d"] _3F_ReduceResults = Union[float, "Floats1d", "Floats2d", "Floats3d"] _4F_ReduceResults = Union[float, "Floats1d", "Floats2d", "Floats3d", "Floats4d"] _1I_ReduceResults = Union[int, "Ints1d"] _2I_ReduceResults = Union[int, "Ints1d", "Ints2d"] _3I_ReduceResults = Union[int, "Ints1d", "Ints2d", "Ints3d"] _4I_ReduceResults = Union[int, "Ints1d", "Ints2d", "Ints3d", "Ints4d"] # TODO: # We need to get correct overloads in for the following reduction methods. # The 'sum' reduction is correct --- the others need to be just the same, # but with a different name. # max, min, prod, round, var, mean, ptp, std # There's also one *slightly* different function, cumsum. This doesn't # have a scalar version -- it always makes an array. class _Array(Sized, Container): @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v) @property @abstractmethod def dtype(self) -> DTypes: ... @property @abstractmethod def data(self) -> memoryview: ... @property @abstractmethod def flags(self) -> Any: ... @property @abstractmethod def size(self) -> int: ... @property @abstractmethod def itemsize(self) -> int: ... @property @abstractmethod def nbytes(self) -> int: ... @property @abstractmethod def ndim(self) -> int: ... @property @abstractmethod def shape(self) -> Shape: ... @property @abstractmethod def strides(self) -> Tuple[int, ...]: ... # TODO: Is ArrayT right? @abstractmethod def astype(self: ArrayT, dtype: DTypes, order: str = ..., casting: str = ..., subok: bool = ..., copy: bool = ...) -> ArrayT: ... @abstractmethod def copy(self: ArrayT, order: str = ...) -> ArrayT: ... @abstractmethod def fill(self, value: Any) -> None: ... # Shape manipulation @abstractmethod def reshape(self: ArrayT, shape: Shape, *, order: str = ...) -> ArrayT: ... @abstractmethod def transpose(self: ArrayT, axes: Shape) -> ArrayT: ... # TODO: is this right? It returns 1d @abstractmethod def flatten(self, order: str = ...): ... # TODO: is this right? It returns 1d @abstractmethod def ravel(self, order: str = ...): ... @abstractmethod def squeeze(self, axis: Union[int, Shape] = ...): ... @abstractmethod def __len__(self) -> int: ... @abstractmethod def __setitem__(self, key, value): ... @abstractmethod def __iter__(self) -> Iterator[Any]: ... @abstractmethod def __contains__(self, key) -> bool: ... @abstractmethod def __index__(self) -> int: ... @abstractmethod def __int__(self) -> int: ... @abstractmethod def __float__(self) -> float: ... @abstractmethod def __complex__(self) -> complex: ... @abstractmethod def __bool__(self) -> bool: ... @abstractmethod def __bytes__(self) -> bytes: ... @abstractmethod def __str__(self) -> str: ... @abstractmethod def __repr__(self) -> str: ... @abstractmethod def __copy__(self, order: str = ...): ... @abstractmethod def __deepcopy__(self: SelfT, memo: dict) -> SelfT: ... @abstractmethod def __lt__(self, other): ... @abstractmethod def __le__(self, other): ... @abstractmethod def __eq__(self, other): ... @abstractmethod def __ne__(self, other): ... @abstractmethod def __gt__(self, other): ... @abstractmethod def __ge__(self, other): ... @abstractmethod def __add__(self, other): ... @abstractmethod def __radd__(self, other): ... @abstractmethod def __iadd__(self, other): ... @abstractmethod def __sub__(self, other): ... @abstractmethod def __rsub__(self, other): ... @abstractmethod def __isub__(self, other): ... @abstractmethod def __mul__(self, other): ... @abstractmethod def __rmul__(self, other): ... @abstractmethod def __imul__(self, other): ... @abstractmethod def __truediv__(self, other): ... @abstractmethod def __rtruediv__(self, other): ... @abstractmethod def __itruediv__(self, other): ... @abstractmethod def __floordiv__(self, other): ... @abstractmethod def __rfloordiv__(self, other): ... @abstractmethod def __ifloordiv__(self, other): ... @abstractmethod def __mod__(self, other): ... @abstractmethod def __rmod__(self, other): ... @abstractmethod def __imod__(self, other): ... @abstractmethod def __divmod__(self, other): ... @abstractmethod def __rdivmod__(self, other): ... # NumPy's __pow__ doesn't handle a third argument @abstractmethod def __pow__(self, other): ... @abstractmethod def __rpow__(self, other): ... @abstractmethod def __ipow__(self, other): ... @abstractmethod def __lshift__(self, other): ... @abstractmethod def __rlshift__(self, other): ... @abstractmethod def __ilshift__(self, other): ... @abstractmethod def __rshift__(self, other): ... @abstractmethod def __rrshift__(self, other): ... @abstractmethod def __irshift__(self, other): ... @abstractmethod def __and__(self, other): ... @abstractmethod def __rand__(self, other): ... @abstractmethod def __iand__(self, other): ... @abstractmethod def __xor__(self, other): ... @abstractmethod def __rxor__(self, other): ... @abstractmethod def __ixor__(self, other): ... @abstractmethod def __or__(self, other): ... @abstractmethod def __ror__(self, other): ... @abstractmethod def __ior__(self, other): ... @abstractmethod def __matmul__(self, other): ... @abstractmethod def __rmatmul__(self, other): ... @abstractmethod def __neg__(self: ArrayT) -> ArrayT: ... @abstractmethod def __pos__(self: ArrayT) -> ArrayT: ... @abstractmethod def __abs__(self: ArrayT) -> ArrayT: ... @abstractmethod def __invert__(self: ArrayT) -> ArrayT: ... @abstractmethod def get(self: ArrayT) -> ArrayT: ... @abstractmethod def all(self, axis: int = -1, out: Optional[ArrayT] = None, keepdims: bool = False) -> ArrayT: ... @abstractmethod def any(self, axis: int = -1, out: Optional[ArrayT] = None, keepdims: bool = False) -> ArrayT: ... # def argmax(self, axis: int = -1, out: Optional["Array"] = None, keepdims: Union[Tru, Fal]=False) -> Union[int, "Ints1d"]: ... @abstractmethod def argmin(self, axis: int = -1, out: Optional[ArrayT] = None) -> ArrayT: ... @abstractmethod def clip(self, a_min: Any, a_max: Any, out: Optional[ArrayT]) -> ArrayT: ... #def cumsum( self: ArrayT, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional[ArrayT] = None) -> ArrayT: ... @abstractmethod def max(self, axis: int = -1, out: Optional[ArrayT] = None) -> ArrayT: ... # def mean(self, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional[SelfT] = None, keepdims: bool = False) -> "Array": ... @abstractmethod def min(self, axis: int = -1, out: Optional[ArrayT] = None) -> ArrayT: ... @abstractmethod def nonzero(self: SelfT) -> SelfT: ... @abstractmethod def prod(self, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional[ArrayT] = None, keepdims: bool = False) -> ArrayT: ... @abstractmethod def round(self, decimals: int = 0, out: Optional[ArrayT] = None) -> ArrayT: ... # def sum(self, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional[ArrayT] = None, keepdims: bool = False) -> ArrayT: ... @abstractmethod def tobytes(self, order: str = "C") -> bytes: ... @abstractmethod def tolist(self) -> List[Any]: ... @abstractmethod def var(self: SelfT, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional[ArrayT] = None, ddof: int = 0, keepdims: bool = False) -> SelfT: ... class _Floats(_Array): @property @abstractmethod def dtype(self) -> DTypesFloat: ... @abstractmethod def fill(self, value: float) -> None: ... @abstractmethod def reshape(self, shape: Shape, *, order: str = ...) -> "_Floats": ... class _Ints(_Array): @property @abstractmethod def dtype(self) -> DTypesInt: ... @abstractmethod def fill(self, value: int) -> None: ... @abstractmethod def reshape(self, shape: Shape, *, order: str = ...) -> "_Ints": ... """ Extensive overloads to represent __getitem__ behaviour. In an N+1 dimensional array, there will be N possible return types. For instance, if you have a 2d array, you could get back a float (array[i, j]), a floats1d (array[i]) or a floats2d (array[:i, :j]). You'll get the scalar if you have N ints in the index, a 1d array if you have N-1 ints, etc. So the trick here is to make a union with the various combinations that produce each result type, and then only have one overload per result. If we overloaded on each *key* type, that would get crazy, because there's tonnes of combinations. In each rank, we can use the same key-types for float and int, but we need a different return-type union. """ class _Array1d(_Array): """1-dimensional array.""" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=1) @property @abstractmethod def ndim(self) -> Literal[1]: ... @property @abstractmethod def shape(self) -> Tuple[int]: ... @abstractmethod def __iter__(self) -> Iterator[Union[float, int]]: ... @abstractmethod def astype(self, dtype: DTypes, order: str = ..., casting: str = ..., subok: bool = ..., copy: bool = ...) -> "_Array1d": ... @abstractmethod def flatten(self: SelfT, order: str = ...) -> SelfT: ... @abstractmethod def ravel(self: SelfT, order: str = ...) -> SelfT: ... # These is actually a bit too strict: It's legal to say 'array1d + array2d' # That's kind of bad code though; it's better to write array2d + array1d. # We could relax this, but let's try the strict version. @abstractmethod def __add__(self: SelfT, other: Union[float, int, "Array1d"]) -> SelfT: ... @abstractmethod def __sub__(self: SelfT, other: Union[float, int, "Array1d"]) -> SelfT: ... @abstractmethod def __mul__(self: SelfT, other: Union[float, int, "Array1d"]) -> SelfT: ... @abstractmethod def __pow__(self: SelfT, other: Union[float, int, "Array1d"]) -> SelfT: ... @abstractmethod def __matmul__(self: SelfT, other: Union[float, int, "Array1d"]) -> SelfT: ... # These are not too strict though: you can't do += with higher dimensional. @abstractmethod def __iadd__(self, other: Union[float, int, "Array1d"]): ... @abstractmethod def __isub__(self, other: Union[float, int, "Array1d"]): ... @abstractmethod def __imul__(self, other: Union[float, int, "Array1d"]): ... @abstractmethod def __ipow__(self, other: Union[float, int, "Array1d"]): ... @overload @abstractmethod def argmax(self, keepdims: Fal = False, axis: int = -1, out: Optional[_Array] = None) -> int: ... @overload @abstractmethod def argmax(self, keepdims: Tru, axis: int = -1, out: Optional[_Array] = None) -> "Ints1d": ... @abstractmethod def argmax(self, keepdims: bool = False, axis: int = -1, out: Optional[_Array] = None) -> Union[int, "Ints1d"]: ... @overload @abstractmethod def mean(self, keepdims: Tru, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional["Floats1d"] = None) -> "Floats1d": ... @overload @abstractmethod def mean(self, keepdims: Fal = False, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional["Floats1d"] = None) -> float: ... @abstractmethod def mean(self, keepdims: bool = False, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional["Floats1d"] = None) -> Union["Floats1d", float]: ... class Floats1d(_Array1d, _Floats): """1-dimensional array of floats.""" T: "Floats1d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=1, dtype="f") @abstractmethod def __iter__(self) -> Iterator[float]: ... @overload @abstractmethod def __getitem__(self, key: _1_KeyScalar) -> float: ... @overload @abstractmethod def __getitem__(self, key: _1_Key1d) -> "Floats1d": ... @abstractmethod def __getitem__(self, key: _1_AllKeys) -> _F1_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _1_KeyScalar, value: float) -> None: ... @overload @abstractmethod def __setitem__(self, key: _1_Key1d, value: "Floats1d") -> None: ... @abstractmethod def __setitem__(self, key: _1_AllKeys, _F1_AllReturns) -> None: ... @overload @abstractmethod def cumsum(self, *, keepdims: Tru, axis: Optional[OneAx] = None, out: Optional["Floats1d"] = None) -> "Floats1d": ... @overload # Cumsum is unusual in this @abstractmethod def cumsum(self, *, keepdims: Fal, axis: Optional[OneAx] = None, out: Optional["Floats1d"] = None) -> "Floats1d": ... @abstractmethod def cumsum(self, *, keepdims: bool = False, axis: _1_AllAx = None, out: Optional["Floats1d"] = None) -> "Floats1d": ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: Optional[OneAx] = None, out: Optional["Floats1d"] = None) -> "Floats1d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: Optional[OneAx] = None, out = None) -> float: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _1_AllAx = None, out: Optional["Floats1d"] = None) -> _1F_ReduceResults: ... class Ints1d(_Array1d, _Ints): """1-dimensional array of ints.""" T: "Ints1d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=1, dtype="i") @abstractmethod def __iter__(self) -> Iterator[int]: ... @overload @abstractmethod def __getitem__(self, key: _1_KeyScalar) -> int: ... @overload @abstractmethod def __getitem__(self, key: _1_Key1d) -> "Ints1d": ... @abstractmethod def __getitem__(self, key: _1_AllKeys) -> _I1_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _1_KeyScalar, value: int) -> None: ... @overload @abstractmethod def __setitem__(self, key: _1_Key1d, value: Union[int, "Ints1d"]) -> None: ... @abstractmethod def __setitem__(self, key: _1_AllKeys, _I1_AllReturns) -> None: ... @overload @abstractmethod def cumsum(self, *, keepdims: Tru, axis: Optional[OneAx] = None, out: Optional["Ints1d"] = None) -> "Ints1d": ... @overload @abstractmethod def cumsum(self, *, keepdims: Fal = False, axis: Optional[OneAx] = None, out: Optional["Ints1d"] = None) -> "Ints1d": ... @abstractmethod def cumsum(self, *, keepdims: bool = False, axis: _1_AllAx = None, out: Optional["Ints1d"] = None) -> "Ints1d": ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: Optional[OneAx] = None, out: Optional["Ints1d"] = None) -> "Ints1d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: Optional[OneAx] = None, out = None) -> int: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _1_AllAx = None, out: Optional["Ints1d"] = None) -> _1I_ReduceResults: ... class _Array2d(_Array): @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=2) @property @abstractmethod def ndim(self) -> Literal[2]: ... @property @abstractmethod def shape(self) -> Tuple[int, int]: ... @abstractmethod def __iter__(self) -> Iterator[Array1d]: ... @abstractmethod def astype(self, dtype: DTypes, order: str = ..., casting: str = ..., subok: bool = ..., copy: bool = ...) -> "Array2d": ... # These is actually a bit too strict: It's legal to say 'array2d + array3d' # That's kind of bad code though; it's better to write array3d + array2d. # We could relax this, but let's try the strict version. @abstractmethod def __add__(self: ArrayT, other: Union[float, int, Array1d, "Array2d"]) -> ArrayT: ... @abstractmethod def __sub__(self: ArrayT, other: Union[float, int, Array1d, "Array2d"]) -> ArrayT: ... @abstractmethod def __mul__(self: ArrayT, other: Union[float, int, Array1d, "Array2d"]) -> ArrayT: ... @abstractmethod def __pow__(self: ArrayT, other: Union[float, int, Array1d, "Array2d"]) -> ArrayT: ... @abstractmethod def __matmul__(self: ArrayT, other: Union[float, int, Array1d, "Array2d"]) -> ArrayT: ... # These are not too strict though: you can't do += with higher dimensional. @abstractmethod def __iadd__(self, other: Union[float, int, Array1d, "Array2d"]): ... @abstractmethod def __isub__(self, other: Union[float, int, Array1d, "Array2d"]): ... @abstractmethod def __imul__(self, other: Union[float, int, Array1d, "Array2d"]): ... @abstractmethod def __ipow__(self, other: Union[float, int, Array1d, "Array2d"]): ... @overload @abstractmethod def argmax(self, keepdims: Fal = False, axis: int = -1, out: Optional[_Array] = None) -> Ints1d: ... @overload @abstractmethod def argmax(self, keepdims: Tru, axis: int = -1, out: Optional[_Array] = None) -> "Ints2d": ... @abstractmethod def argmax(self, keepdims: bool = False, axis: int = -1, out: Optional[_Array] = None) -> Union[Ints1d, "Ints2d"]: ... @overload @abstractmethod def mean(self, keepdims: Fal = False, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional["Floats2d"] = None) -> Floats1d: ... @overload @abstractmethod def mean(self, keepdims: Tru, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional["Floats2d"] = None) -> "Floats2d": ... @abstractmethod def mean(self, keepdims: bool = False, axis: int = -1, dtype: Optional[DTypes] = None, out: Optional["Floats2d"] = None) -> Union["Floats2d", Floats1d]: ... class Floats2d(_Array2d, _Floats): """2-dimensional array of floats""" T: "Floats2d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=2, dtype="f") @abstractmethod def __iter__(self) -> Iterator[Floats1d]: ... @overload @abstractmethod def __getitem__(self, key: _2_KeyScalar) -> float: ... @overload @abstractmethod def __getitem__(self, key: _2_Key1d) -> Floats1d: ... @overload @abstractmethod def __getitem__(self, key: _2_Key2d) -> "Floats2d": ... @abstractmethod def __getitem__(self, key: _2_AllKeys) -> _F2_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _2_KeyScalar, value: float) -> None: ... @overload @abstractmethod def __setitem__(self, key: _2_Key1d, value: Union[float, Floats1d]) -> None: ... @overload @abstractmethod def __setitem__(self, key: _2_Key2d, value: _F2_AllReturns) -> None: ... @abstractmethod def __setitem__(self, key: _2_AllKeys, value: _F2_AllReturns) -> None: ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: _2_AllAx = None, out: Optional["Floats2d"] = None) -> "Floats2d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: OneAx, out: Optional[Floats1d] = None) -> Floats1d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: TwoAx, out = None) -> float: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _2_AllAx = None, out: Union[None, "Floats1d", "Floats2d"] = None) -> _2F_ReduceResults: ... class Ints2d(_Array2d, _Ints): """2-dimensional array of ints.""" T: "Ints2d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=2, dtype="i") @abstractmethod def __iter__(self) -> Iterator[Ints1d]: ... @overload @abstractmethod def __getitem__(self, key: _2_KeyScalar) -> int: ... @overload @abstractmethod def __getitem__(self, key: _2_Key1d) -> Ints1d: ... @overload @abstractmethod def __getitem__(self, key: _2_Key2d) -> "Ints2d": ... @abstractmethod def __getitem__(self, key: _2_AllKeys) -> _I2_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _2_KeyScalar, value: int) -> None: ... @overload @abstractmethod def __setitem__(self, key: _2_Key1d, value: Ints1d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _2_Key2d, value: "Ints2d") -> None: ... @abstractmethod def __setitem__(self, key: _2_AllKeys, value: _I2_AllReturns) -> None: ... @overload @abstractmethod def sum(self, keepdims: Fal = False, axis: int = -1, out: Optional["Ints1d"] = None) -> Ints1d: ... @overload @abstractmethod def sum(self, keepdims: Tru, axis: int = -1, out: Optional["Ints2d"] = None) -> "Ints2d": ... @abstractmethod def sum(self, keepdims: bool = False, axis: int = -1, out: Optional[Union["Ints1d", "Ints2d"]] = None) -> Union["Ints2d", Ints1d]: ... class _Array3d(_Array): """3-dimensional array of floats""" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=3) @property @abstractmethod def ndim(self) -> Literal[3]: ... @property @abstractmethod def shape(self) -> Tuple[int, int, int]: ... @abstractmethod def __iter__(self) -> Iterator[Array2d]: ... @abstractmethod def astype(self, dtype: DTypes, order: str = ..., casting: str = ..., subok: bool = ..., copy: bool = ...) -> "Array3d": ... # These is actually a bit too strict: It's legal to say 'array2d + array3d' # That's kind of bad code though; it's better to write array3d + array2d. # We could relax this, but let's try the strict version. @abstractmethod def __add__(self: SelfT, other: Union[float, int, Array1d, Array2d, "Array3d"]) -> SelfT: ... @abstractmethod def __sub__(self: SelfT, other: Union[float, int, Array1d, Array2d, "Array3d"]) -> SelfT: ... @abstractmethod def __mul__(self: SelfT, other: Union[float, int, Array1d, Array2d, "Array3d"]) -> SelfT: ... @abstractmethod def __pow__(self: SelfT, other: Union[float, int, Array1d, Array2d, "Array3d"]) -> SelfT: ... @abstractmethod def __matmul__(self: SelfT, other: Union[float, int, Array1d, Array2d, "Array3d"]) -> SelfT: ... # These are not too strict though: you can't do += with higher dimensional. @abstractmethod def __iadd__(self, other: Union[float, int, Array1d, Array2d, "Array3d"]): ... @abstractmethod def __isub__(self, other: Union[float, int, Array1d, Array2d, "Array3d"]): ... @abstractmethod def __imul__(self, other: Union[float, int, Array1d, Array2d, "Array3d"]): ... @abstractmethod def __ipow__(self, other: Union[float, int, Array1d, Array2d, "Array3d"]): ... @overload @abstractmethod def argmax(self, keepdims: Fal = False, axis: int = -1, out: Optional[_Array] = None) -> Ints2d: ... @overload @abstractmethod def argmax(self, keepdims: Tru, axis: int = -1, out: Optional[_Array] = None) -> "Ints3d": ... @abstractmethod def argmax(self, keepdims: bool = False, axis: int = -1, out: Optional[_Array] = None) -> Union[Ints2d, "Ints3d"]: ... class Floats3d(_Array3d, _Floats): """3-dimensional array of floats""" T: "Floats3d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=3, dtype="f") @abstractmethod def __iter__(self) -> Iterator[Floats2d]: ... @overload @abstractmethod def __getitem__(self, key: _3_KeyScalar) -> float: ... @overload @abstractmethod def __getitem__(self, key: _3_Key1d) -> Floats1d: ... @overload @abstractmethod def __getitem__(self, key: _3_Key2d) -> Floats2d: ... @overload @abstractmethod def __getitem__(self, key: _3_Key3d) -> "Floats3d": ... @abstractmethod def __getitem__(self, key: _3_AllKeys) -> _F3_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _3_KeyScalar, value: float) -> None: ... @overload @abstractmethod def __setitem__(self, key: _3_Key1d, value: Floats1d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _3_Key2d, value: Floats2d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _3_Key3d, value: "Floats3d") -> None: ... @abstractmethod def __setitem__(self, key: _3_AllKeys, value: _F3_AllReturns) -> None: ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: _3_AllAx = None, out: Optional["Floats3d"] = None) -> "Floats3d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: OneAx, out: Optional[Floats2d] = None) -> Floats2d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: TwoAx, out: Optional[Floats1d] = None) -> Floats1d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: Optional[ThreeAx], out = None) -> float: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _3_AllAx = None, out: Union[None, Floats1d, Floats2d, "Floats3d"] = None) -> _3F_ReduceResults: ... class Ints3d(_Array3d, _Ints): """3-dimensional array of ints.""" T: "Ints3d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=3, dtype="i") @abstractmethod def __iter__(self) -> Iterator[Ints2d]: ... @overload @abstractmethod def __getitem__(self, key: _3_KeyScalar) -> int: ... @overload @abstractmethod def __getitem__(self, key: _3_Key1d) -> Ints1d: ... @overload @abstractmethod def __getitem__(self, key: _3_Key2d) -> Ints2d: ... @overload @abstractmethod def __getitem__(self, key: _3_Key3d) -> "Ints3d": ... @abstractmethod def __getitem__(self, key: _3_AllKeys) -> _I3_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _3_KeyScalar, value: int) -> None: ... @overload @abstractmethod def __setitem__(self, key: _3_Key1d, value: Ints1d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _3_Key2d, value: Ints2d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _3_Key3d, value: "Ints3d") -> None: ... @abstractmethod def __setitem__(self, key: _3_AllKeys, value: _I3_AllReturns) -> None: ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: _3_AllAx = None, out: Optional["Ints3d"] = None) -> "Ints3d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: OneAx, out: Optional[Ints2d] = None) -> Ints2d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: TwoAx, out: Optional[Ints1d] = None) -> Ints1d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal, axis: Optional[ThreeAx], out = None) -> int: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _3_AllAx = None, out: Union[None, Ints1d, Ints2d, "Ints3d"] = None) -> _3I_ReduceResults: ... class _Array4d(_Array): """4-dimensional array.""" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=4) @property @abstractmethod def ndim(self) -> Literal[4]: ... @property @abstractmethod def shape(self) -> Tuple[int, int, int, int]: ... @abstractmethod def __iter__(self) -> Iterator[Array3d]: ... @abstractmethod def astype(self, dtype: DTypes, order: str = ..., casting: str = ..., subok: bool = ..., copy: bool = ...) -> "_Array4d": ... # These is actually a bit too strict: It's legal to say 'array4d + array5d' # That's kind of bad code though; it's better to write array5d + array4d. # We could relax this, but let's try the strict version. @abstractmethod def __add__(self: SelfT, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]) -> SelfT: ... @abstractmethod def __sub__(self: SelfT, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]) -> SelfT: ... @abstractmethod def __mul__(self: SelfT, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]) -> SelfT: ... @abstractmethod def __pow__(self: SelfT, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]) -> SelfT: ... @abstractmethod def __matmul__(self: SelfT, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]) -> SelfT: ... @abstractmethod # These are not too strict though: you can't do += with higher dimensional. @abstractmethod def __iadd__(self, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]): ... @abstractmethod def __isub__(self, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]): ... @abstractmethod def __imul__(self, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]): ... @abstractmethod def __ipow__(self, other: Union[float, int, Array1d, Array2d, Array3d, "Array4d"]): ... class Floats4d(_Array4d, _Floats): """4-dimensional array of floats.""" T: "Floats4d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=4, dtype="f") @abstractmethod def __iter__(self) -> Iterator[Floats3d]: ... @overload @abstractmethod def __getitem__(self, key: _4_KeyScalar) -> float: ... @overload @abstractmethod def __getitem__(self, key: _4_Key1d) -> Floats1d: ... @overload @abstractmethod def __getitem__(self, key: _4_Key2d) -> Floats2d: ... @overload @abstractmethod def __getitem__(self, key: _4_Key3d) -> Floats3d: ... @overload @abstractmethod def __getitem__(self, key: _4_Key4d) -> "Floats4d": ... @abstractmethod def __getitem__(self, key: _4_AllKeys) -> _F4_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _4_KeyScalar, value: float) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key1d, value: Floats1d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key2d, value: Floats2d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key3d, value: Floats3d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key4d, value: "Floats4d") -> None: ... @abstractmethod def __setitem__(self, key: _4_AllKeys, value: _F4_AllReturns) -> None: ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: _4_AllAx = None, out: Optional["Floats4d"] = None) -> "Floats4d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: OneAx, out: Optional[Floats3d] = None) -> Floats3d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: TwoAx, out: Optional[Floats2d] = None) -> Floats2d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: ThreeAx, out: Optional[Floats1d] = None) -> Floats1d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: Optional[FourAx], out = None) -> float: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _4_AllAx = None, out: Union[None, Floats1d, Floats2d, Floats3d, "Floats4d"] = None) -> _4F_ReduceResults: ... class Ints4d(_Array4d, _Ints): """4-dimensional array of ints.""" T: "Ints4d" @classmethod def __get_validators__(cls): """Runtime validation for pydantic.""" yield lambda v: validate_array(v, ndim=4, dtype="i") @abstractmethod def __iter__(self) -> Iterator[Ints3d]: ... @overload @abstractmethod def __getitem__(self, key: _4_KeyScalar) -> int: ... @overload @abstractmethod def __getitem__(self, key: _4_Key1d) -> Ints1d: ... @overload @abstractmethod def __getitem__(self, key: _4_Key2d) -> Ints2d: ... @overload @abstractmethod def __getitem__(self, key: _4_Key3d) -> Ints3d: ... @overload @abstractmethod def __getitem__(self, key: _4_Key4d) -> "Ints4d": ... @abstractmethod def __getitem__(self, key: _4_AllKeys) -> _I4_AllReturns: ... @overload @abstractmethod def __setitem__(self, key: _4_KeyScalar, value: int) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key1d, value: Ints1d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key2d, value: Ints2d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key3d, value: Ints3d) -> None: ... @overload @abstractmethod def __setitem__(self, key: _4_Key4d, value: "Ints4d") -> None: ... @abstractmethod def __setitem__(self, key: _4_AllKeys, value: _I4_AllReturns) -> None: ... @overload @abstractmethod def sum(self, *, keepdims: Tru, axis: _4_AllAx = None, out: Optional["Ints4d"] = None) -> "Ints4d": ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: OneAx, out: Optional[Ints3d] = None) -> Ints3d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: TwoAx, out: Optional[Ints2d] = None) -> Ints2d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: ThreeAx, out: Optional[Ints1d] = None) -> Ints1d: ... @overload @abstractmethod def sum(self, *, keepdims: Fal = False, axis: Optional[FourAx] = None, out = None) -> int: ... @abstractmethod def sum(self, *, keepdims: bool = False, axis: _4_AllAx = None, out: Optional[Union[Ints1d, Ints2d, Ints3d, "Ints4d"]] = None) -> _4I_ReduceResults: ... _DIn = TypeVar("_DIn") class Decorator(Protocol): """Protocol to mark a function as returning its child with identical signature.""" def __call__(self, name: str) -> Callable[[_DIn], _DIn]: ... # fmt: on class Generator(Iterator): """Custom generator type. Used to annotate function arguments that accept generators so they can be validated by pydantic (which doesn't support iterators/iterables otherwise). """ @classmethod def __get_validators__(cls): yield cls.validate @classmethod def validate(cls, v): if not hasattr(v, "__iter__") and not hasattr(v, "__next__"): raise TypeError("not a valid iterator") return v @dataclass class SizedGenerator: """A generator that has a __len__ and can repeatedly call the generator function. """ get_items: Callable[[], Generator] length: int def __len__(self): return self.length def __iter__(self): yield from self.get_items() @dataclass class Padded: """A batch of padded sequences, sorted by decreasing length. The data array is of shape (step, batch, ...). The auxiliary array size_at_t indicates the length of the batch at each timestep, so you can do data[:, :size_at_t[t]] to shrink the batch. The lengths array indicates the length of each row b, and the indices indicates the original ordering. """ data: Array3d size_at_t: Ints1d lengths: Ints1d indices: Ints1d def copy(self): return Padded( self.data.copy(), self.size_at_t.copy(), self.lengths.copy(), self.indices.copy(), ) def __len__(self) -> int: return self.lengths.shape[0] def __getitem__(self, index: Union[int, slice, Ints1d]) -> "Padded": if isinstance(index, int): # Slice to keep the dimensionality return Padded( self.data[:, index : index + 1], self.lengths[index : index + 1], self.lengths[index : index + 1], self.indices[index : index + 1], ) elif isinstance(index, slice): return Padded( self.data[:, index], self.lengths[index], self.lengths[index], self.indices[index], ) else: # If we get a sequence of indices, we need to be careful that # we maintain the length-sorting, while also keeping the mapping # back to the original order correct. sorted_index = list(sorted(index)) return Padded( self.data[sorted_index], self.size_at_t[sorted_index], self.lengths[sorted_index], self.indices[index], # Use original, to maintain order. ) @dataclass class Ragged: """A batch of concatenated sequences, that vary in the size of their first dimension. Ragged allows variable-length sequence data to be contiguous in memory, without padding. Indexing into Ragged is just like indexing into the *lengths* array, except it returns a Ragged object with the accompanying sequence data. For instance, you can write ragged[1:4] to get a Ragged object with sequences 1, 2 and 3. """ data: Array2d lengths: Ints1d data_shape: Tuple[int, ...] starts_ends: Optional[Ints1d] = None def __init__(self, data: _Array, lengths: Ints1d): self.lengths = lengths # Frustratingly, the -1 dimension doesn't work with 0 size... if data.size: self.data = cast(Array2d, data.reshape((data.shape[0], -1))) else: self.data = cast(Array2d, data.reshape((0, 0))) self.data_shape = (-1,) + data.shape[1:] @property def dataXd(self) -> ArrayXd: if self.data.size: reshaped = self.data.reshape(self.data_shape) else: reshaped = self.data.reshape((self.data.shape[0],) + self.data_shape[1:]) return cast(ArrayXd, reshaped) def __len__(self) -> int: return self.lengths.shape[0] def __getitem__(self, index: Union[int, slice, Array1d]) -> "Ragged": if isinstance(index, tuple): raise IndexError("Ragged arrays do not support 2d indexing.") starts = self._get_starts() ends = self._get_ends() if isinstance(index, int): s = starts[index] e = ends[index] return Ragged(self.data[s:e], self.lengths[index : index + 1]) elif isinstance(index, slice): lengths = self.lengths[index] if len(lengths) == 0: return Ragged(self.data[0:0].reshape(self.data_shape), lengths) start = starts[index][0] if index.start >= 1 else 0 end = ends[index][-1] return Ragged(self.data[start:end].reshape(self.data_shape), lengths) else: # There must be a way to do this "properly" :(. Sigh, hate numpy. xp = get_array_module(self.data) data = xp.vstack([self[int(i)].data for i in index]) return Ragged(data.reshape(self.data_shape), self.lengths[index]) def _get_starts_ends(self) -> Ints1d: if self.starts_ends is None: xp = get_array_module(self.lengths) self.starts_ends = xp.empty(self.lengths.size + 1, dtype="i") self.starts_ends[0] = 0 self.lengths.cumsum(out=self.starts_ends[1:]) return self.starts_ends def _get_starts(self) -> Ints1d: return self._get_starts_ends()[:-1] def _get_ends(self) -> Ints1d: return self._get_starts_ends()[1:] _P = TypeVar("_P", bound=Sequence) @dataclass class Pairs(Generic[_P]): """Dataclass for pairs of sequences that allows indexing into the sequences while keeping them aligned. """ one: _P two: _P def __getitem__(self, index) -> "Pairs[_P]": return Pairs(self.one[index], self.two[index]) def __len__(self) -> int: return len(self.one) @dataclass class ArgsKwargs: """A tuple of (args, kwargs) that can be spread into some function f: f(*args, **kwargs) """ args: Tuple[Any, ...] kwargs: Dict[str, Any] @classmethod def from_items(cls, items: Sequence[Tuple[Union[int, str], Any]]) -> "ArgsKwargs": """Create an ArgsKwargs object from a sequence of (key, value) tuples, such as produced by argskwargs.items(). Each key should be either a string or an integer. Items with int keys are added to the args list, and items with string keys are added to the kwargs list. The args list is determined by sequence order, not the value of the integer. """ args = [] kwargs = {} for key, value in items: if isinstance(key, int): args.append(value) else: kwargs[key] = value return cls(args=tuple(args), kwargs=kwargs) def keys(self) -> Iterable[Union[int, str]]: """Yield indices from self.args, followed by keys from self.kwargs.""" yield from range(len(self.args)) yield from self.kwargs.keys() def values(self) -> Iterable[Any]: """Yield elements of from self.args, followed by values from self.kwargs.""" yield from self.args yield from self.kwargs.values() def items(self) -> Iterable[Tuple[Union[int, str], Any]]: """Yield enumerate(self.args), followed by self.kwargs.items()""" yield from enumerate(self.args) yield from self.kwargs.items() @dataclass class Unserializable: """Wrap a value to prevent it from being serialized by msgpack.""" obj: Any def validate_array(obj, ndim=None, dtype=None): """Runtime validator for pydantic to validate array types.""" xp = get_array_module(obj) if not isinstance(obj, xp.ndarray): raise TypeError("not a valid numpy or cupy array") errors = [] if ndim is not None and obj.ndim != ndim: errors.append(f"wrong array dimensions (expected {ndim}, got {obj.ndim})") if dtype is not None: dtype_mapping = {"f": ["float32"], "i": ["int32", "int64", "uint32", "uint64"]} expected_types = dtype_mapping.get(dtype, []) if obj.dtype not in expected_types: expected = "/".join(expected_types) err = f"wrong array data type (expected {expected}, got {obj.dtype})" errors.append(err) if errors: raise ValueError(", ".join(errors)) return obj thinc-9.0.0/thinc/util.py000066400000000000000000000511621461023342500152660ustar00rootroot00000000000000import contextlib import functools import inspect import os import platform import random import tempfile import threading from contextvars import ContextVar from dataclasses import dataclass from typing import ( TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Sequence, Tuple, TypeVar, Union, cast, ) import numpy from packaging.version import Version try: from pydantic.v1 import ValidationError, create_model except ImportError: from pydantic import ValidationError, create_model # type: ignore import numpy from wasabi import table from . import types # noqa: E402 from .compat import ( cupy, cupy_from_dlpack, has_cupy, has_cupy_gpu, has_gpu, has_mxnet, has_tensorflow, has_torch, has_torch_cuda_gpu, has_torch_mps, ) from .compat import mxnet as mx from .compat import tensorflow as tf from .compat import torch from .types import ArgsKwargs, ArrayXd, FloatsXd, IntsXd, Padded, Ragged # noqa: E402 if TYPE_CHECKING: from .api import Ops DATA_VALIDATION: ContextVar[bool] = ContextVar("DATA_VALIDATION", default=False) def get_torch_default_device() -> "torch.device": if torch is None: raise ValueError("Cannot get default Torch device when Torch is not available.") from .backends import get_current_ops from .backends.cupy_ops import CupyOps from .backends.mps_ops import MPSOps ops = get_current_ops() if isinstance(ops, CupyOps): device_id = torch.cuda.current_device() return torch.device(f"cuda:{device_id}") elif isinstance(ops, MPSOps): return torch.device("mps") return torch.device("cpu") def get_array_module(arr): # pragma: no cover if is_numpy_array(arr): return numpy elif is_cupy_array(arr): return cupy else: raise ValueError( "Only numpy and cupy arrays are supported" f", but found {type(arr)} instead. If " "get_array_module module wasn't called " "directly, this might indicate a bug in Thinc." ) def gpu_is_available(): return has_gpu def fix_random_seed(seed: int = 0) -> None: # pragma: no cover """Set the random seed across random, numpy.random and cupy.random.""" random.seed(seed) numpy.random.seed(seed) if has_torch: torch.manual_seed(seed) if has_cupy_gpu: cupy.random.seed(seed) if has_torch and has_torch_cuda_gpu: torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False def is_xp_array(obj: Any) -> bool: """Check whether an object is a numpy or cupy array.""" return is_numpy_array(obj) or is_cupy_array(obj) def is_cupy_array(obj: Any) -> bool: # pragma: no cover """Check whether an object is a cupy array.""" if not has_cupy: return False elif isinstance(obj, cupy.ndarray): return True else: return False def is_numpy_array(obj: Any) -> bool: """Check whether an object is a numpy array.""" if isinstance(obj, numpy.ndarray): return True else: return False def is_torch_array(obj: Any) -> bool: # pragma: no cover if torch is None: return False elif isinstance(obj, torch.Tensor): return True else: return False def is_torch_cuda_array(obj: Any) -> bool: # pragma: no cover return is_torch_array(obj) and obj.is_cuda def is_torch_gpu_array(obj: Any) -> bool: # pragma: no cover return is_torch_cuda_array(obj) or is_torch_mps_array(obj) def is_torch_mps_array(obj: Any) -> bool: # pragma: no cover return is_torch_array(obj) and hasattr(obj, "is_mps") and obj.is_mps def is_tensorflow_array(obj: Any) -> bool: # pragma: no cover if not has_tensorflow: return False elif isinstance(obj, tf.Tensor): # type: ignore return True else: return False def is_tensorflow_gpu_array(obj: Any) -> bool: # pragma: no cover return is_tensorflow_array(obj) and "GPU:" in obj.device def is_mxnet_array(obj: Any) -> bool: # pragma: no cover if not has_mxnet: return False elif isinstance(obj, mx.nd.NDArray): # type: ignore return True else: return False def is_mxnet_gpu_array(obj: Any) -> bool: # pragma: no cover return is_mxnet_array(obj) and obj.context.device_type != "cpu" def to_numpy(data): # pragma: no cover if isinstance(data, numpy.ndarray): return data elif has_cupy and isinstance(data, cupy.ndarray): return data.get() else: return numpy.array(data) def set_active_gpu(gpu_id: int) -> "cupy.cuda.Device": # pragma: no cover """Set the current GPU device for cupy and torch (if available).""" if not has_cupy_gpu: raise ValueError("No CUDA GPU devices detected") device = cupy.cuda.device.Device(gpu_id) device.use() if has_torch_cuda_gpu: torch.cuda.set_device(gpu_id) return device def require_cpu() -> bool: # pragma: no cover """Use CPU through best available backend.""" from .backends import get_ops, set_current_ops ops = get_ops("cpu") set_current_ops(ops) return True def prefer_gpu(gpu_id: int = 0) -> bool: # pragma: no cover """Use GPU if it's available. Returns True if so, False otherwise.""" if has_gpu: require_gpu(gpu_id=gpu_id) return has_gpu def require_gpu(gpu_id: int = 0) -> bool: # pragma: no cover from .backends import CupyOps, MPSOps, set_current_ops if platform.system() == "Darwin" and not has_torch_mps: if has_torch: raise ValueError("Cannot use GPU, installed PyTorch does not support MPS") raise ValueError("Cannot use GPU, PyTorch is not installed") elif platform.system() != "Darwin" and not has_cupy: raise ValueError("Cannot use GPU, CuPy is not installed") elif not has_gpu: raise ValueError("No GPU devices detected") if has_cupy_gpu: set_current_ops(CupyOps()) set_active_gpu(gpu_id) else: set_current_ops(MPSOps()) return True def copy_array(dst: ArrayXd, src: ArrayXd) -> None: # pragma: no cover if isinstance(dst, numpy.ndarray) and isinstance(src, numpy.ndarray): dst[:] = src elif is_cupy_array(dst): src = cupy.array(src, copy=False) cupy.copyto(dst, src) else: numpy.copyto(dst, src) # type: ignore def to_categorical( Y: IntsXd, n_classes: Optional[int] = None, *, label_smoothing: float = 0.0, ) -> FloatsXd: if n_classes is None: n_classes = int(numpy.max(Y) + 1) # type: ignore if label_smoothing < 0.0: raise ValueError( "Label-smoothing parameter has to be greater than or equal to 0" ) if label_smoothing == 0.0: if n_classes == 0: raise ValueError("n_classes should be at least 1") nongold_prob = 0.0 else: if not n_classes > 1: raise ValueError( "n_classes should be greater than 1 when label smoothing is enabled," f"but {n_classes} was provided." ) nongold_prob = label_smoothing / (n_classes - 1) max_smooth = (n_classes - 1) / n_classes if n_classes > 1 and label_smoothing >= max_smooth: raise ValueError( f"For {n_classes} classes " "label_smoothing parameter has to be less than " f"{max_smooth}, but found {label_smoothing}." ) xp = get_array_module(Y) label_distr = xp.full((n_classes, n_classes), nongold_prob, dtype="float32") xp.fill_diagonal(label_distr, 1 - label_smoothing) return label_distr[Y] def get_width( X: Union[ArrayXd, Ragged, Padded, Sequence[ArrayXd]], *, dim: int = -1 ) -> int: """Infer the 'width' of a batch of data, which could be any of: Array, Ragged, Padded or Sequence of Arrays. """ if isinstance(X, Ragged): return get_width(X.data, dim=dim) elif isinstance(X, Padded): return get_width(X.data, dim=dim) elif hasattr(X, "shape") and hasattr(X, "ndim"): X = cast(ArrayXd, X) if len(X.shape) == 0: return 0 elif len(X.shape) == 1: return int(X.max()) + 1 else: return X.shape[dim] elif isinstance(X, (list, tuple)): if len(X) == 0: return 0 else: return get_width(X[0], dim=dim) else: err = "Cannot get width of object: has neither shape nor __getitem__" raise ValueError(err) def assert_tensorflow_installed() -> None: # pragma: no cover """Raise an ImportError if TensorFlow is not installed.""" template = "TensorFlow support requires {pkg}: pip install thinc[tensorflow]\n\nEnable TensorFlow support with thinc.api.enable_tensorflow()" if not has_tensorflow: raise ImportError(template.format(pkg="tensorflow>=2.0.0,<2.6.0")) def assert_mxnet_installed() -> None: # pragma: no cover """Raise an ImportError if MXNet is not installed.""" if not has_mxnet: raise ImportError( "MXNet support requires mxnet: pip install thinc[mxnet]\n\nEnable MXNet support with thinc.api.enable_mxnet()" ) def assert_pytorch_installed() -> None: # pragma: no cover """Raise an ImportError if PyTorch is not installed.""" if not has_torch: raise ImportError("PyTorch support requires torch: pip install thinc[torch]") def convert_recursive( is_match: Callable[[Any], bool], convert_item: Callable[[Any], Any], obj: Any ) -> Any: """Either convert a single value if it matches a given function, or recursively walk over potentially nested lists, tuples and dicts applying the conversion, and returns the same type. Also supports the ArgsKwargs dataclass. """ if is_match(obj): return convert_item(obj) elif isinstance(obj, ArgsKwargs): converted = convert_recursive(is_match, convert_item, list(obj.items())) return ArgsKwargs.from_items(converted) elif isinstance(obj, dict): converted = {} for key, value in obj.items(): key = convert_recursive(is_match, convert_item, key) value = convert_recursive(is_match, convert_item, value) converted[key] = value return converted elif isinstance(obj, list): return [convert_recursive(is_match, convert_item, item) for item in obj] elif isinstance(obj, tuple): return tuple(convert_recursive(is_match, convert_item, item) for item in obj) else: return obj def iterate_recursive(is_match: Callable[[Any], bool], obj: Any) -> Any: """Either yield a single value if it matches a given function, or recursively walk over potentially nested lists, tuples and dicts yielding matching values. Also supports the ArgsKwargs dataclass. """ if is_match(obj): yield obj elif isinstance(obj, ArgsKwargs): yield from iterate_recursive(is_match, list(obj.items())) elif isinstance(obj, dict): for key, value in obj.items(): yield from iterate_recursive(is_match, key) yield from iterate_recursive(is_match, value) elif isinstance(obj, list) or isinstance(obj, tuple): for item in obj: yield from iterate_recursive(is_match, item) def xp2torch( xp_tensor: ArrayXd, requires_grad: bool = False, device: Optional["torch.device"] = None, ) -> "torch.Tensor": # pragma: no cover """Convert a numpy or cupy tensor to a PyTorch tensor.""" assert_pytorch_installed() if device is None: device = get_torch_default_device() if hasattr(xp_tensor, "toDlpack"): dlpack_tensor = xp_tensor.toDlpack() # type: ignore torch_tensor = torch.utils.dlpack.from_dlpack(dlpack_tensor) elif hasattr(xp_tensor, "__dlpack__"): torch_tensor = torch.utils.dlpack.from_dlpack(xp_tensor) else: torch_tensor = torch.from_numpy(xp_tensor) torch_tensor = torch_tensor.to(device) if requires_grad: torch_tensor.requires_grad_() return torch_tensor def torch2xp( torch_tensor: "torch.Tensor", *, ops: Optional["Ops"] = None ) -> ArrayXd: # pragma: no cover """Convert a torch tensor to a numpy or cupy tensor depending on the `ops` parameter. If `ops` is `None`, the type of the resultant tensor will be determined by the source tensor's device. """ from .api import NumpyOps assert_pytorch_installed() if is_torch_cuda_array(torch_tensor): if isinstance(ops, NumpyOps): return torch_tensor.detach().cpu().numpy() else: return cupy_from_dlpack(torch.utils.dlpack.to_dlpack(torch_tensor)) else: if isinstance(ops, NumpyOps) or ops is None: return torch_tensor.detach().cpu().numpy() else: return cupy.asarray(torch_tensor) def xp2tensorflow( xp_tensor: ArrayXd, requires_grad: bool = False, as_variable: bool = False ) -> "tf.Tensor": # type: ignore # pragma: no cover """Convert a numpy or cupy tensor to a TensorFlow Tensor or Variable""" assert_tensorflow_installed() if hasattr(xp_tensor, "toDlpack"): dlpack_tensor = xp_tensor.toDlpack() # type: ignore tf_tensor = tf.experimental.dlpack.from_dlpack(dlpack_tensor) # type: ignore elif hasattr(xp_tensor, "__dlpack__"): dlpack_tensor = xp_tensor.__dlpack__() # type: ignore tf_tensor = tf.experimental.dlpack.from_dlpack(dlpack_tensor) # type: ignore else: tf_tensor = tf.convert_to_tensor(xp_tensor) # type: ignore if as_variable: # tf.Variable() automatically puts in GPU if available. # So we need to control it using the context manager with tf.device(tf_tensor.device): # type: ignore tf_tensor = tf.Variable(tf_tensor, trainable=requires_grad) # type: ignore if requires_grad is False and as_variable is False: # tf.stop_gradient() automatically puts in GPU if available. # So we need to control it using the context manager with tf.device(tf_tensor.device): # type: ignore tf_tensor = tf.stop_gradient(tf_tensor) # type: ignore return tf_tensor def tensorflow2xp( tf_tensor: "tf.Tensor", *, ops: Optional["Ops"] = None # type: ignore ) -> ArrayXd: # pragma: no cover """Convert a Tensorflow tensor to numpy or cupy tensor depending on the `ops` parameter. If `ops` is `None`, the type of the resultant tensor will be determined by the source tensor's device. """ from .api import NumpyOps assert_tensorflow_installed() if is_tensorflow_gpu_array(tf_tensor): if isinstance(ops, NumpyOps): return tf_tensor.numpy() else: dlpack_tensor = tf.experimental.dlpack.to_dlpack(tf_tensor) # type: ignore return cupy_from_dlpack(dlpack_tensor) else: if isinstance(ops, NumpyOps) or ops is None: return tf_tensor.numpy() else: return cupy.asarray(tf_tensor.numpy()) def xp2mxnet( xp_tensor: ArrayXd, requires_grad: bool = False ) -> "mx.nd.NDArray": # type: ignore # pragma: no cover """Convert a numpy or cupy tensor to a MXNet tensor.""" assert_mxnet_installed() if hasattr(xp_tensor, "toDlpack"): dlpack_tensor = xp_tensor.toDlpack() # type: ignore mx_tensor = mx.nd.from_dlpack(dlpack_tensor) # type: ignore else: mx_tensor = mx.nd.from_numpy(xp_tensor) # type: ignore if requires_grad: mx_tensor.attach_grad() return mx_tensor def mxnet2xp( mx_tensor: "mx.nd.NDArray", *, ops: Optional["Ops"] = None # type: ignore ) -> ArrayXd: # pragma: no cover """Convert a MXNet tensor to a numpy or cupy tensor.""" from .api import NumpyOps assert_mxnet_installed() if is_mxnet_gpu_array(mx_tensor): if isinstance(ops, NumpyOps): return mx_tensor.detach().asnumpy() else: return cupy_from_dlpack(mx_tensor.to_dlpack_for_write()) else: if isinstance(ops, NumpyOps) or ops is None: return mx_tensor.detach().asnumpy() else: return cupy.asarray(mx_tensor.asnumpy()) # This is how functools.partials seems to do it, too, to retain the return type PartialT = TypeVar("PartialT") def partial( func: Callable[..., PartialT], *args: Any, **kwargs: Any ) -> Callable[..., PartialT]: """Wrapper around functools.partial that retains docstrings and can include other workarounds if needed. """ partial_func = functools.partial(func, *args, **kwargs) partial_func.__doc__ = func.__doc__ return partial_func class DataValidationError(ValueError): def __init__( self, name: str, X: Any, Y: Any, errors: Union[Sequence[Mapping[str, Any]], List[Dict[str, Any]]] = [], ) -> None: """Custom error for validating inputs / outputs at runtime.""" message = f"Data validation error in '{name}'" type_info = f"X: {type(X)} Y: {type(Y)}" data = [] for error in errors: err_loc = " -> ".join([str(p) for p in error.get("loc", [])]) data.append((err_loc, error.get("msg"))) result = [message, type_info, table(data)] ValueError.__init__(self, "\n\n" + "\n".join(result)) class _ArgModelConfig: extra = "forbid" arbitrary_types_allowed = True def validate_fwd_input_output( name: str, func: Callable[[Any, Any, bool], Any], X: Any, Y: Any ) -> None: """Validate the input and output of a forward function against the type annotations, if available. Used in Model.initialize with the input and output samples as they pass through the network. """ sig = inspect.signature(func) empty = inspect.Signature.empty params = list(sig.parameters.values()) if len(params) != 3: bad_params = f"{len(params)} ({', '.join([p.name for p in params])})" err = f"Invalid forward function. Expected 3 arguments (model, X , is_train), got {bad_params}" raise DataValidationError(name, X, Y, [{"msg": err}]) annot_x = params[1].annotation annot_y = sig.return_annotation sig_args: Dict[str, Any] = {"__config__": _ArgModelConfig} args = {} if X is not None and annot_x != empty: if isinstance(X, list) and len(X) > 5: X = X[:5] sig_args["X"] = (annot_x, ...) args["X"] = X if Y is not None and annot_y != empty: if isinstance(Y, list) and len(Y) > 5: Y = Y[:5] sig_args["Y"] = (annot_y, ...) args["Y"] = (Y, lambda x: x) ArgModel = create_model("ArgModel", **sig_args) # Make sure the forward refs are resolved and the types used by them are # available in the correct scope. See #494 for details. ArgModel.update_forward_refs(**types.__dict__) try: ArgModel.parse_obj(args) except ValidationError as e: raise DataValidationError(name, X, Y, e.errors()) from None @contextlib.contextmanager def make_tempfile(mode="r"): f = tempfile.NamedTemporaryFile(mode=mode, delete=False) yield f f.close() os.remove(f.name) @contextlib.contextmanager def data_validation(validation): with threading.Lock(): prev = DATA_VALIDATION.get() DATA_VALIDATION.set(validation) yield DATA_VALIDATION.set(prev) @contextlib.contextmanager def use_nvtx_range(message: str, id_color: int = -1): """Context manager to register the executed code as an NVTX range. The ranges can be used as markers in CUDA profiling.""" if has_cupy: cupy.cuda.nvtx.RangePush(message, id_color) yield cupy.cuda.nvtx.RangePop() else: yield @dataclass class ArrayInfo: """Container for info for checking array compatibility.""" shape: types.Shape dtype: types.DTypes @classmethod def from_array(cls, arr: ArrayXd): return cls(shape=arr.shape, dtype=arr.dtype) def check_consistency(self, arr: ArrayXd): if arr.shape != self.shape: raise ValueError( f"Shape mismatch in backprop. Y: {self.shape}, dY: {arr.shape}" ) if arr.dtype != self.dtype: raise ValueError( f"Type mismatch in backprop. Y: {self.dtype}, dY: {arr.dtype}" ) # fmt: off __all__ = [ "get_array_module", "get_torch_default_device", "fix_random_seed", "is_cupy_array", "is_numpy_array", "set_active_gpu", "prefer_gpu", "require_gpu", "copy_array", "to_categorical", "get_width", "xp2torch", "torch2xp", "tensorflow2xp", "xp2tensorflow", "validate_fwd_input_output", "DataValidationError", "make_tempfile", "use_nvtx_range", "ArrayInfo", "has_cupy", "has_torch", ] # fmt: on thinc-9.0.0/website/000077500000000000000000000000001461023342500142675ustar00rootroot00000000000000thinc-9.0.0/website/.dockerignore000066400000000000000000000001731461023342500167440ustar00rootroot00000000000000# Avoid uploading large Docker contexts .cache/ public/ node_modules .npm logs *.log npm-debug.log* www/ _deploy.sh *.html thinc-9.0.0/website/.eslintrc000066400000000000000000000017561461023342500161240ustar00rootroot00000000000000{ "extends": ["standard", "prettier"], "plugins": ["standard", "react", "react-hooks"], "rules": { "no-var": "error", "no-unused-vars": 1, "arrow-spacing": ["error", { "before": true, "after": true }], "indent": ["error", 4], "semi": ["error", "never"], "arrow-parens": ["error", "as-needed"], "standard/object-curly-even-spacing": ["error", "either"], "standard/array-bracket-even-spacing": ["error", "either"], "standard/computed-property-even-spacing": ["error", "even"], "standard/no-callback-literal": ["error", ["cb", "callback"]], "react/jsx-uses-react": "error", "react/jsx-uses-vars": "error", "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", "import/no-duplicates": "off", "new-cap": "off" }, "parser": "babel-eslint", "parserOptions": { "ecmaVersion": 8 }, "env": { "browser": true } } thinc-9.0.0/website/.gitignore000066400000000000000000000001301461023342500162510ustar00rootroot00000000000000.vscode/ .cache/ public/ node_modules/ .npm logs *.log npm-debug.log* .idea/ src/fonts/ thinc-9.0.0/website/.nvmrc000066400000000000000000000000021461023342500154050ustar00rootroot0000000000000016thinc-9.0.0/website/.prettierrc000066400000000000000000000010361461023342500164530ustar00rootroot00000000000000{ "semi": false, "singleQuote": true, "trailingComma": "es5", "tabWidth": 4, "bracketSpacing": true, "printWidth": 100, "overrides": [ { "files": "*.sass", "options": { "printWidth": 999 } }, { "files": "*.md", "options": { "tabWidth": 2, "printWidth": 80, "proseWrap": "always", "htmlWhitespaceSensitivity": "strict" } } ] } thinc-9.0.0/website/Dockerfile000066400000000000000000000006511461023342500162630ustar00rootroot00000000000000FROM node:16 USER node # This is so the installed node_modules will be up one directory # from where a user mounts files, so that they don't accidentally mount # their own node_modules from a different build # https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders WORKDIR /home/node COPY --chown=node package.json . COPY --chown=node package-lock.json . RUN npm install WORKDIR /home/node/website/ thinc-9.0.0/website/README.md000066400000000000000000000136431461023342500155550ustar00rootroot00000000000000[![Netlify Status](https://api.netlify.com/api/v1/badges/d249ffd8-1790-4053-b6e8-5967ac68e4e1/deploy-status)](https://app.netlify.com/sites/cocky-hodgkin-996e5b/deploys) ## Setup and installation The site is powered by [Gatsby](https://www.gatsbyjs.org/) and [Markdown Remark](https://github.com/remarkjs/remark). To run the site, Node 16 is required. If you use NVM you can `nvm use` to select the correct Node version. ```bash npm install # install dependencies npm run dev # start dev server ``` A `.prettierrc` is included in the repo, so if you set up auto-formatting with Prettier, it should match the style. ## Build and run the website in a Docker container Rather than installing NPM locally, you can also build a Docker container with the prerequisite dependencies: ```bash docker build -t thinc-ai . ``` Afterwards, the website can be built and run in the container: ```bash docker run --rm -it \ -v $PWD:/home/node/website \ -p 8000:8000 \ thinc-ai \ npm run dev -- -H 0.0.0.0 ``` This is currently the only way to build the website on ARM64 Macs, since the required Node.js version is not built for macOS/ARM64. These commands also work with Podman by replacing `docker` by `podman`. ## Directory structure - `/docs`: Docs pages as Markdown. - `/src/pages`: JavaScript-formatted landing pages relative to the root. ## Markdown reference The docs use various customized Markdown components for better visual documentation. Here are the most relevant: ### Special syntax #### Headings Headings can specify optional attributes in curly braces, e.g. `#some_id` to add a permalink and `id="some_id"` or a `tag` attribute with a string of one or more comma-separated tags to be added after the headline text. ```markdown ## Headline 2 ## Headline 2 {#some_id} ## Headline 2 {#some_id tag="method"} ``` #### Code Code blocks can specify an optional title on the first line, prefixed by `###`. The title also supports specifying attributes, including `small="true"` (small font) and `highlight`, mapped to valid line numbers or line number ranges. ````markdown ```python ### This is a title {highlight="1,3-4"} from thinc.api import Model, chain, Relu, Softmax with Model.define_operators({">>": chain}): model = Relu(512) >> Relu(512) >> Softmax() ``` ```` #### Tables If a table row defines an italicized label in its first column and is otherwise empty, it will be rendered as divider with the given label. This is currently used for the "keyword-only" divider that separates positional and regular keyword arguments from keyword-only arguments. If the last row contains a bold `RETURNS` or `YIELDS`, the row is rendered as the footer row with an additional divider. ```markdown | Argument | Type | Description | | -------------- | ---------------- | ------------------------------------------------------ | | `X` | ArrayXd | The array. | | _keyword-only_ | | | | `dim` | int | Which dimension to get the size for. Defaults to `-1`. | | **RETURNS** | int | The array's inferred width. | ``` If you're specifying tables in Markdown, you always need a head row โ€“ otherwise, the markup is invalid. However, if all head cells are empty, the header row will not be rendered. ```markdown | | | | | -------- | -------- | -------- | | Column 1 | Column 2 | Column 3 | ``` ### Custom markdown elements #### `` Infobox Infobox with an optional variant attribute: `variant="warning"` or `variant="danger"`. ```markdown This is a warning. ``` #### `` Type annotation Should be used for Python type annotations like `bool`, `Optional[int]` or `Model[ArrayXd, ArrayXd]`. Similar to regular inline code but will highlight the elements and link the types if available. See [`type-links.js`](src/type-links.js) for the type to link mapping. ```markdown Tuple[str, int] ``` #### `` Arrays Special type annotation for arrays with option to specify shape. Will link types if available. See [`_type_links.json`](docs/_type_links.json) for the type to link mapping. ```markdown Array2d ``` #### `` `` Tabbed components Will make each tab title a selectable button and allow tabbing between content. Mostly used for longer code examples to show a variety of different examples without making the page too verbose. The `id` is needed to distinguish multiple tabbed components on the same page. ```markdown Tab content 1 goes here Tab content 2 goes here ``` #### `` Simple two-column grid Responsive grid for displaying child elements in two columns. Mostly used to display code examples side-by-side. ````markdown ```ini ### config.cfg {small="true"} [training] patience = 10 dropout = 0.2 ``` ```json ### Parsed {small="true"} { "training": { "patience": 10, "dropout": 0.2 } } ``` ```` #### `` Inline list of meta info Should contain an unnumbered list with items optionally prefixed with a bold label. Mostly used in the layers API reference to document input/output types, parameters and attributes in a concise way. ```markdown - **Label 1:** Some content - **Label 2:** Some content ``` #### `` Tutorial links with Colab buttons Should contain an unnumbered list with IDs of the tutorials to include. See [`_tutorials.json`](docs/_tutorials.json) for options. The tutorials section will show each tutorial name and description with a button to launch the notebook on Colab, if available. ```markdown - intro - transformers_tagger - parallel_training_ray ``` thinc-9.0.0/website/docs/000077500000000000000000000000001461023342500152175ustar00rootroot00000000000000thinc-9.0.0/website/docs/_quickstart.json000066400000000000000000000022371461023342500204470ustar00rootroot00000000000000{ "defaults": { "cuda": "-" }, "options": [ { "label": "CUDA", "name": "cuda", "options": [ { "label": "none", "value": "-" }, { "label": "8.0", "value": "cuda80" }, { "label": "9.0", "value": "cuda90" }, { "label": "9.1", "value": "cuda91" }, { "label": "9.2", "value": "cuda92" }, { "label": "10.0", "value": "cuda100" }, { "label": "10.1", "value": "cuda101" }, { "label": "10.2", "value": "cuda102" }, { "label": "11.0", "value": "cuda110" }, { "label": "11.1", "value": "cuda111" }, { "label": "11.2-11.x", "value": "cuda11x" }, { "label": "12.x", "value": "cuda12x" } ] }, { "label": "Libraries", "name": "libraries", "multi": true, "options": [ { "label": "PyTorch", "value": "torch" }, { "label": "TensorFlow", "value": "tensorflow" }, { "label": "MXNet", "value": "mxnet" } ] } ] } thinc-9.0.0/website/docs/_tutorials.json000066400000000000000000000060341461023342500203020ustar00rootroot00000000000000{ "intro": { "title": "Intro to Thinc", "description": "Everything you need to know to get started. Composing and training a model on the MNIST data, using config files, registering custom functions and wrapping PyTorch, TensorFlow and MXNet models.", "url": "00_intro_to_thinc.ipynb" }, "intro_model": { "title": "Intro to Thinc's Model class", "description": "Defining and composing models, the model methods and working with dimensions, parameters and gradients.", "url": "01_intro_model_definition_methods.ipynb" }, "transformers_tagger": { "title": "Training a part-of-speech tagger with transformers (BERT)", "description": "How to use Thinc, Transformers and PyTorch to train a part-of-speech tagger. From model definition and config to the training loop.", "url": "02_transformers_tagger_bert.ipynb" }, "basic_cnn_tagger": { "title": "Basic CNN part-of-speech tagger", "description": "Implementing and training a basic CNN for part-of-speech tagging model without external dependencies and using different levels of Thinc's configuration system.", "url": "03_pos_tagger_basic_cnn.ipynb" }, "textcat_neural_bow": { "title": "Basic neural bag-of-words text classifier", "description": "Implementing and training a simple neural text classification model.", "url": "03_textcat_basic_neural_bow.ipynb" }, "gpu_memory": { "title": "Using a single memory pool for Cupy and PyTorch/TensorFlow", "description": "How to use Thinc with custom memory allocation to route cupy's memory requests via PyTorch or TensorFlow library.", "url": "04_configure_gpu_memory.ipynb" }, "parallel_training_ray": { "title": "Parallel training with Ray", "description": "How to set up synchronous and asynchronous parameter server training with Thinc and Ray.", "url": "04_parallel_training_ray.ipynb" }, "benchmarking_layers": { "title": "Writing a custom benchmark layer", "description": "How to write a benchmark layer to wrap any layer(s) in your network and log the execution times of the initialization, forward pass and backward pass.", "url": "05_benchmarking_layers.ipynb" }, "visualizing": { "title": "Visualizing Thinc models (with shape inference)", "description": "Visualizing Thinc models and their inputs and outputs using Graphviz and pydot.", "url": "05_visualizing_models.ipynb" }, "type_checking": { "title": "Type checking with Thinc and mypy", "description": "How to take advantage of Thinc's type system and spot potential bugs early.", "url": "type_checking.py", "standalone": true }, "mathy_like_terms": { "title": "Predicting like polynomial terms with Mathy", "description": "How to build a regression model that outputs the number of like terms in each math problem generated by Mathy.", "url": "06_predicting_like_terms.ipynb" } } thinc-9.0.0/website/docs/_type_links.json000066400000000000000000000023741461023342500204400ustar00rootroot00000000000000{ "__default__": "/docs/api-types#types", "Model": "/docs/api-model#model", "Shim": "/docs/api-model#shim", "Ops": "/docs/api-backends#ops", "NumpyOps": "/docs/api-backends#ops", "CupyOps": "/docs/api-backends#ops", "Config": "/docs/api-config#config", "Ragged": "/docs/api-types#ragged", "Padded": "/docs/api-types#padded", "Pairs": "/docs/api-types#pairs", "ArgsKwargs": "/docs/api-types#argskwargs", "SizedGenerator": "/docs/api-types#sizedgenerator", "Array1d": true, "Array2d": true, "Array3d": true, "Array4d": true, "ArrayXd": true, "Floats1d": true, "Floats2d": true, "Floats3d": true, "Floats4d": true, "FloatsXd": true, "Ints1d": true, "Ints2d": true, "Ints3d": true, "Ints4d": true, "IntsXd": true, "List1d": true, "List2d": true, "List3d": true, "List4d": true, "ListXd": true, "Generator": true, "Shape": true, "DTypes": true, "DTypesInt": true, "DTypesFloat": true, "Xp": true, "Batchable": true, "BaseModel": "https://pydantic-docs.helpmanual.io/usage/models/", "Doc": "https://spacy.io/api/doc", "Device": "https://docs-cupy.chainer.org/en/stable/reference/generated/cupy.cuda.Device.html" } thinc-9.0.0/website/docs/api-backends.md000066400000000000000000002130121461023342500200610ustar00rootroot00000000000000--- title: Backends & Math next: /docs/api-util --- All Thinc models have a reference to an `Ops` instance, that provides access to **memory allocation** and **mathematical routines**. The `Model.ops` instance also keeps track of state and settings, so that you can have different models in your network executing on different devices or delegating to different underlying libraries. Each `Ops` instance holds a reference to a numpy-like module (`numpy` or `cupy`), which you can access at `Model.ops.xp`. This is enough to make most layers work on **both CPU and GPU devices**. Additionally, there are several routines that we have implemented as methods on the `Ops` object, so that specialized versions can be called for different backends. You can also create your own `Ops` subclasses with specialized routines for your layers, and use the [`set_current_ops`](#set_current_ops) function to change the default. | Backend | CPU | GPU | TPU | Description | | ---------- | :----------------: | :----------------: | :---------------: | ----------------------------------------------------------------------------------------------------------- | | `AppleOps` | | | | Use AMX matrix multiplication units on Apple Silicon Macs. Added in Thinc 9.0. | | `CupyOps` | | | | Execute via [`cupy`](https://cupy.chainer.org/) and custom CUDA. | | `MPSOps` | | | | Use the GPU on Apple Silicon Macs for PyTorch models, use AMX matrix multiplication units for Thinc Models. | | `NumpyOps` | | | | Execute via `numpy`, [`blis`](https://github.com/explosion/cython-blis) (optional) and custom Cython. | ## Ops {#ops tag="class"} The `Ops` class is typically not used directly but via `NumpyOps`, `AppleOps`, `CupyOps` or `MPSOps`, which are subclasses of `Ops` and implement a **more efficient subset of the methods**. You also have access to the ops via the [`Model.ops`](/docs/api-model#attributes) attribute. The documented methods below list which backends provide optimized and more efficient versions (indicated by ), and which use the default implementation. Thinc also provides various [helper functions](#util) for getting and setting different backends. The current set of implemented methods is somewhat arbitrary and **subject to change**. Methods are moved to the `Ops` object if we want different implementations for different backends, e.g. cythonized CPU versions or custom CUDA kernels. ```python ### Example from thinc.api import Linear, get_ops, use_ops model = Linear(4, 2) X = model.ops.alloc2f(10, 2) blis_ops = get_ops("numpy", use_blis=True) use_ops(blis_ops) ``` ### Attributes {#attributes} | Name | Type | Description | | ------------- | ------------ | ---------------------------------------------------------------------------------------- | | `name` | str | **Class attribute:** Backend name, `"numpy"`, `"apple"`, `"cupy"` or `"mps"`. | | `xp` | Xp | **Class attribute:** `numpy` or `cupy`. | | `device_type` | str | The device type to use, if available for the given backend: `"cpu"`, `"gpu"` or `"tpu"`. | | `device_id` | int | The device ID to use, if available for the given backend. | ### Ops.\_\_init\_\_ {#init tag="method"} | Argument | Type | Description | | -------------- | ------------- | ------------------------------------------------------------------------------------------------------------- | | `device_type` | str | The device type to use, if available for the given backend: `"cpu"`, `"gpu"` or `"tpu"`. | | `device_id` | int | The device ID to use, if available for the given backend. | | _keyword-only_ | | | | `use_blis` | bool | `NumpyOps`: Use [`blis`](https://github.com/explosion/cython-blis) for single-threaded matrix multiplication. | ### Ops.minibatch {#minibatch tag="method"} - **default:** - **numpy:** default - **cupy:** default Iterate slices from a sequence, optionally shuffled. Slices may be either views or copies of the underlying data. Supports the batchable data types [`Pairs`](/docs/api-types#pairs), [`Ragged`](/docs/api-types#ragged) and [`Padded`](/docs/api-types#padded), as well as arrays, lists and tuples. The `size` argument may be either an integer, or a sequence of integers. If a sequence, a new size is drawn before every output. If `shuffle` is `True`, shuffled batches are produced by first generating an index array, shuffling it, and then using it to slice into the sequence. An internal queue of `buffer` items is accumulated before being each output. Buffering is useful for some devices, to allow the network to run asynchronously without blocking on every batch. The method returns a [`SizedGenerator`](/docs/api-types#sizedgenerator) that exposes a `__len__` and is rebatched and reshuffled every time it's executed, allowing you to move the batching outside of the training loop. ```python ### Example batches = model.ops.minibatch(128, train_X, shuffle=True) ``` | Argument | Type | Description | | -------------- | ------------------------------ | ------------------------------------------------------------------ | | `size` | Union[int, Generator] | The batch size(s). | | `sequence` | Batchable | The sequence to batch. | | _keyword-only_ | | | | `shuffle` | bool | Whether to shuffle the items. | | `buffer` | int | Number of items to accumulate before each output. Defaults to `1`. | | **RETURNS** | SizedGenerator | The batched items. | ### Ops.multibatch {#multibatch tag="method"} - **default:** - **numpy:** default - **cupy:** default Minibatch one or more sequences of data, and return lists with one batch per sequence. Otherwise identical to [`Ops.minibatch`](#minibatch). ```python ### Example batches = model.ops.multibatch(128, train_X, train_Y, shuffle=True) ``` | Argument | Type | Description | | -------------- | ------------------------------ | ------------------------------------------------------------------ | | `size` | Union[int, Generator] | The batch size(s). | | `sequence` | Batchable | The sequence to batch. | | `*other` | Batchable | The other sequences to batch. | | _keyword-only_ | | | | `shuffle` | bool | Whether to shuffle the items. | | `buffer` | int | Number of items to accumulate before each output. Defaults to `1`. | | **RETURNS** | SizedGenerator | The batched items. | ### Ops.seq2col {#seq2col tag="method"} - **default:** (`nW=1` only) - **numpy:** - **cupy:** Given an `(M, N)` sequence of vectors, return an `(M, N*(nW*2+1))` sequence. The new sequence is constructed by concatenating `nW` preceding and succeeding vectors onto each column in the sequence, to extract a window of features. | Argument | Type | Description | | -------------- | ------------------------- | ----------------------------------------------------------------- | | `seq` | Floats2d | The original sequence. | | `nW` | int | The window size. | | _keyword-only_ | | | | `lengths` | Optional[Ints1d] | Sequence lengths, introduces padding around sequences. | | **RETURNS** | Floats2d | The created sequence containing preceding and succeeding vectors. | ### Ops.backprop_seq2col {#backprop_seq2col tag="method"} - **default:** (`nW=1` only) - **numpy:** - **cupy:** The reverse/backward operation of the `seq2col` function: calculate the gradient of the original `(M, N)` sequence, as a function of the gradient of the output `(M, N*(nW*2+1))` sequence. | Argument | Type | Description | | -------------- | ------------------------- | ------------------------------------------------------ | | `dY` | Floats2d | Gradient of the output sequence. | | `nW` | int | The window size. | | _keyword-only_ | | | | `lengths` | Optional[Ints1d] | Sequence lengths, introduces padding around sequences. | | **RETURNS** | Floats2d | Gradient of the original sequence. | ### Ops.gemm {#gemm tag="method"} - **default:** - **numpy:** - **cupy:** Perform General Matrix Multiplication (GeMM) and optionally store the result in the specified output variable. | Argument | Type | Description | | ----------- | --------------------------- | ------------------------------------------------------------- | | `x` | Floats2d | First array. | | `y` | Floats2d | Second array. | | `out` | Optional[Floats2d] | Variable to store the result of the matrix multiplication in. | | `trans1` | bool | Whether or not to transpose array `x`. | | `trans2` | bool | Whether or not to transpose array `y`. | | **RETURNS** | Floats2d | The result of the matrix multiplication. | ### Ops.affine {#affine tag="method"} - **default:** - **numpy:** default - **cupy:** default Apply a weights layer and a bias to some inputs, i.e. `Y = X @ W.T + b`. | Argument | Type | Description | | ----------- | ----------------- | ---------------- | | `X` | Floats2d | The inputs. | | `W` | Floats2d | The weights. | | `b` | Floats1d | The bias vector. | | **RETURNS** | Floats2d | The output. | ### Ops.flatten {#flatten tag="method"} - **default:** - **numpy:** default - **cupy:** default Flatten a list of arrays into one large array. | Argument | Type | Description | | --------------- | -------------------------- | ------------------------------------------------------------- | | `X` | Sequence[ArrayXd] | The original list of arrays. | | `dtype` | Optional[DTypes] | The data type to cast the resulting array in. | | `pad` | int | The number of zeros to add as padding to `X` (default 0). | | `ndim_if_empty` | int | The dimension of the output result if `X` is `None` or empty. | | **RETURNS** | ArrayXd | One large array storing all original information. | ### Ops.unflatten {#unflatten tag="method"} - **default:** - **numpy:** default - **cupy:** default The reverse/backward operation of the `flatten` function: unflatten a large array into a list of arrays according to the given lengths. | Argument | Type | Description | | ----------- | ---------------------- | --------------------------------------------------------------------- | | `X` | ArrayXd | The flattened array. | | `lengths` | Ints1d | The lengths of the original arrays before they were flattened. | | `pad` | int | The padding that was applied during the `flatten` step (default 0). | | **RETURNS** | List[ArrayXd] | A list of arrays storing the same information as the flattened array. | ### Ops.pad {#pad tag="method"} - **default:** - **numpy:** default - **cupy:** default Perform padding on a list of arrays so that they each have the same length, by taking the maximum dimension across each axis. This only works on non-empty sequences with the same `ndim` and `dtype`. | Argument | Type | Description | | ----------- | ---------------------- | ------------------------------------------------------------------------------------------------ | | `seqs` | List[Array2d] | The sequences to pad. | | `round_to` | int | Round the length to nearest bucket (helps on GPU, to make similar array sizes). Defaults to `1`. | | **RETURNS** | Array3d | The padded sequences, stored in one array. | ### Ops.unpad {#unpad tag="method"} - **default:** - **numpy:** default - **cupy:** default The reverse/backward operation of the `pad` function: transform an array back into a list of arrays, each with their original length. | Argument | Type | Description | | ----------- | ---------------------- | ----------------------------------------------- | | `padded` | ArrayXd | The padded sequences, stored in one array. | | `lengths` | List[int] | The original lengths of the unpadded sequences. | | **RETURNS** | List[ArrayXd] | The unpadded sequences. | ### Ops.list2padded {#list2padded tag="method"} - **default:** - **numpy:** default - **cupy:** default Pack a sequence of two-dimensional arrays into a [`Padded`](/docs/api-types#padded) datatype. | Argument | Type | Description | | ----------- | ---------------------- | ---------------------- | | `seqs` | List[Array2d] | The sequences to pack. | | **RETURNS** | Padded | The packed arrays. | ### Ops.padded2list {#padded2list tag="method"} - **default:** - **numpy:** default - **cupy:** default Unpack a [`Padded`](/docs/api-types#padded) datatype to a list of two-dimensional arrays. | Argument | Type | Description | | ----------- | ---------------------- | ----------------------- | | `padded` | Padded | The object to unpack. | | **RETURNS** | List[Array2d] | The unpacked sequences. | ### Ops.get_dropout_mask {#get_dropout_mask tag="method"} - **default:** - **numpy:** default - **cupy:** default Create a random mask for applying dropout, with a certain percent of the mask (defined by `drop`) will contain zeros. The neurons at those positions will be deactivated during training, resulting in a more robust network and less overfitting. | Argument | Type | Description | | ----------- | ------------------------ | ----------------------------------------------------------- | | `shape` | Shape | The input shape. | | `drop` | Optional[float] | The dropout rate. | | **RETURNS** | Floats | A mask specifying a 0 where a neuron should be deactivated. | ### Ops.alloc {#alloc tag="method"} - **default:** - **numpy:** - **cupy:** default Allocate an array of a certain shape. If possible, you should always use the **type-specific methods** listed below, as they make the code more readable and allow more sophisticated static [type checking](/docs/usage-type-checking) of the inputs and outputs. | Argument | Type | Description | | -------------- | ---------------- | -------------------------------------------- | | `shape` | Shape | The shape. | | _keyword-only_ | | | | `dtype` | DTypes | The data type (default: `float32`). | | `zeros` | bool | Fill the array with zeros (default: `True`). | | **RETURNS** | ArrayXd | An array of the correct shape and data type. | ### Ops.cblas {#cblas tag="method"} - **default:** - **numpy:** - **cupy:** Get a table of C BLAS functions usable in Cython `cdef nogil` functions. This method does not take any arguments. This method is only supported by `NumpyOps`. A `NotImplementedError` exception is raised when calling this method on `Ops` or `CupyOps`. ### Ops.to_numpy {#to_numpy tag="method"} - **default:** - **numpy:** default - **cupy:** Convert the array to a numpy array. | Argument | Type | Description | | -------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `data` | ArrayXd | The array. | | _keyword-only_ | | | | `byte_order` | Optional[str] | The [new byte order](https://numpy.org/doc/stable/reference/generated/numpy.dtype.newbyteorder.html), `None` preserves the current byte order (default: `None`). | | **RETURNS** | numpy.ndarray | A numpy array with the specified byte order. | #### Type-specific methods - **Floats:** `Ops.alloc_f`, `Ops.alloc1f`, `Ops.alloc2f`, `Ops.alloc3f`, `Ops.alloc4f` - **Ints:** `Ops.alloc_i`, `Ops.alloc1i`, `Ops.alloc2i`, `Ops.alloc3i`, `Ops.alloc4i` Shortcuts to allocate an array of a certain shape and data type (`f` refers to `float32` and `i` to `int32`). For instance, `Ops.alloc2f` will allocate an two-dimensional array of floats. ```python ### Example X = model.ops.alloc2f(10, 2) # Floats2d Y = model.ops.alloc1i(4) # Ints1d ``` | Argument | Type | Description | | -------------- | ----------------------------------------- | -------------------------------------------------------------------------- | | `*shape` | int | The shape, one positional argument per dimension. | | _keyword-only_ | | | | `dtype` | DTypesInt / DTypesFloat | The data type (float type for float methods and int type for int methods). | | `zeros` | bool | Fill the array with zeros (default: `True`). | | **RETURNS** | ArrayXd | An array of the correct shape and data type. | ### Ops.reshape {#reshape tag="method"} - **default:** - **numpy:** default - **cupy:** default Reshape an array and return an array containing the same data with the given shape. If possible, you should always use the **type-specific methods** listed below, as they make the code more readable and allow more sophisticated static [type checking](/docs/usage-type-checking) of the inputs and outputs. | Argument | Type | Description | | ----------- | ---------------- | --------------------- | | `array` | ArrayXd | The array to reshape. | | `shape` | Shape | The shape. | | **RETURNS** | ArrayXd | The reshaped array. | #### Type-specific methods - **Floats:** `Ops.reshape_f`, `Ops.reshape1f`, `Ops.reshape2f`, `Ops.reshape3f`, `Ops.reshape4f` - **Ints:** `Ops.reshape_i`, `Ops.reshape1i`, `Ops.reshape2i`, `Ops.reshape3i`, `Ops.reshape4i` Shortcuts to reshape an array of a certain shape and data type (`f` refers to `float32` and `i` to `int32`). For instance, `reshape2f` can be used to reshape an array of floats to a 2d-array of floats. Note that the data type-specific methods mostly exist for **static type checking purposes**. They do **not** change the data type of the array. For example, `Ops.reshape2f` expects an array of floats and expects to return an array of floats โ€“ but it won't convert an array of ints to an array of floats. However, using the specific method will tell the static type checker what array to expect, and passing in an array that's _typed_ as an int array will result in a type error. ```python ### Example {small="true"} X = model.ops.reshape2f(X, 10, 2) # Floats2d Y = model.ops.reshape1i(Y, 4) # Ints1d ``` | Argument | Type | Description | | ----------- | ---------------- | -------------------------------------------------------------- | | `array` | ArrayXd | The array to reshape (of the same data type). | | `*shape` | int | The shape, one positional argument per dimension. | | **RETURNS** | ArrayXd | The reshaped array (of the same data type as the input array). | ### Ops.asarray {#asarray tag="method"} - **default:** - **numpy:** - **cupy:** Ensure a given array is of the correct type, e.g. `numpy.ndarray` for `NumpyOps` or `cupy.ndarray` for `CupyOps`. If possible, you should always use the **type-specific methods** listed below, as they make the code more readable and allow more sophisticated static [type checking](/docs/usage-type-checking) of the inputs and outputs. | Argument | Type | Description | | -------------- | --------------------------------------------------------- | ------------------------------------------ | | `data` | Union[ArrayXd, Sequence[ArrayXd], Sequence[int]] | The original array. | | _keyword-only_ | | | | `dtype` | Optional[DTypes] | The data type | | **RETURNS** | ArrayXd | The array transformed to the correct type. | ### Type-specific methods - **Floats:** `Ops.asarray_f`, `Ops.asarray1f`, `Ops.asarray2f`, `Ops.asarray3f`, `Ops.asarray4f` - **Ints:** `Ops.asarray_i`, `Ops.asarray1i`, `Ops.asarray2i`, `Ops.asarray3i`, `Ops.asarray4i` Shortcuts for specific dimensions and data types (`f` refers to `float32` and `i` to `int32`). For instance, `Ops.asarray2f` will return a two-dimensional array of floats. ```python ### Example X = model.ops.asarray2f(X, 10, 2) # Floats2d Y = model.ops.asarray1i(Y, 4) # Ints1d ``` | Argument | Type | Description | | -------------- | ----------------------------------------- | -------------------------------------------------------------------------- | | `*shape` | int | The shape, one positional argument per dimension. | | _keyword-only_ | | | | `dtype` | DTypesInt / DTypesFloat | The data type (float type for float methods and int type for int methods). | | **RETURNS** | ArrayXd | An array of the correct shape and data type, filled with zeros. | ### Ops.as_contig {#as_contig tag="method"} - **default:** - **numpy:** default - **cupy:** default Allow the backend to make a contiguous copy of an array. Implementations of `Ops` do not have to make a copy or make it contiguous if that would not improve efficiency for the execution engine. | Argument | Type | Description | | -------------- | ------------------------- | --------------------------------------------- | | `data` | ArrayXd | The array. | | _keyword-only_ | | | | `dtype` | Optional[DTypes] | The data type | | **RETURNS** | ArrayXd | An array with the same contents as the input. | ### Ops.unzip {#unzip tag="method"} - **default:** - **numpy:** default - **cupy:** default Unzip a tuple of two arrays, transform them with `asarray` and return them as two separate arrays. | Argument | Type | Description | | ----------- | -------------------------------- | ------------------------------------------- | | `data` | Tuple[ArrayXd, ArrayXd] | The tuple of two arrays. | | **RETURNS** | Tuple[ArrayXd, ArrayXd] | The two arrays, transformed with `asarray`. | ### Ops.sigmoid {#sigmoid tag="method"} - **default:** - **numpy:** default - **cupy:** default Calculate the sigmoid function. | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The input values. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The output values, i.e. `S(X)`. | ### Ops.dsigmoid {#dsigmoid tag="method"} - **default:** - **numpy:** default - **cupy:** default Calculate the derivative of the `sigmoid` function. | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------ | | `Y` | FloatsXd | The input values. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The output values, i.e. `dS(Y)`. | ### Ops.dtanh {#dtanh tag="method"} - **default:** - **numpy:** default - **cupy:** default Calculate the derivative of the `tanh` function. | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------ | | `Y` | FloatsXd | The input values. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The output values, i.e. `dtanh(Y)`. | ### Ops.softmax {#softmax tag="method"} - **default:** - **numpy:** default - **cupy:** default Calculate the softmax function. The resulting array will sum up to 1. | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------------------ | | `x` | FloatsXd | The input values. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | `axis` | int | The dimension to normalize over. | | `temperature` | float | The value to divide the unnormalized probabilities by. | | **RETURNS** | FloatsXd | The normalized output values. | ### Ops.backprop_softmax {#backprop_softmax tag="method"} - **default:** - **numpy:** default - **cupy:** default | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------------------ | | `Y` | FloatsXd | Output array. | | `dY` | FloatsXd | Gradients of the output array. | | _keyword-only_ | | | | `axis` | int | The dimension that was normalized over. | | `temperature` | float | The value to divide the unnormalized probabilities by. | | **RETURNS** | FloatsXd | The gradients of the input array. | ### Ops.softmax_sequences {#softmax_sequences tag="method"} - **default:** - **numpy:** default - **cupy:** default | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------ | | `Xs` | Floats2d | An 2d array of input sequences. | | `lengths` | Ints1d | The lengths of the input sequences. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | `axis` | int | The dimension to normalize over. | | **RETURNS** | Floats2d | The normalized output values. | ### Ops.backprop_softmax_sequences {#backprop_softmax_sequences tag="method"} - **default:** - **numpy:** default - **cupy:** default The reverse/backward operation of the `softmax` function. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `dY` | Floats2d | Gradients of the output array. | | `Y` | Floats2d | Output array. | | `lengths` | Ints1d | The lengths of the input sequences. | | **RETURNS** | Floats2d | The gradients of the input sequences. | ### Ops.recurrent_lstm {#recurrent_lstm tag="method"} - **default:** - **numpy:** default - **cupy:** default Encode a padded batch of inputs into a padded batch of outputs using an LSTM. | Argument | Type | Description | | ----------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `W` | Floats2d | The weights, shaped `(nO * 4, nO + nI)`. | | `b` | Floats1d | The bias vector, shaped `(nO * 4,)`. | | `h_init` | Floats1d | Initial value for the previous hidden vector. | | `c_init` | Floats1d | Initial value for the previous cell state. | | `inputs` | Floats3d | A batch of inputs, shaped `(nL, nB, nI)`, where `nL` is the sequence length and `nB` is the batch size. | | `is_train` | bool | Whether the model is running in a training context. | | **RETURNS** | Tuple[Floats3d, Tuple[Floats3d, Floats3d, Floats3d]] | A tuple consisting of the outputs and the intermediate activations required for the backward pass. The outputs are shaped `(nL, nB, nO)`. | ### Ops.backprop_recurrent_lstm {#backprop_recurrent_lstm tag="method"} - **default:** - **numpy:** default - **cupy:** default Compute the gradients for the `recurrent_lstm` operation via backpropagation. | Argument | Type | Description | | ----------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | `dY` | Floats3d | The gradient w.r.t. the outputs. | | `fwd_state` | Tuple[Floats3d, Floats3d, Floats3d] | The tuple of gates, cells and inputs, returned by the forward pass. | | `params` | Tuple[Floats2d, Floats1d] | A tuple of the weights and biases. | | **RETURNS** | Tuple[Floats3d, Tuple[Floats2d, Floats1d, Floats1d, Floats1d]] | The gradients for the inputs and parameters (the weights, biases, initial hiddens and initial cells). | ### Ops.maxout {#maxout tag="method"} - **default:** - **numpy:** - **cupy:** | Argument | Type | Description | | ----------- | -------------------------------- | ------------------------------------------------------------------------------- | | `X` | Floats3d | The inputs. | | **RETURNS** | Tuple[Floats2d, Ints2d] | The outputs and an array indicating which elements in the final axis were used. | ### Ops.backprop_maxout {#backprop_maxout tag="method"} - **default:** - **numpy:** - **cupy:** | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------- | | `dY` | Floats2d | Gradients of the output array. | | `which` | Ints2d | The positions selected in the forward pass. | | `P` | int | The size of the final dimension. | | **RETURNS** | Floats3d | The gradient of the inputs. | ### Ops.relu {#relu tag="method"} - **default:** - **numpy:** - **cupy:** | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------ | | `X` | Floats2d | The inputs. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | Floats2d | The outputs. | ### Ops.backprop_relu {#relu tag="method"} - **default:** - **numpy:** - **cupy:** | Argument | Type | Description | | -------------- | ----------------- | ------------------------------------------ | | `dY` | Floats2d | Gradients of the output array. | | `Y` | Floats2d | The output from the forward pass. | | _keyword-only_ | | | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | Floats2d | The gradient of the input. | ### Ops.mish {#mish tag="method"} - **default:** - **numpy:** - **cupy:** Compute the Mish activation ([Misra, 2019](https://arxiv.org/pdf/1908.08681.pdf)). | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `X` | FloatsXd | The inputs. | | `threshold` | float | Maximum value at which to apply the activation. | | `inplace` | bool | Apply Mish to `X` in-place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_mish {#backprop_mish tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the Mish activation ([Misra, 2019](https://arxiv.org/pdf/1908.08681.pdf)). | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `threshold` | float | Threshold from the forward pass. | | `inplace` | bool | Apply Mish backprop to `dY` in-place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.swish {#swish tag="method"} - **default:** - **numpy:** - **cupy:** Swish [(Ramachandran et al., 2017)](https://arxiv.org/abs/1710.05941v2) is a self-gating non-monotonic activation function similar to the [GELU](#gelu) activation: whereas [GELU](#gelu) uses the CDF of the Gaussian distribution ฮฆ for self-gating `x * ฮฆ(x)`, Swish uses the logistic CDF `x * ฯƒ(x)`. Sometimes referred to as "SiLU" for "Sigmoid Linear Unit". | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_swish {#backprop_swish tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the Swish activation [(Ramachandran et al., 2017)](https://arxiv.org/abs/1710.05941v2). | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `Y` | FloatsXd | The outputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.dish {#dish tag="method" new="8.1.1"} - **default:** - **numpy:** - **cupy:** Dish or "Daniรซl's Swish-like activation" is an activation function with a non-monotinic shape similar to [GELU](#gelu), [Swish](#swish) and [Mish](#mish). However, Dish does not rely on elementary functions like `exp` or `erf`, making it much [faster to compute](https://twitter.com/danieldekok/status/1484898130441166853) in most cases. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_dish {#backprop_dish tag="method" new="8.1.1"} - **default:** - **numpy:** - **cupy:** Backpropagate the Dish activation. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.gelu {#gelu tag="method"} - **default:** - **numpy:** - **cupy:** GELU or "Gaussian Error Linear Unit" [(Hendrycks and Gimpel, 2016)](https://arxiv.org/abs/1606.08415) is a self-gating non-monotonic activation function similar to the [Swish](#swish) activation: whereas [GELU](#gelu) uses the CDF of the Gaussian distribution ฮฆ for self-gating `x * ฮฆ(x)` the Swish activation uses the logistic CDF ฯƒ and computes `x * ฯƒ(x)`. Various approximations exist, but `thinc` implements the exact GELU. The use of GELU is popular within transformer feed-forward blocks. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_gelu {#backprop_gelu tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the GELU activation [(Hendrycks and Gimpel, 2016)](https://arxiv.org/abs/1606.08415). | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.relu_k {#relu_k tag="method"} - **default:** - **numpy:** - **cupy:** ReLU activation function with the maximum value clipped at `k`. A common choice is `k=6` introduced for convolutional deep belief networks [(Krizhevsky, 2010)](https://www.cs.toronto.edu/~kriz/conv-cifar10-aug2010.pdf). The resulting function `relu6` is commonly used in low-precision scenarios. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | `k` | float | Maximum value (default: 6.0). | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_relu_k {#backprop_relu_k tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the ReLU-k activation. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.hard_sigmoid {#hard_sigmoid tag="method"} - **default:** - **numpy:** - **cupy:** The hard sigmoid activation function is a fast linear approximation of the sigmoid activation, defined as `max(0, min(1, x * 0.2 + 0.5))`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_hard_sigmoid {#backprop_hard_sigmoid tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the hard sigmoid activation. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.hard_tanh {#hard_tanh tag="method"} - **default:** - **numpy:** - **cupy:** The hard tanh activation function is a fast linear approximation of tanh, defined as `max(-1, min(1, x))`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_hard_tanh {#backprop_hard_tanh tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the hard tanh activation. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.clipped_linear {#clipped_linear tag="method"} - **default:** - **numpy:** - **cupy:** Flexible clipped linear activation function of the form `max(min_value, min(max_value, x * slope + offset))`. It is used to implement the [`relu_k`](#reluk), [`hard_sigmoid`](#hard_sigmoid), and [`hard_tanh`](#hard_tanh) methods. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------------------------------------- | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | `slope` | float | The slope of the linear function: `input * slope`. | | `offset` | float | The offset or intercept of the linear function: `input * slope + offset`. | | `min_val` | float | Minimum value to clip to. | | `max_val` | float | Maximum value to clip to. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_clipped_linear {#backprop_clipped_linear tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the clipped linear activation. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `slope` | float | The slope of the linear function: `input * slope`. | | `offset` | float | The offset or intercept of the linear function: `input * slope + offset`. | | `min_val` | float | Minimum value to clip to. | | `max_val` | float | Maximum value to clip to. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.hard_swish {#hard_swish tag="method"} - **default:** - **numpy:** - **cupy:** The hard Swish activation function is a fast linear approximation of Swish: `x * hard_sigmoid(x)`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_hard_swish {#backprop_hard_swish tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the hard Swish activation. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.hard_swish_mobilenet {#hard_swish_mobilenet tag="method"} - **default:** - **numpy:** - **cupy:** A variant of the fast hard Swish activation function used in `MobileNetV3` [(Howard et al., 2019)](https://arxiv.org/abs/1905.02244), defined as `x * (relu6(x + 3) / 6)`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------ | | `X` | FloatsXd | The inputs. | | `inplace` | bool | If `True`, the array is modified in place. | | **RETURNS** | FloatsXd | The outputs. | ### Ops.backprop_hard_swish_mobilenet {#backprop_hard_swish_mobilenet tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the hard Swish MobileNet activation. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------------------------- | | `dY` | FloatsXd | Gradients of the output array. | | `X` | FloatsXd | The inputs to the forward pass. | | `inplace` | bool | If `True`, the `dY` array is modified in place. | | **RETURNS** | FloatsXd | The gradient of the input. | ### Ops.reduce_first {#reduce_first tag="method"} - **default:** - **numpy:** default - **cupy:** default Perform sequence-wise first pooling for data in the ragged format. - Zero-length sequences are not allowed. A `ValueError` is raised if any element in `lengths` is zero. - Batch and hidden dimensions can have a size of zero. In these cases the corresponding dimensions in the output also have a size of zero. | Argument | Type | Description | | ----------- | ------------------------------- | --------------------------------------------------------------------- | | `X` | Floats2d | The concatenated sequences. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Tuple[Floats2d,Ints1d] | The first vector of each sequence and the sequence start/end indices. | ### Ops.backprop_reduce_first {#backprop_reduce_first tag="method"} - **default:** - **numpy:** default - **cupy:** default Backpropagate the `reduce_first` operation. | Argument | Type | Description | | ------------- | ----------------- | ------------------------------------------- | | `d_firsts` | Floats2d | The gradient of the outputs. | | `starts_ends` | Ints1d | The sequence start/end indices. | | **RETURNS** | Floats2d | The gradient of the concatenated sequences. | ### Ops.reduce_last {#reduce_last tag="method"} - **default:** - **numpy:** default - **cupy:** default Perform sequence-wise last pooling for data in the ragged format. - Zero-length sequences are not allowed. A `ValueError` is raised if any element in `lengths` is zero. - Batch and hidden dimensions can have a size of zero. In these cases the corresponding dimensions in the output also have a size of zero. | Argument | Type | Description | | ----------- | ------------------------------- | ------------------------------------------------------------------------------- | | `X` | Floats2d | The concatenated sequences. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Tuple[Floats2d,Ints1d] | The last vector of each sequence and the indices of the last sequence elements. | ### Ops.backprop_reduce_last {#backprop_reduce_last tag="method"} - **default:** - **numpy:** default - **cupy:** default Backpropagate the `reduce_last` operation. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------- | | `d_lasts` | Floats2d | The gradient of the outputs. | | `lasts` | Ints1d | Indices of the last sequence elements. | | **RETURNS** | Floats2d | The gradient of the concatenated sequences. | ### Ops.reduce_sum {#reduce_sum tag="method"} - **default:** - **numpy:** - **cupy:** Perform sequence-wise summation for data in the ragged format. - Zero-length sequences are reduced to all-zero vectors. - Batch and hidden dimensions can have a size of zero. In these cases the corresponding dimensions in the output also have a size of zero. | Argument | Type | Description | | ----------- | ----------------- | ----------------------------- | | `X` | Floats2d | The concatenated sequences. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Floats2d | The sequence-wise summations. | ### Ops.backprop_reduce_sum {#backprop_reduce_sum tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the `reduce_sum` operation. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------- | | `d_sums` | Floats2d | The gradient of the outputs. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Floats2d | The gradient of the concatenated sequences. | ### Ops.reduce_mean {#reduce_mean tag="method"} - **default:** - **numpy:** - **cupy:** Perform sequence-wise averaging for data in the ragged format. - Zero-length sequences are reduced to all-zero vectors. - Batch and hidden dimensions can have a size of zero. In these cases the corresponding dimensions in the output also have a size of zero. | Argument | Type | Description | | ----------- | ----------------- | --------------------------- | | `X` | Floats2d | The concatenated sequences. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Floats2d | The sequence-wise averages. | ### Ops.backprop_reduce_mean {#backprop_reduce_mean tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the `reduce_mean` operation. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------- | | `d_means` | Floats2d | The gradient of the outputs. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Floats2d | The gradient of the concatenated sequences. | ### Ops.reduce_max {#reduce_max tag="method"} - **default:** - **numpy:** - **cupy:** Perform sequence-wise max pooling for data in the ragged format. Zero-length sequences are not allowed. - Zero-length sequences are not allowed. A `ValueError` is raised if any element in `lengths` is zero. - Batch and hidden dimensions can have a size of zero. In these cases the corresponding dimensions in the output also have a size of zero. | Argument | Type | Description | | ----------- | -------------------------------- | --------------------------- | | `X` | Floats2d | The concatenated sequences. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Tuple[Floats2d, Ints2d] | The sequence-wise maximums. | ### Ops.backprop_reduce_max {#backprop_reduce_max tag="method"} - **default:** - **numpy:** - **cupy:** Backpropagate the `reduce_max` operation. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------------- | | `d_maxes` | Floats2d | The gradient of the outputs. | | `which` | Ints2d | The indices selected. | | `lengths` | Ints1d | The sequence lengths. | | **RETURNS** | Floats2d | The gradient of the concatenated sequences. | ### Ops.hash {#hash tag="method"} - **default:** - **numpy:** - **cupy:** Hash a sequence of 64-bit keys into a table with four 32-bit keys, using `murmurhash3`. | Argument | Type | Description | | ----------- | --------------- | ----------------------------------- | | `ids` | Ints1d | The keys, 64-bit unsigned integers. | | `seed` | int | The hashing seed. | | **RETURNS** | Ints2d | The hashes. | ### Ops.ngrams {#ngrams tag="method"} - **default:** - **numpy:** - **cupy:** default Create hashed ngram features. | Argument | Type | Description | | ----------- | --------------- | ------------------------------------------ | | `n` | int | The window to calculate each feature over. | | `keys` | Ints1d | The input sequence. | | **RETURNS** | Ints1d | The hashed ngrams. | ### Ops.gather_add {#gather_add tag="method" new="8.1"} - **default:** - **numpy:** - **cupy:** Gather rows from `table` with shape `(T, O)` using array `indices` with shape `(B, K)`, then sum the resulting array with shape `(B, K, O)` over the `K` axis. | Argument | Type | Description | | ----------- | ----------------- | ----------------------- | | `table` | Floats2d | The array to increment. | | `indices` | Ints2d | The indices to use. | | **RETURNS** | Floats2d | The summed rows. | ### Ops.scatter_add {#scatter_add tag="method"} - **default:** - **numpy:** - **cupy:** Increment entries in the array out using the indices in `ids` and the values in `inputs`. | Argument | Type | Description | | ----------- | ----------------- | ----------------------- | | `table` | FloatsXd | The array to increment. | | `indices` | IntsXd | The indices to use. | | `values` | FloatsXd | The inputs. | | **RETURNS** | FloatsXd | The incremented array. | --- ## Utilities {#util} ### get_ops {#get_ops tag="function"} Get a backend object using a string name. ```python ### Example from thinc.api import get_ops numpy_ops = get_ops("numpy") ``` | Argument | Type | Description | | ----------- | ------------ | ----------------------------------------------------- | | `ops` | str | `"numpy"`, `"apple"`, `"cupy"` or `"mps"`. | | `**kwargs` | | Optional arguments passed to [`Ops.__init__`](#init). | | **RETURNS** | Ops | The backend object. | ### use_ops {#use_ops tag="contextmanager"} Change the backend to execute with for the scope of the block. ```python ### Example from thinc.api import use_ops, get_current_ops with use_ops("cupy"): current_ops = get_current_ops() assert current_ops.name == "cupy" ``` | Argument | Type | Description | | ---------- | ------------ | ----------------------------------------------------- | | `ops` | str | `"numpy"`, `"apple"`, `"cupy"` or `"mps"`. | | `**kwargs` | | Optional arguments passed to [`Ops.__init__`](#init). | ### get_current_ops {#get_current_ops tag="function"} Get the current backend object. | Argument | Type | Description | | ----------- | ------------ | --------------------------- | | **RETURNS** | Ops | The current backend object. | ### set_current_ops {#set_current_ops tag="function"} Set the current backend object. | Argument | Type | Description | | -------- | ------------ | ------------------- | | `ops` | Ops | The backend object. | ### set_gpu_allocator {#set_gpu_allocator tag="function"} Set the CuPy GPU memory allocator. | Argument | Type | Description | | ----------- | ------------ | ------------------------------------- | | `allocator` | str | Either `"pytorch"` or `"tensorflow"`. | ```python ### Example from thinc.api set_gpu_allocator set_gpu_allocator("pytorch") ``` thinc-9.0.0/website/docs/api-config.md000066400000000000000000000574761461023342500176000ustar00rootroot00000000000000--- title: Config & Registry teaser: Function registry and configuration system next: /docs/api-types --- | | | | ------------------------- | ------------------------------------------------------------------------------- | | [**Config**](#config) | `Config` class used to load and create INI-style [configs](/docs/usage-config). | | [**Registry**](#registry) | Function registry for layers, optimizers etc. | ## Config {#config tag="class"} This class holds the model and training [configuration](/docs/usage-config) and can load and save the INI-style configuration format from/to a string, file or bytes. The `Config` class is a subclass of `dict` and uses Python's `ConfigParser` under the hood. ### Config.\_\_init\_\_ {#config-init tag="method"} Initialize a new `Config` object with optional data. ```python ### Example from thinc.api import Config config = Config({"training": {"patience": 10, "dropout": 0.2}}) ``` | Argument | Type | Description | | ----------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `data` | Optional[Union[Dict[str, Any], Config]] | Optional data to initialize the config with. | | _keyword-only_ | | | | `section_order` | Optional[List[str]] | Top-level section names, in order, used to sort the saved and loaded config. All other sections will be sorted alphabetically. | | `is_interpolated` | Optional[bool] | Whether the config is interpolated or whether it contains variables. Read from the `data` if it's an instance of `Config` and otherwise defaults to `True`. | ### Config.from_str {#config-from_str tag="method"} Load the config from a string. ```python ### Example from thinc.api import Config config_str = """ [training] patience = 10 dropout = 0.2 """ config = Config().from_str(config_str) print(config["training"]) # {'patience': 10, 'dropout': 0.2}} ``` | Argument | Type | Description | | -------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- | | `text` | str | The string config to load. | | _keyword-only_ | | | | `interpolate` | bool | Whether to interpolate variables like `${section.key}`. Defaults to `True`. | | `overrides` | Dict[str, Any] | Overrides for values and sections. Keys are provided in dot notation, e.g. `"training.dropout"` mapped to the value. | | **RETURNS** | Config | The loaded config. | ### Config.to_str {#config-to_str tag="method"} Write the config to a string. ```python ### Example from thinc.api import Config config = Config({"training": {"patience": 10, "dropout": 0.2}}) print(config.to_str()) # '[training]\npatience = 10\n\ndropout = 0.2' ``` | Argument | Type | Description | | ------------- | ------------- | --------------------------------------------------------------------------- | | `interpolate` | bool | Whether to interpolate variables like `${section.key}`. Defaults to `True`. | | **RETURNS** | str | The string config. | ### Config.to_bytes {#config-to_bytes tag="method"} Serialize the config to a byte string. ```python ### Example from thinc.api import Config config = Config({"training": {"patience": 10, "dropout": 0.2}}) config_bytes = config.to_bytes() print(config_bytes) # b'[training]\npatience = 10\n\ndropout = 0.2' ``` | Argument | Type | Description | | -------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- | | _keyword-only_ | | | | `interpolate` | bool | Whether to interpolate variables like `${section.key}`. Defaults to `True`. | | `overrides` | Dict[str, Any] | Overrides for values and sections. Keys are provided in dot notation, e.g. `"training.dropout"` mapped to the value. | | **RETURNS** | bytes | The serialized config. | ### Config.from_bytes {#config-from_bytes tag="method"} Load the config from a byte string. ```python ### Example from thinc.api import Config config = Config({"training": {"patience": 10, "dropout": 0.2}}) config_bytes = config.to_bytes() new_config = Config().from_bytes(config_bytes) ``` | Argument | Type | Description | | -------------- | --------------- | --------------------------------------------------------------------------- | | `bytes_data` | bytes | The data to load. | | _keyword-only_ | | | | `interpolate` | bool | Whether to interpolate variables like `${section.key}`. Defaults to `True`. | | **RETURNS** | Config | The loaded config. | ### Config.to_disk {#config-to_disk tag="method"} Serialize the config to a file. ```python ### Example from thinc.api import Config config = Config({"training": {"patience": 10, "dropout": 0.2}}) config.to_disk("./config.cfg") ``` | Argument | Type | Description | | -------------- | ------------------------- | --------------------------------------------------------------------------- | | `path` | Union[Path, str] | The file path. | | _keyword-only_ | | | | `interpolate` | bool | Whether to interpolate variables like `${section.key}`. Defaults to `True`. | ### Config.from_disk {#config-from_disk tag="method"} Load the config from a file. ```python ### Example from thinc.api import Config config = Config({"training": {"patience": 10, "dropout": 0.2}}) config.to_disk("./config.cfg") new_config = Config().from_disk("./config.cfg") ``` | Argument | Type | Description | | -------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `path` | Union[Path, str] | The file path. | | _keyword-only_ | | | | `interpolate` | bool | Whether to interpolate variables like `${section.key}`. Defaults to `True`. | | `overrides` | Dict[str, Any] | Overrides for values and sections. Keys are provided in dot notation, e.g. `"training.dropout"` mapped to the value. | | **RETURNS** | Config | The loaded config. | ### Config.copy {#config-copy tag="method"} Deep-copy the config. | Argument | Type | Description | | ----------- | --------------- | ------------------ | | **RETURNS** | Config | The copied config. | ### Config.interpolate {#config-interpolate tag="method"} Interpolate [variables](/docs/usage-config#config-interpolation) like `${section.value}` or `${section.subsection}` and return a copy of the config with interpolated values. Can be used if a config is loaded with `interpolate=False`, e.g. via [`Config.from_str`](#config-from_str). ```python ### Example from thinc.api import Config config_str = """ [hyper_params] dropout = 0.2 [training] dropout = ${hyper_params.dropout} """ config = Config().from_str(config_str, interpolate=False) print(config["training"]) # {'dropout': '${hyper_params.dropout}'}} config = config.interpolate() print(config["training"]) # {'dropout': 0.2}} ``` | Argument | Type | Description | | ----------- | --------------- | ---------------------------------------------- | | **RETURNS** | Config | A copy of the config with interpolated values. | ### Config.merge {#config-merge tag="method"} Deep-merge two config objects, using the current config as the default. Only merges sections and dictionaries and not other values like lists. Values that are provided in the updates are overwritten in the base config, and any new values or sections are added. If a config value is a variable like `${section.key}` (e.g. if the config was loaded with `interpolate=False`), the **variable is preferred**, even if the updates provide a different value. This ensures that variable references aren't destroyed by a merge. Note that blocks that refer to [registered functions](/docs/usage-config#registry) using the `@` syntax are only merged if they are referring to the same functions. Otherwise, merging could easily produce invalid configs, since different functions can take different arguments. If a block refers to a different function, it's overwritten. ```python ### Example from thinc.api import Config base_config_str = """ [training] patience = 10 dropout = 0.2 """ update_config_str = """ [training] dropout = 0.1 max_epochs = 2000 """ base_config = Config().from_str(base_config_str) update_config = Config().from_str(update_config_str) merged = Config(base_config).merge(update_config) print(merged["training"]) # {'patience': 10, 'dropout': 1.0, 'max_epochs': 2000} ``` | Argument | Type | Description | | ----------- | -------------------------------------- | --------------------------------------------------- | | `updates` | Union[Dict[str, Any], Config] | The updates to merge into the config. | | **RETURNS** | Config | A new config instance containing the merged config. | ### Config Attributes | Name | Type | Description | | ----------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `is_interpolated` | bool | Whether the config values have been interpolated. Defaults to `True` and is set to `False` if a config is loaded with `interpolate=False`, e.g. using [`Config.from_str`](#config-from_str). | --- ## Registry {#registry tag="class"} Thinc's registry system lets you **map string keys to functions**. You can register functions to create [optimizers](/docs/api-optimizers), [schedules](/docs/api-schedules), [layers](/docs/api-layers) and more, and then refer to them and set their arguments in your [config file](/docs/usage-config). Python type hints are used to validate the inputs. ```python ### Example import thinc @thinc.registry.optimizers.register("my_cool_optimizer.v1") def make_my_optimizer(learn_rate: float, gamma: float): return MyCoolOptimizer(learn_rate, gamma) ``` ```ini ### Valid Config {small="true"} [optimizer] @optimizers = "my_cool_optimizer.v1" learn_rate = 0.001 gamma = 1e-8 ``` ```ini ### Invalid Config {small="true"} [optimizer] @optimizers = "my_cool_optimizer.v1" learn_rate = 1 # not a float schedules = null # unknown argument ``` ### Attributes {#registry-attributes} | Registry name | Description | | -------------- | -------------------------------------------------------------------------- | | `optimizers` | Registry for functions that create [optimizers](/docs/api-optimizers). | | `schedules` | Registry for functions that create [schedules](/docs/api-schedules). | | `layers` | Registry for functions that create [layers](/docs/api-layers). | | `losses` | Registry for functions that create [losses](/docs/api-loss). | | `initializers` | Registry for functions that create [initializers](/docs/api-initializers). | ### registry.get {#registry-get tag="classmethod"} Get a registered function from a given registry using string names. Will raise an error if the registry or function doesn't exist. All individual registries also have a `get` method to get a registered function. ```python ### Example import thinc registered_func = thinc.registry.get("optimizers", "my_cool_optimizer.v1") # The above is the same as: registered_func = thinc.registry.optimizers.get("my_cool_optimizer.v1") ``` | Argument | Type | Description | | --------------- | ----------------- | ---------------------------------------------- | | `registry_name` | str | The name of the registry, e.g. `"optimizers"`. | | `func_name` | str | The name of the function. | | **RETURNS** | Callable | The registered function. | ### registry.create {#registry-create tag="classmethod"} Create a new function registry that will become available as an attribute to `registry`. Will raise an error if a registry of the name already exists. Under the hood, this calls into [`catalogue.create`](https://github.com/explosion/catalogue#function-cataloguecreate) using the `"thinc"` namespace. ```python ### Example import thinc thinc.registry.create("visualizers") @thinc.registry.visualizers("my_cool_visualizer.v1") def my_cool_visualizer(format: str = "jpg") -> "MyCoolVisualizer": return MyCoolVisualizer(format) ``` | Argument | Type | Description | | --------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `registry_name` | str | The name of the registry to create, e.g. `"visualizers"`. | | `entry_points` | bool | Allow the registry to be populated with entry points advertised by other packages (e.g. via the `"thinc_visualizers"` entry point group). Defaults to `False`. | Registry names can be _any string_ โ€“ however, if you want to use your registry as an attribute of `thinc.registry`, e.g. `@thinc.registry.visualizers`, they should be valid Python attribute names and only contain alphanumeric characters and underscores. ### registry.fill {#fill tag="classmethod"} Unpack a config dictionary, but leave all references to registry functions intact and don't resolve them. Only use the type annotations and optional base schema to fill in all arguments and their default values. This method is especially useful for getting an existing config up to date with changes in the schema and/or function arguments. If the config is incomplete and contains missing values for required arguments, you can set `validate=False` to skip validation and only update it. The updated schema should then pass validation. If the provided [`Config`](#config) still includes references to variables, e.g. if it was loaded with `interpolate=False` using a method like [`Config.from_str`](#config-from_str), a copy of the config is interpolated so it can be filled, and a filled version with the variables intact is returned. This means you can auto-fill partial config, without destroying the variables. ```python ### Example from thinc.api import Config, registry cfg = Config().from_disk("./my_config.cfg") filled_cfg = registry.fill(cfg) ``` | Argument | Type | Description | | -------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `config` | Union[Config, Dict[str, Any]] | The config dict to load. | | _keyword-only_ | | | | `validate` | bool | Whether to validate the config against a base schema and/or type annotations defined on the registered functions. Defaults to `True`. | | `schema` | pydantic.BaseModel | Optional [`pydantic` model](https://pydantic-docs.helpmanual.io/usage/models/) to validate the config against. See the docs on [base schemas](/docs/api-config#advanced-types-base-schema) for details. Defaults to an `EmptySchema` with extra properties and arbitrary types allowed. | | `overrides` | Dict[str, Any] | Optional overrides for config values. Should be a dictionary keyed by config properties with dot notation, e.g. `{"training.batch_size": 128}`. | | **RETURNS** | Config | The filled config. | ### registry.resolve {#registry-resolve tag="classmethod"} Unpack a config dictionary, creating objects from the registry recursively. If a section contains a key beginning with `@`, the rest of that key will be interpreted as the name of the registry. For instance, `"@optimizers": "my_cool_optimizer.v1"` will load the function from the optimizers registry and pass in the specified arguments. For more details and examples, see the [docs on Thinc's config system](/docs/usage-config). ```python ### Example from thinc.api import Config, registry cfg = Config().from_disk("./my_config.cfg") resolved = registry.resolve(cfg) ``` | Argument | Type | Description | | -------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `config` | Union[Config, Dict[str, Any]] | The config dict to load. | | _keyword-only_ | | | | `validate` | bool | Whether to validate the config against a base schema and/or type annotations defined on the registered functions. Defaults to `True`. | | `schema` | pydantic.BaseModel | Optional [`pydantic` model](https://pydantic-docs.helpmanual.io/usage/models/) to validate the config against. See the docs on [base schemas](/docs/api-config#advanced-types-base-schema) for details. Defaults to an `EmptySchema` with extra properties and arbitrary types allowed. | | `overrides` | Dict[str, Any] | Optional overrides for config values. Should be a dictionary keyed by config properties with dot notation, e.g. `{"training.batch_size": 128}`. | | **RETURNS** | Dict[str, Any] | The resolved config. | thinc-9.0.0/website/docs/api-initializers.md000066400000000000000000000177621461023342500210330ustar00rootroot00000000000000--- title: Initializers next: /docs/api-schedules --- A collection of initialization functions. Parameter initialization schemes can be very important for deep neural networks, because the initial distribution of the weights helps determine whether activations change in mean and variance as the signal moves through the network. If the activations are not stable, the network will not learn effectively. The "best" initialization scheme changes depending on the activation functions being used, which is why a variety of initializations are necessary. You can reduce the importance of the initialization by using normalization after your hidden layers. ### normal_init {#normal_init tag="function"} Initialize from a normal distribution, with `scale = sqrt(1 / fan_in)`. | Argument | Type | Description | | -------------- | ----------------- | --------------------------------------------------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | _keyword-only_ | | | | `fan_in` | int | Usually the number of inputs to the layer. If `-1`, the second dimension is used. | | **RETURNS** | FloatsXd | The initialized array. | ### glorot_uniform_init {#glorot_uniform_init tag="function"} Initialize from a uniform distribution with `scale` parameter computed by the method introduced by Xavier Glorot ([Glorot and Bengio, 2010])(http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf): `scale = sqrt(6.0 / (data.shape[0] + data.shape[1]))`. Usually used in [`Relu`](/docs/api-layers#relu) layers. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### glorot_normal_init {#glorot_normal_init tag="function"} Initialize from a normal distribution with `scale` parameter computed by the method introduced by Xavier Glorot ([Glorot and Bengio, 2010])(http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf): `scale = sqrt(2.0 / (data.shape[0] + data.shape[1]))`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### he_uniform_init {#he_uniform_init tag="function"} Initialize from a uniform distribution with `scale` parameter computed by the method introduced in [He et al., 2015](https://arxiv.org/abs/1502.01852): `scale = sqrt(6.0 / data.shape[1])`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### he_normal_init {#he_normal_init tag="function"} Initialize from a normal distribution with `scale` parameter computed by the method introduced in [He et al., 2015](https://arxiv.org/abs/1502.01852): `scale = sqrt(2.0 / data.shape[1])`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### lecun_uniform_init {#lecun_uniform_init tag="function"} Initialize from a uniform distribution with `scale` parameter computed as: `scale = sqrt(3.0 / data.shape[1])`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### lecun_normal_init {#lecun_normal_init tag="function"} Initialize from a normal distribution with `scale` parameter computed as: `variance = sqrt(1.0 / data.shape[1])`. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### zero_init {#zero_init tag="function"} Initialize a parameter with zero weights. This is usually used for output layers and for bias vectors. | Argument | Type | Description | | ----------- | ----------------- | ------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | **RETURNS** | FloatsXd | The initialized array. | ### uniform_init {#uniform_init tag="function"} Initialize values from a uniform distribution. This is usually used for word embedding tables. | Argument | Type | Description | | -------------- | ----------------- | ---------------------------------------- | | `ops` | Ops | The backend object, e.g. `model.ops`. | | `shape` | Shape | The data shape. | | _keyword-only_ | | | | `lo` | float | The minimum of the uniform distribution. | | `hi` | float | The maximum of the uniform distribution. | | **RETURNS** | FloatsXd | The initialized array. | --- ## Usage via config and function registry {#registry} Since the initializers need to be called with data, defining them in the [config](/docs/usage-config) will return a **configured function**: a partial with only the settings (the keyword arguments) applied. Within your script, you can then pass in the data, and the configured function will be called using the settings defined in the config. Most commonly, the initializer is passed as an argument to a [layer](/docs/api-layers), so it can be defined as its own config block nested under the layer settings: ```ini ### config.cfg {small="true"} [model] @layers = "linear.v1" nO = 10 [model.init_W] @initializers = "normal_init.v1" fan_in = -1 ``` ```python ### Usage {small="true"} from thinc.api import registry, Config config = Config().from_disk("./config.cfg") resolved = registry.resolve(config) model = resolved["model"] ``` You can also define it as a regular config setting and then call the configured function in your script: ```ini ### config.cfg {small="true"} [initializer] @initializers = "uniform_init.v1" lo = -0.1 hi = 0.1 ``` ```python ### Usage {small="true"} from thinc.api import registry, Config, NumpyOps config = Config().from_disk("./config.cfg") resolved = registry.resolve(config) initializer = resolved["initializer"] weights = initializer(NumpyOps(), (3, 2)) ``` thinc-9.0.0/website/docs/api-layers.md000066400000000000000000003137371461023342500176250ustar00rootroot00000000000000--- title: Layers teaser: Weights layers, transforms, combinators and wrappers next: /docs/api-optimizers --- This page describes functions for defining your model. Each layer is implemented in its own module in [`thinc.layers`](https://github.com/explosion/thinc/blob/master/thinc/layers) and can be imported from `thinc.api`. Most layer files define two public functions: a **creation function** that returns a [`Model`](/docs/api-model) instance, and a **forward function** that performs the computation. | | | | ------------------------------------------ | -------------------------------------------------------------------------------- | | [**Weights layers**](#weights-layers) | Layers that use an internal weights matrix for their computations. | | [**Reduction operations**](#reduction-ops) | Layers that perform rank reductions, e.g. pooling from word to sentence vectors. | | [**Combinators**](#combinators) | Layers that combine two or more existing layers. | | [**Data type transfers**](#transfers) | Layers that transform data to different types. | | [**Wrappers**](#wrappers) | Wrapper layers for other libraries like PyTorch and TensorFlow. | ## Weights layers {#weights-layers} ### CauchySimilarity {#cauchysimilarity tag="function"} - **Input:** Tuple[Floats2d, Floats2d] - **Output:** Floats1d - **Parameters:** W Compare input vectors according to the Cauchy similarity function proposed by [Chen (2013)](https://tspace.library.utoronto.ca/bitstream/1807/43097/3/Liu_Chen_201311_MASc_thesis.pdf). Primarily used within [`siamese`](#siamese) neural networks. | Argument | Type | Description | | ----------- | --------------------------------------------------- | ------------------------------ | | `nI` | Optional[int] | The size of the input vectors. | | **RETURNS** | Model[Tuple[Floats2d, Floats2d], Floats1d] | The created similarity layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/cauchysimilarity.py ``` ### Dish {#dish tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with the Dish activation function. Dish or "Daniรซl's Swish-like activation" is an activation function with a non-monotinic shape similar to [GELU](#gelu), [Swish](#swish) and [Mish](#mish). However, Dish does not rely on elementary functions like `exp` or `erf`, making it much [faster to compute](https://twitter.com/danieldekok/status/1484898130441166853) in most cases. | Argument | Type | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`he_normal_init`](/docs/api-initializers#he_normal_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/dish.py ``` ### Dropout {#dropout tag="function"} - **Input:** ArrayXd / Sequence[ArrayXd] / Ragged / Padded - **Output:** ArrayXd / Sequence[ArrayXd] / Ragged / Padded - **Attrs:** `dropout_rate` float Helps prevent overfitting by adding a random distortion to the input data during training. Specifically, cells of the input are zeroed with probability determined by the `dropout_rate` argument. Cells which are not zeroed are rescaled by `1-rate`. When not in training mode, the distortion is disabled (see [Hinton et al., 2012](https://arxiv.org/abs/1207.0580)). ```python ### Example from thinc.api import chain, Linear, Dropout model = chain(Linear(10, 2), Dropout(0.2)) Y, backprop = model(X, is_train=True) # Configure dropout rate via the dropout_rate attribute. for node in model.walk(): if node.name == "dropout": node.attrs["dropout_rate"] = 0.5 ``` | Argument | Type | Description | | -------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `dropout_rate` | float | The probability of zeroing the activations (default: 0). Higher dropout rates mean more distortion. Values around `0.2` are often good. | | **RETURNS** | Model[T, T] | The created dropout layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/dropout.py ``` ### Embed {#embed tag="function"} - **Input:** Union[Ints1d, Ints2d] - **Output:** Floats2d - **Parameters:** E - **Attrs:** `column` int, `dropout_rate` float Map integers to vectors, using a fixed-size lookup table. The input to the layer should be a two-dimensional array of integers, one column of which the embeddings table will slice as the indices. | Argument | Type | Description | | -------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nV` | int | Number of input vectors. Defaults to `1`. | | _keyword-only_ | | | | `column` | int | The column to slice from the input, to get the indices. | | `initializer` | Optional[Callable] | A function to initialize the internal parameters. Defaults to [`uniform_init`](/docs/api-initializers#uniform_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting (default `None`). | | **RETURNS** | Model[Union[Ints1d, Ints2d], Floats2d] | The created embedding layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/embed.py ``` ### HashEmbed {#hashembed tag="function"} - **Input:** Union[Ints1d, Ints2d] / - **Output:** Floats2d - **Parameters:** E - **Attrs:** `seed` Optional[int], `column` int, `dropout_rate` float An embedding layer that uses the "hashing trick" to map keys to distinct values. The hashing trick involves hashing each key four times with distinct seeds, to produce four likely differing values. Those values are modded into the table, and the resulting vectors summed to produce a single result. Because it's unlikely that two different keys will collide on all four "buckets", most distinct keys will receive a distinct vector under this scheme, even when the number of vectors in the table is very low. | Argument | Type | Description | | -------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | int | The size of the output vectors. | | `nV` | int | Number of input vectors. | | _keyword-only_ | | | | `seed` | Optional[int] | A seed to use for the hashing. | | `column` | int | The column to select features from. | | `initializer` | Optional[Callable] | A function to initialize the internal parameters. Defaults to [`uniform_init`](/docs/api-initializers#uniform_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting (default `None`). | | **RETURNS** | Model[Union[Ints1d, Ints2d], Floats2d] | The created embedding layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/hashembed.py ``` ### LayerNorm {#layernorm tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** b, G Perform layer normalization on the inputs ([Ba et al., 2016](https://arxiv.org/abs/1607.06450)). This layer does not change the dimensionality of the vectors. | Argument | Type | Description | | ----------- | ---------------------------------- | -------------------------------- | | `nI` | Optional[int] | The size of the input vectors. | | **RETURNS** | Model[Floats2d, Floats2d] | The created normalization layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/layernorm.py ``` ### Linear {#linear tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b The `Linear` layer multiplies inputs by a weights matrix `W` and adds a bias vector `b`. In PyTorch this is called a `Linear` layer, while Keras calls it a `Dense` layer. ```python ### Example from thinc.api import Linear model = Linear(10, 5) model.initialize() Y = model.predict(model.ops.alloc2f(2, 5)) assert Y.shape == (2, 10) ``` | Argument | Type | Description | | -------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Callable | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init). | | `init_b` | Callable | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init). | | **RETURNS** | Model[Floats2d, Floats2d] | The created `Linear` layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/linear.py ``` ### Sigmoid {#sigmoid tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A linear (aka dense) layer, followed by a sigmoid activation. This is usually used as an output layer for multi-label classification (in contrast to the `Softmax` layer, which is used for problems where exactly one class is correct per example. | Argument | Type | Description | | ----------- | ---------------------------------- | -------------------------------- | | `nOs` | Tuple[int, ...] | The sizes of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | **RETURNS** | Model[Floats2d, Floats2d] | The created sigmoid layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/sigmoid.py ``` ### sigmoid_activation {#sigmoid_activation tag="function"} - **Input:** FloatsXd - **Output:** FloatsXd Apply the sigmoid logistic function as an activation to the inputs. This is often used as an output activation for multi-label classification, because each element of the output vectors will be between `0` and `1`. | Argument | Type | Description | | ----------- | ---------------------------------- | --------------------------------------- | | **RETURNS** | Model[Floats2d, Floats2d] | The created `sigmoid_activation` layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/sigmoid_activation.py ``` ### LSTM and BiLSTM {#lstm tag="function"} - **Input:** Padded - **Output:** Padded - **Parameters:** `depth` int, `dropout` float An LSTM recurrent neural network. The BiLSTM is bidirectional: that is, each layer concatenated a forward LSTM with an LSTM running in the reverse direction. If you are able to install PyTorch, you should usually prefer to use the `PyTorchLSTM` layer instead of Thinc's implementations, as PyTorch's LSTM implementation is significantly faster. | Argument | Type | Description | | -------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `bi` | bool | Use BiLSTM. | | `depth` | int | Number of layers (default `1`). | | `dropout` | float | Dropout rate to avoid overfitting (default `0`). | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | **RETURNS** | Model[Padded, Padded] | The created LSTM layer(s). | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/lstm.py ``` ### Maxout {#maxout tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with a "maxout" activation ([Goodfellow et al, 2013](https://arxiv.org/abs/1302.4389)). Maxout layers require a weights array of shape `(nO, nP, nI)` in order to compute outputs of width `nO` given inputs of width `nI`. The extra multiple, `nP`, determines the number of "pieces" that the piecewise-linear activation will consider. | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | `nP` | int | Number of maxout pieces (default: 3). | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm), (default: False). | | **RETURNS** | Model[Floats2d, Floats2d] | The created maxout layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/maxout.py ``` ### Mish {#mish tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with Mish activation ([Misra, 2019](https://arxiv.org/pdf/1908.08681.pdf)). | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm), (default: False). | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/mish.py ``` ### Swish {#swish tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with the Swish activation function [(Ramachandran et al., 2017)](https://arxiv.org/abs/1710.05941v2). Swish is a self-gating non-monotonic activation function similar to [`GELU`](#gelu): whereas GELU uses the CDF of the Gaussian distribution ฮฆ for self-gating `x * ฮฆ(x)` Swish uses the logistic CDF `x * ฯƒ(x)`. Sometimes referred to as "SiLU" for "Sigmoid Linear Unit". | Argument | Type | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`he_normal_init`](/docs/api-initializers#he_normal_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/swish.py ``` ### Gelu {#gelu tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with the GELU activation function [(Hendrycks and Gimpel, 2016)](https://arxiv.org/abs/1606.08415). The GELU or "Gaussian Error Linear Unit" is a self-gating non-monotonic activation function similar to [Swish](#swish): whereas GELU uses the CDF of the Gaussian distribution ฮฆ for self-gating `x * ฮฆ(x)` the Swish activation uses the logistic CDF ฯƒ and computes `x * ฯƒ(x)`. Various approximations exist, but `thinc` implements the exact GELU. The use of GELU is popular within transformer feed-forward blocks. | Argument | Type | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`he_normal_init`](/docs/api-initializers#he_normal_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/gelu.py ``` ### ReluK {#reluk tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with the ReLU activation function where the maximum value is clipped at `k`. A common choice is `k=6` introduced for convolutional deep belief networks [(Krizhevsky, 2010)](https://www.cs.toronto.edu/~kriz/conv-cifar10-aug2010.pdf). The resulting function `relu6` is commonly used in low-precision scenarios. | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | `k` | float | Maximum value. Defaults to `6.0`.. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/clipped_linear.py#L132 ``` ### HardSigmoid {#hardsigmoid tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with hard sigmoid activation function, which is a fast linear approximation of sigmoid, defined as `max(0, min(1, x * 0.2 + 0.5))`. | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/clipped_linear.py#L90 ``` ### HardTanh {#hardtanh tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with hard tanh activation function, which is a fast linear approximation of tanh, defined as `max(-1, min(1, x))`. | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/clipped_linear.py#L111 ``` ### ClippedLinear {#clippedlinear tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer implementing a flexible clipped linear activation function of the form `max(min_value, min(max_value, x * slope + offset))`. It is used to implement the [`ReluK`](#reluk), [`HardSigmoid`](#hardsigmoid), and [`HardTanh`](#hardtanh) layers. | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | `slope` | float | The slope of the linear function: `input * slope`. | | `offset` | float | The offset or intercept of the linear function: `input * slope + offset`. | | `min_val` | float | Minimum value to clip to. | | `max_val` | float | Maximum value to clip to. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/clipped_linear.py ``` ### HardSwish {#hardswish tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer implementing the hard Swish activation function, which is a fast linear approximation of Swish: `x * hard_sigmoid(x)`. | Argument | Type | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`he_normal_init`](/docs/api-initializers#he_normal_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/hard_swish.py ``` ### HardSwishMobileNet {#hardswishmobilenet tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer implementing the a variant of the fast linear hard Swish activation function used in `MobileNetV3` [(Howard et al., 2019)](https://arxiv.org/abs/1905.02244), defined as `x * (relu6(x + 3) / 6)`. | Argument | Type | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`he_normal_init`](/docs/api-initializers#he_normal_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm). Defaults to `False`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created dense layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/hard_swish_mobilenet.py ``` ### MultiSoftmax {#multisoftmax tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b Neural network layer that predicts several multi-class attributes at once. For instance, we might predict one class with six variables, and another with five. We predict the 11 neurons required for this, and then softmax them such that columns 0-6 make a probability distribution and columns 6-11 make another. | Argument | Type | Description | | ----------- | ---------------------------------- | -------------------------------- | | `nOs` | Tuple[int, ...] | The sizes of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | **RETURNS** | Model[Floats2d, Floats2d] | The created multi softmax layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/multisoftmax.py ``` ### ParametricAttention {#parametricattention tag="function"} - **Input:** Ragged - **Output:** Ragged - **Parameters:** Q A layer that uses the parametric attention scheme described by [Yang et al. (2016)](https://www.cs.cmu.edu/~./hovy/papers/16HLT-hierarchical-attention-networks.pdf). The layer learns a parameter vector that is used as the keys in a single-headed attention mechanism. | Argument | Type | Description | | ----------- | ------------------------------ | ------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | **RETURNS** | Model[Ragged, Ragged] | The created attention layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/parametricattention.py ``` ### ParametricAttention_v2 {#parametricattention_v2 tag="function"} - **Input:** Ragged - **Output:** Ragged - **Parameters:** Q A layer that uses the parametric attention scheme described by [Yang et al. (2016)](https://aclanthology.org/N16-1174). The layer learns a parameter vector that is used as the keys in a single-headed attention mechanism. The original `ParametricAttention` layer uses the hidden representation as-is for the keys in the attention. This differs from the paper that introduces parametric attention (Equation 5). `ParametricAttention_v2` adds the option to transform the key representation in line with the paper by passing such a transformation through the `key_transform` parameter. | Argument | Type | Description | |-----------------|----------------------------------------------|------------------------------------------------------------------------| | `key_transform` | Optional[Model[Floats2d, Floats2d]] | Transformation to apply to the key representations. Defaults to `None` | | `nO` | Optional[int] | The size of the output vectors. | | **RETURNS** | Model[Ragged, Ragged] | The created attention layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/parametricattention_v2.py ``` ### Relu {#relu tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with Relu activation. | Argument | Type | Description | | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`glorot_uniform_init`](/docs/api-initializers#glorot_uniform_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `dropout` | Optional[float] | Dropout rate to avoid overfitting. | | `normalize` | bool | Whether or not to apply [layer normalization](#layernorm), (default: False). | | **RETURNS** | Model[Floats2d, Floats2d] | The created Relu layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/relu.py ``` ### Softmax {#softmax tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with a softmax activation. This is usually used as a prediction layer. Vectors produced by the softmax function sum to 1, and have values between 0 and 1, so each vector can be interpreted as a probability distribution. | Argument | Type | Description | | -------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created softmax layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/softmax.py ``` ### Softmax_v2 {#softmax_v2 tag="function"} - **Input:** Floats2d - **Output:** Floats2d - **Parameters:** W, b A dense layer with a softmax activation. This is usually used as a prediction layer. Vectors produced by the softmax function sum to 1, and have values between 0 and 1, so each vector can be interpreted as a probability distribution. `Softmax_v2` supports outputting unnormalized probabilities during inference by using `normalize_outputs=False` as an argument. This is useful when we are only interested in finding the top-k classes, but not their probabilities. Computing unnormalized probabilities is faster, because it skips the expensive normalization step. The `temperature` argument of `Softmax_v2` provides control of the softmax distribution. Values larger than 1 increase entropy and values between 0 and 1 (exclusive) decrease entropy of the distribution. The default temperature of 1 will calculate the unmodified softmax distribution. `temperature` is not used during inference when `normalize_outputs=False`. | Argument | Type | Description | | ------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `nI` | Optional[int] | The size of the input vectors. | | _keyword-only_ | | | | `init_W` | Optional[Callable] | A function to initialize the weights matrix. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `init_b` | Optional[Callable] | A function to initialize the bias vector. Defaults to [`zero_init`](/docs/api-initializers#zero_init) when set to `None`. | | `normalize_outputs` | bool | Return normalized probabilities during inference. Defaults to `True`. | | `temperature` | float | Temperature to divide logits by. Defaults to `1.0`. | | **RETURNS** | Model[Floats2d, Floats2d] | The created softmax layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/softmax.py ``` ### SparseLinear {#sparselinear tag="function"} - **Input:** Tuple[ArrayXd, ArrayXd, ArrayXd] - **Output:** ArrayXd - **Parameters:** W, b, `length` int A sparse linear layer using the "hashing trick". Useful for tasks such as text classification. Inputs to the layer should be a tuple of arrays `(keys, values, lengths)`, where the `keys` and `values` are arrays of the same length, describing the concatenated batch of input features and their values. The `lengths` array should have one entry per sequence in the batch, and the sum of the lengths should equal the length of the keys and values array. `SparseLinear` should not be used for new models because it contains an indexing bug. As a result, only a subset of the weights is used. Use [`SparseLinear_v2`](#sparselinear_v2) instead. | Argument | Type | Description | | ----------- | --------------------------------------------------------- | -------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `length` | int | The size of the weights vector, to be tuned empirically. | | **RETURNS** | Model[Tuple[ArrayXd, ArrayXd, ArrayXd], ArrayXd] | The created layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/sparselinear.pyx ``` ### SparseLinear_v2 {#sparselinear_v2 tag="function" new="8.1.6"} - **Input:** Tuple[ArrayXd, ArrayXd, ArrayXd] - **Output:** ArrayXd - **Parameters:** W, b, `length` int A sparse linear layer using the "hashing trick". Useful for tasks such as text classification. Inputs to the layer should be a tuple of arrays `(keys, values, lengths)`, where the `keys` and `values` are arrays of the same length, describing the concatenated batch of input features and their values. The `lengths` array should have one entry per sequence in the batch, and the sum of the lengths should equal the length of the keys and values array. | Argument | Type | Description | | ----------- | --------------------------------------------------------- | -------------------------------------------------------- | | `nO` | Optional[int] | The size of the output vectors. | | `length` | int | The size of the weights vector, to be tuned empirically. | | **RETURNS** | Model[Tuple[ArrayXd, ArrayXd, ArrayXd], ArrayXd] | The created layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/sparselinear.pyx ``` ## Reduction operations {#reduction-ops} ### reduce_first {#reduce_first tag="function"} - **Input:** Ragged - **Output:** ArrayXd Pooling layer that reduces the dimensions of the data by selecting the first item of each sequence. This is most useful after multi-head attention layers, which can learn to assign a good feature representation for the sequence to one of its elements. | Argument | Type | Description | | ----------- | ------------------------------- | -------------------------- | | **RETURNS** | Model[Ragged, ArrayXd] | The created pooling layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/reduce_first.py ``` ### reduce_last {#reduce_last tag="function"} Pooling layer that reduces the dimensions of the data by selecting the last item of each sequence. This is typically used after multi-head attention or recurrent neural network layers such as LSTMs, which can learn to assign a good feature representation for the sequence to its final element. - **Input:** Ragged - **Output:** ArrayXd | Argument | Type | Description | | ----------- | ------------------------------- | -------------------------- | | **RETURNS** | Model[Ragged, ArrayXd] | The created pooling layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/reduce_last.py ``` ### reduce_max {#reduce_max tag="function"} - **Input:** Ragged - **Output:** Floats2d Pooling layer that reduces the dimensions of the data by selecting the maximum value for each feature. A `ValueError` is raised if any element in `lengths` is zero. | Argument | Type | Description | | ----------- | -------------------------------- | -------------------------- | | **RETURNS** | Model[Ragged, Floats2d] | The created pooling layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/reduce_max.py ``` ### reduce_mean {#reduce_mean tag="function"} - **Input:** Ragged - **Output:** Floats2d Pooling layer that reduces the dimensions of the data by computing the average value of each feature. Zero-length sequences are reduced to the zero vector. | Argument | Type | Description | | ----------- | -------------------------------- | -------------------------- | | **RETURNS** | Model[Ragged, Floats2d] | The created pooling layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/reduce_mean.py ``` ### reduce_sum {#reduce_sum tag="function"} - **Input:** Ragged - **Output:** Floats2d Pooling layer that reduces the dimensions of the data by computing the sum for each feature. Zero-length sequences are reduced to the zero vector. | Argument | Type | Description | | ----------- | -------------------------------- | -------------------------- | | **RETURNS** | Model[Ragged, Floats2d] | The created pooling layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/reduce_sum.py ``` --- ## Combinators {#combinators} Combinators are layers that express **higher-order functions**: they take one or more layers as arguments and express some relationship or perform some additional logic around the child layers. Combinators can also be used to [overload operators](/docs/usage-models#operators). For example, binding `chain` to `>>` allows you to write `Relu(512) >> Softmax()` instead of `chain(Relu(512), Softmax())`. ### add {#add tag="function"} Compose two or more models `f`, `g`, etc, such that their outputs are added, i.e. `add(f, g)(x)` computes `f(x) + g(x)`. | Argument | Type | Description | | ----------- | ---------------------------- | ---------------------- | | `*layers` | Model[Any, ArrayXd] | The models to compose. | | **RETURNS** | Model[Any, ArrayXd] | The composed model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/add.py ``` ### bidirectional {#bidirectional tag="function"} Stitch two RNN models into a bidirectional layer. Expects squared sequences. | Argument | Type | Description | | ----------- | ---------------------------------------- | --------------------------------- | | `l2r` | Model[Padded, Padded] | The first model. | | `r2l` | Optional[Model[Padded, Padded]] | The second model. | | **RETURNS** | Model[Padded, Padded] | The composed bidirectional layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/bidirectional.py ``` ### chain {#chain tag="function"} Compose two or more models such that they become layers of a single feed-forward model, e.g. `chain(f, g)` computes `g(f(x))`. | Argument | Type | Description | | ----------- | -------------- | --------------------------------- | | `layer1` | Model | The first model to compose. | | `layer2` | Model | The second model to compose. | | `*layers` | Model | Any additional models to compose. | | **RETURNS** | Model | The composed feed-forward model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/chain.py ``` ### clone {#clone tag="function"} Construct `n` copies of a layer, with distinct weights. For example, `clone(f, 3)(x)` computes `f(f'(f''(x)))`. | Argument | Type | Description | | ----------- | -------------- | ------------------------------------------------ | | `orig` | Model | The layer to copy. | | `n` | int | The number of copies to construct. | | **RETURNS** | Model | A composite model containing two or more copies. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/clone.py ``` ### concatenate {#concatenate tag="function"} Compose two or more models `f`, `g`, etc, such that their outputs are concatenated, i.e. `concatenate(f, g)(x)` computes `hstack(f(x), g(x))`. | Argument | Type | Description | | ----------- | ------------------- | ---------------------- | | `*layers` | Model, ... | The models to compose. | | **RETURNS** | Model | The composed model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/concatenate.py ``` ### map_list {#map_list tag="function"} Map a child layer across list inputs. | Argument | Type | Description | | ----------- | ------------------------------------- | ----------------------- | | `layer` | Model[InT, OutT] | The child layer to map. | | **RETURNS** | Model[List[InT], List[OutT]] | The composed model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/map_list.py ``` ### expand_window {#expand_window tag="function"} - **Input:** Floats2d, Ragged - **Output:** Floats2d, Ragged - **Attrs:** `window_size` int For each vector in an input, construct an output vector that contains the input and a window of surrounding vectors. This is one step in a convolution. If the `window_size` is three, the output size `nO` will be `nI * 7` after concatenating three contextual vectors from the left, and three from the right, to each input vector. In general, `nO` equals `nI * (2 * window_size + 1)`. | Argument | Type | Description | | ------------- | -------------------- | ------------------------------------------------------------------------------ | | `window_size` | int | The window size (default 1) that determines the number of surrounding vectors. | | **RETURNS** | Model[T, T] | The created layer for adding context to vectors. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/expand_window.py ``` ### noop {#noop tag="function"} Transform a sequences of layers into a null operation. | Argument | Type | Description | | ----------- | -------------- | ---------------------- | | `*layers` | Model | The models to compose. | | **RETURNS** | Model | The composed model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/noop.py ``` ### residual {#residual tag="function"} - **Input:** List[FloatsXd] / Ragged / Padded / FloatsXd Floats1d Floats2d Floats3d Floats4d - **Output:** List[FloatsXd] / Ragged / Padded / FloatsXd Floats1d Floats2d Floats3d Floats4d A unary combinator creating a residual connection. This converts a layer computing `f(x)` into one that computes `f(x)+x`. Gradients flow through residual connections directly, helping the network to learn more smoothly. | Argument | Type | Description | | ----------- | -------------------- | -------------------------------------------------- | | `layer` | Model[T, T] | A model with the same input and output types. | | **RETURNS** | Model[T, T] | A model with the unchanged input and output types. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/residual.py ``` ### tuplify {#tuplify tag="function"} Give each child layer a separate copy of the input, and the combine the output of the child layers into a tuple. Useful for providing original and modified input to a downstream layer. On the backward pass the loss from each child is added together, so when using custom datatypes they should define an addition operator. | Argument | Type | Description | | ----------- | ----------------------------- | -------------------------------- | | `*layers` | Model[Any, T] ... | The models to compose. | | **RETURNS** | Model[Any, Tuple[T]] | The composed feed-forward model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/tuplify.py ``` ### siamese {#siamese tag="function"} Combine and encode a layer and a similarity function to form a [siamese architecture](https://en.wikipedia.org/wiki/Siamese_neural_network). Typically used to learn symmetric relationships, such as redundancy detection. | Argument | Type | Description | | ------------ | ------------------------------ | ----------------------------------------- | | `layer` | Model | The layer to run over the pair of inputs. | | `similarity` | Model | The similarity layer. | | **RETURNS** | Model[Tuple, ArrayXd] | The created siamese layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/siamese.py ``` ### uniqued {#uniqued tag="function"} Group inputs to a layer, so that the layer only has to compute for the unique values. The data is transformed back before output, and the same transformation is applied for the gradient. Effectively, this is a cache local to each minibatch. The `uniqued` wrapper is useful for word inputs, because common words are seen often, but we may want to compute complicated features for the words, using e.g. character LSTM. | Argument | Type | Description | | -------------- | -------------------------------- | ---------------------------- | | `layer` | Model | The layer. | | _keyword-only_ | | | | `column` | int | The column. Defaults to `0`. | | **RETURNS** | Model[Ints2d, Floats2d] | The composed model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/uniqued.py ``` --- ## Data type transfers {#transfers} ### array_getitem, ints_getitem, floats_getitem {#array_getitem tag="function"} - **Input:** ArrayXd - **Output:** ArrayXd Index into input arrays, and return the subarrays. Multi-dimensional indexing can be performed by passing in a tuple, and slicing can be performed using the slice object. For instance, `X[:, :-1]` would be `(slice(None, None), slice(None, -1))`. | Argument | Type | Description | | -------- | --------------------------------------------------------------------------------------------- | -------------------------- | | `index` | Union[Union[int, slice, Sequence[int]], Tuple[Union[int, slice, Sequence[int]], ...] | A valid numpy-style index. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/array_getitem.py ``` ### list2array {#list2array tag="function"} - **Input:** List2d - **Output:** Array2d Transform sequences to ragged arrays if necessary. If sequences are already ragged, do nothing. A ragged array is a tuple `(data, lengths)`, where `data` is the concatenated data. | Argument | Type | Description | | ----------- | ------------------------------- | ---------------------------------------- | | **RETURNS** | Model[List2d, Array2d] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/list2array.py ``` ### list2ragged {#list2ragged tag="function"} - **Input:** ListXd - **Output:** Ragged Transform sequences to ragged arrays if necessary and return the ragged array. If sequences are already ragged, do nothing. A ragged array is a tuple `(data, lengths)`, where `data` is the concatenated data. | Argument | Type | Description | | ----------- | ------------------------------ | ---------------------------------------- | | **RETURNS** | Model[ListXd, Ragged] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/list2ragged.py ``` ### list2padded {#list2padded tag="function"} - **Input:** List2d - **Output:** Padded Create a layer to convert a list of array inputs into [`Padded`](/docs/api-types#padded). | Argument | Type | Description | | ----------- | ------------------------------ | ---------------------------------------- | | **RETURNS** | Model[List2d, Padded] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/list2padded.py ``` ### ragged2list {#ragged2list tag="function"} - **Input:** Ragged - **Output:** ListXd Transform sequences from a ragged format into lists. | Argument | Type | Description | | ----------- | ------------------------------ | ---------------------------------------- | | **RETURNS** | Model[Ragged, ListXd] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/ragged2list.py ``` ### padded2list {#padded2list tag="function"} - **Input:** Padded - **Output:** List2d Create a layer to convert a [`Padded`](/docs/api-types#padded) input into a list of arrays. | Argument | Type | Description | | ----------- | ------------------------------ | ---------------------------------------- | | **RETURNS** | Model[Padded, List2d] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/padded2list.py ``` ### remap_ids {#remap_ids tag="function"} - **Input:** Union[Sequence[Hashable], Ints1d, Ints2d] - **Output:** Ints2d Remap a sequence of strings, integers or other hashable inputs using a mapping table, usually as a preprocessing step before embeddings. The input can also be a two dimensional integer array in which case the `column` attribute tells the `remap_ids` layer which column of the array to map with the `mapping_table`. Both attributes can be passed on initialization, but since the layer is designed to retrieve them from `model.attrs` during `forward`, they can be set any time before calling `forward`. This means that they can also be changed between calls. Before calling `forward` the `mapping_table` has to be set and for 2D inputs the `column` is also required. | Argument | Type | Description | | --------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | `mapping_table` | Dict[Any, int] | The mapping table to use. Can also be set after initialization by writing to `model.attrs["mapping_table"]`. | | `default` | int | The default value if the input does not have an entry in the mapping table. | | `column` | int | The column to apply the mapper to in case of 2D input. | | **RETURNS** | Model[Union[Sequence[Hashable], Ints1d, Ints2d], Ints2d] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/remap_ids.py ``` ### strings2arrays {#strings2arrays tag="function"} - **Input:** Sequence[Sequence[str]] - **Output:** List[Ints2d] Transform a sequence of string sequences to a list of arrays. | Argument | Type | Description | | ----------- | ----------------------------------------------------- | ---------------------------------------- | | **RETURNS** | Model[Sequence[Sequence[str]], List[Ints2d]] | The layer to compute the transformation. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/strings2arrays.py ``` ### with_array {#with_array tag="function"} - **Input / output:** Union[Padded, Ragged, ListXd, ArrayXd] Transform sequence data into a contiguous array on the way into and out of a model. Handles a variety of sequence types: lists, padded and ragged. If the input is an array, it is passed through unchanged. | Argument | Type | Description | | -------------- | -------------------------------- | ----------------------------- | | `layer` | Model[ArrayXd, ArrayXd] | The layer to wrap. | | _keyword-only_ | | | | `pad` | int | The padding. Defaults to `0`. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_array2d.py ``` ### with_array2d {#with_array2d tag="function"} - **Input / output:** Union[Padded, Ragged, List2d, Array2d] Transform sequence data into a contiguous two-dimensional array on the way into and out of a model. In comparison to the `with_array` layer, the behavior of this layer mostly differs on `Padded` inputs, as this layer merges the batch and length axes to form a two-dimensional array. Handles a variety of sequence types: lists, padded and ragged. If the input is a two-dimensional array, it is passed through unchanged. | Argument | Type | Description | | -------------- | -------------------------------- | ----------------------------- | | `layer` | Model[Array2d, Array2d] | The layer to wrap. | | _keyword-only_ | | | | `pad` | int | The padding. Defaults to `0`. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_array.py ``` ### with_flatten {#with_flatten tag="function"} - **Input:** Sequence[Sequence[Any]] - **Output:** ListXd Flatten nested inputs on the way into a layer and reverse the transformation over the outputs. Even though `with_flatten` is a layer wrapper, it does not preserve symmetry between the input and output data types. This often makes it hard to compose with other layers. Use [`with_flatten_v2`](#with_flatten_v2) instead. | Argument | Type | Description | | ----------- | ----------------------------------------------- | ------------------ | | `layer` | Model[Sequence[Any], ArrayXd] | The layer to wrap. | | **RETURNS** | Model[Sequence[Sequence[Any]], ListXd] | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_flatten.py ``` ### with_flatten_v2 {#with_flatten_v2 tag="function" new="8.1.6"} - **Input:** List[List[InItemT]] - **Output:** List[List[OutItemT]] Flatten nested inputs on the way into a layer and reverse the transformation over the outputs. | Argument | Type | Description | | ----------- | --------------------------------------------------------- | ------------------ | | `layer` | Model[List[InItemT], List[OutItemT]] | The layer to wrap. | | **RETURNS** | Model[List[List[InItemT]], List[List[OutItemT]]] | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_flatten_v2.py ``` ### with_padded {#with_padded tag="function"} - **Input / output:** Union[Padded, Ragged, List2d, Floats3d, Tuple[Floats3d, Ints1d, Ints1d, Ints1d]] Convert sequence input into the [`Padded`](/docs/api-types#padded) data type on the way into a layer and reverse the transformation on the output. | Argument | Type | Description | | ----------- | ------------------------------ | ------------------ | | `layer` | Model[Padded, Padded] | The layer to wrap. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_padded.py ``` ### with_ragged {#with_ragged tag="function"} - **Input / output:** Union[Padded, Ragged, ListXd, Floats3d, Tuple[Floats2d, Ints1d]] Convert sequence input into the [`Ragged`](/docs/api-types#ragged) data type on the way into a layer and reverse the transformation on the output. | Argument | Type | Description | | ----------- | ------------------------------ | ------------------ | | `layer` | Model[Ragged, Ragged] | The layer to wrap. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_ragged.py ``` ### with_list {#with_list tag="function"} - **Input / output:** Union[Padded, Ragged, List2d] Convert sequence input into lists on the way into a layer and reverse the transformation on the outputs. | Argument | Type | Description | | ----------- | ------------------------------ | ------------------ | | `layer` | Model[List2d, List2d] | The layer to wrap. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_list.py ``` ### with_getitem {#with_getitem tag="function"} - **Input:** Tuple - **Output:** Tuple Transform data on the way into and out of a layer by plucking an item from a tuple. | Argument | Type | Description | | ----------- | -------------------------------- | ---------------------------------- | | `idx` | int | The index to pluck from the tuple. | | `layer` | Model[ArrayXd, ArrayXd] | The layer to wrap. | | **RETURNS** | Model[Tuple, Tuple] | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_getitem.py ``` ### with_reshape {#with_reshape tag="function"} - **Input:** Array3d - **Output:** Array3d Reshape data on the way into and out from a layer. | Argument | Type | Description | | ----------- | -------------------------------- | ------------------ | | `layer` | Model[Array2d, Array2d] | The layer to wrap. | | **RETURNS** | Model[Array3d, Array3d] | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_reshape.py ``` ### with_debug {#with_debug tag="function"} - **Input:** Any - **Output:** Any Debugging layer that wraps any layer and allows executing callbacks during the forward pass, backward pass and initialization. The callbacks will receive the same arguments as the functions they're called in and are executed before the function runs. This layer should only be used for **debugging, logging, benchmarking etc.**, not to modify data or perform any other side-effects that are relevant to the network outside of debugging and testing it. If you need hooks that run in specific places of the model lifecycle, you should write your own [custom layer](/docs/usage-models#new-layers). You can use the implementation of `with_debug` as a template. ```python ### Example from thinc.api import Linear, with_debug def on_init(model, X, Y): print(f"X: {type(Y)}, Y ({type(Y)})") model = with_debug(Linear(2, 5), on_init=on_init) model.initialize() ``` | Argument | Type | Description | | -------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `layer` | Model | The layer to wrap. | | `name` | Optional[str] | Optional name for the wrapped layer, will be prefixed by `debug:`. Defaults to name of the wrapped layer. | | _keyword-only_ | | | | `on_init` | Callable[[Model, Any, Any], None] | Function called on initialization. Receives the model and the `X` and `Y` passed to [`Model.initialize`](/docs/api-model#initialize), if available. | | `on_forward` | Callable[[Model, Any, bool], None] | Function called at the start of the forward pass. Receives the model, the inputs and the value of `is_train`. | | `on_backprop` | Callable[[Any], None] = do_nothing | Function called at the start of the backward pass. Receives the gradient. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_debug.py ``` ### with_nvtx_range {#with_nvtx_range tag="function"} - **Input:** Any - **Output:** Any Layer that wraps any layer and marks the forward and backprop passes as an NVTX range. This can be helpful when profiling GPU performance of a layer. ```python ### Example from thinc.api import Linear, with_nvtx_range model = with_nvtx_range(Linear(2, 5)) model.initialize() ``` | Argument | Type | Description | | ---------------- | ---------------------- | ------------------------------------------------------------------------------- | | `layer` | Model | The layer to wrap. | | `name` | Optional[str] | Optional name for the wrapped layer. Defaults to the name of the wrapped layer. | | _keyword-only_ | | | | `forward_color` | int | Identifier of the color to use for the forward pass | | `backprop_color` | int | Identifier of the color to use for the backward pass | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_nvtx_range.py ``` ### with_signpost_interval {#with_signpost_interval tag="function" new="8.1.1"} - **Input:** Any - **Output:** Any Layer that wraps any layer and marks the init, forward and backprop passes as a (macOS) signpost interval. This can be helpful when profiling the performance of a layer using macOS [Instruments.app](https://help.apple.com/instruments/mac/current/). Use of this layer requires that the [`os-signpost`](https://github.com/explosion/os-signpost) package is installed. ```python ### Example from os_signpost import Signposter from thinc.api import Linear, with_signpost_interval signposter = Signposter("com.example.my_subsystem", Signposter.Category.DynamicTracing) model = with_signpost_interval(Linear(2, 5), signposter) model.initialize() ``` | Argument | Type | Description | | ------------ | --------------------------------- | ------------------------------------------------------------------------------- | | `layer` | Model | The layer to wrap. | | `signposter` | os_signposter.Signposter | `Signposter` object to log the interval with. | | `name` | Optional[str] | Optional name for the wrapped layer. Defaults to the name of the wrapped layer. | | **RETURNS** | Model | The wrapped layer. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/with_signpost_interval.py ``` --- ## Wrappers {#wrappers} ### PyTorchWrapper, PyTorchRNNWrapper {#pytorchwrapper tag="function"} - **Input:** Any - **Output:** Any Wrap a [PyTorch](https://pytorch.org) model so that it has the same API as Thinc models. To optimize the model, you'll need to create a PyTorch optimizer and call `optimizer.step` after each batch. The `PyTorchRNNWrapper` has the same signature as the `PyTorchWrapper` and lets you to pass in a custom sequence model that has the same inputs and output behavior as a [`torch.nn.RNN`](https://pytorch.org/docs/stable/nn.html#torch.nn.RNN) object. Your PyTorch model's forward method can take arbitrary positional arguments and keyword arguments, but must return either a **single tensor** as output or a **tuple**. You may find [PyTorch's `register_forward_hook`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module.register_forward_hook) helpful if you need to adapt the output. The convert functions are used to map inputs and outputs to and from your PyTorch model. Each function should return the converted output, and a callback to use during the backward pass: ```python Xtorch, get_dX = convert_inputs(X) Ytorch, torch_backprop = model.shims[0](Xtorch, is_train) Y, get_dYtorch = convert_outputs(Ytorch) ``` To allow maximum flexibility, the [`PyTorchShim`](/docs/api-model#shims) expects [`ArgsKwargs`](/docs/api-types#argskwargs) objects on the way into the forward and backward passes. The `ArgsKwargs` objects will be passed straight into the model in the forward pass, and straight into `torch.autograd.backward` during the backward pass. | Argument | Type | Description | | ----------------- | ------------------------ | ---------------------------------------------------------------------------------------- | | `pytorch_model` | Any | The PyTorch model. | | `convert_inputs` | Callable | Function to convert inputs to PyTorch tensors (same signature as `forward` function). | | `convert_outputs` | Callable | Function to convert outputs from PyTorch tensors (same signature as `forward` function). | | **RETURNS** | Model[Any, Any] | The Thinc model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/pytorchwrapper.py ``` ### TorchScriptWrapper_v1 {#torchscriptwrapper tag="function" new="8.1.6"} - **Input:** Any - **Output:** Any Wrap a [TorchScript](https://pytorch.org/docs/stable/jit.html) model so that it has the same API as Thinc models. To optimize the model, you'll need to create a PyTorch optimizer and call `optimizer.step` after each batch. Your TorchScript model's forward method can take arbitrary positional arguments and keyword arguments, but must return either a **single tensor** as output or a **tuple**. The convert functions are used to map inputs and outputs to and from your TorchScript model. Each function should return the converted output, and a callback to use during the backward pass: ```python Xtorch, get_dX = convert_inputs(X) Ytorch, torch_backprop = model.shims[0](Xtorch, is_train) Y, get_dYtorch = convert_outputs(Ytorch) ``` To allow maximum flexibility, the [`TorchScriptShim`](/docs/api-model#shims) expects [`ArgsKwargs`](/docs/api-types#argskwargs) objects on the way into the forward and backward passes. The `ArgsKwargs` objects will be passed straight into the model in the forward pass, and straight into `torch.autograd.backward` during the backward pass. Note that the `torchscript_model` argument can be `None`. This is useful for deserialization since serialized TorchScript contains both the model and its weights. A PyTorch wrapper can be converted to a TorchScript wrapper using the `pytorch_to_torchscript_wrapper` function: ```python from thinc.api import PyTorchWrapper_v2, pytorch_to_torchscript_wrapper import torch model = PyTorchWrapper_v2(torch.nn.Linear(nI, nO)).initialize() script_model = pytorch_to_torchscript_wrapper(model) ``` | Argument | Type | Description | | ------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------- | | `torchscript_model` | Optional[torch.jit.ScriptModule] | The TorchScript model. | | `convert_inputs` | Callable | Function to convert inputs to PyTorch tensors (same signature as `forward` function). | | `convert_outputs` | Callable | Function to convert outputs from PyTorch tensors (same signature as `forward` function). | | `mixed_precision` | bool | Enable mixed-precision training. | | `grad_scaler` | Optional[PyTorchGradScaler] | Gradient scaler to use during mixed-precision training. | | `device` | Optional[torch.Device] | The Torch device to execute the model on. | | **RETURNS** | Model[Any, Any] | The Thinc model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/torchscriptwrapper.py ``` ### TensorFlowWrapper {#tensorflowwrapper tag="function"} - **Input:** Any - **Output:** Any In Thinc v8.2+, TensorFlow support is not enabled by default. To enable TensorFlow: ```python from thinc.api import enable_tensorflow enable_tensorflow() ``` Wrap a [TensorFlow](https://tensorflow.org) model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a TensorFlow optimizer and call `optimizer.apply_gradients` after each batch. To allow maximum flexibility, the [`TensorFlowShim`](/docs/api-model#shims) expects [`ArgsKwargs`](/docs/api-types#argskwargs) objects on the way into the forward and backward passes. | Argument | Type | Description | | ------------------ | ------------------------ | --------------------- | | `tensorflow_model` | Any | The TensorFlow model. | | **RETURNS** | Model[Any, Any] | The Thinc model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/tensorflowwrapper.py ``` ### MXNetWrapper {#mxnetwrapper tag="function"} - **Input:** Any - **Output:** Any In Thinc v8.2+, MXNet support is not enabled by default. To enable MXNet: ```python from thinc.api import enable_mxnet enable_mxnet() ``` Wrap a [MXNet](https://mxnet.apache.org/) model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a MXNet optimizer and call `optimizer.step()` after each batch. To allow maximum flexibility, the [`MXNetShim`](/docs/api-model#shims) expects [`ArgsKwargs`](/docs/api-types#argskwargs) objects on the way into the forward and backward passes. | Argument | Type | Description | | ------------------ | ------------------------ | --------------------- | | `tensorflow_model` | Any | The TensorFlow model. | | **RETURNS** | Model[Any, Any] | The Thinc model. | ```python https://github.com/explosion/thinc/blob/master/thinc/layers/mxnetwrapper.py ``` thinc-9.0.0/website/docs/api-loss.md000066400000000000000000000207231461023342500172740ustar00rootroot00000000000000--- title: Loss Calculators next: /docs/api-config --- All loss calculators follow the same API: they're classes that are initialized with optional settings and have a `get_grad` method returning the gradient of the loss with respect to the model outputs and a `get_loss` method returning the scalar loss. ## Loss {#loss tag="base class"} ### Loss.\_\_init\_\_ {#loss-init tag="method"} Initialize the loss calculator. | Argument | Type | Description | | ---------- | ------------ | ---------------------------------------------------------------------------------------- | | `**kwargs` | Any | Optional calculator-specific settings. Can also be provided via the [config](#registry). | ### Loss.\_\_call\_\_ {#loss-call tag="method"} Calculate the gradient and the scalar loss. Returns a tuple of the results of `Loss.get_grad` and `Loss.get_loss`. | Argument | Type | Description | | ----------- | ------------------------ | ----------------------------- | | `guesses` | Any | The model outputs. | | `truths` | Any | The training labels. | | **RETURNS** | Tuple[Any, Any] | The gradient and scalar loss. | ### Loss.get_grad {#loss-get_grad tag="method"} Calculate the gradient of the loss with respect with the model outputs. | Argument | Type | Description | | ----------- | ------------ | -------------------- | | `guesses` | Any | The model outputs. | | `truths` | Any | The training labels. | | **RETURNS** | Any | The gradient. | ### Loss.get_loss {#loss-get_grad tag="method"} Calculate the scalar loss. Typically returns a float. | Argument | Type | Description | | ----------- | ------------ | -------------------- | | `guesses` | Any | The model outputs. | | `truths` | Any | The training labels. | | **RETURNS** | Any | The scalar loss. | --- ## Loss Calculators {#calculators} ### CategoricalCrossentropy {#categorical_crossentropy tag="class"} - **Guesses:** Floats2d - **Truths:** Union[Ints1d, List[int], List[str], Floats2d] - **Gradient:** Floats2d - **Loss:** float A flexible implementation of the common categorical cross-entropy loss that works on various data types. The `guesses` should represent probabilities and are expected to be in the range of `[0, 1]`. They can both represent exclusive classes from multi-class cross-entropy (generally coming from a `softmax` layer) or could be classwise binary decisions for multi-label cross-entropy (`sigmoid` layer). The `truths` are most commonly provided as labels in `Ints1d`, `List[int]` or `List[str]` format. Alternatively, users can provide `truths` as a `Floats2d` for example to encode label-confidences. ```python ### {small="true"} from thinc.api import CategoricalCrossentropy loss_calc = CategoricalCrossentropy() ``` ```ini ### config.cfg {small="true"} [loss] @losses = "CategoricalCrossentropy.v1" normalize = true ``` | Argument | Type | ย Description | | ----------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | _keyword-only_ | | | | `names` | List[str] | Label names. Has to be provided when using with List[str] as truths. | | `normalize` | bool | Normalize and divide by number of examples given. | | `neg_prefix` | str | Prefix used to indicate that a label is negative e.g. "!sci-fi". | | `missing_value` | Union[str, int] | Specific label that indicates the value is missing and should not be considered for training/evaluation purposes, e.g. empty string `""` or `0`. | | `label_smoothing` | float | Smoothing-coefficient for label-smoothing. | ### SequenceCategoricalCrossentropy {#sequence_categorical_crossentropy tag="class"} - **Guesses:** List[Floats2d] - **Truths:** List[Union[Ints1d, List[int], List[str], Floats2d]] - **Gradient:** List[Floats2d] - **Loss:** List[float] This loss runs the `CategoricalCrossentropy` over a `List` of `guesses` and `truths`. ```python ### {small="true"} from thinc.api import SequenceCategoricalCrossentropy loss_calc = SequenceCategoricalCrossentropy() ``` ```ini ### config.cfg {small="true"} [loss] @losses = "SequenceCategoricalCrossentropy.v1" normalize = true ``` | Argument | Type | ย Description | | ----------------- | ------------------------ | ------------------------------------------------------------------- | | _keyword-only_ | | | | `names` | List[str] | Label names. Has to be provided when using with List[str] as truths | | `normalize` | bool | Normalize and divide by number of examples given. | | `neg_prefix` | str | Symbol that indicates that a label is negative e.g. "!sci-fi". | | `missing_value` | Union[str, int] | Symbol for "missing value" among the labels. | | `label_smoothing` | float | Smoothing-coefficient for label-smoothing. | ### L2Distance {#l2distance tag="class"} - **Guesses:** Floats2d - **Truths:** Floats2d - **Gradient:** Floats2d - **Loss:** float ```python ### {small="true"} from thinc.api import L2Distance loss_calc = L2Distance() ``` ```ini ### config.cfg {small="true"} [loss] @losses = "L2Distance.v1" normalize = true ``` | Argument | Type | ย Description | | -------------- | ------------- | ------------------------------------------------- | | _keyword-only_ | | | | `normalize` | bool | Normalize and divide by number of examples given. | ### CosineDistance {#cosine_distance tag="function"} - **Guesses:** Floats2d - **Truths:** Floats2d - **Gradient:** Floats2d - **Loss:** float ```python ### {small="true"} from thinc.api import CosineDistance loss_calc = CosineDistance(ignore_zeros=False) ``` ```ini ### config.cfg {small="true"} [loss] @losses = "CosineDistance.v1" normalize = true ignore_zeros = false ``` | Argument | Type | ย Description | | -------------- | ------------- | ------------------------------------------------- | | _keyword-only_ | | | | `normalize` | bool | Normalize and divide by number of examples given. | | `ignore_zeros` | bool | Don't count zero vectors. | --- ## Usage via config and function registry {#registry} Defining the loss calculators in the [config](/docs/usage-config) will return the **initialized object**. Within your script, you can then call it or its methods and pass in the data. ```ini ### config.cfg {small="true"} [loss] @losses = "L2Distance.v1" normalize = true ``` ```python ### Usage {small="true"} from thinc.api import registry, Config config = Config().from_disk("./config.cfg") resolved = registry.resolve(config) loss_calc = resolved["loss"] loss = loss_calc.get_grad(guesses, truths) ``` thinc-9.0.0/website/docs/api-model.md000066400000000000000000001220561461023342500174160ustar00rootroot00000000000000--- title: Model next: /docs/api-layers --- Thinc uses just one model class for almost all layer types. Instead of creating subclasses, you'll usually instantiate the `Model` class directly, passing in a `forward` function that actually performs the computation. You can find examples of this in the library itself, in [`thinc.layers`](https://github.com/explosion/thinc/blob/master/thinc/layers) (also see the [layers documentation](/docs/api-layers)). | | | | ---------------------- | ------------------------------------------------------------------------------------------------ | | [**Model**](#model) | Class for implementing Thinc models and layers. | | [**Utilities**](#util) | Helper functions for implementing models. | | [**Shim**](#shim) | Interface for external models. Users can create subclasses of `Shim` to wrap external libraries. | ## Model {#model tag="class"} Class for implementing Thinc models and layers. There's only one `Model` class in Thinc and layers are built using **composition**, not inheritance. This means that a [layer](/docs/api-layers) or composed model will return an **instance** of `Model` โ€“ it doesn't subclass it. To read more about this concept, see the pages on [Thinc's philosophy](/docs/concept) and [defining models](/docs/usage-models). ### Typing {#typing} `Model` can be used as a [generic type](https://docs.python.org/3/library/typing.html#generics) with two parameters: the expected input and expected output. For instance, `Model[List[Floats2d], Floats2d]` denotes a model that takes a list of two-dimensional arrays of floats as inputs and outputs a two-dimensional array of floats. A mismatch will cause a type error. For more details, see the docs on [type checking](/docs/usage-type-checking). ```python from typing import List from thinc.api import Model from thinc.types import Floats2d def my_function(model: Model[List[Floats2d], Floats2d]): ... ``` ### Attributes {#attributes} | Name | Type | Description | | ------ | ------------ | --------------------------------- | | `name` | str | The name of the layer type. | | `ops` | Ops | Perform array operations. | | `id` | int | ID number for the model instance. | ### Properties {#properties} | Name | Type | Description | | ------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `layers` | List[Model] | A list of child layers of the model. You can use the list directly, including modifying it in-place: the standard way to add a layer to a model is simply `model.layers.append(layer)`. However, you cannot reassign the `model.layers` attribute to a new variable: `model.layers = []` will fail. | | `shims` | List[Shim] | A list of child shims added to the model. | | `attrs` | Dict[str, Any] | The model attributes. You can use the dict directly and assign _to_ it โ€“ but you cannot reassign `model.attrs` to a new variable: `model.attrs = {}` will fail. | | `param_names` | Tuple[str, ...] | Get the names of registered parameter (including unset). | | `grad_names` | Tuple[str, ...] | Get the names of parameters with registered gradients (including unset). | | `dim_names` | Tuple[str, ...] | Get the names of registered dimensions (including unset). | | `ref_names` | Tuple[str, ...] | Get the names of registered node references (including unset). | ### Model.\_\_init\_\_ {#init tag="method"} Initialize a new model. ```python ### Example model = Model( "linear", linear_forward, init=linear_init, dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) ``` | Argument | Type | Description | | -------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `name` | str | The name of the layer type. | | `forward` | Callable | Function to compute the forward result and the backpropagation callback. | | _keyword-only_ | | | | `init` | Callable | Function to define the initialization logic. | | `dims` | Dict[str, Optional[int]] | Dictionary describing the model's dimensions. Map unknown dimensions to `None`. | | `params` | Dict[str, Optional[FloatsXd]] | Dictionary with the model's parameters. Set currently unavailable parameters to `None`. | | `refs` | Dict[str, Optional[Model]] | Dictionary mapping specific nodes (sublayers) of the network to a name. | | `attrs` | Dict[str, Any] | Dictionary of non-parameter attributes. | | `layers` | List[Model] | List of child layers. | | `shims` | List[Shim] | List of interfaces for external models. | | `ops` | Optional[Union[NumpyOps, AppleOps, CupyOps, MPSOps]] | An `Ops` instance, which provides mathematical and memory operations. | ### Model.define_operators {#define_operators tag="classmethod,contextmanager"} Bind arbitrary binary functions to Python operators, for use in any `Model` instance. The method can (and should) be used as a contextmanager, so that the overloading is limited to the immediate block. This allows concise and expressive model definition. The following operators are supported: `+`, `-`, `*`, `@`, `/`, `//`, `%`, `**`, `<<`, `>>`, `&`, `^` and `|`. ```python ### Example from thinc.api import Model, Relu, Softmax, chain with Model.define_operators({">>": chain}): model = Relu(512) >> Relu(512) >> Softmax() ``` | Argument | Type | Description | | ----------- | ---------------------------- | ------------------------------ | | `operators` | Dict[str, Callable] | Functions mapped to operators. | ### Model.initialize {#initialize tag="method"} Finish initialization of the model, optionally providing a batch of example input and output data to perform shape inference. Until `Model.initialize` is called, the model may not be in a ready state to operate on data: parameters or dimensions may be unset. The `Model.initialize` method will usually delegate to the `init` function given to [`Model.__init__`](#init). If sample data is provided, it will be validated against the type annotations of the `forward` function, if available. A [`DataValidationError`](/docs/api-util#errors) is raised in case of a mismatch, e.g. if the forward pass expects a two-dimensional array but the model is initialized with a three-dimensional array. ```python ### Example from thinc.api import Linear, zero_init import numpy X = numpy.zeros((128, 16), dtype="f") Y = numpy.zeros((128, 10), dtype="f") model = Linear(init_W=zero_init) model.initialize(X=X, Y=Y) ``` | Argument | Type | Description | | ----------- | ---------------------- | -------------------------------- | | `X` | Optional[Any] | An example batch of input data. | | `Y` | Optional[Any] | An example batch of output data. | | **RETURNS** | Model | The model instance. | ### Model.\_\_call\_\_ {#call tag="method"} Call the model's `forward` function, returning the output and a callback to compute the gradients via backpropagation. ```python ### Example from thinc.api import Linear import numpy X = numpy.zeros((128, 10), dtype="f") model = Linear(10) model.initialize(X=X) Y, backprop = model(X, is_train=True) ``` | Argument | Type | Description | | ----------- | ----------------------------- | --------------------------------------------------------------------------------------------------- | | `X` | Any | A batch of input data. | | `is_train` | bool | A boolean indicating whether the model is running in a training (as opposed to prediction) context. | | **RETURNS** | Tuple[Any, Callable] | A batch of output data and the `backprop` callback. | ### Model.begin_update {#begin_update tag="method"} Call the model's `forward` function with `is_train=True`, and return the output and the backpropagation callback, which is a function that takes a gradient of outputs and returns the corresponding gradient of inputs. The backpropagation callback may also increment the gradients of the model parameters, via calls to [`Model.inc_grad`](#inc_grad). ```python ### Example from thinc.api import Linear import numpy X = numpy.zeros((128, 10), dtype="f") model = Linear(10) model.initialize(X=X) Y, backprop = model.begin_update(X) ``` | Argument | Type | Description | | ----------- | ----------------------------- | --------------------------------------------------- | | `X` | Any | A batch of input data. | | **RETURNS** | Tuple[Any, Callable] | A batch of output data and the `backprop` callback. | ### Model.predict {#predict tag="method"} Call the model's `forward` function with `is_train=False`, and return only the output, instead of the `(output, callback)` tuple. ```python ### Example from thinc.api import Linear import numpy X = numpy.zeros((128, 10), dtype="f") model = Linear(10) model.initialize(X=X) Y = model.predict(X) ``` | Argument | Type | Description | | ----------- | ------------ | ----------------------- | | `X` | Any | A batch of input data. | | **RETURNS** | Any | A batch of output data. | ### Model.finish_update {#finish_update tag="method"} Update parameters using the current parameter gradients. The [`Optimizer` instance](/docs/api-optimizers) contains the functionality to perform the stochastic gradient descent. ```python ### Example from thinc.api import Adam, Linear optimizer = Adam() model = Linear(10) model.finish_update(optimizer) ``` | Argument | Type | Description | | ----------- | ------------------ | ----------------------------------------------------------------------------- | | `optimizer` | Optimizer | The optimizer, which is called with each parameter and gradient of the model. | ### Model.use_params {#use_params tag="contextmanager"} Contextmanager to temporarily set the model's parameters to specified values. | Argument | Type | Description | | -------- | ---------------------------- | -------------------------------------------------------------------------- | | `params` | Dict[int, FloatsXd] | A dictionary keyed by model IDs, whose values are arrays of weight values. | ### Model.walk {#walk tag="method"} Iterate out layers of the model, in breadth-first order. ```python ### Example from thinc.api import Relu model = Relu(512, normalize=True) for node in model.walk(): print(node.name) ``` ![](images/layer-traversal.svg) The `walk` method supports three iteration orders through the `order` argument: - `"bfs"`: breadth-first. Iteration order of the example above: _1 - 2 - 4 - 3 - 5_ - `"dfs_pre"`: depth-first preorder, outputs a node before its children. Iteration order of the example above: _1 - 2 - 3 - 4 - 5_ - `"dfs_post"`: depth-first postorder, outputs children before a node itself. Iteration order of the example above: _3 - 2 - 5 - 4 - 1_ | Argument | Type | Description | | ----------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | | `order` | str | Node iteration order. `"bfs"` (breadth-first), `"dfs_pre"` (depth-first preorder), `"dfs_post"` (depth-first postorder) Default: `"bfs"`. | | **RETURNS** | Iterable[Model] | The layers of the model. | ### Model.remove_node {#remove_node tag="method"} Remove a node from all layers lists, and then update references. References that no longer point to a node within the tree will be set to `None`. For instance, if a node has its grandchild as a reference and the child is removed, the grandchild reference will be left dangling, so will be set to `None`. | Argument | Type | Description | | -------- | -------------- | ------------------- | | `node` | Model | The node to remove. | ### Model.has_dim {#has_dim tag="method"} Check whether the model has a dimension of a given name. If the dimension is registered but the value is unset, returns `None`. ```python ### Example from thinc.api import Linear import numpy model = Linear(10) assert model.has_dim("nI") is None model.initialize(X=numpy.zeros((128, 16), dtype="f")) assert model.has_dim("nI") is True ``` | Argument | Type | Description | | ----------- | ----------------------- | --------------------------------------------- | | `name` | str | The name of the dimension, e.g. `"nO"`. | | **RETURNS** | Optional[bool] | A ternary value (`True`, `False`, or `None`). | ### Model.get_dim {#get_dim tag="method"} Retrieve the value of a dimension of the given name. Raises a `KeyError` if the dimension is either unregistered or the value is currently unset. ```python ### Example from thinc.api import Linear import numpy model = Linear(10) model.initialize(X=numpy.zeros((128, 16), dtype="f")) assert model.get_dim("nI") == 16 ``` | Argument | Type | Description | | ----------- | ------------ | --------------------------------------- | | `name` | str | The name of the dimension, e.g. `"nO"`. | | **RETURNS** | int | The size of the dimension. | ### Model.maybe_get_dim {#get_dim tag="method"} Retrieve the value of a dimension of the given name, or `None` if the dimension is either unregistered or the value is currently unset. | Argument | Type | Description | | ----------- | ---------------------- | --------------------------------------- | | `name` | str | The name of the dimension, e.g. `"nO"`. | | **RETURNS** | Optional[int] | The size of the dimension, or `None`. | ### Model.set_dim {#set_dim tag="method"} Set a value for a dimension. This raises a `ValueError` if the dimension was previously defined with a different value, unless `force` is set to `True`. ```python ### Example from thinc.api import Linear model = Linear(10) model.set_dim("nI", 16) assert model.get_dim("nI") == 16 ``` | Argument | Type | Description | | -------- | ------------- | ----------------------------------------------------------------------------------------------------- | | `name` | str | The name of the dimension to set. | | `value` | int | The new value for the dimension. | | `force` | bool | When set to `True`, allow changing the value of the dimension if it was set before. Default: `False`. | ### Model.has_param {#has_param tag="method"} Check whether the model has a weights parameter of the given name. Returns `None` if the parameter is registered but currently unset. ```python ### Example from thinc.api import Linear, zero_init import numpy model = Linear(10, init_W=zero_init) assert model.has_param("W") is None model.initialize(X=numpy.zeros((128, 16), dtype="f")) assert model.has_param("W") is True ``` | Argument | Type | Description | | ----------- | ----------------------- | --------------------------------------------- | | `name` | str | The name of the parameter. | | **RETURNS** | Optional[bool] | A ternary value (`True`, `False`, or `None`). | ### Model.get_param {#get_param tag="method"} Retrieve a weights parameter by name. Raises a `KeyError` if the parameter is unregistered or its value is undefined. ```python ### Example from thinc.api import Linear, zero_init import numpy model = Linear(10, init_W=zero_init) assert model.has_param("W") is None model.initialize(X=numpy.zeros((128, 16), dtype="f")) W = model.get_param("W") assert W.shape == (10, 16) ``` | Argument | Type | Description | | ----------- | ----------------- | --------------------------------- | | `name` | str | The name of the parameter to get. | | **RETURNS** | FloatsXd | The current parameter. | ### Model.maybe_get_param {#maybe_get_param tag="method"} Retrieve a weights parameter by name. Returns `None` if the parameter is unregistered or its value is undefined. | Argument | Type | Description | | ----------- | --------------------------- | --------------------------------- | | `name` | str | The name of the parameter to get. | | **RETURNS** | Optional[FloatsXd] | The current parameter, or `None`. | ### Model.set_param {#set_param tag="method"} Set a weights parameter's value. ```python ### Example from thinc.api import Linear, zero_init import numpy model = Linear(10, init_W=zero_init) assert model.has_param("W") is None model.set_param("W", numpy.zeros((10, 16), dtype="f")) assert model.has_param("W") is True ``` | Argument | Type | Description | | -------- | --------------------------- | --------------------------------------------- | | `name` | str | The name of the parameter to set a value for. | | `value` | Optional[FloatsXd] | The new value of the parameter. | ### Model.has_ref {#has_ref tag="method"} Check whether the model has a reference of a given name. If the reference is registered but the value is unset, returns `None`. | Argument | Type | Description | | ----------- | ----------------------- | --------------------------------------------- | | `name` | str | The name of the reference. | | **RETURNS** | Optional[bool] | A ternary value (`True`, `False`, or `None`). | ### Model.get_ref {#get_ref tag="method"} Retrieve the value of a reference of the given name. Raises a `KeyError` if unset. | Argument | Type | Description | | ----------- | -------------- | -------------------------- | | `name` | str | The name of the reference. | | **RETURNS** | Model | The reference. | ### Model.maybe_get_ref {#maybe_get_ref tag="method"} Retrieve the value of a reference of the given name, or None if unset. | Argument | Type | Description | | ----------- | ------------------------ | -------------------------- | | `name` | str | The name of the reference. | | **RETURNS** | Optional[Model] | The reference, or `None`. | ### Model.set_ref {#set_ref tag="method"} Set a value for a reference. | Argument | Type | Description | | -------- | ------------------------ | -------------------------------- | | `name` | str | The name of the reference. | | `value` | Optional[Model] | The new value for the attribute. | ### Model.has_grad {#has_grad tag="method"} Check whether the model has a non-zero gradient for the given parameter. If the gradient is allocated but is zeroed, returns `None`. | Argument | Type | Description | | ----------- | ----------------------- | --------------------------------------------- | | `name` | str | The parameter to check the gradient for. | | **RETURNS** | Optional[bool] | A ternary value (`True`, `False`, or `None`). | ### Model.get_grad {#get_grad tag="method"} Get the gradient for a parameter, if one is available. If the parameter is undefined or no gradient has been allocated, raises a `KeyError`. | Argument | Type | Description | | ----------- | ----------------- | -------------------------------------------------- | | `name` | str | The name of the parameter to get the gradient for. | | **RETURNS** | FloatsXd | The current gradient of the parameter. | ### Model.maybe_get_grad {#maybe_get_grad tag="method"} Get the gradient for a parameter, if one is available. If the parameter is undefined or no gradient has been allocated, returns `None`. | Argument | Type | Description | | ----------- | --------------------------- | -------------------------------------------------- | | `name` | str | The name of the parameter to get the gradient for. | | **RETURNS** | Optional[FloatsXd] | The current gradient of the parameter, or `None`. | ### Model.set_grad {#set_grad tag="method"} Set a parameter gradient to a new value. | Argument | Type | Description | | -------- | ----------------- | ----------------------------------------------------- | | `name` | str | The name of the parameter to assign the gradient for. | | `value` | FloatsXd | The new gradient. | ### Model.inc_grad {#inc_grad tag="method"} Increment the gradient of a parameter by `value`. | Argument | Type | Description | | -------- | ----------------- | --------------------------------- | | `name` | str | The name of the parameter. | | `value` | FloatsXd | The value to add to its gradient. | ### Model.get_gradients {#get_gradients tag="method"} Get non-zero gradients of the model's parameters, as a dictionary keyed by the parameter ID. The values are `(weights, gradients)` tuples. | Argument | Type | Description | | ----------- | --------------------------------------------------------- | ------------------------------------ | | **RETURNS** | Dict[Tuple[int, str], Tuple[FloatsXd, FloatsXd]] | The gradients keyed by parameter ID. | ### Model.copy {copy# tag="method"} Create a copy of the model, its attributes, and its parameters. Any child layers will also be deep-copied. The copy will receive a distinct `model.id` value. ```python ### Example from thinc.api import Linear model = Linear() model_copy = model.copy() ``` | Argument | Type | Description | | ----------- | -------------- | ------------------------ | | **RETURNS** | Model | A new copy of the model. | ### Model.to_gpu {#to_gpu tag="method"} Transfer the model to a given GPU device. ```python ### Example device = model.to_gpu(0) ``` | Argument | Type | Description | | ----------- | ------------------------- | ----------------------- | | `gpu_id` | int | Device index to select. | | **RETURNS** | cupy.cuda.Device | The device. | ### Model.to_cpu {#to_cpu tag="method"} Copy the model to CPU. ```python ### Example model.to_cpu() ``` ### Model.to_dict {#to_dict tag="method"} Serialize the model to a Python dictionary. `Model.to_bytes` delegates to this method to create the dict, which it then dumps with MessagePack. Serialization should round-trip identically, i.e. the same dict should result from loading and serializing a model. ```python ### Example model_data = model.to_dict() ``` | Argument | Type | Description | | ----------- | ------------- | --------------------- | | **RETURNS** | dict | The serialized model. | ### Model.from_dict {#from_dict tag="method"} Load the model from a Python dictionary. ```python ### Example model_data = model.to_dict() model = Model("model_name", forward).from_dict(model_data) ``` | Argument | Type | Description | | ----------- | -------------- | ----------------- | | `msg` | dict | The data to load. | | **RETURNS** | Model | The loaded model. | ### Model.to_bytes {#to_bytes tag="method"} Serialize the model to a bytes representation. Models are usually serialized using `msgpack`, so you should be able to call `msgpack.loads()` on the data and get back a dictionary with the contents. Serialization should round-trip identically, i.e. the same bytes should result from loading and serializing a model. ```python ### Example bytes_data = model.to_bytes() ``` | Argument | Type | Description | | ----------- | -------------- | --------------------- | | **RETURNS** | bytes | The serialized model. | ### Model.from_bytes {#from_bytes tag="method"} Deserialize the model from a bytes representation. Models are usually serialized using `msgpack`, so you should be able to call `msgpack.loads()` on the data and get back a dictionary with the contents. Serialization should round-trip identically, i.e. the same bytes should result from loading and serializing a model. ```python ### Example bytes_data = model.to_bytes() model = Model("model_name", forward).from_bytes(bytes_data) ``` | Argument | Type | Description | | ------------ | -------------- | ----------------------- | | `bytes_data` | bytes | The bytestring to load. | | **RETURNS** | Model | The loaded model. | ### Model.to_disk {#to_disk tag="method"} Serialize the model to disk. Most models will serialize to a single file, which should just be the bytes contents of [`Model.to_bytes`](#to_bytes). ```python ### Example model.to_disk("/path/to/model") ``` | Argument | Type | Description | | -------- | ------------------------- | --------------------------------------- | | ย `path` | Union[Path, str] | File or directory to save the model to. | ### Model.from_disk {#from_disk tag="method"} Deserialize the model from disk. Most models will serialize to a single file, which should just be the bytes contents of [`Model.to_bytes`](#to_bytes). ```python ### Example model = Model().from_disk("/path/to/model") ``` | Argument | Type | Description | | ----------- | ------------------------- | --------------------------------- | | ย `path` | Union[Path, str] | Directory to load the model from. | | **RETURNS** | Model | The loaded model. | ### Model.can_from_bytes {#can_from_bytes tag="method"} Check whether bytes data is compatible with the model for deserialization. | Argument | Type | Description | | ------------- | -------------- | --------------------------------------- | | ย `bytes_data` | bytes | The bytestring to check. | | ย `strict` | bool | Whether to require attributes to match. | | **RETURNS** | bool | Whether the data is compatible. | ### Model.can_from_bytes {#can_from_bytes tag="method"} Check whether a path is compatible with the model for deserialization. | Argument | Type | Description | | ----------- | ------------------------- | --------------------------------------- | | ย `path` | Union[Path, str] | The path to check. | | ย `strict` | bool | Whether to require attributes to match. | | **RETURNS** | Model | Whether the path is compatible. | ### Model.can_from_dict {#from_dict tag="method"} Check whether a dictionary is compatible with the model for deserialization. | Argument | Type | Description | | ----------- | -------------- | --------------------------------------- | | `msg` | dict | The data to check. | | `strict` | bool | Whether to require attributes to match. | | **RETURNS** | Model | Whether the data is compatible. | --- ## Utilities {#util} ### serialize_attr {#serialize_attr tag="function,single-dispatch"} [Single-dispatch generic function](https://docs.python.org/3/library/functools.html#functools.singledispatch) that serializes a model attribute in `Model.attrs` to bytes and can be customized to support other objects and data types. By default, the function uses MessagePack to serialize the attribute value to bytes. To register a serialization function for a custom type, you can use the `@serialize_attr.register` decorator and call it with the custom type. If an attribute of that type exists on a model, the registered function will be used to serialize it. ```python ### Example from thinc.api import serialize_attr @serialize_attr.register(MyCustomClass) def serialize_my_custom_class(_, value: MyCustomClass, name: str, model) -> bytes: # value is an instance of MyCustomClass that needs to be serialized. You # can perform any custom serialization here and return bytes return value.custom_serialization_method() ``` | Argument | Type | Description | | ----------- | -------------- | --------------------------------------------------------------------------------------------------------------------------- | | `_` | Any | An instance of the value to serialize. Its type will be used to determine which registered serialization function to apply. | | `value` | Any | The value to serialize. | | `name` | str | The attribute name. | | `model` | Model | The model that's being serialized, e.g. to retrieve other information. | | **RETURNS** | bytes | The serialized attribute. | ### deserialize_attr {#deserialize_attr tag="function,single-dispatch"} [Single-dispatch generic function](https://docs.python.org/3/library/functools.html#functools.singledispatch) that deserializes a model attribute in `Model.attrs` from bytes and can be customized to support other objects and data types. By default, the function uses MessagePack to load the attribute value from bytes. To register a deserialization function for a custom type, you can use the `@deserialize_attr.register` decorator and call it with the custom type. If an attribute of that type exists on a model, the registered function will be used to deserialize it. ```python ### Example from thinc.api import deserialize_attr @deserialize_attr.register(MyCustomClass) def deserialize_my_custom_class(_, value: bytes, name: str, model) -> MyCustomClass: # value is a bytestring that needs to be deserialized and transformed into # MyCustomClass. You can perform any custom deserialization here and return # an instance of MyCustomClass. return MyCustomClass().custom_load_method(value) ``` Since the type of the attribute is used to determine the deserialization function to use, attributes of custom types need **a default value of the same type**. For example, creating a `Model` with `attrs={"custom_attr": None}` won't work, because there's no way to tell that the attribute should be an instance of `MyCustomClass` (and deserialized as such). Using `attrs={"custom_attr": MyCustomClass()}` makes this clear and also means you won't have to handle `None` attrs in your model. | Argument | Type | Description | | ----------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_` | Any | An instance of the value to deserialize (the default value of the attribute). Its type will be used to determine which registered deserialization function to apply. | | `value` | bytes | The bytestring to load. | | `name` | str | The attribute name. | | `model` | Model | The model that's being deserialized, e.g. to perform other side-effects. | | **RETURNS** | Any | The loaded attribute. | --- ## Shim {#shim tag="class"} Define a basic interface for external models. Users can create subclasses of `Shim` to wrap external libraries. The Thinc `Model` class treats `Shim` objects as a sort of special type of sublayer: it knows they're not actual Thinc `Model` instances, but it also knows to talk to the shim instances when doing things like using transferring between devices, loading in parameters, optimization. It also knows `Shim` objects need to be serialized and deserialized with to/from bytes/disk, rather than expecting that they'll be `msgpack`-serializable. A `Shim` can implement the following methods: | Method | Description | | ---------------- | ------------------------------------------------------------------------------------------------------ | | ย `__init__` | Initialize the model. | | ย `__call__` | Call the model and return the output and a callback to compute the gradients via backpropagation. | | ย `predict` | Call the model and return only the output, instead of the `(output, callback)` tuple. | | ย `begin_update` | Run the model over a batch of data, returning the output and a callback to complete the backward pass. | | ย `finish_update` | Update parameters with current gradients. | | ย `use_params` | Context manager to temporarily set the model's parameters to specified values. | | ย `to_gpu` | Transfer the model to a given GPU device. | | ย `to_cpu` | Copy the model to CPU. | | ย `to_bytes` | Serialize the model to bytes. | | ย `from_bytes` | Load the model from bytes. | | ย `to_disk` | Serialize the model to disk. Defaults to writing the bytes representation to a file. | | ย `from_disk` | Load the model from disk. Defaults to loading the byte representation from a file. | ### Available shims {#shims} A shim container is **not** a Thinc `Model` subclass itself, it's a subclass of `Shim`. | | | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `PyTorchShim` | Interface between a [PyTorch](https://pytorch.org) model and a Thinc `Model`. For more details and examples, see the [`PyTorchWrapper` layer](/docs/api-layers#pytorchwrapper) and docs on [integrating other frameworks](/docs/usage-frameworks). | | `TorchScriptShim` | Interface between a [TorchScript](https://pytorch.org/docs/stable/jit.html) model and a Thinc `Model`. For more details and examples, see the [`TorchScriptWrapper` layer](/docs/api-layers#torchscriptwrapper) and docs on [integrating other frameworks](/docs/usage-frameworks). | | `TensorFlowShim` | Interface between a [TensorFlow](https://tensorflow.org) model and a Thinc `Model`. For more details, see the [`TensorFlowWrapper` layer](/docs/api-layers#tensorflowwrapper) and docs on [integrating other frameworks](/docs/usage-frameworks) | | `MXNetShim` | Interface between a [MXNet](https://mxnet.apache.org/) model and a Thinc `Model`. For more details, see the [`MXNetWrapper` layer](/docs/api-layers#mxnetwrapper) and docs on [integrating other frameworks](/docs/usage-frameworks) | thinc-9.0.0/website/docs/api-optimizers.md000066400000000000000000000300601461023342500205140ustar00rootroot00000000000000--- title: Optimizers next: /docs/api-initializers --- An optimizer essentially performs stochastic gradient descent. It takes one-dimensional arrays for the weights and their gradients, along with an optional identifier key. The optimizer is expected to update the weights and zero the gradients in place. The optimizers are registered in the [function registry](/docs/api-config#registry) and can also be used via Thinc's [config mechanism](/docs/usage-config). ## Optimizer functions ### SGD {#sgd tag="function"} Function to create a SGD optimizer. If a hyperparameter specifies a schedule, the step that is passed to the schedule will be incremented on each call to [`Optimizer.step_schedules`](#step-schedules). ```python ### Example {small="true"} from thinc.api import SGD optimizer = SGD( learn_rate=0.001, L2=1e-6, grad_clip=1.0 ) ``` ```ini ### config.cfg {small="true"} [optimizer] @optimizers = SGD.v1 learn_rate = 0.001 L2 = 1e-6 L2_is_weight_decay = true grad_clip = 1.0 use_averages = true ``` | Argument | Type | Description | | -------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------- | | `learn_rate` | Union[float, List[float], Generator] | The initial learning rate. | | _keyword-only_ | | | | `L2` | Union[float, List[float], Generator] | The L2 regularization term. | | `grad_clip` | Union[float, List[float], Generator] | Gradient clipping. | | `use_averages` | bool | Whether to track moving averages of the parameters. | | `L2_is_weight_decay` | bool | Whether to interpret the L2 parameter as a weight decay term, in the style of the AdamW optimizer. | | `ops` | Optional[Ops] | A backend object. Defaults to the currently selected backend. | ### Adam {#adam tag="function"} Function to create an Adam optimizer. Returns an instance of [`Optimizer`](#optimizer). If a hyperparameter specifies a schedule, the step that is passed to the schedule will be incremented on each call to [`Optimizer.step_schedules`](#step-schedules). ```python ### Example {small="true"} from thinc.api import Adam optimizer = Adam( learn_rate=0.001, beta1=0.9, beta2=0.999, eps=1e-08, L2=1e-6, grad_clip=1.0, use_averages=True, L2_is_weight_decay=True ) ``` ```ini ### config.cfg {small="true"} [optimizer] @optimizers = Adam.v1 learn_rate = 0.001 beta1 = 0.9 beta2 = 0.999 eps = 1e-08 L2 = 1e-6 L2_is_weight_decay = true grad_clip = 1.0 use_averages = true ``` | Argument | Type | Description | | -------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------- | | `learn_rate` | Union[float, List[float], Generator] | The initial learning rate. | | _keyword-only_ | | | | `L2` | Union[float, List[float], Generator] | The L2 regularization term. | | `beta1` | Union[float, List[float], Generator] | First-order momentum. | | `beta2` | Union[float, List[float], Generator] | Second-order momentum. | | `eps` | Union[float, List[float], Generator] | Epsilon term for Adam etc. | | `grad_clip` | Union[float, List[float], Generator] | Gradient clipping. | | `use_averages` | bool | Whether to track moving averages of the parameters. | | `L2_is_weight_decay` | bool | Whether to interpret the L2 parameter as a weight decay term, in the style of the AdamW optimizer. | | `ops` | Optional[Ops] | A backend object. Defaults to the currently selected backend. | ### RAdam {#radam tag="function"} Function to create an RAdam optimizer. Returns an instance of [`Optimizer`](#optimizer). If a hyperparameter specifies a schedule, the step that is passed to the schedule will be incremented on each call to [`Optimizer.step_schedules`](#step-schedules). ```python ### Example {small="true"} from thinc.api import RAdam optimizer = RAdam( learn_rate=0.001, beta1=0.9, beta2=0.999, eps=1e-08, weight_decay=1e-6, grad_clip=1.0, use_averages=True, ) ``` ```ini ### config.cfg {small="true"} [optimizer] @optimizers = RAdam.v1 learn_rate = 0.001 beta1 = 0.9 beta2 = 0.999 eps = 1e-08 weight_decay = 1e-6 grad_clip = 1.0 use_averages = true ``` | Argument | Type | Description | | -------------- | --------------------------------------------- | ------------------------------------------------------------- | | `learn_rate` | Union[float, List[float], Generator] | The initial learning rate. | | _keyword-only_ | | | | `beta1` | Union[float, List[float], Generator] | First-order momentum. | | `beta2` | Union[float, List[float], Generator] | Second-order momentum. | | `eps` | Union[float, List[float], Generator] | Epsilon term for Adam etc. | | `weight_decay` | Union[float, List[float], Generator] | Weight decay term. | | `grad_clip` | Union[float, List[float], Generator] | Gradient clipping. | | `use_averages` | bool | Whether to track moving averages of the parameters. | | `ops` | Optional[Ops] | A backend object. Defaults to the currently selected backend. | --- ## Optimizer {tag="class"} Do various flavors of stochastic gradient descent, with first and second order momentum. Currently support "vanilla" SGD, Adam, and RAdam. ### Optimizer.\_\_init\_\_ {#init tag="method"} Initialize an optimizer. If a hyperparameter specifies a schedule, the step that is passed to the schedule will be incremented on each call to [`Optimizer.step_schedules`](#step-schedules). ```python ### Example from thinc.api import Optimizer optimizer = Optimizer(learn_rate=0.001, L2=1e-6, grad_clip=1.0) ``` | Argument | Type | Description | | -------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------- | | `learn_rate` | Union[float, List[float], Generator] | The initial learning rate. | | _keyword-only_ | | | | `L2` | Union[float, List[float], Generator] | The L2 regularization term. | | `beta1` | Union[float, List[float], Generator] | First-order momentum. | | `beta2` | Union[float, List[float], Generator] | Second-order momentum. | | `eps` | Union[float, List[float], Generator] | Epsilon term for Adam etc. | | `grad_clip` | Union[float, List[float], Generator] | Gradient clipping. | | `use_averages` | bool | Whether to track moving averages of the parameters. | | `use_radam` | bool | Whether to use the RAdam optimizer. | | `L2_is_weight_decay` | bool | Whether to interpret the L2 parameter as a weight decay term, in the style of the AdamW optimizer. | | `ops` | Optional[Ops] | A backend object. Defaults to the currently selected backend. | ### Optimizer.\_\_call\_\_ {#call tag="method"} Call the optimizer function, updating parameters using the current parameter gradients. The `key` is the identifier for the parameter, usually the node ID and parameter name. | Argument | Type | Description | | -------------- | ------------------------ | --------------------------------------------- | | `key` | Tuple[int, str] | The parameter identifier. | | `weights` | FloatsXd | The model's current weights. | | `gradient` | FloatsXd | The model's current gradient. | | _keyword-only_ | | | | `lr_scale` | float | Rescale the learning rate. Defaults to `1.0`. | ### Optimizer.step_schedules {#step_schedules tag="method"} Increase the current step of the optimizer. This step will be used by schedules to determine their next value. ```python ### Example from thinc.api import Optimizer, decaying optimizer = Optimizer(learn_rate=decaying(0.001, 1e-4), grad_clip=1.0) assert optimizer.learn_rate == 0.001 optimizer.step_schedules() assert optimizer.learn_rate == 0.000999900009999 # using a schedule assert optimizer.grad_clip == 1.0 # not using a schedule ``` ### Optimizer.to_gpu {#to_gpu tag="method"} Transfer the optimizer to a given GPU device. ```python ### Example optimizer.to_gpu() ``` ### Optimizer.to_cpu {#to_cpu tag="method"} Copy the optimizer to CPU. ```python ### Example optimizer.to_cpu() ``` ### Optimizer.to_gpu {#to_gpu tag="method"} Transfer the optimizer to a given GPU device. ```python ### Example optimizer.to_gpu() ``` ### Optimizer.to_cpu {#to_cpu tag="method"} Copy the optimizer to CPU. ```python ### Example optimizer.to_cpu() ``` thinc-9.0.0/website/docs/api-schedules.md000066400000000000000000000301071461023342500202700ustar00rootroot00000000000000--- title: Schedules next: /docs/api-loss --- Schedules are generators that provide different rates, schedules, decays or series. They're typically used for batch sizes or learning rates. You can easily implement your own schedules as well: just write your own [`Schedule`](#schedule) implementation, that produces whatever series of values you need. A common use case for schedules is within [`Optimizer`](/docs/api-optimizer) objects, which accept iterators for most of their parameters. See the [training guide](/docs/usage-training) for details. ## Schedule {#schedule tag="class" new="9"} Class for implementing Thinc schedules. There's only one `Schedule` class in Thinc and schedules are built using **composition**, not inheritance. This means that a schedule or composed schedule will return an **instance** of `Schedule` โ€“ it doesn't subclass it. To read more about this concept, see the pages on [Thinc's philosophy](/docs/concept). ### Typing {#typing} `Schedule` can be used as a [generic type](https://docs.python.org/3/library/typing.html#generics) with one parameter. This parameter specifies the type that is returned by the schedule. For instance, `Schedule[int]` denotes a scheduler that returns integers when called. A mismatch will cause a type error. For more details, see the docs on [type checking](/docs/usage-type-checking). ```python from thinc.api import Schedule def my_function(schedule: Schedule[int]): ... ``` ### Attributes {#attributes} | Name | Type | Description | | ------ | ------------ | ------------------------------- | | `name` | str | The name of the scheduler type. | ### Properties {#properties} | Name | Type | Description | | ------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `attrs` | Dict[str, Any] | The scheduler attributes. You can use the dict directly and assign _to_ it โ€“ but you cannot reassign `schedule.attrs` to a new variable: `schedule.attrs = {}` will fail. | ### Schedule.\_\_init\_\_ {#init tag="method"} Initialize a new schedule. ```python ### Example schedule = Schedule( "constant", constant_schedule, attrs={"rate": rate}, ) ``` | Argument | Type | Description | | -------------- | ----------------------- | -------------------------------------------------------- | | `name` | str | The name of the schedule type. | | `schedule` | Callable | Function to compute the schedule value for a given step. | | _keyword-only_ | | | | `attrs` | Dict[str, Any] | Dictionary of non-parameter attributes. | ### Schedule.\_\_call\_\_ {#call tag="method"} Call the schedule function, returning the value for the given step. The `step` positional argument is always required. Some schedules may require additional keyword arguments. ```python ### Example from thinc.api import constant schedule = constant(0.1) assert schedule(0) == 0.1 assert schedule(1000) == 0.1 ``` | Argument | Type | Description | | ----------- | ------------ | ------------------------------------------ | | `step` | int | The step to compute the schedule for. | | `**kwargs` | | Optional arguments passed to the schedule. | | **RETURNS** | Any | The schedule value for the step. | ### Schedule.to_generator {#to_generator tag="method"} Turn the schedule into a generator by passing monotonically increasing step count into the schedule. ```python ### Example from thinc.api import constant g = constant(0.1).to_generator() assert next(g) == 0.1 assert next(g) == 0.1 ``` | Argument | Type | Description | | ----------- | ------------------------------------ | ------------------------------------------------------------------------------- | | `start` | int | The initial schedule step. Defaults to `0`. | | `step_size` | int | The amount to increase the step with for each generated value. Defaults to `1`. | | `**kwargs` | | Optional arguments passed to the schedule. | | **RETURNS** | Generator[OutT, None, None] | The generator. | ## constant {#constant tag="function"} Yield a constant rate. ![](images/schedules_constant.svg) ```python ### {small="true"} from thinc.api import constant batch_sizes = constant(0.001) batch_size = batch_sizes(step=0) ``` ```ini ### config {small="true"} [batch_size] @schedules = "constant.v1" rate = 0.001 ``` | Argument | Type | | ---------- | -------------- | | `rate` | float | | **YIELDS** | float | ## constant_then {#constant_then tag="function"} Yield a constant rate for N steps, before starting a schedule. ![](images/schedules_constant_then.svg) ```python ### {small="true"} from thinc.api import constant_then, decaying learn_rates = constant_then( 0.005, 1000, decaying(0.005, 1e-4) ) learn_rate = learn_rates(step=0) ``` ```ini ### config {small="true"} [learn_rates] @schedules = "constant_then.v1" rate = 0.005 steps = 1000 [learn_rates.schedule] @schedules = "decaying" base_rate = 0.005 decay = 1e-4 ``` | Argument | Type | | ---------- | ------------------------ | | `rate` | float | | `steps` | int | | `schedule` | Iterable[float] | | **YIELDS** | float | ## decaying {#decaying tag="function"} Yield an infinite series of linearly decaying values, following the schedule `base_rate * 1 / (1 + decay * t)`. ![](images/schedules_decaying.svg) ```python ### {small="true"} from thinc.api import decaying learn_rates = decaying(0.005, 1e-4) learn_rate = learn_rates(step=0) # 0.001 learn_rate = learn_rates(step=1) # 0.00999 ``` ```ini ### config {small="true"} [learn_rate] @schedules = "decaying.v1" base_rate = 0.005 decay = 1e-4 t = 0 ``` | Argument | Type | | -------------- | -------------- | | `base_rate` | float | | `decay` | float | | _keyword-only_ | | | `t` | int | | **YIELDS** | float | ## compounding {#compounding tag="function"} Yield an infinite series of compounding values. Each time the generator is called, a value is produced by multiplying the previous value by the compound rate. ![](images/schedules_compounding.svg) ```python ### {small="true"} from thinc.api import compounding batch_sizes = compounding(1.0, 32.0, 1.001) batch_size = batch_sizes(step=0) # 1.0 batch_size = batch_sizes(step=1) # 1.0 * 1.001 ``` ```ini ### config {small="true"} [batch_size] @schedules = "compounding.v1" start = 1.0 stop = 32.0 compound = 1.001 t = 0 ``` | Argument | Type | | -------------- | -------------- | | `start` | float | | `stop` | float | | `compound` | float | | _keyword-only_ | | | `t` | int | | **YIELDS** | float | ## warmup_linear {#warmup_linear tag="function"} Generate a series, starting from an initial rate, and then with a warmup period, and then a linear decline. Used for learning rates. ![](images/schedules_warmup_linear.svg) ```python ### {small="true"} from thinc.api import warmup_linear learn_rates = warmup_linear(0.01, 3000, 6000) learn_rate = learn_rates(step=0) ``` ```ini ### config {small="true"} [learn_rate] @schedules = "warmup_linear.v1" initial_rate = 0.01 warmup_steps = 3000 total_steps = 6000 ``` | Argument | Type | | -------------- | -------------- | | `initial_rate` | float | | `warmup_steps` | int | | `total_steps` | int | | **YIELDS** | float | ## slanted_triangular {#slanted_triangular tag="function"} Yield an infinite series of values according to [Howard and Ruder's (2018)](https://arxiv.org/abs/1801.06146) "slanted triangular learning rate" schedule. ![](images/schedules_slanted_triangular.svg) ```python ### {small="true"} from thinc.api import slanted_triangular learn_rates = slanted_triangular(0.1, 5000) learn_rate = learn_rates(step=0) ``` ```ini ### config {small="true"} [learn_rate] @schedules = "slanted_triangular.v1" max_rate = 0.1 num_steps = 5000 cut_frac = 0.1 ratio = 32 decay = 1.0 t = 0.1 ``` | Argument | Type | | -------------- | -------------- | | `max_rate` | float | | `num_steps` | int | | _keyword-only_ | | | `cut_frac` | float | | `ratio` | int | | `decay` | float | | `t` | float | | **YIELDS** | float | ## cyclic_triangular {#cyclic_triangular tag="function"} Linearly increasing then linearly decreasing the rate at each cycle. ![](images/schedules_cyclic_triangular.svg) ```python ### {small="true"} from thinc.api import cyclic_triangular learn_rates = cyclic_triangular(0.005, 0.001, 1000) learn_rate = learn_rates(step=0) ``` ```ini ### config {small="true"} [learn_rate] @schedules = "cyclic_triangular.v1" min_lr = 0.005 max_lr = 0.001 period = 1000 ``` | Argument | Type | | ---------- | -------------- | | `min_lr` | float | | `max_lr` | float | | `period` | int | | **YIELDS** | float | ## plateau {#plateau tag="function" new="9"} Yields values from the wrapped schedule, exponentially scaled by the number of times optimization has plateaued. The caller must pass model evaluation scores through the `last_score` argument for the scaling to be adjusted. The last evaluation score is passed through the `last_score` argument as a tuple (`last_score_step`, `last_score`). This tuple indicates when a model was last evaluated (`last_score_step`) and with what score (`last_score`). ```python ### {small="true"} from thinc.api import constant, plateau schedule = plateau(2, 0.5, constant(1.0)) assert schedule(step=0, last_score=(0, 1.0)) == 1.0 assert schedule(step=1, last_score=(1, 1.0)) == 1.0 assert schedule(step=2, last_score=(2, 1.0)) == 0.5 assert schedule(step=3, last_score=(3, 1.0)) == 0.5 assert schedule(step=4, last_score=(4, 1.0)) == 0.25 ``` ```ini ### config {small="true"} [learn_rate] @schedules = "plateau.v1" scale = 0.5 max_patience = 2 [learn_rate.shedule] @schedules = "constant.v1" rate = 1.0 ``` | Argument | Type | Description | | -------------- | ------------------------ | ------------------------------------------------------------------------------------- | ----------------------------------------------- | | `max_patience` | int | Number of evaluations without an improvement to consider the model to have plateaued. | | `scale` | float | | Scaling of the inner schedule after plateauing. | | `schedule` | Schedule[float] | | The schedule to wrap. | | **RETURNS** | Schedule[float] | | thinc-9.0.0/website/docs/api-types.md000066400000000000000000000261271461023342500174640ustar00rootroot00000000000000--- title: Types & Dataclasses teaser: Type annotations, data structures and more next: /docs/api-backends --- | | | | ------------------------------- | ----------------------------------------------------------------------- | | [**Types**](#types) | Custom type annotations for input/output types available in Thinc. | | [**Dataclasses**](#dataclasses) | Data structures for efficient processing, especially for sequence data. | ## Types {#types} | | | | ---------------------------------------------------------- | --------------------------------------------------------------------------- | | `Floats1d`, `Floats2d`, `Floats3d`, `Floats4d`, `FloatsXd` | 1d, 2d, 3d, 4d and any-d arrays of floats (`DTypesFloat`). | | `Ints1d`, `Ints2d`, `Ints3d`, `Ints4d`, `IntsXd` | 1d, 2d, 3d, 4d and any-d arrays of ints (`DTypesInt`). | | `Array1d`, `Array2d`, `Array3d`, `Array4d`, `ArrayXd` | 1d, 2d, 3d, 4d and any-d arrays of floats or ints. | | `List1d`, `List2d`, `List3d`, `List4d`, `ListXd` | Lists of 1d, 2d, 3d, 4d and any-d arrays (with same-type elements). | | `DTypesFloat` | Float data types: `"f"` or `"float32"`. | | `DTypesInt` | Integer data types: `"i"`, `"int32"`, `"int64"`, `"uint32"`, `"uint64"`. | | `DTypes` | Union of DTypesFloat and DTypesInt. | | `Shape` | An array shape. Equivalent to Tuple[int, ...]. | | `Xp` | `numpy` on CPU or `cupy` on GPU. Equivalent to Union[numpy, cupy]. | | `Generator` | Custom type for generators / iterators for better config validation. | | `Batchable` | Union[Pairs, Ragged, Padded, ArrayXd, List, Tuple]. | --- ## Dataclasses {#dataclasses} A dataclass is a **lightweight data structure**, similar in spirit to a named tuple, defined using the [`@dataclass`](https://docs.python.org/3/library/dataclasses.html#module-level-decorators-classes-and-functions) decorator introduced in Python 3.7 (and backported to 3.6). Thinc uses dataclasses for many situations that would otherwise be written with nested Python containers. Dataclasses work better with the type system, and often result in code that's **easier to read and test**. ### Ragged {#ragged tag="dataclass"} A batch of concatenated sequences, that vary in the size of their first dimension. `Ragged` allows variable-length sequence data to be contiguous in memory, without padding. Indexing into `Ragged` is just like indexing into the `lengths` array, except it returns a `Ragged` object with the accompanying sequence data. For instance, you can write `ragged[1:4]` to get a `Ragged` object with sequences `1`, `2` and `3`. Internally, the input data is reshaped into a two-dimensional array, to allow routines to operate on it consistently. The original data shape is stored, and the reshaped data is accessible via the `dataXd` property. | Member | Type | Description | | ------------ | ---------------- | --------------------------------------------------------- | | `data` | Array2d | The data array. | | `dataXd` | ArrayXd | The data array with the original shape. | | `data_shape` | Shape | The original data shape, with -1 for the first dimension. | | `lengths` | Ints1d | The sequence lengths. | ### Padded {#padded tag="dataclass"} A batch of padded sequences, sorted by decreasing length. The auxiliary array `size_at_t` indicates the length of the batch at each timestep, so you can do `data[:, :size_at_t[t]]` to shrink the batch. For instance, let's say you have a batch of four documents, of lengths `[6, 5, 2, 1]`. The `size_at_t` will be `[4, 3, 3, 3, 2, 1]`. The lengths array indicates the length of each row, and the indices indicates the original ordering. The `Padded` container is currently limited to two-dimensional array content (that is, a batch of sequences, where each timestep of each batch is a 2d array). This restriction will be relaxed in a future release. | Member | Type | Description | | ----------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `data` | Floats3d | A three-dimensional array, sorted by decreasing sequence length. The dimensions are timestep, batch item, row data. | | `site_at_t` | Ints1d | An array indicating how the batch can be truncated at different sequence lengths. You can do `data[:, :size_at_t[t]]` to get an unpadded batch. | | `lengths` | Ints1d | The sequence lengths. Applies to the reordered sequences, not the original ordering. So it'll be decreasing length. | | `indices` | Ints1d | Lists of indices indicating how to put the items back into original order. | ### Pairs {#pairs} A batch of paired data, for instance images and their captions, or pairs of texts to compare. Indexing operations are performed as though the data were transposed to make the batch the outer dimension. For instance, `pairs[:3]` will return `Pairs(pairs.one[:3], pairs.two[:3])`, i.e. a slice of the batch with the first three items, as a new `Pairs` object. ```python ### Example from thinc.types import Pairs pairs = Pairs([1, 2, 3, 4], [5, 6, 7, 8]) assert pairs.one == [1, 2, 3, 4] assert pairs[2] == Pairs(3, 7) assert pairs[2:4] == Pairs([3, 4], [7, 8]) ``` | Member | Type | Description | | ------ | ----------------- | -------------------- | | `one` | Sequence | The first sequence. | | `two` | Sequence | The second sequence. | ### SizedGenerator {#sizedgenerator tag="dataclass"} A custom dataclass for a generator that has a `__len__` and can repeatedly call the generator function. This is especially useful for batching (see [`Ops.minibatch`](/docs/api-backends#minibatch)) where you know the length of the data upfront, but still want to batch it as a stream and return a generator. Exposing a `__len__` attribute also makes it work seamlessly with progress bars like [`tqdm`](https://github.com/tqdm/tqdm) and similar tools. The underlying generator function is called _every time_ the sized generator is executed and won't be consumed. This allows defining the batching outside of the training loop. On each iteration, the data will be reshuffled and rebatched. ```python ### Example train_data = model.ops.multibatch(128, train_X, train_Y, shuffle=True) assert isinstance(train_data, SizedGenerator) for i in range(10): for X, Y in tqdm(train_data, leave=False): Yh, backprop = model.begin_update(X) ``` | Member | Type | Description | | ----------- | -------------------------------- | -------------------------------------------------------------- | | `get_items` | Callable[[], Generator] | The generator function. Available via the `__iter__` method. | | `length` | int | The length of the data. Available via the `__len__` attribute. | ### ArgsKwargs {#argskwargs tag="dataclass"} A tuple of `(args, kwargs)` that can be spread into some function f: `f(*args, **kwargs)`. Makes it easier to handle positional and keyword arguments that get passed around, especially for integrating custom models via a [`Shim`](/docs/api-model#shims). | Member | Type | Description | | -------- | ------------------------ | ------------------------------------------------------------------------------ | | `args` | Tuple[Any, ...] | The positional arguments. Can be passed into a function as `*ArgsKwargs.args`. | | `kwargs` | Dict[str, Any] | The keyword arguments. Can be passed into a function as `**ArgsKwargs.kwargs`. | #### ArgsKwargs.from_items {#argskwargs-from_items tag="classmethod"} Create an `ArgsKwargs` object from a sequence of `(key, value)` tuples, such as produced by `ArgsKwargs.items`. Each key should be either a string or an integer. Items with integer keys are added to the `args`, and items with string keys are added to the `kwargs`. The `args` are determined by sequence order, not the value of the integer. ```python ### Example from thinc.api import ArgsKwargs items = [(0, "value"), ("key", "other value"), (1, 15), ("foo", True)] ak = ArgsKwargs.from_items(items) assert ak.args == ("value", 15) assert ak.kwargs == {"key": "other value", "foo": True} ``` | Argument | Type | Description | | ----------- | ---------------------------------------------- | --------------------------- | | `items` | Sequence[Tuple[Union[int, str], Any]] | The items. | | **RETURNS** | ArgsKwargs | The `ArgsKwargs` dataclass. | #### ArgsKwargs.keys {#argskwargs-keys tag="method"} Yield indices from `ArgsKwargs.args`, followed by keys from `ArgsKwargs.kwargs`. | Argument | Type | Description | | ---------- | ------------------------ | -------------------------------------- | | **YIELDS** | Union[int, str] | The keys, `args` followed by `kwargs`. | #### ArgsKwargs.values {#argskwargs-values tag="method"} Yield values from `ArgsKwargs.args`, followed by keys from `ArgsKwargs.kwargs`. | Argument | Type | Description | | ---------- | ------------ | ---------------------------------------- | | **YIELDS** | Any | The values, `args` followed by `kwargs`. | #### ArgsKwargs.items {#argskwargs-items tag="method"} Yield `enumerate(ArgsKwargs.args)`, followed by `ArgsKwargs.kwargs.items()`. | Argument | Type | Description | | ---------- | ------------------------------------ | ---------------------------------------- | | **YIELDS** | Tuple[Union[int, str], Any] | The values, `args` followed by `kwargs`. | thinc-9.0.0/website/docs/api-util.md000066400000000000000000000241431461023342500172710ustar00rootroot00000000000000--- title: Utilities & Extras teaser: Helpers and utility functions --- ### fix_random_seed {#fix_random_seed tag="function"} Set the random seed for `random`, `numpy.random` and `cupy.random` (if available). Should be called at the top of a file or function. ```python ### Example from thinc.api import fix_random_seed fix_random_seed(0) ``` | Argument | Type | Description | | -------- | ------------ | -------------------------- | | `seed` | int | The seed. Defaults to `0`. | ### require_cpu {#require_cpu tag="function"} Allocate data and perform operations on CPU. If data has already been allocated on GPU, it will not be moved. Ideally, this function should be called right after importing Thinc. ```python ### Example from thinc.api import require_cpu require_cpu() ``` | Argument | Type | Description | | ----------- | ------------- | ----------- | | **RETURNS** | bool | `True`. | ### prefer_gpu {#prefer_gpu tag="function"} Allocate data and perform operations on GPU, if available. If data has already been allocated on CPU, it will not be moved. Ideally, this function should be called right after importing Thinc. ```python ### Example from thinc.api import prefer_gpu is_gpu = prefer_gpu() ``` | Argument | Type | Description | | ----------- | ------------- | ---------------------------------------- | | `gpu_id` | int | Device index to select. Defaults to `0`. | | **RETURNS** | bool | Whether the GPU was activated. | ### require_gpu {#require_gpu tag="function"} Allocate data and perform operations on GPU. Will raise an error if no GPU is available. If data has already been allocated on CPU, it will not be moved. Ideally, this function should be called right after importing Thinc. ```python ### Example from thinc.api import require_gpu require_gpu() ``` | Argument | Type | Description | | ----------- | ------------- | ----------- | | **RETURNS** | bool | `True`. | ### set_active_gpu {#set_active_gpu tag="function"} Set the current GPU device for `cupy` (and for `torch`, if installed) and return a `cupy` device. Will raise an error if no GPU is available. ```python ### Example from thinc.api import set_active_gpu set_active_gpu(0) ``` | Argument | Type | Description | | ----------- | ------------------------- | ----------------------- | | `gpu_id` | int | Device index to select. | | **RETURNS** | cupy.cuda.Device | The device. | ### use_pytorch_for_gpu_memory {#use_pytorch_for_gpu_memory tag="function"} Route GPU memory allocation via PyTorch. This is recommended for using PyTorch and `cupy` together, as otherwise OOM errors can occur when there's available memory sitting in the other library's pool. We'd like to support routing TensorFlow memory allocation via PyTorch as well (or vice versa), but do not currently have an implementation for it. ```python ### Example from thinc.api import prefer_gpu, use_pytorch_for_gpu_memory if prefer_gpu(): use_pytorch_for_gpu_memory() ``` ### use_tensorflow_for_gpu_memory {#use_tensorflow_for_gpu_memory tag="function"} Route GPU memory allocation via TensorFlow. This is recommended for using TensorFlow and `cupy` together, as otherwise OOM errors can occur when there's available memory sitting in the other library's pool. We'd like to support routing PyTorch memory allocation via TensorFlow as well (or vice versa), but do not currently have an implementation for it. ```python ### Example from thinc.api import prefer_gpu, use_tensorflow_for_gpu_memory if prefer_gpu(): use_tensorflow_for_gpu_memory() ``` ### get_width {#get_width tag="function"} Infer the width of a batch of data, which could be any of: an n-dimensional array (use the shape) or a sequence of arrays (use the shape of the first element). | Argument | Type | Description | | -------------- | ---------------------------------------------------------- | ------------------------------------------------------ | | `X` | Union[ArrayXd, Ragged, Padded, Sequence[ArrayXd]] | The array(s). | | _keyword-only_ | | | | `dim` | int | Which dimension to get the size for. Defaults to `-1`. | | **RETURNS** | int | The array's inferred width. | ### to_categorical {#to_categorical tag="function"} Converts a class vector (integers) to binary class matrix. Based on [`keras.utils.to_categorical`](https://keras.io/utils/). | Argument | Type | Description | | ----------------- | ---------------------- | ---------------------------------------------------------------------------------------------- | | `Y` | IntsXd | Class vector to be converted into a matrix (integers from `0` to `n_classes`). | | `n_classes` | Optional[int] | Total number of classes. | | _keyword-only_ | | | | `label_smoothing` | float | Smoothing-coefficient for label-smoothing. | | **RETURNS** | Floats2d | A binary matrix representation of the input. The axis representing the classes is placed last. | ### enable_mxnet {#enable_mxnet tag="function" new="8.2.0"} Import and enable internal support for MXNet. ### enable_tensorflow {#enable_tensorflow tag="function" new="8.2.0"} Import and enable internal support for TensorFlow. ### xp2torch {#xp2torch tag="function"} Convert a `numpy` or `cupy` tensor to a PyTorch tensor. | Argument | Type | Description | | --------------- | --------------------- | ---------------------------------------------- | | `xp_tensor` | ArrayXd | The tensor to convert. | | `requires_grad` | bool | Whether to backpropagate through the variable. | | **RETURNS** | torch.Tensor | The converted tensor. | ### torch2xp {#torch2xp tag="function"} Convert a PyTorch tensor to a `numpy` or `cupy` tensor. | Argument | Type | Description | | -------------- | --------------------- | ---------------------- | | `torch_tensor` | torch.Tensor | The tensor to convert. | | **RETURNS** | ArrayXd | The converted tensor. | ### xp2tensorflow {#xp2tensorflow tag="function"} Convert a `numpy` or `cupy` tensor to a TensorFlow tensor. | Argument | Type | Description | | --------------- | -------------------------- | ----------------------------------------------------- | | `xp_tensor` | ArrayXd | The tensor to convert. | | `requires_grad` | bool | Whether to backpropagate through the variable. | | `as_variable` | bool | Convert the result to a `tensorflow.Variable` object. | | **RETURNS** | tensorflow.Tensor | The converted tensor. | ### tensorflow2xp {#tensorflow2xp tag="function"} Convert a TensorFlow tensor to a `numpy` or `cupy` tensor. | Argument | Type | Description | | ------------------- | -------------------------- | ---------------------- | | `tensorflow_tensor` | tensorflow.Tensor | The tensor to convert. | | **RETURNS** | ArrayXd | The converted tensor. | ### xp2mxnet {#xp2mxnet tag="function"} Convert a `numpy` or `cupy` tensor to an MXNet tensor. | Argument | Type | Description | | --------------- | ---------------------- | ---------------------------------------------- | | `xp_tensor` | ArrayXd | The tensor to convert. | | `requires_grad` | bool | Whether to backpropagate through the variable. | | **RETURNS** | mx.nd.NDArray | The converted tensor. | ### mxnet2xp {#mxnet2xp tag="function"} Convert an MXNet tensor to a `numpy` or `cupy` tensor. | Argument | Type | Description | | ----------- | ---------------------- | ---------------------- | | `mx_tensor` | mx.nd.NDArray | The tensor to convert. | | **RETURNS** | ArrayXd | The converted tensor. | ### Errors {#errors} Thinc uses the following custom errors: | Name | Description | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ConfigValidationError` | Raised if invalid config settings are encountered by [`Config`](/docs/api-config#config) or the [`registry`](/docs/api-config#registry), or if resolving and validating the referenced functions fails. | | `DataValidationError` | Raised if [`Model.initialize`](/docs/api-model#initialize) is called with sample input or output data that doesn't match the expected input or output of the network, or leads to mismatched input or output in any of its layer. | thinc-9.0.0/website/docs/backprop101.md000066400000000000000000000704061461023342500175730ustar00rootroot00000000000000--- title: Backpropagation 101 teaser: How to trick yourself into understanding backprop without even trying --- Imagine you're a project manager, somewhere deep inside a vast company. You have an inbox, an outbox, and three people in your team: Alex, Bo, and Casey. Work comes into your inbox, you allocate it to someone in your team, they perform the work and get the results back to you, and you move those results to your outbox. Some time later, and potentially out-of-order, you'll receive feedback on the work you submitted. Of course, when you receive the feedback, it won't be labelled according to the person who did it --- the bureaucracy above you neither knows nor cares about Alex, Bo and Casey. All the tasks will have an ID attached, and you'll pass that ID on when you move the results forward. Later you'll use the ID to figure out how to handle the feedback. ```python def handle_work(team, inbox, outbox, feedback_from_above): ... while True: if not_empty(inbox): task_id, task = next(inbox) worker = choose_worker(team) results = worker(task) outbox.send(task_id, results) if not_empty(feedback_from_above): task_id, feedback = next(feedback_from_above) ... ``` Because you don't know when you'll get the feedback, you have some state to track. You need to keep track of who did what task, so you can route the feedback to the right person. If Alex did the task and you give the feedback to Bo, your team will not improve. And your team members have some state to track too: they need to understand each piece of feedback in terms of the specific task it relates to. You want them to be able to get feedback like, "This wasn't ambitious enough", notice that their proposal was way under-budget, and see what they should've done differently in that specific scenario. Alex, Bo and Casey should each keep their own notes about their projects, and the specifics of exactly what they should do differently should be up to them --- you don't want to micromanage that. You have a great team. If you just route the information around, they'll take care of the rest. So to make your routing job easier, you ask everyone to return you a _callback_ to pass along the feedback when it's ready. The callback is created by the worker on your team, and it should wrap whatever state they need to act upon the feedback when/if it comes. With this system, all you need to do is file all the callbacks correctly when you're passing work forward, and then retrieve the right handle when the feedback comes in. ```python def handle_work(team, inbox, outbox, feedback_from_above): pending_feedback = {} while True: if not_empty(inbox): task_id, task = next(inbox) worker = choose_worker(team) results, handle_feedback = worker(task) pending_feedback[task_id] = handle_feedback outbox.send(task_id, results) if not_empty(feedback_from_above): task_id, feedback = next(feedback_from_above) handle_feedback = pending_feedback[task_id] handle_feedback(feedback) ``` This system definitely makes your job easy, and all the information is getting routed correctly. But something's still missing. Alex, Bo and Casey have feedback too: about their inputs. They are getting feedback about their work, and are doing their best to incorporate it and improve. But their own performance is also dependent on the specific inputs they were given. It's always the case that if the input for a given task had been a little bit different, the output would've been different as well. When incorporating the feedback on their work, the workers in your team will thus have feedback on the original inputs they were given, and how those inputs could have been better to ensure outputs that would have been closer to what the people above you really wanted. Currently all this feedback is getting lost, and there's no way for the people who produced those inputs to learn what your team wants from them. So you need another outbox, pointed in the other direction, to propagate the feedback from your workers to the people preparing their inputs. ```python def handle_work(team, inbox, outbox, feedback_from_above, feedback_to_below): ... ``` Of course, you need to make a clear distinction between the feedback that your team received on their outputs, and the feedback that your team produced about their inputs, and make sure that the correct pieces of feedback end up with the right people. Imagine if Alex had created a proposal that could potentially run over-budget, and you had passed that proposal upwards. Later you pass along feedback to Alex that says: "Not ambitious enough; client asked for bold". That's a feedback message for Alex, about Alex's work. The team who made the input proposal then needs to hear Alex's feedback on the original inputs: "The client context was originally described as 'risk sanctioned', which is ambiguous phrasing. Please be more clear when specifying the requirements." If instead you passed them the feedback intended for Alex, the team below you would be misled. They'd move in the wrong direction. So you need to be careful that everything's routed correctly. The feedback into Alex and the feedback out of Alex are not interchangeable. ```python def handle_work(team, inbox, outbox, feedback_from_above, feedback_to_below): pending_feedback = {} while True: if not_empty(inbox): task_id, task = next(inbox) worker = choose_worker(team) results, handle_feedback = worker(task) pending_feedback[task_id] = handle_feedback outbox.send(task_id, results) if not_empty(feedback_from_above): task_id, feedback = next(feedback_from_above) handle_feedback = pending_feedback[task_id] feedback_to_below.send(task_id, handle_feedback(feedback)) ``` With work passing forward, and corrections being fed back, your team and the people feeding you work are operating smoothly. The corrections you're asking Alex, Bo and Casey to make get more and more minor; and in turn, the corrections they're passing back are getting smaller too. Life is good, work is easy... So you start to have some time on your hands. One day you're watching a TED talk about management, and you hear about the "wisdom of crowds": if you combine several independent estimates, you can get a more accurate result. You only have a crowd of three, but you're getting a lot of budget estimation tasks, so why not give it a try? For the next budget estimation task, instead of giving it to just one worker, you decide to get them all to work on it separately. You don't tell them about each others' work, because you don't want groupthink --- you want them to all come up with a separate estimate. You then add them all up, and send off the result. ```python alex_estimate, give_alex_feedback = alex(task) bo_estimate, give_bo_feedback = bo(task) casey_estimate, give_casey_feedback = casey(task) estimate = alex_estimate + bo_estimate + casey_estimate ``` Looking back on what you know now, just adding them up does feel kind of silly... But the rest of the TED talk was some weird stuff about jellybeans and you stopped paying attention. So this is what you did. Anyway, the estimate you sent off was way too high, so now you'd better give everyone the feedback so they can adjust for next time. Since this was a numerical estimate, the feedback is very simple: it's just a number. You don't actually know very much about this number and what it really represents, but you get a bonus if your team outputs work such that smaller numbers come back. The closer to 0 the feedback becomes, the bigger the bonus. You incentivise your team accordingly. The first time you just sum up their estimates, the combined estimate way overshoots, and your feedback is far from zero. How should you split up the feedback between Alex, Bo and Casey, and when they have feedback in turn, how should you pass that along? ```python def propagate_feedback_from_addition(feedback, give_alex_feedback, give_bo_feedback, give_casey_feedback): # What to do here? ... return feedback_to_input ``` One way to think about this is that there's three people, and one piece of feedback. So we should divide it up between all three estimates equally. But you think about this some more, and decide that you really don't feel like micromanaging this: you just want the _combined_ score to come out right. So you figure that you'll just give all of the feedback to everyone, and see how that works out. Sure, your team may be a bit confused at first, but they'll quickly adjust their spreadsheets or whatever and the combined estimate will get closer and closer to the mark. There's also the question of how to pass on Alex, Bo and Casey's feedback about their inputs. It turns out for these cost estimates, everything comes in a nicely structured format: the "inputs" are just a table of numbers, which were all estimates from another team, who are passing information into your inbox. So Alex, Bo and Casey all produce feedback that's in the same format --- it's a table of numbers of the same size and shape as the inputs (because that's what it relates to). Alex, Bo and Casey take their bonuses seriously, so they're very specific about how their feedback should be interpreted. Each of them gives you their feedback table and tells you, "Look, tell the people producing this data that if they had given us inputs such that these numbers were zero, our own feedback would have been zero and we'd all make our bonus. Now, I know we shouldn't leap to conclusions and base everything off this one sample. And I know I need to make adjustments as well. If I make some changes and they make some changes each time, we'll get there after a bit of iteration." So now you have three of these feedback tables, that all relate to the same example. How should you propagate that back? The only sensible thing is to add them all up and pass them on, so that's what you do. More of these work estimates come in, and you keep passing them through your combination team and passing the feedback back down. It's kind of a hassle to keep track of all the internals though --- it's messed up your neat system. So you have a bright idea: you create a little filing system for yourself, so you can keep track of the combination and treat it just like another team member. Alex, Bo and Casey all behave with a pretty simple interface when it comes to these estimates, because the data is all nice and regular. We can specify the interface using Python 3's type-annotation syntax, so we can understand what data we're passing around a bit better. The inputs are a table, so we'll write their type as `Array2d` --- i.e., a two-dimensional array. The output will be a single number, so a float. Each worker also returns a callback, to handle the feedback about their output, and provide the feedback about their inputs. ```python def estimate_project(inputs: Array2d) -> Tuple[float, Callable[[float], Array2d]]: ... ``` It'll be helpful if we can refer to objects that follow this `estimate_projects` API in the type annotations. The type-annotations solution to this is to define a "protocol". The specifics are a bit weird, but it comes out looking like this: ```python from typing import Protocol class Estimator(Protocol): def __call__(self, inputs: Array2d) -> Tuple[float, Callable[[float], Array2d]]): ... ``` This gives us a new type, `Estimator`, that we can use to describe our worker functions. As we start combining workers, we'll be passing functions into functions --- so it'll be helpful to have some annotations to see what's going on more easily. To make our combination worker, we just need to return a function that has the same signature. Inside the addition estimator, we'll call Alex, Bo and Casey in turn, add up the output, and return it along with the callback. For notational convenience, we'll prefix the feedback for some quantity with `re_`, like it's a reply to that variable. ```python def combine_by_addition(alex: Estimator, bo: Estimator, casey: Estimator) -> Estimator: def run_addition_estimate(inputs: Array2d) -> float: a_estimate, give_a_feedback = alex(inputs) b_estimate, give_b_feedback = bo(inputs) c_estimate, give_c_feedback = casey(inputs) summed = a_estimate + b_estimate + c_estimate def handle_feedback(re_summed: float) -> Array2d: # Pass the feedback re output 'summed' to each worker, and add up their # feedbacks re input re_input = ( give_a_feedback(re_summed) + give_b_feedback(re_summed) + give_c_feedback(re_summed) ) return re_input return summed, handle_feedback return run_addition_estimate ``` We can now use our "addition" worker just like anyone else in our team. And in fact, if we learned tomorrow that "Casey" was actually a front for a vast system of combination like this... well, what of it? We'd still be passing in inputs, passing along the outputs, providing the output feedback, and making sure the input feedback gets propagated. Nothing would change. After a few iterations of corrections, the combined-by-addition "worker" you've created starts producing great results --- so good that even the vast bureaucracy around you takes notice. As well as a great bonus, you get a few new team members: Dani, Ely and Fei. You start thinking of new ways to combine them. You also make some quick changes to your addition system. Now that you have more workers, you want to make it a bit more general. ```python def combine_by_addition(workers: List[Estimator]) -> Estimator: def addition_combination(inputs: Array2d) -> float: callbacks = [] summed = 0 for worker in workers: result, callback = worker(inputs) summed += result callbacks.append(callback) def handle_feedback(re_summed: float) -> Array2d: re_input = callbacks[0](re_summed) for callback in callbacks[1:]: re_input += callback(re_summed) return re_input return summed, handle_feedback return addition_combination ``` As for new combinations, one obvious idea harks back to your original "wisdom of the crowds" inspiration. Instead of just adding up the outputs, you could average them. Easy. But how to handle the feedback? Should we just pass that along directly, like we did with the addition, or should we divide the feedback by the number of workers? It actually won't really matter: the team members all understand the feedback to mean, "Change your model slightly, so that this number becomes closer to zero. Also, give us similar feedback about inputs." If you give them feedback that's three times too big, and they make changes that pushes that number towards zero, they'll also be pushing the "real" feedback score towards zero. You can't really steer them wrong just by messing up the magnitude, so long as you do it consistently. Still, messing up the magnitude makes things messy: if you're not careful, it could easily lead to more relevant errors later. So best to handle everything consistently, and make the appropriate division. ```python def combine_by_average(workers: List[Estimator]) -> Estimator: def combination_worker_averaging(inputs: Array2d) -> float: callbacks = [] summed = 0 for worker in workers: result, callback = worker(inputs) summed += result callbacks.append(callback) average = summed / len(workers) def handle_feedback(re_average: float) -> Array2d: re_result = re_average / len(workers) re_input = callbacks[0](re_result) for callback in callbacks[1:]: re_input += callback(re_result) return re_input return average, handle_feedback return combination_worker_averaging ``` Looking at this, there's a lot of obvious duplication with the addition. We're doing the exact same thing as it, as part of the averaging process. Why don't we just make an addition worker, and only implement the averaging step? ```python def combine_by_average(workers: List[Estimator]) -> Estimator: addition_worker = combine_by_addition(workers) def combination_worker_averaging(inputs: Array2d) -> float: summed, handle_summed_feedback = addition_worker(inputs) average = summed / len(workers) def handle_feedback(re_average: float) -> Array2d: re_summed = re_average / len(workers) re_input = handle_summed_feedback(re_summed) return re_input return average, handle_feedback return combination_worker_averaging ``` If you only use each worker in one team, and you keep the team sizes fixed, the addition and averaging approaches end up performing the same. The extra division step doesn't end up mattering. This actually makes a lot of sense, considering what we realized about the feedback for the averaging: in both approaches, the workers are going to end up making similar updates, just rescaled --- and over time, they'll easily recalibrate their outputs to the scaling term, either way. Summing and averaging are sort of the same, but surely there are other ways the workers could collaborate? So you go back and read more management books, and everyone seems to be saying you should just listen to whoever speaks the loudest. None of the books say it _like that_, but if you actually followed their advice, that's pretty much what you'd end up doing. This seems really dumb, but uh... okay, let's try it? Your team really doesn't communicate by speaking, so "loudest" can't be taken too literally. Let's take it to mean selecting the highest estimate. ```python def combine_by_maximum(workers: List[Estimator]) -> Estimator: def combination_worker_maximum(inputs: Array2d) -> float: max_estimate = None handle_for_max = None for worker in workers: estimate, handle_feedback = worker(inputs) if max_estimate is None or estimate > max_estimate: max_estimate = estimate handle_for_max = handle_feedback return max_estimate, handle_for_max return combination_worker_maximum ``` You combine two workers, `Dani` and `Ely`, into a new team using this maximum-based approach, and you can almost feel your bonus slipping away as you put them into action: surely if we're always taking the maximum, our estimates are going to climb up and up, right? But to your surprise, that's not what happens. The worker who submits the high estimate is the one who gets the feedback, so they'll learn not to produce such a high estimate for that input next time. Dani and Ely aren't competing to have their outputs selected --- from their perspective, they're working completely independently. They're just trying to make adjustments so that their feedback scores get closer to zero. Is it weird that only the worker with the highest estimate gets any feedback? Shouldn't we be trying to train all of them based on what we learned from the example as well? We actually can't do that, because we don't have feedback that relates to all the outputs: we only submitted one output, so we only get feedback about that one output. The feedback represents a request for change: it tells the workers how we'd like their output to be different next time, given the same input. We don't know that about the other workers' estimates, because we didn't submit them. Your `combine_by_maximum(Dani, Ely)` team works surprisingly well, so you decide to break your usual hands-off policy, and actually look at some of the data to try to figure out what's going on, even going so far as to set up a `combine_by_average(Alex, Bo)` team for comparison. After a bit of sifting, you discover some interesting patterns, especially concerning two of the input columns. Based on the estimates and feedback, you see that if the inputs have a 1 in the column labelled "Located in California", that generally means the estimates should be higher. There's also a column labelled "Renewable Energy", and a 1 for that also leads to higher estimates, generally. But when there's a 1 for both columns, the estimates should come out a fair bit lower than you'd expect, based on the two columns individually. The `combine_by_average(Alex, Bo)` team is really struggling with this: whatever they're doing individually, it's not taking this combination factor into account --- they're both overshooting on the `California+Renewable` examples, and when there's a run of those examples, they start _undershooting_ on the examples that are just `California` or just `Renewable`. The average doesn't help. | California | Renewables | Alex | Bo | Output | Target | | ---------- | ---------- | ------- | ------ | ------ | ------ | | 0 | 0 | \$1.5m | \$0.5m | \$1m | \$1m | | 1 | 0 | \$6m | \$4m | \$5m | \$5m | | 0 | 1 | \$7m | \$9m | \$8m | \$8m | | 1 | 1 | \$11.5m | \$12.5 | \$12m | \$10m | While the averaging doesn't help, the `combine_by_maximum(Dani, Ely)` team manages to follow their individual feedbacks to an interesting "collaborative" solution. Effectively, the `max` operation allows the workers to "specialise": Dani doesn't worry about examples outside of California, and Ely doesn't worry about projects that don't concern renewables. This means Ely's weighting for "California" is really a weighting for _California in the context of renewable_. Ely doesn't need to model the effect of California by itself, because Dani covers that, so between them, they're able to produce estimates that account for the interaction effect. | California | Renewables | Dani | Ely | Output | Target | | ---------- | ---------- | ---- | ----- | ------ | ------ | | 0 | 0 | \$1m | \$1m | \$1m | \$1m | | 1 | 0 | \$5m | \$2m | \$5m | \$5m | | 0 | 1 | \$1m | \$8m | \$8m | \$8m | | 1 | 1 | \$6m | \$10m | \$10m | \$10m | It's hard to overstate the importance of this. Nobody involved went out and learned that there were relevant subsidies in California that reduced the cost of renewables projects, figured out that they were throwing off the estimates, and included an extra column for them. And later more examples will show even more subtlety: the subsidies only matter for certain years. That fact gets taken care of too, without anyone even having to notice. The `combine_by_maximum` approach can learn "not and" relationships, which is something summing and averaging the different outputs could never give you. Once you start looking for places where summing and averaging fails, you start seeing them everywhere. It will make a great TED talk some day: _non-linearities_. Previously when you thought about relationships between quantities, you were trying to decide between three options: unrelated, positively correlated and negatively correlated. This often comes down to "is this factor good, bad, or irrelevant". How much salt should someone have in their diet per day? How much sleep should you get? How long should a school day be? There are very few relationships that are linear the whole way through. It's much more common for the relationship to be linear in "normal" ranges, and then non-linear at the edges. Often there's a saturation point: you need enough sodium in your diet. If you have too little you will die. But once you have enough, excess sodium is probably slightly bad for you, up until a point where it will be extremely bad for you, and again, you will die. Almost everything is like this, because almost every relationship is indirect --- we're always looking at aggregate phenomena with a huge web of causation behind the scenes, mediating the interaction. So you'll always have these pockets of linearity, interrupted by overheads, tipping points, cut-offs at zero, saturation points, diminishing returns, synergistic amplifications, etc. So the ability to model these non-linear relationships is no small thing. And it's happening through this simple process of feedback and adjustment: with enough examples, the individual predictors are getting more right over time, and you're able to combine their predictions together to account for "not and" relationships between logical variables, and to interpret numeric variables as having different significance in different ranges. Business is good, the bonuses keep flowing, and your team expands further. As you succeed further, efficiency starts to become a factor. Instead of receiving one task at a time, you start processing the work in batches. This is helpful because there's a bit of routing overhead involved. There are also little waiting periods after they finish their work, as work is happening in parallel, and sometimes you need to wait on another input somewhere else before the next bit of work can get started. Batch processing keeps everyone busier, but it does make your routing a bit more difficult sometimes. For some of the tasks you're given, the workers will take in a whole table of numbers and give you a single number back. For other tasks, you get one number per row. For this second type of task, you think you see a useful way to do the batching --- but you want to do a quick experiment first. You need to know whether the order of the rows matter or are they really independent? ```python def with_shuffled(worker): def worker_with_shuffled(input_table): shuf_index = list(range(len(input_table))) random.shuffle(shuf_index) shuf_input = [input_table[i] for i in shuf_index] shuf_output, handle_shuffled_feedback = worker(shuf_input) # We should undo our mischief before we return the output -- we don't # know who else might be relying on the original order. # We swapped items at pairs (0, shuf_index[0]), etc -- # So we can unswap. shuf_index_reverted = [shuf_index.index(i) for i in list(range(len(input_table)))] output = [shuf_output[i] for i in shuf_index_reverted] def handle_feedback(re_output): # Our worker received the rows in a different order. We need to # align the feedback to the view of the data they received. shuf_re_output = [re_output[i] for i in shuf_index] shuf_re_input = handle_shuffled_feedback(shuf_re_output) # And unshuffle, to return. re_input = [shuf_re_input[i] for i in shuf_index_reverted] return re_input return output, handle_feedback() return worker_with_shuffled ``` You decide to grab Alex for this test, and do something just like the "combination worker" you created earlier, but this time with just one worker. You quickly determine that your trickery is making no difference: the order of rows doesn't matter in this input. So now you can handle the batched data easily. You just need to concatenate the rows to form one giant table, submit it to the worker, and split apart the results. Then you need to do the inverse with the feedback. Give it a try! ```python def with_flatten(worker): def worker_with_flatten(input_tables: List[Array2d]) -> Tuple[List[Array1d], Callable]: ... def handle_flattened_feedback(re_outputs: List[Array1d]) -> List[Array2d]: ... return re_input_tables return outputs, handle_flattened_feedback return worker_with_flatten ``` By now it's probably worth dropping the allegory: the "workers" in our story are models, which could be individual layers of a neural network, or even whole models. And the process we've been discussing is of course the backpropagation of gradients, which are used to iteratively update the weights of a model. The allegory also introduced Thinc's particular implementation strategy for backpropagation, which uses function composition. This approach lets you express neural network operations as higher-order functions. On the one hand, there are sometimes where managing the backward pass explicitly is tricky, and it's another place your code can go wrong. But the trade-off is that there's much less API surface to work with, and you can spend more time thinking about the computations that should be executed, instead of the framework that's executing them. For more about how Thinc is put together, read on to its [Concept and Design](/docs/concept). thinc-9.0.0/website/docs/concept.md000066400000000000000000000334231461023342500172010ustar00rootroot00000000000000--- title: Concept and Design teaser: Thinc's conceptual model and how it works next: /docs/install --- Thinc is built on a fairly simple conceptual model that's a little bit different from other neural network libraries. On this page, we build up the library from first principles, so you can see how everything fits together. This page assumes some conceptual familiarity with [backpropagation](/docs/backprop101), but you should be able to follow along even if you're hazy on some of the details. ## The model composition problem The central problem for a neural network implementation is this: during the **forward pass**, you compute results that will later be useful during the **backward pass**. How do you keep track of this arbitrary state, while making sure that layers can be cleanly composed? Instead of starting with the problem directly, let's start with a simple and obvious approach, so that we can run into the problem more naturally. The most obvious idea is that we have some thing called a `model`, and this thing holds some parameters ("weights") and has a method to predict from some inputs to some outputs using the current weights. So far so good. But we also need a way to update the weights. The most obvious API for this is to add an `update` method, which will take a batch of inputs and a batch of correct labels, and compute the weight update. ```python class UncomposableModel: def __init__(self, W): self.W = W def predict(self, inputs): return inputs @ self.W.T def update(self, inputs, targets, learn_rate=0.001): guesses = self.predict(inputs) d_guesses = (guesses-targets) / targets.shape[0] # gradient of loss w.r.t. output # The @ is newish Python syntax for matrix multiplication d_inputs = d_guesses @ self.W dW = d_guesses.T @ inputs # gradient of parameters self.W -= learn_rate * dW # update weights return d_inputs ``` This API design works in itself, but the `update()` method only works as the outer-level API. You wouldn't be able to put another layer with the same API after this one and backpropagate through both of them. Let's look at the steps for backpropagating through two matrix multiplications: ```python def backprop_two_layers(W1, W2, inputs, targets): hiddens = inputs @ W1.T guesses = hiddens @ W2.T d_guesses = (guesses-targets) / targets.shape[0] # gradient of loss w.r.t. output dW2 = d_guesses @ hiddens.T d_hiddens = d_guesses @ W2 dW1 = d_hiddens @ inputs.T d_inputs = d_hiddens @ W1 return dW1, dW2, d_inputs ``` In order to update the first layer, we need to know the gradient with respect to its output. We can't calculate that value until we've finished the full forward pass, calculated the gradient of the loss, and then backpropagated through the second layer. This is why the `UncomposableModel` is uncomposable: the `update` method expects the input and the target to both be available. That only works for the outermost API โ€“ the same API can't work for intermediate layers. Although nobody thinks of it this way, reverse-model auto-differentiation (as supported by PyTorch, Tensorflow, etc) can be seen as a solution to this API problem. The solution is to base the API around the `predict` method, which doesn't have the same composition problem: there's no problem with writing `model3.predict(model2.predict(model1.predict(X)))`, or `model3.predict(model2.predict(X) + model1.predict(X))`, etc. We can easily build a larger model from smaller functions when we're programming the forward computations, and so that's exactly the API that reverse-mode autodifferentiation was invented to offer. The key idea behind Thinc is that it's possible to just fix the API problem directly, so that models can be composed cleanly both forwards and backwards. This results in an interestingly different developer experience: the code is far more explicit and there are very few details of the framework to consider. There's potentially more flexibility, but potentially lost performance and sometimes more opportunities to make mistakes. We don't want to suggest that Thinc's approach is uniformly better than a high-performance computational graph engine such as PyTorch or Tensorflow. It isn't. The trick is to use them together: you can use PyTorch, Tensorflow or some other library to do almost all of the actual computation, while doing almost all of your programming with a much more transparent, flexible and simpler system. Here's how it works. ## No (explicit) computational graph โ€“ just higher order functions The API design problem we're facing here is actually pretty basic. We're trying to compute two values, but before we can compute the second one, we need to pass control back to the caller, so they can use the first value to give us an extra input. The general solution to this type of problem is a **callback**, and in fact a callback is exactly what we need here. Specifically, we need to make sure our model functions return a result, and then a callback that takes a gradient of outputs, and computes the corresponding gradient of inputs. ```python def forward(X: InT) -> Tuple[OutT, Callable[[OutT], InT]]: Y: OutT = _do_whatever_computation(X) def backward(dY: OutT) -> InT: dX: InputType = _do_whatever_backprop(dY, X) return dX return Y, backward ``` To make this less abstract, here are two [layers](/docs/api-layers) following this signature. For now, we'll stick to layers that don't introduce any trainable weights, to keep things simple. ```python ### reduce_sum layer def reduce_sum(X: Floats3d) -> Tuple[Floats2d, Callable[[Floats2d], Floats3d]]: Y = X.sum(axis=1) X_shape = X.shape def backprop_reduce_sum(dY: Floats2d) -> Floats3d: dX = zeros(X_shape) dX += dY.reshape((dY.shape[0], 1, dY.shape[1])) return dX return Y, backprop_reduce_sum ``` ```python ### Relu layer def relu(inputs: Floats2d) -> Tuple[Floats2d, Callable[[Floats2d], Floats2d]]: mask = inputs >= 0 def backprop_relu(d_outputs: Floats2d) -> Floats2d: return d_outputs * mask return inputs * mask, backprop_relu ``` Notice that the `reduce_sum` layer's output is a different shape from its input. The forward pass runs from input to output, while the backward pass runs from gradient-of-output to gradient-of-input. This means that we'll always have two matching pairs: `(input_to_forward, output_of_backprop)` and `(output_of_forward, input_of_backprop)`. These pairs must match in type. If our functions obey this invariant, we'll be able to write [combinator functions](/docs/api-layers#combinators) that can wire together layers in standard ways. The most basic way we'll want to combine layers is a feed-forward relationship. We call this combinator `chain`, after the chain rule: ```python ### Chain combinator def chain(layer1, layer2): def forward_chain(X): Y, get_dX = layer1(X) Z, get_dY = layer2(Y) def backprop_chain(dZ): dY = get_dY(dZ) dX = get_dX(dY) return dX return Z, backprop_chain return forward_chain ``` We can use the `chain` combinator to build a function that runs our `reduce_sum` and `relu` layers in succession: ```python chained = chain(reduce_sum, relu) X = uniform((2, 10, 6)) # (batch_size, sequence_length, width) dZ = uniform((2, 6)) # (batch_size, width) Z, get_dX = chained(X) dX = get_dX(dZ) assert dX.shape == X.shape ``` Our `chain` combinator works easily because our layers return callbacks. The callbacks ensure that there is no distinction in API between the outermost layer and a layer that's part of a larger network. We can see this clearly by imagining the alternative, where the function expects the gradient with respect to the output along with its input: ```python ### Problem without callbacks {highlight="15-19"} def reduce_sum_no_callback(X, dY): Y = X.sum(axis=1) X_shape = X.shape dX = zeros(X_shape) dX += dY.reshape((dY.shape[0], 1, dY.shape[1])) return Y, dX def relu_no_callback(inputs, d_outputs): mask = inputs >= 0 outputs = inputs * mask d_inputs = d_outputs * mask return outputs, d_inputs def chain_no_callback(layer1, layer2): def chain_forward_no_callback(X, dZ): # How do we call layer1? We can't, because its signature expects dY # as part of its input โ€“ but we don't know dY yet! We can only # compute dY once we have Y. That's why layers must return callbacks. raise CannotBeImplementedError() ``` The `reduce_sum` and `relu` layers are easy to work with, because they don't introduce any parameters. But networks that don't have any parameters aren't very useful. So how should we handle them? We can't just say that parameters are just another type of input variable, because that's not how we want to use the network. We want the parameters of a layer to be an internal detail โ€“ **we don't want to have to pass in the parameters on each input**. Parameters need to be handled differently from input variables, because we want to specify them at different times. We'd like to specify the parameters once when we create the function, and then have them be an internal detail that doesn't affect the function's signature. The most direct approach is to introduce another layer of closures, and make the parameters and their gradients arguments to the outer layer. The gradients can then be incremented during the backward pass: ```python def Linear(W, b, dW, db): def forward_linear(X): def backward_linear(dY): dW += dY.T @ X db += dY.sum(axis=0) return dY @ W return X @ W.T + b, backward_linear return forward_linear n_batch = 128 n_in = 16 n_out = 32 W = uniform((n_out, n_in)) b = uniform((n_out,)) dW = zeros(W.shape) db = zeros(b.shape) X = uniform((n_batch, n_in)) Y_true = uniform((n_batch, n_out)) linear = Linear(W, b, dW, db) Y_out, get_dX = linear(X) # Now we could calculate a loss and backpropagate dY = (Y_out - Y_true) / Y_true.shape[0] dX = get_dX(dY) # Now we could do an optimization step like W -= 0.001 * dW b -= 0.001 * db dW.fill(0.0) db.fill(0.0) ``` While the above approach would work, handling the parameters and their gradients explicitly will quickly get unmanageable. To make things easier, we need to introduce a `Model` class, so that we can **keep track of the parameters, gradients, dimensions** and other attributes that each layer might require. The most obvious thing to do at this point would be to introduce one class per layer type, with the forward pass implemented as a method on the class. While this approach would work reasonably well, we've preferred a slightly different implementation, that relies on composition rather than inheritance. The implementation of the [`Linear` layer](/docs/api-layers#linear) provides a good example. Instead of defining a subclass of `thinc.model.Model`, the layer provides a function `Linear` that constructs a [`Model` instance](/docs/api-model), passing in the function `forward` in `thinc.layers.linear`: ```python def forward(model: Model, X: InputType, is_train: bool): ``` The function receives a `model` instance as its first argument, which provides you access to the dimensions, parameters, gradients, attributes and layers. The second argument is the input data, and the third argument is a boolean that lets layers run differently during training and prediction โ€“ an important requirement for layers like dropout and batch normalization. As well as the `forward` function, the `Model` also lets you pass in a function `init`, allowing us to support **shape inference**. ```python ### Linear {highlight="3-4"} model = Model( "linear", forward, init=init, dims={"nO": nO, "nI": nI}, params={"W": None, "b": None}, ) ``` We want to be able to define complex networks concisely, passing in **only genuine configuration** โ€” we shouldn't have to pass in a lot of variables whose values are dictated by the rest of the network. The more redundant the configuration, the more ways the values we pass in can be invalid. In the example above, there are many different ways for the inputs to `Linear` to be invalid: the `W` and `dW` variables could be different shapes, the size of `b` could fail to match the first dimension of `W`, the second dimension of `W` could fail to match the second dimension of the input, etc. With inputs like these, there's no way we can expect functions to validate their inputs reliably, leading to unpredictable logic errors that make the calling code difficult to debug. In a network with two `Linear` layers, only one dimension is an actual hyperparameter. The input size to the first layer and the output size of the second layer are both **determined by the shape of the data**. The only choice to make is the number of "hidden units", which will determine the output size of the first layer and the input size of the second layer. So we want to be able to write something like this: ```python model = chain(Linear(nO=n_hidden), Linear()) ``` ... and have the missing dimensions **inferred later**, based on the input and output data. In order to make this work, we need to specify initialization logic for each layer we define. For example, here's the initialization logic for the `Linear` and `chain` layers: ```python ### Initialization logic from typing import Optional from thinc.api import Model, glorot_uniform_init from thinc.types import Floats2d from thinc.util import get_width def init(model: Model, X: Optional[Floats2d] = None, Y: Optional[Floats2d] = None) -> None: if X is not None: model.set_dim("nI", get_width(X)) if Y is not None: model.set_dim("nO", get_width(Y)) W = model.ops.alloc2f(model.get_dim("nO"), model.get_dim("nI")) b = model.ops.alloc1f(model.get_dim("nO")) glorot_uniform_init(model.ops, W.shape) model.set_param("W", W) model.set_param("b", b) ``` thinc-9.0.0/website/docs/images/000077500000000000000000000000001461023342500164645ustar00rootroot00000000000000thinc-9.0.0/website/docs/images/layer-traversal.graffle000066400000000000000000002346551461023342500231500ustar00rootroot00000000000000PKหMSS๑ง]c&9 data.plistํ}iทขศ–่็ช_‘]ŸU) NuซW0ƒ‚‚ ยสตz1 ศ( ˆต๎/z?ใฑจ็่ัs2๋พ}‡NซVสฐงˆ=ฤŽฯŽ_๓GŸn^i๒งŸเฯะOŸฤN ๑๔“"SฟL~๚ฯ฿~๕฿ˆ.๋K๒SE๙iฉ`s๔ำ/>ศฒศํ๗ ™๘ดœณ+๙SCฃ฿'…Ÿ>ไ—e๖๏~UUŸอ๊ณฦ-`ั_ๆiๆๆe=oˆา |vJ็ง†อ™๚8อS'ฐห฿~แืะญkูถY6๏ี3ุฏ๖y๓ฺฬsณฝ๘แืขฬ๙kุ}Nใ$๐๒tŸ}^4Wtnn6‘;ตนF ๔3< ผ๛ตฅู๑ฦำ(อั7AไOุ^ไแ ํ˜ฅyj_6ท€_‘วฬŠ'8ูXฺฒ#ŽLืิิร&(เะ/6jยฉลณIX–ขๆA๓Y)*ม2ยJ‚X๐๐YZdwูโA5ฬ*xC๑|.rพH๚ซ๖Jํ๎Oญž๔ชนา[นฐขลsRีมl:Eห๓ฝืษฎุ‘ohญ4~'’bภพัโuฯ‚๊Œs… ฯ4 ํUื~ฌj๎Cใ*gั>รY'QฃjiเดG‘ำ^N;พกลจฅู^๖ฝk๛KS}ปม@ว7thukถˆŽ/oGาJl฿ํ{o๑ ๘™ฆกvํmžXlhวQาโ™Œ่อh>c rธ=oEซ‹V!‡ลFวนพๆB–ึ๓ญคi8-EEdา้k๕/lษกฐีK>@o๔ด๊๐เฮฆ8Iแ^!€๊๙–K๔๘กืขณOElบฑHฏQ‘๙ฤ2>้l–Ÿ5j ‰- ๏่bA่ซD•ๆrkา์ไฤW-ฅ฿SำะX W6Fnฯd$ศ&าร|เ œz˜u๚ำ๘ฝŽผq‡wเฏฐ฿/o>ทx/พr์;&๔ใBึ‘นฬ๎๙Fšแ;ฺj๑Xชำ฿ึBŽgอz๖๓uD๑ๆ+์ค„†UGฏร{‡ๆG๔:=าผ4๖xk‹sŠ๋์ำˆีฺะ†[c…iฆฆLm˜tvK™CG+ภ2๋ถxถˆWฌ‘ซ๛V.ต๕_$ฺuใGศ04ืRง? A=SCฟๆ๏่CZ/ๅl‰Šš์W]R›`€aมNผ+ucณซ:PฺKส 8าืฏ}ฤGฝฟ~fห๎+2ฃพ€รœยาl'๚-ฅc€{` 0ะ"pฮƒYc๊€`Pq %‰ุ “OmŒP(ะ+,4lฆjย.NถhB)ฎ.I…‡`‚ร;=€น €ภฏƒบ"D (ฉ,0ชš ถิAฏ"1 ฺ!’2Bฌลc*2ซใ=2ŠI"ล•ล4‘๒€fc–Gม`]a^EฯมbฑG๛?3ฤ ‘›ฤj‘‘€bจศd`รb=%€Wแ`่๘ผbQ’x‹ทช8DnT$)๎ƒูdžzณไ:^‰๓9(๓”&‚๓๓Ž฿Q'X‘/มษ#ฤJX8% Oจม%oกKไb&6UKฏil็G=Qค[ Y –Q+ ฉอ“ถ(๕0ถ"co•bs<Yฦdฃนืโa"D1@ษ19ฅVขชcšM9•Fc†NežcถBมโ:ย6:yบ†6โ UำIQH›ž1ฦาŠND๓€&Ek‹ซlซ f):K !ธ6 ™ธ}lส2Cqƒโ `™สซqRg5ฯ฿ใ,หF^ฐร็( y_\‹G‚0ยๅ”“ซ(ฤื!ทญโทR๎T%พ)fค˜&๘šฉ แ)9‹มn฿โแ…2€„Wลœ๕Š!“sS|่อ p`๑9๏‰ีŠภS^ฌŽ6ม(ธน๕๊„เˆง!B็ม€PSมศ‚0Cกช.ฑ๑d…๎‰0\`ุo๑ˆฌX”xE์ั%.N""—ko:"†๚ฒจ๚KขW‰ธb’ไE]ยz$Wˆ-^"ึไR‘ศc๓Ÿ2‘,ฉQž™Jตฤคคgฏ8ŸฃศX\๙ุlK =๒ษš—ลcYP^ฮฐ%E๖๓ล„"Cล๔Wsj)'_ฎ(‰ULีจตงถx๑Q›R.ะ{‹ฉ0ิ,ฬ\R9ซมพ5ขŽะZ”œˆBรu๎oVT฿ึ้ฃ฿๙-M+zเZP๔žzดขๆ1–hห6RJาAj*R6 3ิย็นฝ“pง‡pีgๆ}ดdฌเgbีโ!'rล+้ัา#~รึณ-ทๅณข† ^เ!ด9-PพOBณ“  !„"w~ซ@ฐZใยB„“Q ;ษv( `›๕Q…๘๏ 19ย๋ษฐล;ษpฑีGฑซ๛ษx.—๙b”ŽGD•,ie’งํrลNu๑—.่ฑฤะk๑–;ะC‰‰ฟDศ~บํ".ƒฤcqแ`3…ฺ‰ๆ‡l%&^*๓xส:ป(K ” ีLโ‡9ซชddิ ิ)v่dUาIe\hVM _Aิล]มแ%ฺฎฬˆ›้`•ภณc๋0ฐ0รC ใo‡๕H9a"ฒ์•แ^ฮ% งœ<–$ C‰{˜ค“b˜‰•-ตฺPsF9 ๒^์บ<คo(bดZชBฉฮ(VmN#`รVw‘6…Rrk”๒๋5ššu๓‡=•2อฅ™E9ฌAชฉ‡hMจถด๕สq\jภญฬตจัt]M7บฺ๋๒จžŠเ;}y๔e„๔ฌด™ญฐญˆ,ึzฏ Ezฅ‹(ZjฺสpธำƒfฎŒฝŸ,5W6zQบDอ\3‰MsCํV๔ncœ\F๖‰ูŸ*RบE๔KF†–ฯํMdLZวแมฅ๛’—•Ÿž-gวhอTvXึYยc6 wr๎ฑqj :1J๊่*Œ6’9Y‰๔GsฦJฎฝห‡ณ$ๆ\ืIษฎหฯJ๋ƒพมฉ‰ท>๙…šฆkฤ\ฏJ& *๕‡:ฦxณรS*๗lคoyvถ๒+BE#ฟpv“๒ํ\”ฎ็ๆฟมฃ_๛ื๋+>pbžฺaK๓ž“ฐxเาAซAXัƒ`:นz ฯฦฆ็โ้พแ™?J๓ ฬฆฟ437ฬุˆ๙๋)ฤ%rหฮ›ฟสfœ>fำฝยไ๗ žถŸมA‘๑t<๙ำxŠ๙+L[๋“v›ยmŒผ๑ฃ:๕K็M๕/งู฿‚ู๋่R•\ำY$Q๕€๑,?ูณvนYป9›8๎๑fศฟŽ ะํ`rE—)pถ๛ข|‚฿มhฬฒ‘๐M/}ฬ3ํฐอJœn์ ฆkK. -T๑๚ี่eŒŒ~๔ห๙็Oฟเ๓'d8๙ฮ๎/t๐ศ,ž‘นlฅญฦ‹ฯธ™ฬโ‰x๔Xโ–ุ;ฝ(ญฌ#๗๚ต‰—ดฬ7ดบธ9รนYสรs+๙แ‡›ิ์•A™งก๛7apw"ห๎ฑจฑํ{ฅ‰ท4KŸŽ๊ฬ‰ํฟ&{ทœm7y:๏^žอชp4ฟั ฯส&‚&ƒhณฟโ<ะ?ฆวฟƒŸ?5ๆuoW74ล„~ฝ‹u๏_qiƒ‡แตื„โ' Ež54๖qขภ{ๆ ๐ปซfบะ l/8M^6hฒโ๎โœŠ,jฆ‰ถ=i๚”•Ÿ๔ฉป8>6๋โeEป~ƒhญDQZอMหˆ<อ๎lgcF…ฟ~๋๛/’5๙ณ๛ิล/3Š๔>;{๎8v๚ฝใย<y แy๒†๛ฉzŽฝ…พs๘WัŸ:3ใFทlR๖"]จบ3ษรศฦŸฆม>๎ฅปxyc}ำ7๓ ๑{ิWป}l/sขิkZตัๅc‰จ›;ผ‰y7F๗ ษ;ผ{ผ๔/ฟPI๙mภผขfi๐.โ๏ราŒ_่่๓ฯิ๐_ ึœฑ๐เkBไNOตธl™{แ]_K?|Uจ7B<}ŸXย&ˆขฏ9๐ใ๐๘๘๘ฬ!ว๘ฟ —‡—วˆ๕ิขฌท&ั…จiัM0ธB{:CะOข็_ตx๕ค๛.มร๕Lป~ำ5wสห~0sู ขฟ,?Š„wืoy>ไศ7I๒B?šjาdn๎9๒Wส.=~ž ฃฃ๛7บไทน ๆ&๎›8*๓๒ฺ•๗˜มำuซ ŸžŒษ฿:ฉ๛pV๗ํม๎{ๆ/’๙ฃqๆ?๙ืJำ๓—๚_๛ŸL?์‹o์๛เ{:๓ฯ:ล€๏cโฟศ˜๘แ๐ร1qฏ5&ขใiแแ ๔5"~๛ˆ๘AO|ƒX฿วร๏ใแ?๋xˆ|ท‡ฆDއฃ๏ใแ7‹๕Wฯ๑Fฤ๛>&~๗‰฿ฒI„L็ทˆง<฿่฿ทˆIๅ๛ัช-"๔๏พE๔Qจ ฦท๐ว๏ก๎๚{จ๛ู๊Bใพุ?^จ๛{ไtำ๖๏๎๚{ ๛ู่๒่Pi>๙{ไt๒๏ก๎๚{จ๛ู๊B?๊nWฃ;Nt8๗๛Jo&ฒ…x๘ฌ๋fฬญ5vะผนM๓ๅญ‹?ฤX๓Y`„>รฯยก™~pxใฎล&~๘AOฐย\ O Y U™ฮ1Fd'Bf!Cใ ษัTญ#~ๆฤjญโd 0ฃงซ[‡แWะ๔2ฅ&" ๅข Mย์XHอuCฏ$Y\•j ™BgHะ1^UkFB#u%ํํXภ"ด Ž@"}^ก$ร>Cส‘@X\5๒DV"Te(ทืไP‘ia 8๙ iำิึP'"6o๊ษกงๅโN/mGŽพ=8U[Žวัใj~w๗{^โ่miผตLcคA๛…r_)กตRtu U๎ )ฑ€๐€(แD"ศถˆ฿‘•้hoUฌV6ฒืgศVz๖\’9yo‹b86Pพ>*Y.y.~ฺU4๔บ*›Ojซž!งฅ~ฉ Hศsลู'/-๚†ฯHŒฺฺ ตW]=BBธึภฤฮmeL@mี ๖้คร’sะใุ+MLช๚šํS๚ •\๏็ฌ3ไ๕ฉx~ZฺฐญัŠw}ย`อฝพศ‰wEYq45์:กป7ฎ5‰3d[๚เRแhpึ>ํi—†FฺjˆฤซœšถOฯUตJq-ูWฤม1น่่i๐ๆ2ึ>tำŸคpฐ™จ65'up๊u่๑r8\เkฌโ iฌ%hฎถึU๚v,z—๏]๑ตบ็ŽVี`}ซMฎซ๊ษ’%žn*xŠ……<๙\ซจ@.้RrฃŠใ]}ึ'4๏+ดZุลฒตฟ…๘j!/ต_้™ั๔๗ภoZA ู ํWšฌทืฐว‘r_a” #๊ )ึX๊0Rต&gเ ๆq้๕ฐซี๛(g‹๗ฦObwgฏ๖9์ขยm]R–”"#ฆ`ซ‰ญ†ฯ,-,z v๊ขเ ”o+:฿p ›๖บทถFํ dกฤjlฌนศŠ…ˆฅŒฌ๑ˆฬŠํึ๗]ศิฆ{ถ‰ฌฯ,๘ฑEm๕ุ*วž!฿ซ{[;๖+ฺdZyํ[Hl๖= ฌkด "“ฦt—efHฒ*€k๗RฝฑuฒโTฺ๋ข๛ษตr๔w์])าษ+$n#QrึF(‘่้ตv^|Nผกู๐kcจF5C[เเ=0Dqวd ไชจฌ=l hX"Vฦ›&ิ_hฒ:ช&xs ˆ=|f"ุ‰๘ฬYPV๘๐ไ…ๆั#ๆ@h:D$,ฐ`(9h‚็ิ#ฦ@$1ฌ"… M‰วh‘€•‚อ*ฒฒ‡-=ŠJ#ŽG@ปŽGFEํมZม6€&€^`กG›ภ$ฑHb•ศ\Fmเ"2>pClโ1ฃ6 ซย9=€ญw๑#Qไๆ ๑ตศ% !qื›‘ E๑ฬฐซ๐า›_^8,ฮ=ฐ/๐ฉุD™ช (๗A  š\ฦ#อb0`bค30ิ‰ิ[์ม8%ŽีR=ะtภrx†ฤ€ุ่a8D.*‰ล(…ิ+้ˆ1(น+›yไฒ๔dx--QŠ[ิยS9LmบฉRšบNEžc–BลตŠน 5๕tบwhฎาmท]ไ–๔˜ถ›ะฐ$lฯำSัfฐcศฬ*{zก M]t ี™Xt lร‘ฎทยŽlL†สสภf$นใWีฑ‰Nษ~ูฃ@M๒Ž‹œ(๒Pi ท••$ํ(ถPrI^œ!ฉ%PI_(UW]Lณ( RQL'จ@ืV’QP้D;CพฅQ‡ดษาŒB”u น{jสฎงGฯขI Rp้yz6ัai;ขWภค(ง า(‰C{ข9๓3‰Nl๓ ™๘9E๏+‹ยŠ1๐Vเ๏kzšฺภฏv ลฺ๎ฑž!พ1+ rลvl 1›wฦช1!pMค09๊ž!GาDfN่ฦ”z 3žlFPY’๔,ืY^๔&8y™MฐŠ็;+ฺgmิ๏ีlยFJเณ[B[<เQั/#|‰ณ}2ต$pL๎jูไฤ0Zเjสvtฌื?โป_L†หํx„:…‰ธ97ญRbๅ๕g ™^ๆGมV™‰zถภฃ|f@„ง๘lซ์L|gอŠI‚9Cฮ0OVi”bฑ:๎็3ถ€kˆŸ+d้H>wษE›มŸง์พฌว๛y-ด 'อ'๖กฟ0OWUFึ’—ุf–Cใผ•'[vวว|Ÿๆ _A'i+๔๙ฑw:CNd1hJถฒ.H<,ห#ุ,—›๙Iย"๙ึบŒ›B-tยต…ฉ„_\ฐZ!ตPุแๆO›ptfะ"gGใSQ.bผา%nO น— ~สna น4ษ)J 2ฝ”{หš์๋r/X๖8ภBX(6ฉr‘™จeXN2{q‹แv8ƒลƒC,Ba*N0@seไฉ๑IUฉ8\ปRภัdๆาcลK์—0ลŸฏ8Š…กะYiทS’jตuf%'[—S ล’W=ŽŸ…วZžgแ™lย€D#9.Jhd่มBจ๏(ธ#ฺ*>VDCR(ฺR\cลซD)™„…อ%ณe๒4’p•*ฌค๊ZUซH_ชัQฉึ@…ค๕…fด๑4|ชoิํ\“2รTcT๓SvฑvP-Iซ—่SmAญ้ต`8 ฃk;r้hXฌsxCภS=.yฆak}–y}šZ๊&็O5Žำณc0กB:"]zเคpค)Sรเข!ขOŒ‹Gด=5†B2าผพษ›ำaY6ั2ึฬฆป)R.อ‘“๗‘ใฺšMKœ†/-+ฺ“๑0ท ้ภฤSิšRีl€ำ๖;.Zต7ุeฝฬbปขN๋๕u0 ฒ™wV>์ฏืพณ"๑ภB/yl Ё'น๔=1แฮีฃแpั๎NcLนu'ไึ5ถYPSq๘๊้ษ฿ิB฿g๚‘Gบ`ว’ืQFc'ญผl†OYaํw$ฃฏ€ฟXPชๅพ7บŒ›vjญำžIP ่˜=ฅแ)0bฎŸfaP์ๆ<ปฟDฺ _๓:zšmeZˆูA›‹S:Aถร‘ˆeุ>L้โC: }zๅf๓m!r™‰^ฤ๎”)งn";n,ึผุRTํึŽฑ๑bฒึ๗\ฦn๔น,Kอณ!ม๊KT Œำ ัV” Aฒmฃ7O๚;ฯ4 =U\ฟฑ๑%‚eๆ Hฺ3Cu'3™D;S7ณt๗MgŸ๕๐‹•–ษnถ3S{—๖rฐ+แ]/.ึณ“˜+ซr?C/c\พฃิฎ7/^9ฑ+4็ผ(fงล|ฑ/qํ’๙'sE.๕,cX๐9฿x{*F!+šํํูh1มgศ}=gใส?p๛)e!หƒท๋๙๓q0ุ๕ง6VU‹ำ5Wœ0*๊ใศDะซฉL*ถผ8*ชๆ ๚X,ัv๛gศšฐ>ีV2[๐ปA}ฒๆeQมง๙Zl>mญห[“มiผ>‚ไ“t(ู>T0ฒ$,i˜L”zช^ a‡ัTวาa๘ดF?D[ร’#’Xfoบo’๏๕UG%$ หe„Q0จ“M:๘า‚แัh =แ2rกฝCh๗ไษP—cยmๆ:อ,b็z๕h~สค}"Žขร๎?ฒ๕…ฟ‡คฑqฺฯ#h ‡ำำ'‹๕ั>0—ถOาำ‰,’)!CีAงฮฑ6ึxŠๆ(ฝ าžผฝdชว~ถ๎ํ7cง_1}n;mQ?<๔หiู๏๗WL .qžา๐ฒทื58าpikัิษFิำuu๏ฎ+x&ปๅจใBบนg}YำๅHธDZ=ฮ"} ท\bv^ ำ@รŽH˜ืดุNJj@ุ`%b< ศv"aณjฆ@ z‰uอ<ฦ3b3o™ฃ ๘œ*ยB"q๑8bU<€ฦ„" Š+„F ฆˆหผฐ“]ธฟฮUำ'ณ8ม๕๔ง3ไM…เg;<๏Qมใ๎ฮ‡O‹ปฝ|($๗ฒndฉ๛_Tฝ-วดลXo6m>ฌy6sLN฿ึ0ป๙]๏๙วฟํ&ม-ษซ”ๅฅ•š๙›}หว?Aiห ไฎ้M/^6-ž๕zW฿๓งฬ๗๗Tีภญƒ๘hขแš๎หw)@ฤ7%od~๛+๕’ฒ™{n๙Lี๐ณาŠv)$ฤ]ๅธ๋Vศไa/คƒo73ฟ/u๚ฮfc‡u‚‘‰$ฯใคๅ“ึดปถi๛Ds7๑๎๖oฏŒ่Aฆ ๚ภธฃ๑…-ซ4 พ็ญฟ<ซ๛qiมfŒšVพู๏~) ™I๘ู+ธ~|Sผ๖-บ"อo้–๔xz0!๏ฒP&Šบ*1&ๅ ีฏ๘บ๔“วG‹<˜ฬQŸฬwyœณ$‚†‡b‚I€ื Œ๓iMศ=Ÿ~„ตีตู =ทˆ>ณ"ณข|+Ž"ซ์๐Hฌ=;ษิธZ_sรKxํฦ๚–Nป’่ะTf53ถvU๖^pถํ-›šS7™v5ง]†าะg์˜Š๘ ีu๑ญร!๕ตไ“ฏ|1›ม Sบ๎ฒฆ(;kฌjF0๔ต=ดฑไดดโะ“มYทฏŠk๛:น•Eqj]3b‹V.[!ละเช+!ใ|&wม;๗I3ฑgijoเ˜บ๊p&/|ล๘ุ๔Wฑ7Rdญฯ็่5mˆqgมผห yจWญPyx]ZŽ?ถ;ฏ๋ม}๗ข'บ๛)8๋ฐธฅbม็eว‹œ์Y †’ฐpภe๘ฬR$V"^W็ฯ4:ผnภกฤๅล |54ค0ธ=OํU8cำG๎3^KSย๚บd๚JC5๘GภUZผ'ฒ„Hc’‰Wะซ๔ๆญื๊Xo;lตมด๗8วํฌปGมeวฆnŸ ํ3"mŸ๕: z๘UถNƒ$Cเปmนำ/ํ#๑1ปฯ<๙ดฏธ้ฯซ๐m๛เ–ล™ษ5obS;FํŽศผ๊”๛โฒFm›ŒฒBส’>๙ฺG(3าฒซ—>ื]Cัf\้’๓)ญ)*l%mYt.๓QแK๐N<cยV์Vfๆ2E๑v@๐ ฏS|แCt๗“WพL t๖ฟ:ฬซ’บ๛v็ฅ‰uม„ผ๏ฯs>๛๖ผ‹.Z$n›~ำIi๕GŠใ6เ฿\ท+ุ-ๅณั๑\อ๗M๎ึa)Iฐปทฟ8๛P ๕คน—ƒ ิ4pfnถ7?y๏„Ulๆeื_ํŸ”žOธ8ฟ๛เ€‹นอึฬฤv ฎRธdR๙:_•ูมhAโคี๛G*เ๛6เ8,฿t8์f๋ไ๒ ฏaใhm ๒๕ /้๊๊_๙เ๕ื@ึŽ\๙c:ล๘Wพomํ๐Uฏ_รq'ฯkWญoฆ๙ฯ›๋U๏฿ๆุ‹ฃ‡™o6ํ7โโn๘wปrส๘7ษ๖Wปใฝ๕Mใm<ต-ใmญ~ฟ๗๊ฉ“ฟ๑๖Nบ฿ว๑28๗o็ฉs๖7รฬ๗น์=ดต~ใญ=~Ÿืล๔{ฟฃม๗๑o:ž3๗q2;๕๏้rึ๐๗kดฟ๗{xŸ๙.ฟ›ฑ฿็ีฎปซ็ะืษเ๛ฝ^Ž็๔ฟ๋nปvnZฟ้yปlถvวu~ฟฦ๔๛๕ืผŽ}Ÿฺ๋U“๏ื]ี๛๏้s๖๛ฝ^ s~ฏษw:[Ÿ0๙Nz€ธ๋gภWิหฮฯ๋›"ฺ๎ืnx898z‰hปอNฤภอFZRD๎ฐœ,|ปฟบรืำฟ์IO๗๏}๎™ o‚๛ๅ๎๏}WR :๘F๏อ๘mจjฑ๑๖๐๙ต๏[ ่ภจธ~@ุค9@ P4เ` œ,€K€ เธ€/ยhเ.ค@e@5P4ํภเ=0Œ“ภ๐ภx€@`V'„‚€ˆA$ r# ˆไ$ไ ฤrโqƒxC กhH"$’y)…ผ„4A^Cz!ฃ)ศgศ:d‡JรBรE#DณŸF†ๆ!อ9š‹44ืinาฆ‰ฃy@“M๓œฆŠฆ‰ๆ อ อ$อšM(e†๒@๗@ฅ G ฺPcจ%ิ๊ ‚FA“กูะbh-ดฺ„.Cทi้i9iEhฅhUi๕iMimhฏำัฦะฆาๆำVัถา๖ำNัbi)tฌt‚tt*tt็้่|้ย้’้r้*ฺ้่้ๆ่๐๔๔๔<๔โ๔ส๔๚๔๔ฮ๔๔1๔้K่้{้g่7a0?Lฆ3†Yรผ`แฐ‡ฐ็0 ฌ6#003 ไt,B’ ๚ˆŒ์ŒbŒ*ŒฦŒถŒ7ใŸ0ึ2๖0ฮ1™8˜ฤ™ิ™ฮ193bzภTฬิฦ๔้+33๓^ๆฃฬง™˜ƒ™0ฟ`๎džbfูลrˆE›ๅ‹7KKK#ห(หWVVึฌšฌ–ฌ^ฌqฌฯX[X?ฑุ8ูคู ุlูะlilUl}lซpFธ\ ~ ~ž /‡๗ภ—ูู๗ณkณ[ณฑงฑฟdf฿ไเไๅ0ๆpๅˆแ(เxอฑธ ถk.]ถปn๏สูีฒk†สนS›ำ†3”๓ g็=—8——3W4Wื;.,๗.nn3n?๎4๎W“ƒXแัน*๒@คUปGp๏=Y{ํ!๎฿kบ7doษ๛˜๖ูgฟ๏พๆ}XQ„จ‘h€hก่˜ฃุ1Gฑฑฑญโ๛อ๗G์ฏฟ(ฮ'n ~SผPรึศืd8H๐ศA—ƒพ?DsH๑ใกดC=4JN%z%้$JบIfKKฑHiI๙HJMI๓HŸ”‘ฎ–^••ฑ”I้กV<|๕๐“รใฒปdOศ†ศึสฎห’ณ‘K“g•ื•Gหืศใ$์าF9#›ษJสJJลJŸ•E•/+?R>ยuฤไHฬ‘ฮฃtGEญ?บญขคโฅRฆฒฆ*ฅ๊ขZ บจ&ฎfง๖DmF}ฏบตz–๚ค†ˆฦeLIไค529ญนOำV3WsA๋ –ณึsญีc‡yซ<ถฅญขจxz\๏xิ๑w:ปtLuRu>้๎ีuะ-ิล๊)๊๙๋5๊ำ้๊'ุ่<3ภžP>xขีล๐ฌaชแ๔ษC'=Nึั0บg๔แ”ุ)ทSีฦ€ฑ๑=ใ&โ&ืM๊NำŸ69vzŒ์™€3g9ฯขฮœลŸ;v.ธ้Soำf3ธูณgf[ๆวออ'ฯหœ<ฦBภยษขฦfif™kนiฅc•d5wA๑B๘…ก‹โ.พพ$p้๊ฅW(8สU~™๎ฒ๙ๅ‚ห$kc๋l๋อ+W]มฺhคุ|ฑีดฝo๛ูN.ัnม^>ั~ัAแžรgGคcฒใฒ“ถSชฮY฿9รyหลุ%ฯ…zีj‰+ƒ๋eื—nป\Z…{ฏI\ ฟ6y]ๅzาuฌ‡กGฎ'ฤ๓ขg’บฝx‡yO๙h๘ค๙|อ|ห8บoบycแฆ๎องด6อ{nLjfA‚ฎ5ฃ๗กoฃ็‚๕‚๓o1rน๕6ไpHbศFจyhํmกมทgย๔ย รูย=ย‡#T#2๎ะqบ๓.R>๒a$%ส6ช+๚ptr4)ฦ&ฆ+V6๖A,5ฮ>๎]ผR|๚]๚ปnw‡ ๙‰‰7g๎ซบ/r?๊F*้uฒBrF SŠwสไƒ“jŠ>ผ๛”๊˜:˜v,ญไ‘เฃศG[m๗ฅkฆgeDg์d:eŽd้eUe๏ฯNฮกฯ๑ษ™b๖คใ้‘งฯrrฃsษyny“๙g๒[Ÿ)?{V X_HS่]๘๙๙…็๏‹ŽีKg•๐”Dฟ^xฟX*ฝ\:TfXึ\~คผธBฌโQ%geTค๊Fถฺฑzฒฦขฆ๗ๅ‰—อตชต•uาuy๕{๊ำ^qฟŠo`jธ@ลฤl6^k\nrhšiF5ทœoh=๚ฎอฐญณ]ทฝฅCซำฉYZๅ๕หฎ#]ีo”Tu+vWพU|[๙N้]UrOอ๛ฃ๏k{ีz๚}Mว๛  ž์2พ0<9b;ฒ8zu7ๆ3F@๗!๊#๛วไO‚Ÿฒ'N”L*Mพš:>ี=}vz|ฦfๆหฌ็,i๎๖<๋|๒bแูขbgฯ๏—ฌ–ๆพ\๛B\_แXyดz`ตbMsญ{;‡๓ภQืcพ๒อPุh4ู„wลทข„ํ#;ๆ; D_Œ๔€|\K1ค| บRฉืฌ=ฌPh์ม:d=ฤฦภ โr&ซ_ฑ๕/ ๒k=Z™๘_๑๗/M r†เœ?œ| SA8 ŽkVฐ(@#/w๓ด——๛u,๗ั}ขRฟ‚vศwฉTb6•Jฮ…nฟb๚oMฌ/|aครแƒmเํWผtใ+๐MเฏิF€ƒv€B๖4(„ฺ @ู่ ฟด฿&€ะ@i้่a ŒLฬเ•์  ฅก…าัั‚ พะrะํฺ#ซEฯyฺถ๗:—ญ„,†}วJ›ธฯ๔bEๅฏx„02๑๐๒๑ ˆํ?p๐‚ข’๒‘ฃ*ฺวut๕๔ Nœ=gjfB9[;{G'gO/o_ฟ7Co‡…G‰ŒJผw?)9ๅมริ์œ'Os๓๒Ÿ”•WTVUืผฌmnimk๏่|ีื?084<2:65=3;7ฟฐ๘y ทucฟEุ๙ฆิ๓ท๖W๕โ๕ขกฅ…ายพ้ก๑v-Y๚]Zงaึื9๗สbเ:–UฺฤธO –๛ŠG/จย”๎›jฟh๖_S,ไา์ปbฟ๋5h4ฟ4(๘C…B้่้ภFฯ@ญ101า˜wc๙ฅฑ}k๐๏ํ pZZZ๘รฮฬศฬw7๊GmSว(t&(€ศค์จภO๚ท%(๕O๘7'(ต๗ง›”ฺ๗ำอ Jํ๑}  e',<ษA:งเB›ƒ อjขำc›Xม‡w{จDŠฤmำ„กw/ก์&1…ŒทQWษฐ’bฌ ๛็นv3(ห=[*่Š๒“l•ƒ7ณพโŸ“ห๋ํ๐Bวึ.ข ๊nDZ; &Ž[ั\)u™†ืต@ตtM1˜…t“ๅmfu*"ฒ๓DูุEๆ้'ฐๅ์ ‹.ท‘ุ3๑#wัอฝ•T QH› $bSš0XŒ๑mJฯผ >๏(‡4Mอ}๒|างณฬ๐y |_ ๗b …!h2“มใงŠฮง๋ มH;ไิฒNๆ"A๑„ฦหเ :บรT๐†StKฺ1ŒฐO!ƒ•?Mๆุ9ไX%ผ†žดฯก];๙>ˆธOiEnœsEca&T`ึ๙ฃcจภTบNfMgลซG’6ะ-เญฮˆjBTเVj<X„โฯR„ฯูฉ@๏้๏Šๆy’ ุw2€P๒SฅPEลผ— ฐ%็ฃฏb})๔ฮHRI&|ิ๘OŠๅy‚B\ Eดx?:นFb@oฃ๔HG๑YT ซผi‚ภำn?ํ๖ำn?ํ๖ำn?ํ๖ำn?ํ๖ำn?ํ๖ำnvหD7@^ู{ 0meaฟTZx๏=@ะ<…Ÿ%'จY_ซJ•i‹ฅณ๗เ6[]<Ÿ,ž‰pๆฐอะB™8ํฤeŽ๊ไ6?}i์T]N*ฏล>๏Mณ3ZmT—o z,;eยV.-œxั[o:sฟoSคX/€y ฒ็ฝ`๚‡แ7cผฑh็ž‘Ž๖c๏ฺฟ\"\/”ธkใ-˜`u!์ศ|?”ฎ๙ฆฌ™pฤ+ํ2`>Sฒ Z‚๎6ข๙ <œ OVaใฃNhป<;~ยษw=Fiจโ๙Mz›ย1O #ภ์จšจ?๖ %-„C+ใ๙~ฌnH๛๘ะศชa๗=l‚๓aY ษษ‡ฺbคูฬ,Lย“">ฐ`…|™œี ๓ั`๒รLฯ็"xดdEพใqษ+แhฐD{Oeฯพฬฃ%ณžxw‚๖4GโำJฑCu๊Ÿ๖ิg˜แ่ณo$H™’ฦŸ•ฟ—Oๆศใc[’ถ0#สฦฯำจฑ\œZเŒมำ๗A็/๐อึhEา๏้aอ<–.๚ „‹Tภz•’ภGฺOpว:4Q˜ จฉ/ฦlŸy&ฏ์>ื”พm{๔†ญ๚']{๕ท^—8ฐ)แ$บฉX™ฆtxt_ลEOชV†็uGฆฃdรNHŸ}”่a z๏"7ภuZ็q/P]๎Bว”K<้–œwงยฎ'€•’lƒ8Ÿ฿กว็}๖พข‰(งะ๎ฦ๑ˆ;Tภฎ๐™ฦ…๗DxJ๙!๓ํโŠ—bHQๅ๓€ยี ๓๓อตb๎จโ0…ัŠ่๋,,ง„)—igี)๖๖w4&ํKmแIœ็;W~พ{!9Q.หf๋.—๘ก4ฬีzำ)w6ยLหอŒP’U^[มโX[}rตOy๑โ|๘้สคˆ,มะN‘a\9ั8€gพ์@4B๙9hพJYL1qะj-r์™ฺ๋]ืบdใร๛BV1&ล=,hWGฮ€‘” ภH^˜!„ด‰พŒd3ตดg‚QN%f]๖ส฿๛_พ,‹ะิม:(@qyๆณ3uฑœ“โที่\ฤ“Œ‹o|n๘),ZD‘ีFฏธD}E๖สดธ่ศโำไVญUท5ฉ '†๙#+3ผๆL๐œ‡Yโไฆ๓h์…ั โMސm>Bไ-ฤh#Ze„nศางถi[Zก2QŠ๔๎R+ๆMฤ๓s?ภ๚ร[‘` ฆฏ—W'ฯษ’oๆฉกŒ|ใฌ๚ฐnลึแรแ ปf>พ Zžำ#๑HsรkG~ฐm›V?š2๒`•w›SSฬ€ดงqหฑฺํ๐Uฏศ)ก™ฺ;œ]ฺฯ4็ŒwW'Dิ ณJf( N๒ั=1X่บBโŠ๚ภฤ-า—X&Mิ–เิก๕ทฉ™'ƒesPUฅ†(ฃ_็|ค#oA๘ถ˜ๆผํIaNข0ชเฏfl'žยพป?— ุ(ืgปๆC7}~{ร„‘@O–"ึ‘[‡?cvhwžข’0ุ๓๑ โฏ 23ฐอKaฝuL fณC„้%…;,% =ฅ๗_ฏฯ฿๔ษแŸ>๙?ญ|๒ว>œ๒ฏ๕ษ๕žX4oฝv๗T๘KœK{้EฃlBเๅฑv5{้Fโ๓ๆ๏:H้้รจ`ฆพ"หศ4๕`r!ข('3แCQ๋๗Œภ_(]*น9.นZน~YขuI{ฬ5F8๑็ตEzงuธ‰ฐ=ฝ6†มป`แwึ๊๗ฬGชว9=฿5n~ศ|ุCํเฅSZc3Ÿ‚5Bณ<ฑ+พDYฟิ luXƒธฃenIมษd|UีVi}๙‰ฆ;™ณฅ๊tšt\ง> 2ฃMWณ๏ัซึ่ ฦยอุ^u๛0ๅŠ%๎ศB™o๐ฃz2๙๗O฿HˆŒฯฟr+มระ“Oฉภบ เB~™0ฆIEhกJr$บษ ฬvP ‡2จ@ž„%Eีš…M!ลZ*“ƒฦั‹m%kn˜cFt็`zxฅšcIม/๓,ำ€"gฃฏ"nM”}จUฏn{ujพ๏ห%ƒู๒๐ก>ซ”ฉ.˜hๆX4๐กภ=3Aาk”hึย~mถ\‹๔f ๙|นฟศs\n๛žม0ๅก l)ฅ ฅมFมnYฮŒฯฝ่๕’๐I7ฟขฌ฿r;๊pะFข—ว๙[จV™6ิห๊ถŒศ „ดโ8b›@าPŽคณกค๎๔ฑiE๑วฅ!ม%dpeฎRXDe\)ห'ไซธญxKฉ๐ลๅหWูEํ์ํ“]Ÿฤหพ'*b*jฺ ฒฉํำ;q_l4ฅItฃ(ƒ…„gไ;ู่U zไuธิฝจฑสฟฟ๔ุถKฐชฟงE^F€ฑํ’มCค"ะ‘Zัฏ3ฉ rมม9M`ฌ6j›1ภŽ ซภ(aจ๗vh ๔Ÿ;ๅ๕ิ฿ฎก์S[Ÿ๎๊’ทศฑ/&l4iภ-€uชฮp*ภำฅ}Yี='k‘ื๐Hศ—]‡›ุl:ล1 ฮ‘A}7#–๛‰*ฮ*kaซAoง{vLีMฤ์๊~พ๐็:4g0ฉV$ŠขพZ\์^l๊ีรUiiก'‰|uu/฿ศหพฝ—h,๚ถX๊N8Tฝ?3ํแด 6z๔HU๏๓์ศ๘ึ0อu๕'ะฑ๗๒ ด๓Š๎YลŽvO!็#ขOอ/ฉ€ฯัsA|%๊ltF„ฮ P ธไVๅ;?oโณ/Nawบ…ญšจc}9"๓ตbิฤF2๒~ฺฆำ 9ๆT)Cww๋ENzฆ‘ิ๒รย – cมH9…’๑x|CoTšqt๚{๎ฦ(๕แ……ตžิล€=  šƒ๚/1พ —‰ผ๎Dุฝ25๏ำ \^…‘ฎาึ่W‚ุฃqว5–CฯlZoV‡’ ŸชตŒ/๛ภ;T๗Lฝ"ไ8ึŽ>ูภ$q›€š๙(>ัฯ พ“ฌ๘r๑˜ุปฬ†ŽEŸˆฒตr\น0ฺ้ฅ„7จ+ƒ5@^ฆลฉ(็น)‡จ<.ฎSVS๙ๆถ(o!๕ร3ผ$๕ |ศฬฝ† ดƒ=คšt‘ „EM?4ฺๅh๚ไฌS&ป4๚=Zศ™ถ็ำ>"ีeย[(ŒD— ะ&•2๒3VoๅP ‹ฉm๘\๋!^ฑR๎zงฝี]+แณ‚ูGถJ>t‘ภ}ขภ ฮเMT6ฦ‰Ÿญ^ฏtฟ3พผ๋pหฉr)บ‚Œยํพะถ–๎„ +‰eรอ‹^H˜><žd{O;W™E๒ฒ&หะY’Aค๖ย์้๛ม^ˆสj—๒dวrกh๏K๘4F/47ึv)›ตๅ€ปธj2ะr7๋า1UฅปƒmY S)๑R€^บฦล›ใ;žฒ๎ูใ‡4zท|/ฯฟอ8L|+ƒผ–nๆ>-Z2ทl/๗•"“7JZW๛H– ฝ[]6”—M4,ั"cQำ)2œ%กN‚—ึิgื„jo ์่?z>๛$ฎV๗tบ|*ฐqs5ึ์?ˆน7‹ฆ-|/]๎“@&*๏ŠST/c'(Lื‰6$•œบ”๖ผ63—XอYF_ฎเ› พPH’็„š๙$i ฿v๑€3MฟถK„ศ7ะ‘ฮ($gรa๋E,โo”งทšQhษ\<„"I๐YhหŽ],zฦrŒw+ฤhช ฒƒ‰ษSบFโš™rXA๘:L jฆรp›o&+แUBำสวฅ‘|แ'eEiุฎ๏๘ขs๖ธจ๙*๕)ศk๊}Ÿdgw”ๅ‰ƒZˆฤNธถถA#ีT "ฃew ]€Vฏkูžฒซ65,”๔โ#bM9‹'ษŠ๏๋ะuL โNฌuฦพถ`ุีŒฆศ2ง๛๖•๕+ŽŸ็ฎyn๒n18qT๔€`*%ง Ohขb.ํxมฬF๎ €ฬŽ]#q—ใ[08๚‡6ฯืX฿ศึR{]นโIŽปฃ‚ไืไR*เๆŽ.“พลฅ’็๐๋?c„”g˜•]์~เพŸ] H’œตๆ ๎ฦtฤ% ษIฃฮjฅ=‚ใ๒ีพษMฅ„ฎ_ฌn๋‰า โฤ[\๕ฎื๑ฑ6ญๆฦžา๒eŠHษkํ๐ฝGr˜ุบ2M`Cผ`V›จ์i 4sIC๓MพUŒ_}ฎฆauUนสฝk 5ภu”#บIŒ 8"โPวV z์๕E„]งORUฯะ๊KRญพJลน> l-ก†งšuืkโฅ฿6ถอK๔dLมขลฆฦฎ9ธ๛F @y๒Wz_ไdMฦ๚’8(a5a๘๐”"ฺ%@์โƒ3*L็“ะธ”ๆgำG7๔็ขฆ.ญŽwtU„๒๔g;Q๒้l›šคบฟฬ๏ึผ–McŠa&|f(Š’ƒqv'ˆc–ฑT๏AˆŸ‰‡‘ิใO mHฑแืปๆผ…tบฯถpุ–](SbX์าZิโ&ีผ‡ L”ยI'šeˆ T€, A4+™ฮรƒ‰็^A„๛ม ‘ฃƒv๘ปKV๓9wฯ>ŠŒ2/คL4S1็ ืซ)ฬ ขูJ<ูาภhgค‰ุ ฦIV๔ฌ.…RณˆุแDk%‘ถyŸ\PS ๒ƒTBฟ~ม%Gซ้m?SX๚6โ๙šฆฌ™฿*ผVL๛˜m๘4ฬf฿ีา•๕V7ี๔U๓้ศZฤ†ูs4๖ฌ 5฿*rฑDF(DฟEท๒พ๘\k˜ณวำ๓๚6Y]eีบRฆ‚Lฤk8฿™jิDXๅ๎วฐIฝฐY\tcฒา}ึE‚g!๛๖มtำ•ไ๕ภฒร๚ฐ^ไ‹็บ๑ศZk๎Rๅ๔5ำ/๘dผูkŽ%9•+แษก>ƒบnk“6ธ ิ๋ 0้O#ซ๔ขžzf-ํ˜฿suJแญาม#Tเ&qล(ใš^•ฤ<š;h S™ห=3 ้wปCSะŽแแ6ฉ“'๔J๙2แK๘„6lว”๙๒็™7่;*Eœ„Pํฏ/ฌ๊ฺ6>ึ5 ^ื~ญ|๘Sฃ5ฏไ):4๏`NมาNU]เผขO=๙—Œถjž&a>๙Šfดy71zˆ[AŽi๕}Tภpoษj2&,ใb‚†0zคํ ๘lkJ๎7ญ‚…ค ŒmLๅ๘'๕ธ๐4๗9ว ืa๓˜fๆA ำ%‡:~š๎‰อ๓y1ด9kV‚ฦV ํถIฎนใต-iIƒ์๙oา๘ฏณNรu˜ฮุใฃ0๗o”๔d\r๊๙‘"<๗๋vjDหG้Xƒ7ฬฌว+[iทจ€ีBฌ2(วoกmGฏไห'ีแ‰7ชึž๙ชฎ฿qฝโ„&œฟIฑDN&RpŠˆล'|St}่'–`†rฌท3AqๅฮWpค๋0™2ญแอjฐ1Ÿ.=ลัPXe=:Rq›œ;AีMPฎจ€^๚MดaโI%~_Ph๙ณ8V๒ป,OๅO๔5ศ{ šU7c"j{ฺโ#5๘ NSธวฺญca•ทbne๊S&ส>“๎xA; E•M`uAหค87(,%—ี˜๐JึM"ฝซg'T[hณต๋(@ศ{ศๆZๅ[โู‰–ปไŒ๏%‹–ฅ๖QfyzŸŸŽo:gŽ๗=#กล—†/ลฝ+ึ9‰%/Z:‡7tUL?J้พw#qก œ4ว๋(าส‹Eษ `{ฬญ@ห@ใs๕ล˜แ‹oEK9๑•.,9B50k#-xo์ย๒0ัาภึตOสƒ2ฤัใ‹ใฎKœ"NP%ศAŽGš ๛ล")’. ข Kร‰Sย฿ZQ่*’P Pp3ˆ๑aผ/hp๔(ฆuGฐชม 3Etฺ ไ9วŸ$ใบืใ eฅ9”“-ใฐ[ม๔$ถฬฺ]q„ŽpbgฆถZ\ฉsNm…oฌฑŽ่ำฟrฅส๘Gมl๚์l๚|mฉฝ๔[Bˆฌืู7r+ยึ'Vk:ธํ๒pั6?ๆx=ย+*pๅจ^ถ%&J…2Œt฿V@GOเ%—P;b…„œL๘3ฬฤถ*ๆ6 /V ; ๆ๘"T›๑Ÿ?Žสป๓RIืAR” 'wซธSn)=๛fึAH: gdศื฿#7$–(ก_J๏ฟ<ษอƒ็๚ nํ%9ฌLฮ=อsฏCฉ{ๆ[™~‘๙ฺ )‘ญฌLงPปŽะญฺ(จ^ฤœzCwฌ๋เฬฌ,ฉH†r็รAEัส„Z’ภ๊QI XฝปA  CFงโ&|9Œง ฅไย้’ๆhtDขŸX๓าึวJ_p๋|3‰ ษฮ›™“Oƒ๎ฃ›,ฆ_ลใq๒ค3žT๗’ธจภฬTแืKม๓ไXŒ5<UI&ฏๆ<ฝค3U[\ฎœ๚ช่€ำ๚รVวŸŒš๊ำ žใxYึ_sศd,ฆฌ'b2ฒ"฿ๅำกZฤต/ทโ‰ฒใบq9_$7I้ฌCh๛ƒ$ุำวา๗bW‹nHg9๏Z‡…O–\Œมิฑ้ถ๕.ชโญ่า’ๅRฌ๒$ˆWำ™DDคบ=ฮ?๏็o–ฌ๚ๅ–ุๆ€ุีน7๊ใoD„zระE๒t“ pฮ`$‰8‹IขŠ ลjืgฦ๕๚gสc[ \๒>ฤฆ(sๆี๑ซึพf‘&ย?'ฌn5ฉGJGdเe;hฏA’‰ษ;~ฦทeุ3 ลแ$zo„นฆ˜Ÿษ‚f_T1๒b5lXฉ่T๛ชbศืค๚c"๓mูฮˆัค;Š$E’ มฆ€ฤKจœ๎ ป94๛.G฿ื+บ๒ฯ’v—ฌ–aาโ Rˆ&$Aฏa?มjฆ*ษฝชฟ-9๏ไฟอNฃ=ฏ'๙ณk็้ฦLx{ ฃ_†9ึ<ชย฿qืถ@z่ wด‹๘–xe‚],†ฤeรยI4tBTˆท‚.ฃ=ฅฏฌูซvิฮ็ฮnŸ7oฌูำฦ)K๎g๑f‰ซมปO€๑pYยุ†5ฆpล/gMฉk์ภ๗YเŽ กOwถจ^*b:ผฤโ๓fืau>สeด-2d=MฮQใภv้วิzoฎ๗<ณษ์_ค/ˆW-พฯฮX“‹$—๋ ^ื-=žล˜š๒lเรLCh9๎บคpแซค3(vฟc”}tC๙G์๖6z๊๘ะธF"Šฒ๑e[ŒE$ุ+‚!๑”ณ๐‘สฑะ้UEฎ"|ฆ๕Ÿrจw๏=ปrh‹>)G/งฬG˜ฦไ๒R้ˆB_vิร_=] ฺŸฺs&Dโ ณม1Wsฑ…ฬ[{ืeทไณ …ฑ๒tโ] ๘žBCrมฎEช)๎:9exกH‘๙ลสฏ{๕˜žšแ—มsฯ$ฯpะ")ฏ‘`˜F“๘ฦม+†ภฮcFล)hรฌธv๛’\M]EoฝŽเ้†W> u1ุ ด๗u‚6ศ>สนžQ"๎–$ค]ฦŽ@€ธ5ส$‘พ•ษ[#xไ-—Smใ*€U๋ก9ovฮxิžม๊>ฉ@ื@น์X๒™H|F”K’$‰ญณ}Qt๔,‚ dๅตฃ By่๕ฺ`ไ28Lˆ:๚๕d9z'ๅk8ๆ$rช+ฃฌ‡ฬช!OWภH›4ธ6Q๎@โŒ˜๔]ฎฦ!(<มŠ%ฮ*%# ฅK)f‰ใwV™’]_Xjއ7ลgฆร๙B…™›(ํB9ฏเ>fุdf(!ล๖ธธ…ษ-Aา๔ำy7์ัƒฬชฯ๓น“jLฏ  P(bQงฤurJฆ๗cุต&CTขHU„*@{œF‘\Jัุ‡ฝ‚fซtฉ–ู๛9*๑s๗rIZฐ4<ธ๏FFBช%ถษ`y*แ‘j๐ขOดอ}ญฏ‹U,ฉLzqฝ๓kเ๎DŸ ๓!˜Qฦ๔P‹ปๆฒoœ™ฤQช—9L๘ธlฅ0xOWผฯ#Y–ฅN ƒ.๎ีŸp/|y=รup‘ย Z APšณ#DโNPsี*—2ธฃ‰ ้Šv&ผ‘ฬyทึึณjฑV๊ีVTู’wปฮl™๛ส+Ÿ้n-mไทท †ˆ3Ÿ˜๓W}่*}ทCญs้fแม&ุข ัภLOข%งIฦ ™ค่ยณ$ƒฮํ<šฐ$_BQsO’๛mถ๋ษเc1ๆํยา <ช”nแร8๛ส้๑"t›ง‹oตrปำหษุส๎ุƒq0kไๆp{Hข1hจ&‚ชน1œPง=D์ฌQCีKQอpS๔ สๆ•ไƒำSืpP‰ƒ‡tต`๏‡geไ>ำzŽ)4ิO๙ึ๔้ๆะS๚PWkกมฏฯSฮŠUธ์ชีwุฤ"$_\œ&X%Šะ'}๛†y—๖|๒๋f์~๘สcIH ๑R:K;๚ๆ๙๚N=โ&"X2ณซ]ŸB…ง3 ี๛ฯธŒlแฺ•‰KซN €žภ‚#lM5#‰หฃ๛XL"€ฆ๗2-œY๓ชฆฆ๒ŽU‹dkพฃ ฯ ˜3ฌไฦฦฆ๑๓ช๚ฉN qG๓8๘159*šdย9) 9Xใืฅธ๊บ‚qา0Kข_(B•ำฎm&f“ๅำฑียxK2ฎ„†œฤfE‚ “aงณ‹†ข๓:๐CุทพฮปT๕\ณ๗งผƒ9o๓=c%x',zๅ4๖i‚๛t`UuŽฒ€Y6งW2o'Cœษ16Ÿฮ‡wZ\ญ7sAHŠ>(N๏๛ุำฒฅrึiซืneแไซขeๆWiภฏgฒ+ศœฉ๑ึ 7๙ษ€`Š]˜‡็b#ภ”ฯ6JธงŸ&YGฃ}฿๎้ aๅ_žŠPึฦษPJฐฺญg_Mด ๘–(l7ุาฬ บฝนท\๋0WN@H#:…ฮw-2Xg{ว^oe[๐้N˜ย`๋ฯwศใ/Aw"Tบณ Y–&Oิฝ~าO˜“„อ›ีม`ฌน“๔ฏfฟ$$แ$NM™}ภ๏ุท๔A3&›ืQ๏4 ” Ff๔ะ๘1ทฃ8๋อ๓ˆF๖—ลKe ++R๗<_.,ไ$๛์1ี’ิค%ย(;ห ุฬฯ–ก3ฦŠ+฿ิlkํ=ธพb}ไuะ Qซ+วa(‚จภA~ฌัฤAฐืqjํชขž,<;ฦนศƒซ€๙Pว7 2;‰œŒC–‹Gฉ้๘ฅ™เั3ตƒซy๕IW^๕ทบˆต<ไqUฟcr~F๔‘/ธU*ฬทฑ‡P๔2k๚ณ‚๗๖-ะ็ศษ่E'\ๆ4A*.Š…๊V`็รr 7๋,?๛ผkตyGหPwเ –oฬdu>ฬ๔HEฎBฮ๖Rdะ#ๅฯะ‹ษ%ำq˜zD$€{G#ูHzุ7ญ‰=๔)ำŒฤ‡Rgผขฆ˜ไu฿g5ฅK ฟrคไMฯ_ษ @'ฅน๎‹fภ,๖S ว’Kฬa ntำ~*เ€ผไ ล![า๗เL?=›Š))สฎฏ/๕๗Mๆ|yฎlตขn›ณ๛ษt(‹=ญ‰ผ+sๆแKนL)ฺ็7œlฬX<,˜w 3!่J฿e฿้’•"ร!‡ฏ๓๘žกŠQ;+ ˆรZQ|rS3rœ›\pฮS›ปี˜vฑLGไPWฃ 5vญษPMฤk™P๔d!ช }ป่ฬปต6ž }Q{ย(™ [‰ๆ๊ม77ฌฉ]นHณ๋!ทฌ"ทฅ1™\A่ฒ…˜UแฏญhฆzeOฯ=’_๗งั๎zฉ>ฆŸฤ?:eLโŠ—Gb โป)G5aุm๗ฑaสญOผ`MุCฤzฉ<™\„^šB“x?P๕‹AŸั-คฬŽ˜€œ2ฬกm๙ัฝ๚1„9 ˆ‡ ดฬa\P;0?(’”ขGาฐยWRL฿0*€EyRืฤงT€DŽม,wBŸ yฤ|–ํจภ๑}R.˜น!Xy~ฤŸ„^M!ฉ~ลห8๘๔“ ณh\rj"ฃ4…ผ+v฿zˆ3MนY/๔ฅDีขฐk=#o(‘บ `้8@"‚‚ฺQ'พ๓ำF?m๔Ÿู่)ชRฆ%ƒฐฟc9cJf#DR่“Qฌฐษ]ฌjื๖ฟ93๙šXฃE\ฏS†!฿9q4ŽCsถ•ดฤำŽ;bNร*ฏ๕พ่cMฐ๊“คา7ช๗> ‘ูAa'Zฅ˜๑h๐A<“ผูั}ๅฅyถส7จ”าIC@7ๆฅ ๐\๗หhM) ŽJฤŒ(L~˜6LYแด ํน_ฦvmsK๚$)pu฿ a6ุฐ ๓*z[:žPฝV\šk L˜lX ‰_ถ rํp(ถš‚"Z‚ๅ™j3 ศผคณตศฉ๕‰ส2ด^ๆcอร’2\บ?๘H&ผyโฯ๓/IHŒๆ/—๎๔|$ษŒใ๔9EFr฿[๏ง‰~š่ง‰3‘mึ96:์ฟzํฺ ๙`ภส๕ถฎ๛EŸUQ๋Œฺ๋G.RCฆI‰=โupƒ™y#yะŽษdฤ๚ฝดk™'vp,.nšJlTส.๊>9Bo5ป6R๗ํAy |แ€5."’…ยG๐JไT*‹~‚JrOWๅบ5ัCภž^แ(q™ษI:Bฐ ๊P>b๘JD_$.ดŽQฒ๖พ-pQ^nฺ๊ฎ–ๅำแhNค้‡Bw‚ษ ศ+๐0D™yDyfซb฿งVN“a7š๒!ฝV%ว๙๙Gž$OึษBšค=e์ฬคqศU "@บืบืห_ใD[ษ๕ปP#ตˆ๙dฦ7ฒโ|PPื๘‹รทtด„ Œaฯ๗“o3mจฬv.ๅs+’61เสิZิj2ใ;ค))™7ฦ/~{ฌ™P8)"dธ;๎P„Y๛/Œ{Jแใ^?Œณฏพิw๋%lง้ึผ๒ๆ>ฎโง‚๔f|"๋ า+J๓๖,†3€•าCฐย5[ลณ 'Z\ป‡wŽy™`ฺหจ@ฒ!”l!ยะณ๑z ษCp่|๓ ๕6 tะหi๙qฌS,œ๚`J›–-;ร^ p+!ˆ]ส˜ฮสฐ"?ธj๓b(๎๓I)อฆบN<9ฑใศ๙งซึำJึ%ฬz9h`GŽ&9y>ัc$่’ldำb>7EsNUิ1”uhX"๖ษJSใ.‰ห—กDก์zๅIุ 'ถŸ„UะP%\,(šรtฅ๘$ZหHฺ๏ฟ๛Aู eญ–œร๓ฏบฉ ๓#๒lๆ๏$‚ พ\ฏม๔๚ฆผำ๐ี†ฝธณVหGD!‡ทํ๋ฎg์Eœ Y๋ๅŠํฮD']%|มvเฑ:=๑”C.ฒŸ-ฏ=oํรEฃ˜็J8hญม๎๗ื่-ข๒%‘ษ2ใป๑B!๑ยืฉภฃ๛ฑT 8ั›วRจŽ'๑sKะชaป๑f฿ฝา๘6šฦบ2ัjND OHืฤท๚‹ำฑFฉชBƒ',ฯ/ˆ]9ๆฃEsํ’ž;‰วจ๘ฮn๒ไงัS/—ใึZๅ„’i“/ืฬฝำ“[=ชœg๖kฝืจlหภ์า๐‚เ=}มu™PD<;R๙*k\=>l$)๙ิาN$฿W”wl3}gj{68ฌญmžžœzฑยวว'แนI รt”ยnS.  ๘ Oญy้ น 9™žG:?ึ@๓8า#˜I๚ีั์KฮBˆ—›u‚ขไf ฮ]zเคƒ:škวพดYf๗D๏%8ฮ-ั็-mNเS๒3ทศ๚ช๋“F~3ล/สหฤ›$9๒๓ >นtA๙‘ีš—…mO*W@่หŽ4^ R Ÿ ง^ขAะ› &คณ1-&”"ๆดผอ[บFg๘…๑| มV„” pฝภถoœi็‡*EดZIŒ.X=>†ˆฌ่รถIด๛๎:ต(อลRaWv๘DสY€า_าถ6bNaJส0ฆผ#u>jๅ๘ฝย7ู ฝuv๏=sฝนฺ้วxŽNฟ|ี+ฌ๒ฏ$น_oุ'่ห๔Drฏ‘๛ กฟำ.‚็T v{บส`ั†:DฬO_ฏ้#9งg7ฏ\ใึตˆ„h‰2QnHยมต่ !ํฉ๘ฆฃาjŠXrด๖u฿{ž%เh๊BžY ำ๐๐บฬ Axไ]g CCXด์ฮ™ว Tฌ‘มบทRฦ%az%มฝxั๒นฝjดแq*!ช…็.๊]fบซฉ8ซ‰่Š_yMhqห Rkญ่ฐ7ืงัแs1‰nคิ๊ซMฯุ=%”w๚VŸf %–ศbษำ•kท1ฃT€ ้hนูC—)Y้Y๋ฒrPๅQง•”๓๚ฬฏŽeRN๖๓‘k1“Iฮโ&„—Dฉ๓’สH…- ๏:ี๚T_;ท๙‰,*|^ีFQ{Iว:ฝยึั๚‰w@dะ๋๑)ฑ๔กี1d์๋I^ข์…๖˜xไ(3~†PN"คั๘อฉ๑‹ตH็Msว๘กฎ‰†WHMืžX‡+5r๗9fะธq-ล‚tฬ€Zh, s๓๒N฿฿|ัโmLฏฌํƒYิ)m๘Cรƒ,š๊q?@ญ๓ฯ Ÿซ/Qษ#ดr,mJfน|rg๚Xื—iฦธoฅำห๖นภ‘Qkญ๖ํ /๙Š Rฎยy ํ 14D'xG๎1Œ-kmIษ#รวุ(ำt{:็ขhžb—ฐ๙Yแศ๕ Š'‡ึผgเฮถ๊W\ญxQ๕ฑE๒†7ฆ%ๆ?oฅ ๕eTฦw ว:๐7ฝ7ไมJLฝ38๖aว™DํJ ลา|‚žฏ๒๓\ƒj)-ุ฿ถ 7ฺ)M฿ฃxtน^ญอพผิบ๋ี(ฟม<โkทฝฺ่ผเUข8^™ฤ๔บVํfํ!ฟ๘Žญำฎ๕C 1Pžฉฏฺ๖'/FืัํAุLZเSp x๚฿๘?zษี {ิ%็Iื{Nf์kฆปrNF7ึนzKๅฬลmšpึeZ ๐žn™dกg0†๑qไะลO .Œฌ$}ว฿ห8บ?บUc“;sŸsmD‘\`ฎ หiุ sฌ5vธ•Yf฿ู sทRท™ซขn‹kํฦ‘ f_Z่์€Iคอฤxส”๛ŠหŽม—LยXปศNx˜Zp'ะ่T๔hฆ'ู ุNชฤš๊ขvํร@ฃ0ู.y๖ค/ จ๛[ข/‘dขv๗ศ Œwต๗Lฟ|“S>้ลศRO๏น๓าVฤGz๛฿>นณลณ>PุGe๚ŠŠF๒R„ุฐฆ`iน3 ฒ?ึ๖ฐํนนป!fljeUlšณดมpญWฏส๛ฏ. (๒ฯTVV๊&[<ฝœะ!ภฺฝ๚6ธ ำ„9$*@๙€ฦš~–ฦThpฝแm?าเ(Sๆ‘ผmญ9=๗ แ›‚ทm‘Jใป}ขW/ํฺ.Zjบ_ฺFณขwhุฝ.zุ! )5 |`—ณธfpาbAz๏Co)!พ{๒>gนKX่”Bจ!๘@Up†vo#dู€›”b;?/Ÿ”ฯKP๑šsMK1Jใ1I๓“ๅิŠG0 ฑ์„๏ฤ"Dเ+ณ;oฟ~ป ?B6zS_ฑ† ฬfZง}2h๕{u๙A„ล ์ฦ–c›-วu›1ใ๚,UคpLจ่ป—ฅ_ (๘9C‘ญ็ฬฑœLtื๛2ฅ แ-Xy$pโŠE๓bižฟ๒gฃdอำ๐ยฎƒสซS7…ญม’ƒพพ#lฐมรจ`|,‰๒‘Tเั7\šฌ้„87cs6้ศr+ๆ!๋Žk€"_x๏› _+Zฑเง#_†๋_’Œย›ก"พผํบษž{๑Lล…ุ7ฺ่๒#f…ฬ^NXอำื้4u˜ˆI๛{?Iฎ พํ๒"ธ‚FP2ฃ๎H้p0™ๆ$๋ธภวคIVใ@5โ6flsบ๎Fฃธษข“aa‰ัOK'ฅ)}IฆึC}๙ฤ%ฯeภีAG} 8'%Ÿ ธ๘ฦg]แz+;ใIŸ~J๛็N/ปญสKฬi™โ๘ฌ๖มzถ๏ึt`ป3;ดธเa—ฤ๛•๕่žT=ฉโZ‡เŠ๎ธณ ด…๘64ว|ผ-ๆcรScx๑-vIใY้Bnโฃ[ต$;p)‚๑๊2,๘`ํ1%,ค˜mฝฦ-iง๋๊Qร1ชฃ๒Œอฬธ8=ช๏d2ศ–3ซGณQ์๗ะ๘D๚ฆ:ฑื|ขฉ€๕…„๒ฯะ{dน;;5:แYi*้ƒžู?หj mฦp ™บื?Hฺ \แ.ฯ‹พว*uทwถOwโFMม~"Šti\nxณ็Tr–๋เีแŸโ7tƒHวuMฬุy]a฿ˆ.ัShดQแ'Šาo฿ภq€32โxr4๖เfร&‚ไขwมไาIมg๕ืั่+,ง‚\3ำŒW>อWJšษืื๑๚oํรโ,บƒƒ „แHณ>‰œ่Xr๖cQ`=๓“่ !จาs†๛ำ)aขqhBผDdซๅธฅœvg!ฒnึม0ฦฺˆ ˜–)ceํป#O4:็Žฮžๅ7๖o~วอิŸgฆ%โป๑ฤธะ9ฤ:3‰|ต!ฦ2n๎์—’WžŽL%*๏NฐsŸ^8’2Oไzษ„‡ป๎K +RJ?h|๙NKkทท๕žcZเ|arx๎SDyWโใv3ccู่ธ%ก•x‘ไ@4'มš‚ ใ TEโ…ข‚+u”w}It.๛ผฆ^1A’žม๋๕^;&ž+สF#dศ1“9•ฌ๙™ˆ ฉฏซs˜\=CyŸ Ežึ๎Lเ”•’จ็ไฺf'q์nฏ'D2iqร-ฮz qญ)ฯeฮฏU ?†Rพ+j๚บูชˆKJไอŸ@>u๑ฟMชหฎ9แ5ฅฌ์šโG๑mุษ๊ีฑฑๅ:นJตI5a?แ‡HE๎๐ํw๊'ุDส^ะำ—…›ใšี˜ฑฤYใJ฿็ทood/ฬ”i†ฏH'TvvDeGงEฦ„Obp—’%ภAอ)ฒ>ัฯGO ‡•“ไžT ด…ด๋ผ0–|‹?cใ๛งไM|!Š’๕ฑŒณำฎ{b/๚ฒญwA‚ฏฅ๎บ๎ไค/(\ ขvˆ~ฟ๐Kƒ>ํ๕ิ๚ฺ่ *ภ๐ื฿„]ฃqPศs4^(qศ‹ํฮ็ฑgำฮง๘Žfjแ˜๏{แจดC”่tfธ4EAโ- ั่๗Ÿ๕„I๎Uƒ๚ท|[)U3Fฃ}i$้wˆศƒมฎ- ์Ÿ•๕”fTดฑ&4N—)ๆd~ydŸำัฐนข7ฒ‡Ÿž%) ฒำผž้ะ @puขๆยUฌ๒ศเtCแB’mมขW†i\[hาอ๐F,ๆF˜ฑะ,ไร™iVwฆวจs=ทพc‚VŠ๖6:0๑ž‰|y๙ luช20Qฬฯ™๔sฤjๅค7ู’ฑญบีs?zา"๛xบX‰>’ฅ)ŸซถฟwŒ’Cอ–YVš†[M.ณฑte๏วฎด”ีฎœ์AfRL|sฤ:ถ„นj^qบ"ล_^p'รอ%ลY*‰ต@+๛ษpทง๐3ฑšคๅะ๗–่d–ฏบnMจ๘T‘}7ฮ†SตG~lฎาˆ‹ปึ่9 •ooVM~ zๅ=–y~@๎ำ!ณ๏็4ฎ7BF,šแฺฤงำ–๑ ็ร:<ผ๚นZ๋G+Gj๊N๊—™ยTหƒI๔Gฆ#<๋x~๚ŸŽ๏๑R˜๋nŠHBy๎”-ืy?ฒ8ีึืฟศTาMy›๏ov\€ผ๚ทhnข};lŸิญญ๚ศˆ6 ีโ๘6ฝิuƒS”%9ฤ”[ฃWฅ#lฎ๏Ÿญ…๓]#ฃฑแavTตH๑bEฬฒ_"๎xห”!u7ŸtสŽภพ ›-Rฮp&ขbฬN3EP‚ฯธBd\ธ7ิ€CyPCE ำโuKรFเ(ฉTเบๅ#*Pasxง4ธŽ •๑ฎฐ๏"cมƒ-ฉฮN#ูบ{tท?ยgš‘D  Yyuฝ๘"า™ูขฦ`•m.IํๅํอL1‰ซ{•œ๑Œ=ฤฃิp๐|‰‘f8…!t˜[ษˆ2l›าช๗IฑD}sฯLต3}fฮวU๕ุzD๖ำwํ5[ ญŠ6ฐJๆuw’PŠป…Wh!aelชlมม ฃ๕„DสOHธ<ิ฿vืฉ่ ˆ}$ฅ ใ‚ŠยTฃc& Tฮy วy์ญ๑ ํgตาt๒gLzl!'ภ1*€.jฦŽ5I?—‘~ช>>0/–!Bธ…+ำณCd๋๚“งชูC๎ ฮiCV%ฏฯแ฿2ึ:ก„ˆลึ7อuลฦ=\ฝŸeฤฒnญฏIี—CฆRวce้‡1^j“ณ˜๕wT ๙่๕๔[๚Œf_./ู๕^€“I[Oบ  fล๑ุ_ฐ=…[dลฉŸป์๏>ล1๏‡V‡ฐu …I6Aคใ๓89™…J9‰ัค๓Žtิi"xณ#$”อ8จทQ9ฤ*2ํ8ร๛%๗kโIRสbƒŠccใ™Vu๎ef–—Xต๐ฒฬ%ํ็ยูำู€:๓น๊?ž™พ๛_’แ~D\ แ1NซŸฆูใ๎Ÿพ}>์&lžcV•7q…O<~ๅธหV™›œeู€คฃh=”ฤAvค$‘-!ฅ2ฝ]›าฎ(yไIUู%>ขฝ4Wหฺห๗Fฤ:•PxCตดณฆDณ๖ดi Agึอ_+C•%g}7ำUพปT:v%เ”[ำทC”/xฎ˜ˆเRะ”ษT๚bๅโ1!ํฌ‹%e}| š'ีฅnย๚ฒึ‡iฤดvดๆ มํ)yฅEฃz‚9E™–QUU+}Bvyใกy7'ฟเZŽ)xซ๐`ฤ๔…U๗Šก%M™H–ฅ็@จ †xd˜8๗#^ โp+ฯd>ฒŽฒL‚{๏วA:่ฑ๒‰iื#šEŠT`ˆ D|@L๗วI๒ ‘๏โhฺ= bง!๗qธาวX‚๖าwEัฦtO"…ฐไs6 สฬ^ดi/฿๕|็,pm\อ๓9_ษ„ฟฅ—นีึื๙ฅlำฉ”ฐผn`ev โdม้ศ^?fูl๒นฟm"ฝญำกY†*}๐>!ซUIูซŸ‰ูmušŽ๔O๒\(?~IูมyšlDบƒhบ๐†Ÿว’5w$…‰๐ษ็๏฿wล[ =มr"๚f1E๗ขไธพc‰s฿ผ’ฏโวฦเฤa‰Ž่pHอx้บ฿๕/Z+zeฦ.h฿ใEศJ;Kชพ3%แฦ•„ฌme๏3n๗๘”ท#ีทuโiHA’็bO๙ท;~๓ฦฅy†qA\+ ท) /ุ#ษ!)@๔.Bผ๚6๗Œอ{ถั-5ผน= ็=ใ|้๙้ๅ๚ำ(†`“™Žจmš@๓™ก?oŸRีจ~๙–e.ัDแAืMฝJ^‡XนXู์•[‚ฉง=๑7ฤq มญาW”YvซAอ{hjฉะK1'ะaA“฿ทžฮ]ฑป่9฿ต’5๙.ๅqƒŒ๓ุXำI‡Žป฿=๓Dพบ๓E(Ÿkเ๖Ÿ` ้฿฿Z๚{้1 pสsŒxˆญไŠbŽำW\=0ผAฯฎข•ีw๓๊๎๙œ:บ‰:๊?&๑; ’!ูดฎvไํเjษฅCKฃSญ>ม๗สyมVIไ”Aœ–๒วบฯฬ?ๅ7RฅณwษNำmx2’f.?๋ฏผ‘p๒แa* ‰šmข™~ิบ‚ฦˆิเWผ๐๙q_ B!หฉสฃ›‰alซ|J…ฌม*้์ตว!คw๓นึ|A>.VฤgŸ*pเ:˜}Mต4รถลสฉ@ใ/โ[๐˜‰@xก๖d๗๚)x2!ซsญgPณH*ะ@v‰ž$๋ก3๊ธ, ำ'ฏ*b’ฤkI%0Vฟ’ ภMจ@8HOrC (Œ 6S๋wฺํSษฤ๓zrTภฐBfง™kิf?€ฅภฒ„ `yจ>ั์_มi๖Iš…‚ชะ๒_?V๘ซ,&.า7ฅณ”พ iEฏBpะ{ o˜;HLฆ๑4h\‚ๆ/h‚ๆ/h‚ๆ/h‚ๆ4o’' „&"„คMิด๎ฟนทeีqฎ<๓ฤ&ส~ฃAƒ คMfFh๔Ž-ดถฎBr ๛Pชเ!žพ%ฌึ็Iฦ}b-ูแปRQศ๏ฐ'๛ [ฮต่ฅ<๚ฮ%ฐSส/อจ8อhฟw60•ฌ“ํ9ชยXEŠ ํˆ๏ุ]รฮPฟฅ็:]ฌF๒ฉŽฏmำ2Œุq ;/EนฃN๗š"Ÿ7ม&yh|™Fึ ?„จ€ฌใ๏@๋Iฎ/มๆเร{P"฿c&dyI^*-dhฃm๏ ิะ_อฉdฌใW]คฌ10K:ฎTเoKพK-ึษฟžำฯฬ_=fƒhv™Qใฃนœ็ad[„8๘X…ฟT:Jยฏž๛ีGย: a๓6ฟล&หaล1ผ ๏&2P`0 ๒=๙Kv=ฌMฟˆ$>Jธ, _ฑแึE9๐๒ฺสŠ๗Oฺ™eณj8ชBำƒ0l˜้|D๕NcŸ™W้๗ะ’ Guณ ๏้fศฯŸเฤˆๅว๓็hZj ีณ9ฎฒลเโ ั*qะค]๐ิาใ™ศ ๅAษ“WสฎVh,๓็๓šฺxp„็ฆ3โท๚ต7#ีyลื] @>๓EX คฺ,P9Sิlำฯ@ๆฌŒ้˜’ฏQแํ;tUrฤฐพ=่๗วE/^DVำ๑B„aJ๔–ฤ•ๅ์ไฤ๊มํ'ษfŸัใT Gƒ1oไ b๔๔๚ฆd\e๕าใ—“‰kฺOฉ@^…"b้ฌ๛oึฬ๓W`;ค†+พi๘:ัvึ#๑KOˆ›V}C(ฒ๊‘+า๙'๊/‹๘Y๘ ššฝ""‡$„S^ย9t่ฑp ๕q๊ๅื ๕—฿ZฏYxซš/งฺัs–|ฐ฿j"Y‚Pฺ‡ฐŸ\ญ[ี‡่ธ*ำ๊xฅ\gLภu˜JผำU:๚ใว{ฝฦŽV๔~ซฮK‘ehฒ€ฝ%๘ศE๏ฑืัร‘{cR zิ-‰f›ฺ‹ฏฦุŽ๒่EJ1L$ุ๐‰ๆjฆฌคกฦตdา &I 9ฆDhฏzิฏึ์}็‰๋ใ1$แb,Eั…D>.{@ŸoU ”ำ–ภ8m%ˆต’ฟ ๙ šฟ ๙ šฟ ๙ š.hธเํฃUล˜สe๒โะ<้ปLจน๘฿ผ)[]O> ™ัฎ1ืLท์ไ# •ธ3@ท?—Tœ#(gIึBญตI ก๔E5kxr}ซฦn,ๆ๊œท^๎ิฺc&B4น๊ซซฎLw‹ŒๆJ๙Qa^ฉใ+eจำce–ศสๅๅzOำ๏น|HžฦtXFaช„บเG›sU-Reุนใญชy}T๘ถK็๎“ )ไ•'แWลซจt*เ@7ร*์›฿|๐,)ธ-Jศwœ4า๑๖์๙Xใšzะ :ฃร0 r๔0ิพR๑ศM)@ำl‰!Fjฐ๋t๏ภLUอsฤฬœ๊๓‚‰+‰|-vฉฆ๊บส%ธC฿˜ฅ,0Ž›K่S๊ม“.B’*๘คบษ๏ฉI=Nb6^nษ_ัี1๗๑๔บv hญž 04ูq2–ฃzw]˜[!ขŠล=Aฏฯส–ฃณฤKK ฟซฝH‹N—๑;’[8Šqก‘AH ฒ"จูษ›ฏ;iฎqึ่. › š[+ˆG“qๅฌIwSุฏ…=7เiใท:›by|Žฮึฦลึdฟด‹-ํ฿… ฑ$58ฅเุ›c›q |Uรชl^๑VgทดXŽ7j\5‰$๎ฅYอ-\:ŽBD@Sฑ“ž ๋ ฌK[0แ`ณqS@๒%kŸRaŠ€l”ร†ปง5ุa๙Hy๑ฐ๑หู๚oP‚7q๑M๕ศ๋•Cธrดน[ณํ฿'3ำ้w4%a*•A ษ'žc พ่ฉฬ† WŸ’ฑ‹4๗ฌw๘ขg}F1#ภํ”!&6้Kธ1L\ฑษพมแณ3p(๗0+oz† kชBรผฅ&L็“ืฌ˜ fF๐ O๘็U’E๘'P‚*]ƒ๑ณษฌ๊๓/สx‹ำijž–d้ซร<5u,ฮZx๘Bัœ…ง-%7œ๕ถท๗L(s่ี ๋ธ๖Kอ วๆีฮš3)I Tภฒ็N5)/}จ€{๒๘ิJ‹ะอัถ†Aƒฃgbฅฟ๓ูฐฮt<ฉํš…iยI๛ ™ฯ•pชšR*}๕œาA{่1Nc็ฌ.D๎-œ>/ฮyป?I:อ๑Aศุ[ต@ถฮมXิฺบ;ใS•6ฬอ€ฮzญพษ`Dู’YibพOL!ฌ๚ศ’Dพ‚wqศๆ{๚h6A3ฉdฃsvธ๊<,๋kQv5555qŸ>ษFN1\žKาb{ง๖ญ:\ฃk8๕‡g3อSV>ฌผ0Tญ{kSE•EYoผฌก•’ฉ๛y*ฐ๎Jรฑx๏nั€ทo\ฝฅว8ง^*ํtZC5z#ๅฐ๔ืผ3t&xใo&ซW๙้ศvp=b,ษ ผ"พ˜)šฬœnœqm๘XNYxจoJ๛‘Œ ใาฉแทๆO฿Iฌัwต‰ร0ช:šKีf‘^aœึธ:กห”พฅฎ7r‡lžb3ํ{๚“ฐ}wIml่<ๅEƒเโ\sฆX’~Yฯ๓vขใฉ\9Ej>+~หฺEา2ฯม-tฒE-j ฒ๊โฒ‡fa๋žฏ<๏ฟ๖ไ:p๙ซgิe7ŽnศI!ญWผJPู~ษกื|_Ÿ9ไS]ช)ฟC7aนูphš_‡3 q สส๙ยพศำXKฟŠ.^(Ÿp>ืR๘Ÿ q๏ŸnEฤ4 รZชHRัIž}ค]„#Yก?˜=”ดŸ#ƒณ`—{œ1xwc[w2บ[โ แ4ฑ–aEฤพ=ฒ๛<กณ็ฦ…`ฆcyUฝแw๐B3โ[™5_ชHa> ฿อ”ฟ  HพC๓,Ž3ฟDู’_ šค|ๆk(ๅ^3 )hGษ"พะ^ิ˜โ๛’\jะ 3Mใnผชpk’ีe"ซ๔:ฮ8ั›+ใูƒ@˜ก๔`ฌส€nฤQ๖o‘๔†หW-H‡‚ฅฑ$[แฏ@p)S ๊7ยฮฒJ)P&]ุžปด~)WปBI๐Kูึ™N“—wทใฺงด(๖?kqiGg,#ทWุล๐;๐ฒ๊6@f๎ Šy#Š@ฃšลHฮฤลำธฝ1TแHภœPืw“๐โ†เ๖’ฅ๗หe๖XO?Y0ฉ[ 6Q2สs˜#dFLDถใžำ๊าbZ‘yฦ2ีˆ… šฟN#b9’uZ๋Tขศ๙ˆƒCษŠxสจ2”ํ็9bศฺ$ทนvWแqมมKUfqPฉk6`V๙"ฮ_ ำo ์ฬT@>T‡ณ]~‡ฆEuจ@ ถฒท๓™ l๋N ธ>z'จ๘g›าtาดP˜ฅ”xั"0ฝ:์Lœ@ly@…จภฺๅa่v๎k๚ ฺข6Bt}_†˜iฒBญ2aา7‰ฒ๖ไS๕8๗ฺ’กฟๅ/A๙KPฑ |๙๓J ‚วsฯไ๚†Xิ*t ฿| ๔ๆว๚gล๊qS฿ฆีฺ2&}นไGงP&฿ Fb2ร[!6E*0๏ โˆ0PาฤธXC9Lจ@ช็บ—ใ ูฌ`”ผม8•๛vฒ-ะ[3R๐ฒ‚กฌ=`เ&ตE—ฯq๎ฟ3-\ฉ ”†ีp)oแ็๑ ษ3onˆ˜๚ข\ขƒ˜๋Z๛ิwุuศNลศ5h›ล๑ฮะ_…|๙\xกT`ษ๕เŠ@ส9มb ว,๎ฏbฌธfผJ่ฦ} ์zN,๕ ๐†๎CฦS‚๒mไ…แํ๏๐’MŠ^aT •&Jƒ๗๒น=AVฺสหz‰ƒะ7pS" ZbฆSa[!๗ํ)~ZR๘•๖š5%:s0M6๚ผ5ุฌXVึข„ตจ@ฺ‰๑2Xz„š?๚๛ไsŽ๎ัw{ๆ ๋$=8€gDF5จี8Wฒูšบ_>ึ๋ถCธ; …e%Oบ ฬ#q[cมธD4†’ใ aบd1J ิ3ม์ุ€lขยgfUL,ะ$Vษo]LxIrมk‰ฝฬ yžKJพ'„{I๔l1S้›I‡sซตv!iฺJฯn0Iอษ”^ฏtๅAv*"ฉภƒ‹ผํ็ษฏN฿š$†KŠiพพpญป๛>ท ฤศฎึ/0ขŠ;9W( บfQISCIฯaCรu ฮฑ๗คb,ว IœŽ€บaฆs [7`์˜ีม*pAHkGNS! cT ]šx• 8ga๖jQตฟ5ฟช#Urยด่Ÿ-ขฤe/‚)}ฐ–@„?ดชˆœƒlณ$ h๕SecขW%R.%ฆฅ์ฏัrwšป9xธ˜xตDฅ-Zf(ุ–+FL ๒น`M„^็๒ศ1—‡Nก>H :็U‹\__๋†Lœ๐๕K[ฆkclo๓ำ,6ะใอETD'ƒ2ซขY-T`ผ฿*ซd\ลQ|VTล๒b๛=Ÿpฯ[NฤŒO’ฒ๎$†?ฃ™.pp"+บŠƒ‹เ…ห]LU{<&ธsdำฝKke zคu฿Oฯƒ>†~ส,ร๎ช|_๋ฟs็จPš™p}ฝคูอฒHk+๛ฯะJิZ“P€Oึ™น™]™c๋ ๆ๛๎r›ซ+ฏ@ั%ž๗‘“ฬทS„“‡•ฤC›I|&k ’วเส ๘gณW็3ง็ชf๏๖S4๙้ˆ0๑4#้>€COฆ#O0๐|ต_ัYKฅŒg‰8›J\›g ,2.“ช๚]sลNcQlฌณรT S3ํ P8?ฺซ‚ฌ เƒฎxขษlC*Aพvjฤพ ใ&~ƒ)4$Bฌผ6H‰1ฐ๓kqช3ณd ๑@/pF-6{๐Cศ๔ี *ฎงGž;ล;ฝพpqเ}3ฃƒ้฿๎๐Ulไ6 ฌ&/าŒณโV˜ๅy;4Iํด{“ต:์ะ•๙ถPกuฐทlแ๔Iz™Lšํ7ตญฝˆ$9ฒ ต,) ท๗\)Uด%8N3žcๅoหบVฬ?ชibGนžAฬื[ฤาsุB‹3Eํ๊}T๗Šภ8สตIา3E›>ฺ่_ˆoจ€‹0f;SŠา์ั ŠY‚ุ>mฟ%๒;Y1{ฑจะ^[F{mF‰Kก๑จภoแฺ๖kHฒ` xแh‚ x† ผ $Ž@hบ wณซ–w’&ฝ7h}ฝ?"ฬซษˆ&^ข มซ`[:ญsอOŠ๊#Rฮ++#อ#žซหiS฿DอR#ฅฅVY#ิม•ฒQ ๐*B@/๔๎rถžSฆ–L_m๎๛ธ)๎๐ํด{โ•๙ฉไkไ0โlBi6ฏ๏ิaํำ0,ชฝาฺโ~๛)๗ไiฎณ‰ม?oสM*ท"Kจภtถ&pt ฏ ๒Pึ+uไ“ธ'Fฏคบใ—มตฌ-5โwศๅๆส๗จO๗iสM‰ฆ‚xื๛ฃฮาtCk%ๅH6&๑ุ™ฮลlน!ู0kbj`†…ฤใwWi +FฺJ/ภQbk{wพ(ํ{ไุŠy MๆsฯวฯQ๎;ำฆฉyกaฝ;ฬฏmอ฿9TiไV๕l$ญ ิ4zํใ ฑW7:พแK/vJ{๘์^ิŒsƒอ ศแฅๅ#.๓าญ€Pฒหg.Žทo๋ƒณชOaฤ๊นU๋/ƒŽlwxสwช2o˜lKv$ขๆ’1ZˆX$ำ—ภ7ญee™YšงWe‹;I๗u>…kล9Ab๋r{G0ฬุ_-ู>6Ot6๓pะีษโ3๗ }ฃIทrด{E€ฐ_ไBhุzฟ*–ไลšลกสŽ:ucŸjํฎ-๏LTSj2^Nv…„†(žaเ~"—iฬ๖8ฎVนทบ๔ุ(งpฬd^.*ูทไ๖๊sโ™u๖NทG+(olถฟfฆ\aT •4ล๘q๑ำ๕x pvIwหŽ ฒ“›90XŽ\hgœโ_ฒ f6i#ช]~9{=†mG๔Lk@!้ป\ศ,MƒT่•…มƒ๐$ต’d๏,T๏x\5ษลM บ`(๗๋?zฤ๋ั\@น…๘ัGญn6ญlDษ(zs|“M4$] Z|ฐว]BCืEe„นสDฺช๊j๗ปW—i4ัม,พณ_ิญm›ypLฬ—ง?ฟฯg๔ฺR๚peฆ!_็+}3“…ฒซญจy แ‘2ห5Žž‹‰ๅnํhพLโiz;)“แ๔Q๎ภฌ‚WฯW‚Fv๋ฐ D๒ก๘iอฺiัโฒณt๙๛ฒ:หอ3bฦฤฟPษ[๔ป๛—ฝNมํจ@gMดl๛๎5Rข2,<wฦ%G}งีŒเFoœ–L5ี5๓๑ษ้N:ํฉ2ํฉ?%$am#ฒ;๐์ญHNฝณ๕jท…Nย…Žl๑Oaึ‹=ูa;”ํr)Xข0S๛`IัมNC–S‡้Iฤ‚‚ ฑZจ!ษH|Uกœ%บ๐”ู{ yAฌZxญฒ๐มบ3ข ŽbชŽA+vs๏ฮ~ฎŒฟ๔EEถฆฆฌ๒i7 ๕พ}`ฎv{จใ๘X<G๊รn[ภศlต๏:@vO|PฐNตูซดฤŸIก๋ฤ๑tาฐ}ิ/ิt€0ข•๖d{šืภŒ๏i†ฒ”๊‹{จwฬฒ7fm ๔sž”๓๐‘{ ’${ภ™าหh‘r`1d“iไ„–šX๘gวา†K๖C1’7r|ิฤŸnู๐Œฝ?บ†Xื" †าพิจnGl‚}๑ก์Z0Xทp‹Oฬ3ww/‰ื%cว›€โ้ ๅYUฯ๏สฝ42ไใtKญพ>•้œSใำ–ฮ.๚๓‚nโฃ3ํ\D• คjฅ๘\i฿Hฏm'•ถ๋˜‘wนบวัQ…q๒Tเฦ‡–ฏฃ๓Aํ‰T€zK ƒs฿6ผ|๓-ญผH‰ฑHKq๊xfย๋qBAนํ—L}˜‹KุฉฆWห™ƒฮฮWOถTžf&{7สฦˆก’ฏธ๑™y้ย๓1(๏ี|Cโ“cR'ถž›ญูา†N.70ั,I8์,๑ๅZV๎VƒJ™ธ9ย5#kXฎๆ†ญ๏]1.‚็wЁŽR&ุc%ฺ<ฉษฬ~ฒอWŸ‹ข'm๔~J@=๛‚[์ภฒWเ:Z}น`DO;ฐ+tฺ„ตX@ ๐ตˆ๙ &W)€ฐ‡V ษYำˆuกGAม2ํ้ๅŽ ๘oๅ๋”KมEำ๛oนY!ฯ’้[Žkซฏบิฺ”๚%รอฦ/;ฅถต(๖K 9ุนๆ„x\ุbs,ฺš —a๐—BNฮ๖“ึะM๚qบํ’5ู)ต๖๚บ=4,Š T!ษศYš%ๅi- ‰\็พ”†.oธืๆบ=aฐSnR/ฬค้ฑฯจ9‘f๓žโa`3@™@hŠพeS_ 1 5€ภ).`ผศFค๓๐SD_๔ขฏŒ5ษ_{—แFะ๗ช๘:ๅTาใ้รก(Nฃr›ค5*Œt6|@๒0‘๔–่ก%”‰5ฤ๙ฤ-ีูฦ๋_:ผฎ2็๗›gคฺ๑๎[lท๓ถ}_โ6yokŽ‘Y?{๋A^ศŸพบยS *f(ฌแC_#ฐZี$š๕n2ฤฦฦcชน๊‹ภM๑^'ฑ1ไ3ZWNOx'ึŽ’~#๓skหbโ๔ถpฉัoœืฎ>„ฮOkฤrอJด\๔ู$M๐$u%Ÿฆ”๋๑ไ-?Rดฒตฬl3hPพFงžน#›๗=ผ๎ธอ8าpœX<]๎yฎ…zฌUjb๕จ๋uฦ]‰oฝioถ’8…oธ?tFPฮPJb1๏x(Cฺ_ำ๏@Aึ๏8sขI%Xฟ[ื6 oQโธP|ฤJ64~žทC,๓ั ƒFณ•๖lI2ืฒฦญ“œ9ฯ “ี.ิD฿๒:ฬYฝDcd มUž!ฆ’คˆึ •fี0ๆ๗sO@๔ธซช#๊ FnK85๓“็ๅ1ลjDE*ฐฮ>ำOC 2๏%๎XUz‚{ภ[eฐงใZ…า•ฏว%ธ฿๎š#?๔ตŸึ†>™H๔๚แลจ๒ัNอ๎7๙J‰๒ษQ๏ฏพ>ุ่qฮฐb’jždึฅโเ๘Sจอ7๏™jO!๏„ตธ Ahย&/ษตบ๗๛]ปษ„!33#bจภ๕v=ฑป๐[฿๏&t„š'ำฟ$่ jํSZฤึ}คtMFLk"[`ป ๚ด๑หl“มว็ภ3ะะXฟ๕{‡uรLื@ถ๎ไัD „ขZj๏ฆะ„ศ1DW{ฐุfŠุฎภˆฆ' @–,* ๗ฃFPFRTะจๅ{˜l5ข4Œœี/ซ@lืLa^NฯwG.,LtO8๕t]bๆyA๓งฅ๗ีh่h.ฝผฺ:Mั>$jแFญ๊pM}๒–๋^VV๙;ว6tฝ”Qc่ะM›c&=~’‘ท‹ูHค+žษณZ”L=๖p๏ชžห‡๊๐ฒ)ๅ\z?ธดูๅฅจ@ฑ)แ๑้ศ{Cฒx>ื—M!Dำ5Œg?wŸฬ-ฅpกG้ๅ^U3G Œ(I?ห7{l?^#ฆ฿`ัส๖’กไ3IถT ฯปpู ŠŸดย–ปฏ ษ)ฏี6ฎ/ๆS67ตฯ๘๏ํ๊3๏รถUcฎฯข+c๏ว"wง/ Fcีื(oื|ฌีS๕{๋ดVsVN01ฒK๋’ฺ้๑;E๚ฬฤ˜ฆ9tี#ฑiซะ1Cพ-/จด4ˆŽ\6ีฯ5)G ัxศ†ว…ฮพ+rŸ$ˆบKฏ $้vไฌ‹žฏ<โ '7N้ต†ฦ]x ๚5(’ๅˆฑ8“๖,$W๘แฅส['ืห)ฎ ผ๏6OอL:๋ำ›`l(า)า ็บW$X\RLคยรชศ9…ตo๘ก6‹Oƒค‡Pสญ2฿ฬ๎๘•uฟ#ฺร๐ˆS๓b„—Ÿฐ๚บsํ#๖™Z’A งT› R™mU‚ฃผตA'ฝท:ฝ d็‘rฯ3„ส’ฏ'ื;ำ,ใ;ขยโXฐ!rฐt‹P2ม๔บ๛ฤ6ฌ-็Y”Zhื9`k“ถุๆป'_ง2^]-Zำ!ู#Zฎยีโžฟj*Xut~ฉ u๓•1ฐษ<ย้ซžป3JฬˆX†ต‡…ท!šDิอ2๘UgขBฟGMาฃ<@ก|Zwฬ)๐ฟ3z๛3๓๖w#v๒Y|M:nดQ_†…าฆโ8R=.ฏ{9๛Rแทšiฮ๙๛๗ฒT[’า[1๔แบมศตd‰Wซ{ˆ่qๆ=9ฑฉS‹๖นง;y๊…)ฏB~M8ร5ˆ่ึ t"ถ„ุใœีๅ็๊d<้ s๊Kขr"ฑRูคฯ3า qง#ใ'Œ๋ดLxCY~wใr๚๑%อ…ฒ…hE๒Xว& ๊}P‚฿™™๔ๅ0+vพ*๗DฐขKฺรง๙ฦ@ชชXz.5ŠAาsฅ๙>viV_„ศlDtภhApOึ`9<pfaีฃฉ1PAชRr>‰ฤู ''/ัข˜nตvนฟ๒xนมแ5้ผ2ท๑๑‘ฯ‰ห…฿ฅ"ื้๏.ง_รL8l]8้ถ๕ŽจQ'dฌณ ๚f’ซว๑‡็ัำั๕ 'ฟ›C้<ฅญขv๎2ืฤfซๅLืถ/šงลฃจดษpRํฏuฤ)~๛๏‰กๆ๑อน ๖ั'๐#8ปขูห๙ืำ๚=}ฐ7?พ๗.Wบ6ฏt\a0B=@ƒทYณ๐๔Hฺ๖{ูoำsณNEข†vธ[วศž๋ษ‘œcŸม•‰[4‰œ –ศฎ’ฟq๋ห3฿ะ#Oั{ๅfY”'zlไทx*ฐๆBฒซ ๚nŠมŽ(W๕๎E ]<ญ:ญ1<Ÿ6าๆโืr ๕หkzR๑^ง*๔Aม}]๗๘˜๎ ฉ>ว+=]ZR‡x<๒ฉ8“uำ๚:Pแ ๘ัŽจฐoํ คhM‘šณ+;k_๚์ชช4uไ๋ฉดค‹}ท์nว”SŽเไณ๘˜˜ช~มเx-…ห5q[ƒณ2OฒY?๋๙4๔พv‹ ”‚@ไxะ๔ีถ\fS๔ศฆ ส[ลnbม$IZๆqza:@€ˆฅ\ˆฅTเ์(๕7gShžd่zบ‚% าœ}ิV๔m๒งqอA&Hณ ?๐อยXวn๑šฐ'$uดTNXSH’H†ฯ฿ฟHบŠhฒ๛ณฟัx*&?šฐvWขห์ั}ทสมป็๋๓ฬฌ(ฤ9€ซnP้๓8B4 ,™YVœต™็;โุIะนุsG<ฝ๛w๓Qำ๊ถ9มRฏ๛๛•{ืฎvtMณ”M7€ผpฆq›ศ๒๐‰ฝฉัl๗ธ58”]จ:)๐6ำ†nฌฦO๘่ถ ‰ ๎‚๏๏@އ6#๙dฏ…ฮr\ฐ8ญ๛ๅฬ=นb—Lฒ3,ษ•enAรO'ึวQฉบwลo<๋^. Kพ™…ฝพอgvg?ผœ้๑๒๚ฦFGๆอ๋f i€M๗ ฉขfฒืพeฝy O3[Rตศ๘˜F?Mv”—ึิyๅฐb/ุฒ้Hฉึk‹<3u๖Šo]Eแ๑.สmlภV*€หผ=‚ญๆj%\š8฿๒ิ›eลwๆpภ&11^๙DpฎGฌม‡ึฝ–ถ0V!–…a„ปŽh6aF—”‰ดฟฎ#ถ฿ตฑg“าฤ๖/๏@tฅยUฉสK9~e๔๋“฿œซรฎO ’ัฯ$›4ชลมชท๔…แ‡3•vฦ›cึYงXฒงNฤฒu‰?๕=ึ๊g ฬฐ€แAฬ|‚T’ษมžT€้(bK aฃ…ใZ็ก-~yJ6ย=๗j๓ฮฤณ)ฉ็7ฒ,lิM9ตฏ\่MioฤuŠผp^ฆ้_9ส#ฤ๔Sค`8c๘gAจ€ัDมM‹ฯk๏œ›”7$W _wี๚"%ŸNฦCX_\•)R/@^^ูCๆ&ัม ๙ุP@3ป**D ๏ฒโŠฌฯ™\…i‚l“$๗เจซว๚๎šใฆ{ฬห~๔c฿(/ภSท่๗Š๐แล3a\อu จ9ฯ๘PKฎ ว>92๚{` |H~C{“IxY๔๖อถjฅสWjn:่ฅ|;๋”ิปุ แŒม›าˆ?๐๏yโ-;QK––์TกO:ร~‹ะ,|Q_p @Y Vtว๙<<ึ{uพฌ๚ฆk—l๋‹tX“โ~8ฬค*ดPgอP2€๔aศ‚ึำH๒!ค๘6,แี†>hวˆณํะแ้'.๒ฬOงัฅร฿ถ_ot๎%ย‚ปไ‰ภีCoPงห“ป{ฃ"๐Lศ™ุ๋%๎†Ifก73N'•ข฿1"$ท้(ด้nโง‘O2jโ0•”ฌOถ/ทำหqš๙้-ด^ผผRผ#ˆIB ํ\DkDuGไOฅZrฎZkEอƒฐ๔(ฒฒFษo๙[บAม\*เEssq…Tเ&B6Œ๔•ฑBๅ Y^๓k#ฦ{ป๘ตฐSมธY>ืwย(ฑž ฐcฯ‰ๆzB>PN*SQv`‚ f(ฑน'฿เx6Dย5ัผ> —MLgชฟgห@c†มแรSผCjฅdŠX‹j ๅ,OฦVม.V8@Iฎ)VX๒m{ดˆ ์ŸนP(ฯเ<ธO—ฯ:fไฦ}]นโศ์^หฐ3.๓ห*hsี„%*#ฺ'ฉ€09tจแเ๘DkNฃ๓c็‚ฝอญŒžŽ—7ำลฺCฒ@๛ฐขืqงหฮfšพ~๗>ชˆ|Šไ;๓}>†e๖๕)/๒8iTe—™๙นW๐ธ๗ดAj๛C_ถท?ๅh/ดฝึ?Hž&”Oซž`Iส1โฌฅ9;MLiฮ/้๔s๙ไNK?ะ1๓6Gฐ=ฅ“› (ŸL๔…N qŸhS๑€ž ฤๆs=Q๓ฺจZํฺ&-eณ็8ˆqฝmrฺ๖IR+ฯC็E’*๙z‘ฟำใŸอ˜ซ๘ษา๐•๛Y—ห‰ญwC๔๏\‚O์–…ฺวญžl/š•ธN‚ผด๚ฒ˜นฒเพ|๓i|็ขฐศMู์พ|ฎอ…#ฎูวฒ9ำ€๎ฦy๎ศX;ŒฬฯZลPข๚มธ$LI8ชUวY…’ ำtXNฉ}‹่ฉŽฝiใญŸ›žปGij๛ขknOณดล1p๑3s‡-Aฦพ D4แ#1U-z{2EฐงัYครฐถ/I๏ฏLœqŽc//K)Lฎอำไ ุˆ™ืค๑dะ#„๋GฑึฺG|^แ๋U“)ฃ‡ณตซUr๏ฏบœทq*g&™ฬ7I8Mผ๚ขฅ่2ฤะ/ฎภผ๏พภฐ| $,ช๓VJ‹ณโ‡๒มOะส(ฝ‹ฎsพlpF สใe_๕ฯ่,O=c›[_cขตN๎ญ–๘o“๔Lf-นˆะำ๑ะธŸJa2ฆCื^๙๖ํ\YำAฯแฏฬ_>3} G€cHœbd๓†ป3คื๑๖ญB็ :ต',ษT…?็FฎB€๏ษŸ(•˜้า๛q;-ˆqชDฉธลึ’Wบ=ฉŸใe}ณ ?†#žP–„dKOq}1้ ๕*4>'ฦC.ำXucรฟทื฿Lv>ฝ๋2L$\3˜4‡m=e=ิš{f}oไu‹ฎq็ตX&™h–ญ{gF94็m-฿๚~ฉU1!ฝ‘c ไAœe|ƒ41ณงiŠq`#๐›๏ลฐLBf๊ฑŠฺ ฟœIา FทcIlˆ&ีํไ‡:ูAm˜ไH฿๖าอ๒ม”’‘“WrํL|์BŸฌ™lฬ๙ุ‡2๚ััธi“*ิ•bB%บแefณฦแwๆ~™ueˆญขh„—~•ด3MCy—ะB ณฮิŽ฿ne€ฌำTŒ|:ถ%า( ูD4๕,Aฯ]฿ๆkNใLD#ษyE4 ภาF^”\คYxณ(ฤš€+อ…ไลค๔ฃ.บŽฟwงพD•๒3๗HšใcCฬ฿ญโ+04k๔@Aาะฃ1>8~”ฏ@๋์ฝบwต ะ;ภณไ ]5ˆdOพN1‡ ์IŒy3พพzด}โx์‘S ฌ๒™๚cฉkฌŽ#E>ัB น'ศdฤtป/hŒZEด!c LzG ‰ ‡‰‘ฃ-ูZต๎ตpรใูท๏)ฆฆรฟLO฿ฅ"๘ ดŸฮเ๔t-œŸศu  _บ:“๗oสฃ Jีำษ'zFค—•–ถ๕ฎœšrJVฆุr˜VpศfD๒—‹$อฺNๅ0D<ฬbฌษณl๔๘๒šณฆ" †˜i๔:า'09jโT ฮlถ็p๕ ีย„‡ว์Ž ๋!qžฎŠ?”1‘yำ?]}keฏEsdGQE_ชู;4-๏Uฒ8๖๎~e็|%฿Š™Vฎค‚;ำuCR“Xฮrงไุ+ฅฑŒฬizโ 0dKฒ‚Kิwq\ํ67#ฯ\_ห‡ฃsฌaL๒Uกtš๒›ัู,2๗ะฤ7Kเg?)|Ÿ™qžw]ต2ๆ-๊ซง‹ežท(ัwJ%๐8วใg qˆูŽG ‡=œ;ขตt=ืใ’Žะeสฌห†ฆ๘`0Dำ…V*ะœC)ั3น[4น{R-ฑ™ูOฯ&นหUฉ!%o ฌ ะ‘Vชu[OžJย~Bk‹>แน2ูนgzำjinIคาึ*ศFย๑8ณซNึkฒแ—๒ Nฑ5ปGWพชพ–OœทGะ˜zฑ‰FTœ&8BN(4็mฐจC{2งป†n๓ไบเ qฤฮแ0uจ$fบ &„˜ัฃIร\užา,๙PA•"ง๚h>ํ๚๕ท”Ÿฆ๙ ‘Gฬt2rŸฤ\‚Zบˆฃ็ˆ7Oฌ่4ๅฃ™๕เๅฑ/˜+ณษจี,๕.ฮไง‰Vaส(Lz ? ซSึwแhŽชื *p›ภ gคไ้โํ†S}ทฏžjKEใS๋†ฎ๎ฆ|ฆ’ฆEAY___-ฅษDซง>๏^„ธe+o™ฮWี˜O3“อ{…y"*_์ฝgXS]ท.ผ(Š‚้%*(HตPTJDDลˆ (‘&"6คส”QQQ ้Ho"R้Iฐะ %,Iฒr–{็บ๖~|พณฟw็ูgฟฯแวฬ$+kฮฑ๎1ฦ=Fๆฃฉุเ Sqา๏–๊๛หฐาปา„ คฆไำฌักq\ณ(ซ๘฿g\พ๗ _ิOH&†ธ/ัtŒjuไฃ์ตต?EฑฮK๒>v“฿]ว x฿ำC“ArวาผCห4=ฤF^(.*1”ฑ0ฉxสงฬZ’ฬดXZ{กBบฐตห็40„a๏›eู๋ž'%†-ผ>ก[ฦดJธZ\$฿ฤฐฎฯๅษษาO›ดอควg8ะฐ๕(>hฏuWี้ํŒป“ ๑c3wež8YLIz๙€” จหฐs_0ไฤ†ณน๔l9@ศzjส2ˆฉIWŒiˆฌ]y–jขX  ผnC/๒า=aเ˜๗๐ณฎƒ”q3“๔JŠ}0-ง๎6rKŸž้าvณิฯu{az๕ห†Y)ภท_ ๐ลD‰‘JŠFK๐bJฟbค๎›baตŽ๊lิ|าDyRƒฐ“ฆ๓™>6';๏W˜7ำbš#ฯพ$eฉfฤฝžoe›W ไ™Kอ;(NผฦE-rอy ธ,ุž่ ƒอn|gzcœ}S‡=นคพy>ฺฤw๛โม“ฐ\`ญะืทJ'ฯพ]'็T๏P-๏ัQรณbm‡<ีƒU4"k+Fdฒใ‹๘๘Qu๊่œ๛V\T•ๅฅ…~๕}D/Wž๙er'k“ ยดfค’+=r nษ๓;๒|ึิ,ํ—Œ๊ึฝึž๖ๆ[ํ„!โก>i[Pาฝก”hk สWธ ฌฌšปYIเ;จยดdgม๚ รา hDึlญˆS‰>ๆปญGํK์ฒ_L„qีบ๊ธ5|—‘๐4๚-ู,ำ๗ๅลนญช|าฬ46x‘…จศ6,ยดgd‹ยŠ‚ผYลoH3 ๘*{ ‡ฮnu7nฆ๋‰ค'ํ฿œฃฒ!gงฤ–ปตผึtEฆM€ฤ#Ux3tZ8ฎผฦ๗ๅๆ‚๒Aฌ{็m^V˜ัSบึ 2.Mณ™ ๑'ัฐิ5/m$=QS1ะ fดโพEฟdƒl5@ `;Œuำ๓ถ*ะ<}จถ๋ำ2ฟ1ฐ ฌ=‚q?kฐ๎@s฿’Uf3ุgิเ๗แ๚3ฒ"ซเฯฝ๊a๚Ž|’“แt‡ือ๋2ยุฝ-ษ-Ž‘็"…Ÿ;฿xƒ‘~๒”'&ษ๏A!๋E$^แu‚aพ/เY1ๆ๓}aฆไx}b–[cBAฺจSQ ๏๙…;dดภด*–ิ)Xwีหฮo~ดฎ{+๋ๆpKพ 1zaึ“lZ_-MVฌวnุCƒ8ภAฺวTiวตุญE1˜jyn๊”Y:๊ โษ่๘๔ถLuค{›งํ๖™zฤŸป›Y™^/ืจภ๋‘Xrพ’ ะผs,4}ฺ๊t๑LE7'[kพูggzย8๔s๛1 โm อ|„‘s_6"uฒ„—๋๐โ›|t(๗pขo=0dๅnีbลR๓๛ลึซ??ง4™Sk=Nr‘](ฟˆ0vA€4H›ํd8Aw฿4พ„ยR,ž๋ทGtร{ุฉฒe{ๅต…ž9โษว…(w}\ขDฦท+ภ…่ด%š6Ž฿ภบ์Uซ ฒโชดพฃลเ=,-H’4M” 8ู๏ฑhฎY2๘a๘S์–จQ ขjxมEโ๑.hˆ๎งuฒE‡:Y"ฆˆS:v‹ ๚^˜ฟ“i=]cะ๏ๅ6บปัว†2e๔สญ๓ีไ๒&ม๘ไ Iต๒E17Y_ฏ*hดเืbH้๘าๅ&\ผฒM‡`ํ*บzฦšวž3vj๗,*Vบc๖–`Bอ๐8ธžลๅAห"ƒ๗j$ฯ<็ ีฬัWSฟt2~ฯ@]zCษCฯธฏ๗์ &เ!%qVšK#ศภณEeA็๗€wฆกึ?M!ฑŸ"ผHํy1;lฬMต๊ๆIภT+t๋ข#ตX—๚Lnฐ๕iลwชเŠ๔'พลณ›๖N)’ๆ‚ฝ<#ึฝคะ]$+&ฏบ€Q๘J–7–ฉŠkP๒ํqสฯm์BฬU\$บ˜๙ตค,ษ\ไฝ_ภ‡A็hiฒOหนูถgว๖ฃi๓–|ช‹x–hใ%zN…ื๘83 6ัx+ี“๗ฮน๋y‚—5~็ศb`ฝ€ี รlห%ฤK๑_ฐใ|Tวœํณั\4dy฿| vMวy~f”œุุม|sˆ@ฏ๘๊r—}Ÿ%Iใiฤ‹ &ปU! เIrŸท†ัฆ๘Iค‘qน า*^rยSyศ๑ƒ: #zscg(ฃฟฏฯZjG๕ฦ"ฟ{n›๑๎ส7๒อ”ƒฮ_c!๒ธรFnrYcs`/Qฒ':fืขท;ห\ํํ]‡๒ชง 9;๊›Ÿ๎ใ6ณ•T๘๙คม‘•จ๐ค 1C๛ซHYาQ#s๓ฒข‘ŽฝมwWžE[ย๖CNxC“ไjLณฝRฏšนรJ3ญkN้t„‚ไนS]&2„ง W ywžฺแƒ…ื=กa•`-๚wbาร‚cถผŽณrบษอ]มห„ๆ9๊ผ็ๅ‰KŸˆŽ๛ด\บไ๐Pู๑ื๒1gนXˆ;@Xก ข๋ฑa+`*vฯห^Oxภ[ณ๛ศpฤ๓hW฿ํฮ[ฯ”rฆ๕ใp?…๘ฌuฤ@ฐ ‹bฉาRpฌ!“ฮ‘ฅฆ์—~]??…์sไ7’ธˆX%ช๕หืข+ˆ4ฃฮŸฒ5*เcˆํ้_ฤโ>YB‹๑9ฌ"ศqp\QGเ–ธทภ่ฉQ™L†ณhณ‹z2Toฬ+ธ_ืIˆ๘"๛ๆ4ฎฝ๔“ำฃ9Gำฅkฅพ`†~๚Šk๚-ท‡-?xH งล๐\’k^K ำˆจYW#้รlภ ฒLžja6Ž O.ห\Tห|ž8H#=ˆฮฦำŽQGกc๔ฝอr้?nm๔7ย[7‡–}สH๚ึย๔ดฎฮฦฮR„7e/EjถB(ฺe7AЇษดลc—ญ6฿ญ๎_@ค๋ํม๓ฐF{ztูšํ< ทงฅัฬ์Lฦ[Sg+ๅ๚็ผwkณ•x'๋W/฿‰ฟฒ|ต&&1โ๐ ‰([๐฿ืN–ฮ่้๖ข‘ฃํั ๑Mปะท๗ซอๆdh(วฟU๙้F N3@†Šอ๘อ8~CาTO,˜๏๛Lcศcเชšท\วX.0w(พบ ชว๓ช&๕xIEq"%y็ๆœๆmฒนนY †ผB~Rภส8CX์งŒ,ืฑq ๓>ึ3+ฦM/76nฟีcฦ๛ษไโ—nำ˜ฬŸญฬj•%Xๆ&ฟขRЇvฤs€ค๚}†๔d๎ ๐ข‡๖ูฬn”#ๅQ „คฅ๏ํ6)ฟyœ&ณS_ sqt[๒rศwZ ฟ*๕|;Q:%น=ธ ๅKkŒๆ Sฎเ)%๚?& ˆd 8Š๚^Ÿุ‘7l2ก )แX›ใšIK@„‰ปเ„†F hXฒิ=แZW๏Ÿจ ^ฺtxy“ฬNปผooฉC็๓_ึพ๕˜EkO ออถ[๗ก๓๛Y"‡ู‰5ศฯ™็ำ?wFfUwฟ๊n,J^๏Uุฑแ•y›™|+ฐAฐผ#นฆพa +JปA่ฏS฿l„‡\bูฒ3 tY;้|๑RP฿•9ฏ5…]›ฯู <Œ๋ย:ฏTชฯiก์ฎ็๚Tึ•๛ั๏Yค‡lฤn1฿t…ฆฉtuaj๚:ูuxf^Ž ๏ŠัEx^@>:<๛๕ฌJ:kŽษ=…_แ๎_๒7ลd14kŸzTwธ๖€5I˜–ชูM"ษ~บโัt Šyุsํา๋ผฺผN[์^ฯ๗‘ฦ๓Pบศz)แ™์XpB<$uciฐฌ0Q้Og‘้fโษัญlQ๖ฐฦทฒf igฉะฌˆห'i 1โzkคดฃ(ฒ›F๋šพm๚๎จ#แ›&พ’“ั›ปŒb(g‰X3์กvฆ6$N๑Ž-bŸฐป‰+๔MูhH‰ฉ่TpผฬคฮงŠิจ‚0โ_ผUYพXใม~†(5๚ฆ #ฌ๔k{IeIxรžZญ/•ๅ๎I6#็Nป]ะฆ0(^|๘u๘eี!‹tว|จฺษ.zเแg^pZฮ๏9“อ\Lต?;;ฌB&^แOช๊tทN๘ข7้ษ…`Y(๋=๊๖๑†AKฦใซพaย<ต฿ฏดอuฝ7ŒKสบำ๚aG`‰xb5"๓$iฃ(“`h7xƒฐไ1นฟZ‚|พยฺ[s† โ1ไ`} 8U~Cศล˜2†„Yฒลฬ#6x๎!โ๖#Wำฐ่Ÿ๚่PCd๏H&".๋฿~ษ;3‡ˆ „— Pก฿ฉQ‘ฝๅs๑ภ:MLมฯo/|๊~Ž]}ไฌใข+J๗+  ˆ2๕1ย›'0Rz*ฎW็ ะU“ฏMฅ’&๙ฏฤฃํ+$ถh๊ญท“๐†HŒ|EQ !‹ษ<๕6†Gๅ_cy/QhŒ‰ภทV 0–eM3ต5zีท๎xชฐใวQEล6ฎไcืฬ>nฎŒ๚ล>C๎๔c๑ฺ1Qรq0์ภRธWฅำ%งVตปktLฆ ญMทํSพถgก๚"‚ณRx€>I้X๊P6 โกชฝ4ฬป.™ตvสA๎+Et—HŽฦ๖๊ํ}]'- `ฝะœ8ee{I~๘&ิoMฦ@TแืvYฌr๊ด๏แฮ ถญ^w๖ญ˜~=รˆ_ีา $ปนร#ฬฒฃEฬmู๐n}[ฆุิีwตg_๐๑่ น๐์o๔uZŠ}โซm๊ๆuตq{ุ™ญา„5็ฮrฏ›]G˜ๆcฺงfุ9ฦฅฅ‹‡b_Aม”†w#SJ๙็ ๗ฐถœj“๐Zk วแมk ^‚$% ห1Rจ๘Uภ ษ๐F๑C๔ข…w [ŸŒ[์^จคฮฏ—ฅ๓?๎9ˆyROฎฝ5=ฦ ฃ๗=ิBฃฌ๙฿•ญุ9žย:๓tY2™XJŸแตโ4bน{H{ุAŽพ]oมิ๘“<-/!Tฝฃด-&๗ย~~”d#เoภfžfI฿Ÿ›a{†^‰๊๗kผ[yxฤ๘Šuะ็{%อN2๕[YภWี~•%wOi‡นžK์ชตฒ:’)gศข,ตŒt?EkสgณN|fI*w>…Yฅ|<๒ั1iง๚ื ๔qHz?–q^๖ :a8ธ–ฯ๖ส_ถ‚ฏงQ>Œr›œœwH/>=+๑@ฎC‚0Bิ&’u*ฐ-ล€˜=๔ำฆณaฝํ๙2Uฅ๕—žภ“มVN—ูำนซx)์ด4๓k็1Ÿ*_Œ[cc(ๅํคช'eรึ2รฆณสำ‰ๅ’ไ๗ห!มnภHืฌaeงU๙๛าๆ(aVฎพผrฬxKปํศ{3ชฒ†ฤ’}๒ 7rEƒ-พ๊๏ew\‚6า๎s€0,•’+=…ฮํ็9สV7Fผ4•ฟUDfร‡gพ^วลเE‰คzป~ใr-&"Db$2ชพTAI1ศS-XQ3>fฐศ-‘็ ŒวดW+4ย•}R๊jล/สๅy}kช-๕dTiืรฅY†ฝMลใcBS ฝ‡fฤค๗฿_๓๑๖ฯ๛{K๖iญธgƒตาw๗ฌ๚k$ˆงฎืศšxYฬ.ษ/ด๋ผK$Eแะ^บ ๖ั๑แEา‡:บ^๕Z~6 $jU:*,K็ o๖`มฬEฤ8๑ๆฐ#ผโ๏๙]!)6ฦ๊็Xพ’ะŒ5 ์)tc์!Uu็ธเบ&)฿ขืาF4…;pดใscŒฝjึZUฃฺt ี„ฉฯใฟ๊ฟ‰Wืๆๅฮ…/E๙Z‹ฎศ#Ž[M;‰8๎ฮ(ภวฌ(€;ฆ้๑Œเ‰u๋– Jg4ž†ฤใ๙ฒb•xฎcbX}gื Žศ{โQv™f๊ณƒ1_;~ul"†aoœ^เ๙wฺšส๗ชBำ%ƒ7ฉg{='๛+2ยg`฿Sf JภำฝiO‡ไ^้๛ฯๅx)(ฝึGวžฺๆ๛nยJz๖Iำทโศ—๒d๗Woฅ)เ]4Eง+ฦาƒ&=)ฑ8ภ1๑‹˜}CO‡ผƒŽส?exŽ”๘!ั2}]W™wู@ก_ -์พ้ษ’mไท ๚๖nร-T(GAฮ2๓฿อืโฎ„‡ถ6Š ัก;Oฐธ^Aโฟuhฺ8z%ำƒ,ทaค1ฮฤŸ๛:CA†ึธbทผกy"ฎl]=เ_ ่„€H ฮ4‚…SญšO3uX๒ฐ5žฑณิ๘บ๓”แ1RœŒดHว|ํjŠใ?‘โXie—€คTๆล€ร]z[๐๋Jโ_ช?๖๘ตkTA@ฏ0R‡vฬseุcะฯE?g ]g[uฒJ8๓Atฆ๕2k_3œใ‚์๙Œ$cม๕กX›โฑ…Ÿ‰TลcฝฯQ54–"œckฆ›frณพ„โ‰ , lลภํธ5Es๗xp;ดลuผw0gˆŽฃW_๎๑˜ศ/๗q!ญ๊€n งชะฦ ใ›pย›QPฯษ:ั้xํ}hๅปษฅฉ‚ปŒv๐8ฮ–9้ฝ&ฌ#P Œ$๖ƒT`/,_Oฌูไžณๅ{้bัฅ่ึุฆ๋.XพCธEหต๕็ƒL)ฆ Xh›gcวท@1Ÿiำ~Ugอฯง๎|9YฑิvทŸ็%`Ds๙…™–,ฺR้]–,eฎxB[)่์ิmบ}๓ี่ฎmพ|)|\ขuมŸ๘'ทƒตวม+ุศ MMคงZdฆท+ป2บฮถLีฏ X\๋%1Sฐaนร_ ฯ&2ส*ž5๊…yl–๑Mšฺ+jภ*KnณUฆ0กฺแxๅ๕ใ. ฦ)๋๖žuี*ฉ๚ญEฺ”ฐbpdย\ฃ๖ล(œ2ใ-ฐ=8‘๔A4Jพฝ,{B€๊‘์™ฬ-ญSฤw„(†ํผ[ฃฦ~2 :รI*๋5ิผึฦKึ๔_ฟีžผ_ั;ขสือไSฝgs๗…ฮ?ภ!ฌคๅJ†่~บAๅ_ฃห>แ๋?ขSมฃZ?U˜;~ผ๕ฌวMR้žวกBv๙ฦ๊๊ฯ/GSูแ oฯ›’า~Qฯ<๏พฆห.เ๒ฮึ ฟŽศ%ห)ุๆTy ศณะ พ$F~pMKmŸ๊)™4‰#ณd:@ฌ„8ื5ozซv‹ฯL’ีไO>\[~“r6๋]ผื๔โ2Gอหโbt˜วpฑZบƒฮ†Z$๙งฌ‡04,aUเ2‘oBผŒMo๓๊8.ฉf๙Yฦ๛œห๎รwž}โ[โbJˆขŒ37@ทnหgวB‘“Žูฯ™??วƒjO๘˜ู*S~UZJCAส:3y6>wOฑ_ย“ฏฆ œ๚#o1Fถ7๚C2E7n๔„๒f8=tษF}:(ฯ—เส๑ผmฎล ฑ๎ะฦ-๋็6]ถ—ฌนฒผ2ๅฃ Oบs่ƒฤยŽ๑+ใdฅ็œ้่ะŒ๛ไฮˆซ’i็'ๆพบ=ี=ฐ๛ Ÿ๗๗“๔๚ฟใW‰x๒"๕T_%šwL€NยJi…ฅtธ}"Bั‰ฏ‚0๛XL ธ^ซ'ณซส’nฺP‘†฿#๑ญไ‘eลฎฃ๗.DสoZWLเ#|fcเuCLัใสซhQWk}ฝึ\ŸŽศ{?\"ึ!ฤฺ9ึษW0ƒ^฿๙ฺXzงฦ(ผลดYAk˜๙๘๕ฤกบ,Y น tXA ‘ฮรx =q!แ๘าบ ฬLๅIบ฿9ะู[N’”เฟฅาOษ7ำNnF\ฮ†€4นPฺxm๒‹Nc5ำ๊vฝ๒’ใšg1Wฝ๗ป\อmธ฿š;Š_Klฆ=“ใƒฮฅ๚x›อฮ{๔ฮ&๖“Q(ิg>ไูว]-„ูM$ฝ%ฮ;๛•ฒC‰l)๗Ÿz*ศจ`?ษo7Œฐไ9ภฝpX,ถทa—ฮเ=†.#ฅm ้gŸŒ5?'ดฮ{#บๅทฌ๎ฎลY:acl1›โฃŽ‹Y[]lgขg๖๋lู{)2ห& ๑ธœข฿‹ฌฬ{#่พ‰„ฯ}˜แ—`"ฮW™๗gT" ภจ๔”9ส๔ @๊ ีร3๔ฮใพ3ะก&™3ๆ—ภ็T์(K ๘ทt€Z#ึ…Tศธป`plˆH‹า"ฤdพ๔ี๑5ธTi๏ฎฎpัฯๆGOWํจ๘็)ฤ ๛ƒค็U—ฦรศ์ ก6alx\ล0st๒B?Quz6›ฦ—pี FeaŽ‚em๏ก—dwยZ(ผymฯQb์๓ sƒ๎ม6ณ๑๋aฆ)}3/ ๅ>ข2‰ƒ”๛๋ฐQฃูนZ่fญ__N†ูKท์า’ฏŒ“ย^ธŽ+M[ื);ฝฐ!@ สtf๎ฃ.p‚0ผ>ฮต;ป๒nณS ึOฃ‹tšึ ิ} ซa]iไฏ้ˆq~1W๑8ํ๎%ร’9๖™ึ/X๊l:๎ั6๗ฤาไ ๋o๚zD;f พ,›฿,แ์tะไbOršeะํ&ด2(m‹ฺ%wG‹pˆ’แฯ(h™2ื4E” ๘ี3๕Q#Qxุ'๒lƒEซvCœD๐ว–็‘ง”๚’„*๏ฐ"B๔่cทใOำิซ]{อ_Ž˜˜๖j^$L`x?๔๊›šžmฎม&ณณหฃ(ง)ู<๋“ŽฺN˜| ฏ#ำธผ[ทDŒ“Zผkส^๏ษ…Vcฝ๚#็#›6ฬ๓.ˆLKํ"๕7แ โY›t)๑1UFยเก1XXƒ฿๖@สษ'ธำD~Cแา็<ฦฏฦ}ฝบo]f8n๒ุ‘nM"jRF0M4,5หHถธธJy“’C่!S)%ฒๅ q”า/่๑_—๙]-ฝฏ–‰O”‰๎‡ธsว๒ฟ~394=่`Pฟœ๑3๊‡ื]mำ‹Y‡เQtˆ๏p€-†<‚4่ภx:oีถWํc,Cึ|3xฃoV~ทA๛๚D"?+๙Ž4฿oศ~`Aฒmๅi]ำธูM๘=-B?ฑ*w6โ[$uอ—๚ๆพf*ุซ^ร%z›).`lVjึ ซŠฌ=1?>Žีสm็๊qห฿IQzt๖ึยๆ;[ฮูาาQ๕xHแPaเ€อ9‹„ ƒl์ป๙๗ฐ31—พˆ„^ั๖จฒฯภulณOcฦŽž๚Qูไmใ/†q็ๅ฿]Š*รฉ x ฤ๔†Dซ(Rs่'wีย]๗เต›0Gแ*ษ=ฤz€LŽ›ถ๚ไ…ฃฐีฏ๊0ชŒVJ}II=zไร5Ÿด๖ใฝคNlแ๖ŒDเแ1F'L*2๔่฿ „›d0:/sSัสฦ‡U3‚`wn†X)-E1•๙Om\"5ไs~0พ๎เQHป` qox•ŸJศ๏|ๆ๛›ˆ%ุี+™"Fไcัื๖Kว ทeฐ[ี%ฑeš\ฬiฤใ Zaฟฤ“]๎2t๋!ifๆ(3ชฦ•€พNย ุ’]ย4ไw ื’™’ฏb+2๛ฏGG 1sZ Wฌป?ึ‡Šสฯ่แกE  „ตกYG\\XฌlวVฦ3iv&]G0ขŽธฆกอ๑ฤ‹เเซY๑ฐ2*ฌbภ๚„…:ต—ze!:R๘LฎRกผข aืiv$๙`ิ฿นฤกหCmŸUำฯทfOv9‹ศx”6ฆศ3งw)ป๕๐)ฎ•BZ?E1ิ@อe%’ขkบ๔ e?eH๒?ธถ~Hมใ—^wVข]#จ€˜t•žทฎฬภ(๚ƒำำ่Kๅ๗iำe{&๛๙๘ฏๆ= ฝฯๆ>;ฏHีodŸ๑ ๐…ิ(๙Xี#Qช๘ฉ‡ฟQo‚žธี[Y้ฯGฆโช%%ึžฎ|า๋Oท-๚ฯโค‚„zZtEŠ๓บN'๚f†ฯ๚ฏN%io”ฉจสyืœ˜ุ.w2ฑล;๑H[ Xบฬฺ^฿ ูaK๚๑^อXหS๚|ฃฟขบ0ผค[็E๑|ไี ้_ž&o๏Mgฅฒƒ‰Ž๑B} จˆ]u๏ฏc๛จaี•‘…MŸwxG+ ฯwwpตu๛ด^4ฺผ‹‰pbDu“–ล๐ัำษฃ&…teฒ–„Cฟy๐๑†ฤฑ…6ฐRน*ึชฐฐจ‡บๅปPตผผฤ‹QJฝLฅ6พy“(๑‚@Žๆ?T<๖ใเ๚ีOs ™!ล3๒}$'”X4r2ปNศRmˆ pV‰4ญ“>!ล‚EŸC฿ธฃ ๙ข5ฤ$ฏnฟoIฃ'mฺmมh7๎ค;nษ ฬa/ ๆPั,E$ฐ๓ฑตขแขU{NvทŸป2Kส,0ฺ๓ภk‰/d?_b( ๋ฬŒัๅŠY66ฏฃW{๗0bห}\์"บ>ฟึ๕ฮ๋ฝm„`ืถก/ด๗$qฑŸZเฝ+emพY‹) {โ@[ฆฆ๙xS. g:๏—t,<`ฒกไI5๏s๚๔จ~›`g๏_SZํฏU• m๒ ใึ๕็Qzh฿wxึก๗ธญžื่{ฒษฬ›๕ณืธถ๐ ‘ะ8ูs ‡ฬa ฝ55นKุ๊Y•Q๛–uฅ%๑ๅnhษฆู.z;ๅncงึH๛d1ุ๊oSE์kž6จชจ!^-˜w,‹ฏ,9ไฏผถัอฮgน3L ลฌผฅผ๏-–o’‹สlWัห๒ฤ๏:^(8ดล๐yยwช8ั๓Knเ>นMษฦF๎‰าฎ2 ๔JIํ:w—=่Kป†ปผ๐-l ๚eพ๑faก-q๛z•฿ฤ(gK\ŸธNIL๔วลbจ้wค_iZ7ด˜ฦ*jฌฐy HCฬN,…i’qEk=JMAuํ๏0›๚‘ไจ๛„( 5N|สPคS?ฆพqGฃด/\ฝข๎ธmtา:จำs—ซบศVํwอJ#ำLปทŠอเฦtภษ.zขpี,่‘๙ผษ’ธo›๑์๎}‹Nตฒฑh@DI%c›5sฮๆ๎ะ๋fo^Ÿจxt6๔Dม6Sm˜:จ\ฐบโ(:๗ฅซคห๙ย?ูฯ@ๅ•ฌ&"อ ๛eจฑtำ๙ษ ๕ืd๋_cU,๎_ะo{๙ฅrfึ๘žUถƒ่ผํk3eLB™ฑv‹!|๙U›…Aี‚‹GตP,)c-ˆ 'Cpคษsp๗j๔๓fํ7e8q€็•ฟz๕‰fq€๙hฺ7๔ภ#8l iHVxะขษ๕Cca:ึฅิ‹กน!Hdภ่pqeปT8ผq๛:ฐ่Œ[‘ฎยq€`l๙ฤ๗˜ิำXศwgœตY วบขC8ภฤƒหhH3šฤXg~eด`?'ฎาAx`=(็ˆุุzŽฝ)ึˆฌM้Q2(ภ^Xdƒคn xท}๊๏ื™ษช฿๘UqญŠkU\ซโZืฟื›ฐ๖z€j‰,ลด%ฃg"™ฺฌ ษบa๖\=ทชฉzิ$JอGสหœฯ/๓ฟ๗?ษทะ๓ซHญj Fภ•๊:ฎ‘้ yyต:_ฟผ)ฏก5Uwwซ ~บ๏’ฒ”นงิHฑ4i˜:ิšI"ชFfrืD…เ}๔ฃ5U๒D+oวd_™๙ู†B9ณ•แ2hhœฆB&P…Iาแ˜อš๙ูnฅฝS๊›พw_[gFVปปฅœD ู“+ivzf๓Iพy]ๆ™_ลิ่vฌ„๖Gฐ๖บabซD4/ง:ฏg:คึฃ!l?ฏ>มL>u;Œ%„„Ÿมตนิลc#Q2%คmถำห"&w ์22ู๛ไ+โฺq^า][ุaญ๓ๆูะ4y6m%ตุุู้๐žู'๔ช’<แฤ๊ฏ#ัคะ,qฉCo|๎“7D๏cvบๅ†™,ฏ฿žญฒ8X\๘ฑ8x]#SijoCช3jฑ๘jb-่J'ฐแยD ‹ƒnฤฯดs#oDหh*X๐U X@Q,~๛แลน?นCnรjฐ7Žjp€๗yเส๓ƒ™AซTzˆฟ_†hšธจใCไE6LGํMะิ*ย‰?น2–ษ`๎แŸF(ˆฒ๓๗p€Ÿkƒ๔š €›ม?Zกj?น0~Ubซ[•ุชฤV%๖Jฬ2H*ซ๓r๔ฅล1v๐หๅK‡่›iทฅv๖•csเ๕ึ4qn†9Ž6ฅkDzzแ6*0hฃร็๔+ อe.ษh๚๊ะi*ำ#ืY{†# Cลั ง qถฉEๆพเำfทZทฦิิ๋RพฏwZฝฎpที|๚†่RษฏbuUbซ[•ุชฤ‰‰nฃวฎ{#ยWg๛#ฐถุ๕AเลโC?Ÿคމณ„ฑŒ ฆuข๕ถลี-`ฯร˜ š\tlRร5แ…lŽ9ัškmฐ๗๔>9owlGฮut†้รา๔2ๅ:‡ทb€ลj-]FลSทฟ๏แ$^—๐ฃtถGญ๛Š!M‘ต ฯุKณl๐๖N“ฌขง_ศqŸo{";จค๑tขลด๘ฮห็s์}Šฆ ํDดSบ›˜ขชช—$6ผIgR‚0{9€C'ดผGtYŸgฐe‘<ึˆ๖6ฬ๗>๋v1ผoญYต๓ํEc™ยภ7/๛…ม?๔%๙๋7]~ี๙๑@ฑ.—OŒญ\.&Lทฦ e…ืhะX๙‘Nพ้ ยd{dมๆํdkvT N0ฒฐWdjr€ึ๒_gd๒O# ํ^็>๔~้รมC๙—ใOpX&ข/O๖SLYย๐‰R;Dv&€ปโฮƒ๙9ภk๚iธถ œ<ฃ%r^{p?ฏœฑ@”ญ{H €_Ÿุ5๘‡าซซศ[Œฟ2ปV‘๙๗ dvฏ"๓๏7ศ์YEๆ฿o-ูปŠฬฟ฿๘[ ๓๓*2~ใoฬ฿OTฌ"๓Ÿ~-นšฯŽฟ2W๓™ร๑ท@ๆj>๓o8ศ\อg ว฿™–ฯ,—๔้ฏร ๔๖๛S8€ฌปX…XtึซŸณsฯ:~ปธวŒ|ๆR{ iMเNึา9——"บเภ:#_‹\w]*U@0V๔…hŠฑAž";m‘‹™e ขํp…คภƒ๖še‰Cอsฯ‡๖ท MZ%๗Eคตo‰๙’NIอgฑK@๗'2•๖t%ล‹'ฆ_%๘ธ/›@‰†ฅmeเE5ล“%ูษป8ภฦ<ๆyฐหžฎo๘ม(3gฒ๙๗๛x‘ 4้อ1๒>IำMrz}๊ล์‰bu๕รWi›Tสฟ$~๑& €, ฯpCฌ฿ ศ’\|ฮ2…๚Kฌ้๒™ xGpๆ€๋ลFฌ๐ูษม+ยCถถ๕ู๋7(oฺืetA9เ๚ฤ฿๕'๋ไbฟํย5Š&ยŒ฿ึ๙‰Qi nฦA„๑|ัƒTQ–ล๏ฤ๖8ะฝศšnปW'บ:ั &*1(ฮฺฬรhงอL_w ใฮ>์Iฏt%Xำ=zŠb:’ ˆใธฐท  Vrตn“฿ํƒI” ๓X๐Hc.๎๙aณ๛Mไ/<+/j~๕“บ‚ ฦ‹=่วm๐ชe็p{Vtk,ํอkพ๑i๖ยฤฎคทZ›f่8์_\ถ/ภi8B@งฒ1sz๒›AbีxฃํN–ถขง#B_eZj#พ‰ๆใ"ัb ฉ,r‰~ปฃฒ{9™ฦ๓๑ฐ็ท' ขRฏ่๔R‰%M.ถกฎ๑;้:wŸ๎r>v๘kด[_ธฆ๔lo w>ธ ฒี‰ฎN๔ฟวDมฺรเkฌ ~9 มV#nยขวๆฝ*ๆุQ:`ลึท"0^ณ3ผศำc๋กvŠ}u๎ฤ`าบู+ณ„๏ษ๋v]•Œ฿"็ต@   ิ๗ฎXฦ๙ธXฆฌ-๖ฯ3๐.}˜~ฺต}+ŸฅSฆูrธุd‹ำ<หี‰ฎN๔?7ั—แŒ!๖๔๋์่;ๅ™ƒ1o1;.*๑0ฯพ &Œqƒตง0(๓&=ะG ›ๆ˜กห ซ… GfwS๙ภSQ์์4"ฉทกสหƒ๏'โ#_ฬึาีvฏ˜D(`ุ%kๅณ์น'๙จEฝpOัˆผ๕ิฌ/ฅ]NqbนkUฮอั1;ผ๖โzัืฟU3ืŠๆุDุะsƒ…ห๕wl)๑ ถcnl,v๕œศฆ๒H‡L&/้q%ํป๙sMs๛็yญ1dฟ&๊ชค๑…{ @*dV๗›Lวณลผบ๊o#dt>lฐH3i.["'ห<๗‚า >2๙ฝ๑อํ๚ทษ ิ|šฉ{R๕๒^๚ปaRฬ๘Ewe,กv dŸ8ภฐื`ฟึ’tชxbeHั๖Tฦ๋โ42๐a˜œฤลJtyฮ"ึ ™w์4สƒŽฃศFตำั Œ๖-็Nซež;^™<ฐgOaู–รยp๎ต\’Ii๒๒ฬ Eถหต"ขjะ);#€Qm;สฏาธ6ีณูeG๕‹}‘ผืทหxc@b๓‹ีWcเFš< ฬrผยฐWงอฆพตmY็:—ทต„/[E๙~B':C;ŠธO้Hํ˜ .b@žqๆ๋/7 ์el๚R>ฯ๐?tัเวหภg]ัYMA˜"พ}๚‰ฺฅHลฎนผ—:R:šๅ ถ ฉ6๋ƒNฝๅjHต๋๋ๆ ถ+ฟ๊ด๛Ž1ะลkceL|nq€ศ=้ก ย๕9ถM€{„๕‹6โเึfz๚Pน#ณpด–ศล๒‡ผrvCัJOไHrqปปฑG T]zfoyฝ… ‰ขฐ หŠบกg|4๛qดิa›ฐฤื /ๅ+‹/฿๛&ํ๕ถค&3I”คOŠjEG 4_ gf‰ำš;ึ[‰๖QƒหK7Vฮ”&Šศ~เ]๚นŠ„Žบดฤถ๊šฟคป?ห‘Hฯก6น-KYe]ฎm›ถžœ่—›Xถ!ำO8ฅ3ฤ—๊7ีgๆz๖ภMนนY[ฤ๒% แFเข๕e–H8ใE/่F บn็Sแ…o2zrซฺraa8(8o๖หํฝ;ŒZโมธ๔ฌ—–๕ฐฯJม6rฆ˜–ญxyๅฦ๏Š‘ธัš(pฟฝ›8ƒzN<ว๕mวhG?๕ชUเ๗+Yp”(๛ย_€ำ H.‚ฝzอ$ˆ‹ษRp,…(ฤ~’ .ฒž—ฟt’ฯอŸอ๊]RัTฌMi็ึ uP0•฿ขHํ Iฑผเฑ~pb;ขู žๅพด 8 fP’DdŠnๅำฌ+้จม9hซœืฃ,ozฏฮฃ๛X Zตเศ‡สะฏ€ŒHฬผ๛ส ย๗hx#ฐ}กวPลณีJ “ท๗uu–Iน๘bl#>่N0`/ํfCฯอ“Ÿ๏[T๕ส๑Fcjeห .p9๎—Uก๗รrป™๎`ื™^ฬ\#W•3?ฤีA=๐&เd•ฎฬ์zWฟ;ั[๔ึ+.hœeV$ญ ด๚ฤ7„ฆัใ‡lแจWฯ9@ bฯ~UL๛ใ;พฎ์Dp9i Tฯง#ฦ˜ๅ–”fผแ/๖ฃXBc€ž,ก!ŸfjโฝOŸไD1uฑr.M;ฉ1$nฝ$QQึะS๐ฆC๖๔;ล ๆkา7iีษฟ&tญํ้{อ5fย~Cœˆ๓ฉW›ฯrฎ–&ออd1ฑnDq=แ์)ฬzฝsnn๎o :4ทฯ\7–ฒ3๙0Kฒด’ฬAstZoๅ๘ฟOณz:v๐4lIษbGฅ€:p๕^เ LQ๋)พหี๊doM!†M*ฬTvbZ‚Yˆหw1A๔C)บH˜๕f๘s€$>Z?˜*๘ศ้(\[nชท'–Fๆ๐4ผฝืฃ(uO๋†๛#v 7 ๆฮ9”ฝผ#jnฌ@U)ๆ๚Œ5๊j7ไกXS๙คยtM…คฬx๙๛}2t*ำ1p'ซลผ๔๙แห:ง'ำึๅงฦ%พPก(9โ:?ำุ4ผ๋“ยาํงzy–+)๑,ัzฦ1ผฉJช>ึl}-ะญ่“%ตแธฑMๅ๖‰ฎpพR™ถAK\(สฺN„ฤ๎่=ศสปž—นมดโๅณtpฬ„˜Vฑ„Yหฺ}ฆ‹ตza}๛}1๎๑ณoษ}ไ?Diฃ๘าŠธ˜O^"ศน จ)ฉูd?่วฦ[GฃอŸ๚{๐ ้-บภณAบE“(<<ธฆ๒ฉ@ฅuษi๗*†ศ^ญ)๓”2๊ผ๕ย8&lL8Pฦฮุ‘Žช$„ฮบ๐6‹ฝvิฟ_&{4wโ^ห๋gธุ‹ฃฑ๓=๖ด%–TฺSPชรำห]นƒทซT™r/g็Œแถ*ยxgs<7ัž Œฤ 7’>Qสร๚ฬTฉํM _ๅ„์ อ\b5‚ตˆWˆ›แD1M<ฏ๛สำcด๑F๋D›หb…๙ฎนNฉ%g๖c*•|ฟว?:"๖ rั๐' o4&ฬ๚%ต็zfYๆžemทึ2@๊ƒถxภ•Ž '’็p๙D6ฏ%Jไโv?๊Qะฮาณy]๏ษ?ๅ—ไ.ทตLฌ๙ซƒณMฯ’สฅญใฮใZš๒^^–ห๑}q™ฆ•วภk&/ •ี›ชท่ ๓nห็ฮ >ัVด๐HMผ˜๋^้;ุร•!Œ>‹ฯŠ% วค7คโ[ฎ5พ†จบ“ษ:]'วGD;ะตSณ—ท”jAŒRัฝ‡_BT*ำQฺP5ฑฯS#๋Ž\ณeธ๚ี็™žื่ฯ“ฐฃm MูwืH;EvKณ๐ฏ>กถ’ย70‚ยึ3ฒมƒพ฿3๐ฉ ฝ>มฅใŒ/บํ๏{เ=ดˆฟEvส๗ledrี๏>T!K^ล“ˆฐF‹รcไฑแ^ฃฑ…95ีYำeฅŸ‰_ฯZ*งสRๅษ"ิห €€น๕ตท<4ิ฿v6ร N†ฦ๓tํ6y\ฤˆ00ฒง…Œ@iEuBI7OWปฦ–9ŠWTๅE${฿_บะม{R–ฝข๘iๆ9แCRŒ ่žฉ8$แ๗˜nงYzŠ.ฟ1\ ƒญ= ๊โIuปซธ&๚ๅˆOmzFšฮม าล+"œสc#Ha=:Eกs€y3๗Vบี^|!ไH/ฺ\ั‹^‘5รซ|,ๆขฬ๓*&เL๚ฯs๚#+xผ‚{ตjKg#xฏะ;ืƒเLdWฃพU-i&Eฺว ๎BodtbNˆA๙พฝํทF ฉงzƒนฌ†อ๚ ?RˆหG็ฦผถๆnSฅ–._ฬ์ๆฟ]jeHQC6Xm๕`Ug.…๎!ฃRz๓š๊๒ฏ.™ ธqKœ๘๚&ท”บฎczŽTท žุ ูA ‚์‰=๛ีผŒW1ชs˜จ๖๔I8zŒ>‚ไืZฮŸO,†ฆำHใq7Y9oีซ“ŠYjA'{๎ฝ'ยฉผ›$GbtœV’เRศQโ]ฟŒ‰น–ญeํ้วช’s๏ืฌXWD9>-ึ]2UผŠมล3€’ยoอVlอ*/:}ฝ’‚nTผม‡~ac{๗+ฺJธ ‘๎’™๐hf›SG†‹ ๛)ึUฦLkZœ‘ฒฟ๊•ŠŒ%alยฒuŸ฿oO๑,HศSอ?Žป‹๘~^ฉ“zฌV-ษ2ๅ๔'ถม^ถ6ช`.?ฒœ;2Sœผ๎์.މีLธ ฎฐไ{นะวัW์iQฑโจ๋ขฝ๚ซM_x„p}}<ต)ถช‰›bCŸ+ลำD(”3W‡YN๙๘๑\9s๗g‘ไ.จvภ่yป6bH( L๒ธ‘ท+p>จยBึฮ][ฃ}ชQ&฿"ธ=ธฅE™Žฆ๒zโ†?โ‘‘“ชไพ‚wฑžพฌ้™Oฟ*{ๆ ณค_+1W”–^†—๑UำWbฯI Yฟ€ง}J€ำโž1€E฿‰mซUฐ‰~IฃIR=!wฤ—dxG๋—้-ฉเโŠmšสฟ฿)ธ6๕ญใŠB โ2ีสถeํ:๒Dึhaยl+ถG–+ฌghKd ร๒h S้N@แ๋#ฺ่ว*(_|ตขw}qqโSจ8•iiysใ€‘๐Jฯฦ๒งฅ๊ผšž6ณุจwมาๆ<6ำ์ฏ๊าฏI๙’ฉL ˜ธ ‰~Tม$J3ู_Oฏ*ฤ'h6ถบต๐cโ๊r ตณ rl~@โช›?จ˜ม}eyัฬ„ข๏jsภˆKTฮพ2sฯๆภ7"ชัŸUดฬO/ฌFa‡ๅ2E…ฯ…–Šrl/ฏE“R4‡‡}U#%”สฟซ tฝ›’๑ˆH๙สร”)ฯผั#ุZ„ฟ1ๅŽฏeFป๓T๎73UF?F๙บV๊nทZฃ๛ะa๐rฬ bb\Šทˆ๗ฺๆ2•<6เยๆ์๕ร๒VฮืDญZ๚ŠMXญ/0เ1qดษ8๔ญ ท.% Eญฯ๗o›C3ฐKXPฮ;ูŸษ~j#ศ”Vq๑o;%ฟรPƒ‹Zฤฒฝ๎ข*rzyuยฃ‘G“ตQ็~๊H?X๘“วำŒฮ>CฑดงA˜[ ฆ+cศ=› ๚77%฿คMฐŽžjํx[๏C1บลดkZะ;ฒ80ีbqแำ_H#7P`—ล8iLขU้??}ุzาหถเM5\&ะŸz\x%˜^^ํ ƒH„ˆ‡๔M๑ำMœU๗สTdหกˆsยู๛˜ฅ฿ษฑฑ๔้bธLvCO€"Nสป•ปุ?ฉ นฏ\˜(˜0”๙ว^ุ9>ถ๔#ฝ-วฉ—mK฿XเฬมMs๕M๋![OลN_3ญ๐ŽqวTV‚ำNษ†Beศcเ… ะ2 ีx*Hฆ\„U–ๅ„ญ]ัQ$ดสซิžฤTใ๘Qบย8ภไฯ ฿MนZ–ฬpท`„จW+ูๆ'เ jqวdๅ๋’สูพ uหสช1ีQญฒ™ำ๘a™SUoโoอฆ\ฒธืDqซฬ„าs‚"ี˜์ด๓ะญ#@9าๅR๑8]เรOc?1บขaา’‰Yqค%r,ท]YošษAพย๑แk๏นeFฮT5๏๛ศ=๎๛5ษซaุบใR๏m0สฆฝ"ำ…'Nภ&C8๕ฺ’;็ห‚๖๓นKŸไึ฿ธ“๐๐พำW6์”(ฦ†)-z-๘Žิ’^-3|„ึาฐVวŠ'Ÿซpuกทแฏ$ิมณcชy&šซ}eRdๆฺ4—มy“๛ค(ฮ…๓lCฦH=จ<ั*แ…ถ'็ทŠไ(์ก.|Oemฮ=/ญ็ฑŸ ส๛T๔yๆ=แ>0?|หธZอEktK›l=ี~Vภ&‚nžCŠPqัTeา5๒€{6ดF5Bkผโf—S[ล๖6เXงฦ๘›L~อธ6˜Ÿี†8ˆVH‡p๕“๛ำ1/ัd9W*?N6›ๆาวดาlผ,๊mโMbAๅหง_ ชวl?#;งCagฆซะ"้# ™‡FŽมIฅn–BVณธปๅฑนw้œFVนีw3ไ›rฟ‹รJ™wฏz๎คฉ{(ย)D‘9td๚ชaA$-ๆEฮร3mM=ฬš!N6ฟ0yุ๏jฯŽฆฬฑไP๎ษZ=_ฺฑษฅศ>škร*รสะz๖ฮw‹มŒฝ7ี„‰‚—กฃ้วืS/v" หน.\Lุ่Qวvpีž8w2ภฦ็SาiSv2ึ"@Dธ>ะCu ๎ฯ๕q$่7U@๗…) gCฦหๅ˜ณำ~*ฯ๔์h›%ญg์ฦมศ ซ/P1๎Rศมพ-Œชฤ›(ชŸK( }Aqท„ฌFกl2๚๖&โ>แ[Rœf ฮ, ๏x1ๆฌ\๚F—&_๒˜Qผแิท•—L$ิข กP๒ตฯy…y5ืŽ๎ืทฎg}๗5ถฮํง+ๆเ‰N๋๓2ฬฃ๐ ฏ?kD4CซMN๐๊>ƒx๐žO‹ญ@๎=”g&ูาู‹€ฌ1ก†Mน…๗?ดjBฬ“vีU#งถƒ@>g%ๅ/ZใQ8b๔ฆsส%ฎaœ(*ฌ_Keงน๚[dBณžsYฅz๕M•ทoo[vใ55เซ—๘ŠลM-yฆv ย.s“$XํœบIขหSuษืฒ€7๕Q๛--์mษ’ฺxด๔งVฑ๐Uzgx๐ๆ๛ดPคฃ๊a„-{+๖TŸ ค฿ูvšศหv4ฬ60ฆืXžฑ%ทโG6ฅธฆผ๓๔/ŸW>o-ŸฟซI–./ฏ4N”9น5๎ฤงO_ฆzภม๊ืH"W)ฎŒฐร๗o3k้oฝ฿•ใ๏ํทu_๚l๒ ั2Dฒiฦ:r//gช—“ฌd2“ฒผั3c๙2%@ KฯX…๚"ฃฆxสถ …nฦดI้๎f#q้ฒK)็FnทKa"ฝ.u?ข]Xk8vธฐฌไฌŒ}"ošD›0zžˆ"X2ฌ๔HดwํQผพ8ฌ^ฯ>Wดษ Bยi/ยXฎโฌkt}ๆัƒ‚ฤ๏Š%กึษ๏:ภ…+Rฆ-ิ=tTูซ๓พs9‡กz๗Rด๗2่lห”‚*5 a_|๓้ฑ6†๛šภ_ฃ้ๅวj.#ฯ‘#9–๏ 9๕hถ-๐ีZซณ:ส8ฤ}d๛่~“ง"ษย๓hฉcE~๐ธ๗ก๋-tฎއa๔Zฎใุ-jมeถm๐๑ฒ<"7€ฺฟmeๆBƒ๚>•XRๅ๗ธt๓ฆวฑ"I9ฬบกIึeร่ๅศ฿โร4้)„Pˆ๔‡pL๕ฬน#y”~๕หผพˆ์WถฅM_พ Wฃš๖ษซDฝ\OZqํ›be“]๗O ™ฏืฅ`Vsry‚2๚uะฆr€/d$๓D๚0R"!ู‚z๓ู~T๒ƒฤQs5–วRul‘ด_HŸOZ-ณIฟiฺ EอๅNฐฉLฦ้YMต |า Nฌ๔ฑจ”%ไ!”วม[$Y็kด_ฬ฿ค†`ŽGr(8ฐSงf=ํ•ฎMs‘ๆชฃ]ฏO๘ษ_q๓yD_ฅี<Tขคจšื ๓+Y—๚ฐใญ“eืqฆา้fบขโษg:;ฒป๕@/จศฟ— gแm;ย๑)›ใ“๎o+ต"")ี;ญ˜ ก–ห=ธVกVื[-CAC ม๓ู _žRf{ฺูท) ฏฒ๔€!ฮ‚๕จiZVˆž๕[“ฆ ™@ูฤๆ+”๋ร”[?ำ$หN;฿`ธณ{q?๕4zD๕ ’`ฅ3ลVwฤŽAุ1ZLจCy฿๋ทธ_b>+i™ึ๘frIwขบ9€4อ€7‚n ›X'ัW{4{tั#Œ5G$ธ๖]qกฎ๋œIwญ~ๅฏฮ€ื2Cv$ย๐“ๅฤรธถจBช>‘๙lฅ็หีญ๖~์ศ๕DHฦy™J#้อธงKก,ไ$:ฤ—่Gm#u˜œzB  ใ1[—4Uฉ@|šภL”ชร๖€ฦY)—แWา ใไ ๆอถ๗หฺvฮMMKœอ•™”ฟ—r’จ]่&ง๑Rrผ7_•ุ/u๑๑ขfไฐŒ\ส‡Cฝบq์W…/˜ๅeฤR๘๗;]ƒP-“„`{ z๔j:งU$B‚ “8‹)Sึน|'pญบ"ัฒงฮ6ƒn รeม7P ฉ ทฎ?b"z7rG0ž=๒Žู›ะu!ุึvะT!t5Q>uฝ[3z.Q๔E๘ำฆ=ƒK]m+‰ณร„]ร ถฤก-ข Tฝ#฿}ใ฿ัฬWo]ฺ&w5vŒ€ค&Yส"tu๋ฅ นƒศ|38{ร]ฒื1ชRถํ{ผ๒ Om–Dย\j-n/‡ฆ๒Mแ,๊-žJˆ“pผqมgšะ๗‰ุฉwM>แีูส“j6อ8ฆฃฐ โ[%1‹P๋ภ๛]ฝ„-J ศˆvKlx‚^^น5ด)™>8ืE๗gŽ˜ฦถกท๕๐ฌu๙kJ๎แะพฺื*-Z.}˜”š'ญฺžSต N๒b*๋(ื-ง็J๏‰ฑŒ๖i˜๑๓ ฆนฉ<ฟ6๔M^4ข„3˜K'ŽดˆJŒฅ๋ไHขธธ1๊i‰u"!฿งx้Gฑc!0F'ี4—nำ๑”%ฑ6'ณj์blWO‰ๅฏสQŽQ]iiตgผณWคร_–฿sR;–ะx๒€ฅฅ๐œฬ๕๛'วรูwมฬ]ว}pQBขื@?ฯ-“ฏขฒคOษ๋}Tง่ๅ–ว Y็Š#wณถชต*>ฤผ…‘eซฑ่EบJษ–HฯฺษP)Cใ;\ผบ]}๘^9•œฺhฝn้6SŠ/7Yืฅวƒ/€lWš ’j๏าะึขโฮ:rจp0I;‚ัฎq๗ผ'ด:นนศQ๘ปพำ˜ฯ"t .ดว@+Zุถ_qฏ!k_œ๙ม=œ&นฤk๔F5ไข’-เ7Cค๘เแึ› `แ zVใ?]“uh๘ไ_ถ๑&=#+GS฿ธ†ƒ~x=š˜-KBaฎ`fˆEnภ |ภŽ฿ณฃ้/้  ปGrwX ?sฏ ฏ‰XPƒk๙wั9#ฆญ๛o†@Je%wyลฐyนวzๅŠโณไ/Alt6:€“ุ่Tqล}o>ž>ๅ๕i๗Œ[็QฆธวWฺ^ žNํโzตX‡”qฏ#z’^ร{ฆ[?ฉSv<ต=u$ช‡ ~)ž๊.w~ŒŠพฤ96,0๏$ั๘|๘ู6 ‹ฏ>[ุฤบ |a๗Žซ<็%Ÿ๗![-มจ8Uี{ฬถี^ดค’rฎ๔}ญ2Eนว@รณ๗๋fฏxvฉ ย„K W‰ถ๔,œž˜‰y้ˆA„ค^<B‘ขยa๛0๎LณtoูฆKƒŽQดาถQ•†สj™G๚w’_2S ?iPvT(ฌฌ'ก‚m˜u฿ฟ2ต่pPuTฬ ต~&ฯLกฐœ8˜/นqƒ&Ÿo™"ƒพV‰{_†๊ค:9ถ‹ฑ ี$๔ิA;S๎%GSXจ rŒrŸปลฺ๊๎^nไห~ญ}—เซ6{'ม‡์q๚s€'2‚ *3>%P !ธZผ๖ญŒT‚\ฉฝa\zER๊๋vโด่ฒผPุแ‚-U:{4ม‚.$ทz?^@6Xช_š”ฌm๏|Qๆ,#ฌฃ,๊X](BB/‰าฌ‚ky`c›Wศ่ใปจfณ~B้ม6zOฮ{๙4—๛]๗$ล๗ศ;b๊ มขI3‡}S“HpหV๒Gฆ๏Ž๓ฅถ.ŠจZ3Fr#yAำq๖๚#uRไบู OจTminทu๗eล›๎ู#ืํใฒ˜๊ัKtฺ๔๒WH[ฅœ:r๖ญGcลCูpํทฝ๒’๙q)ฬ๓ `ฦุจืˆ๋ำ•ัP>ฒึuฃUOŠุ\น˜z‰<๏tE๑$sส~6ซํ. ”/ญ\!โ—อaM“‚ฅรพํฝœo=ฏU&ฺ 8ฯ4fcิศ/—๓ภ๋ฒฺ6%dzฬŒ”6ฤœaฑิ+ฝ8-xฆดQ†O๎OึฦŠมวrฏ ณฟฎธฅตwŠpW“kภู™ำ  >MW…๙ืIา{เฬtw!นคZฎาN๒หWณฅฑฎFA-zฌฺ้โฏฤo>ึขๆ„LN•\ฤ”ภ[f-๔hD Œปฝะ๘โŽ(?๊Z™zู)ฌ]ธMพฝ-ลˆb๕๗ƒ@Rเ๔ษ9ฺ—Z<ณฅ๎ะภฃ“ิ“~ส฿&”ผ–Kr*ๆ=*ํ™vNฦ็9?มi ฺŒ:ฉ’ˆม\๔น๔›ขึ›ก,o*/อซwy‹(Žuา~‘2lKwอ4GสP~Gbฤ(ีSŸ5๙ผp฿C?Hh ศ๒(yzฅ—m!š*0BฟุА/u/@ถ9R.Fุ?J>ฌ!Y๔v8มŒฤAส2ร<‰B-{/ :แ๋็(ฆ9ก?แ๐,XศNษ›Iบiใ™ูhญ น!}`ต*ŠƒDf<“ณ–กx„_/O+)๏๎(Œ“h…ฉ่5T๏œ2ศ2๓4;฿/'แดฬƒึ}Ÿ๗}}กฐฃ…\ฆ”ฯzืส^๘จRฦGabTj~Œ+มŠ้ศBส2Aฑ U๊hม๎งบVnจs.(?qz๋๎กๆ\5]ืํ>9(ณช์๛—n˜OYนˆ๙TIL1ชE†ำุ1าKอ2แ9Lนlbw(ฝะLa†ปYu *V†>ั‡0lฉ๘s/ฆืๅ{vaE”,en4™QWื^m}๘€ล{=๛0A0|+ถ&จ #œeิืpห8แЉ…"c@BิZ9บ๔๘jLอ4?ำ๓xXืญ#“ึิ k]7_X+J€.9?ญจ๎่โฯL!ฒ]แำ™Gํ>?gผ$ฬ:hmq‡‰ญXk#€tJ@2ฯวqวKฌีฌไ*^ห‚นคSŠส.ุ…ฮF>4 คZN'ขรวˆขุค๐ZŸS…ne็D_›=Ÿ‹A^ฎ฿๘œฃŒใ™‘&UะjRbฒj8ฝ>f5๋ํฬ*‡้=M๗ท’รeC“`'‹๏นฆใฟฺRล4ฝรม•V s @บp'ั%ษทYRnนอtี๕หฝX๏สŸpj๙บใ6ชyqT๔;ฐQ ๒ถP๕L6นฆฉG5|X™aY๊ษตšณธใŽgIJrv๐๔ภจ#q)(>DErฑZyซ[ซ'ผ\Bิ'ๅf#‡]ฃ:2๒*๎\]˜cแวพฺมฯT„VฆpVซขรE$Kˆฤbช…›ำฦฦ฿ฯ4สอexล1ธcYฌธˆร็แค% nฬ+6ŠM Ÿว\ฆ๖%@.jXมL"›.โM๒b๏‹๑ชT‰Q$q ุแ๘๋ฅ…มl3๓๕%า$„ะึ์อตด—ป|7ผฟวช๔๋ืดPนปฺ๕ล๖gš5ะ'Mำ ๎ยœ0ญุ#๋ตW>›‘ธ๘๚oฝœ\๘่’~9ขภ/๚rŸŽ๘วไ้ƒไDณi๎Vˆ yfฺฅฦwšห…๋พๆค\l*cย<:s‹๚!T!ุYŽตšศ:ืึ‚‰† ˆaoบ๙ }xฅฯ๒ยOY๔™žSผoOฏีด!pk`‹BณูใาธP‘พฑฑ8ฌ{;Rฤิ้ฑ๎ณ—อิ €ๆม8Uฒฌษ๊™e7๔4AฺM;8›ั2(xIƒถ HW‹ฃฑƒl#‡P"8ฏF'AOภฑM~ำvะ5.…NัœาJฺฑWL๘‹-แkหOฐ†ัvAฆเ{จผำy๏‚X@ŽสqซMห‰7M ขD]คถ‹8U&IdFเ|แOก๒ธ>ณทŠฯ=\‘?I =แ-w’Ÿ ึ3๋Šแ8่ห ฿N&{โผำฑy‚{Vัw๏ฉ‰'ย๎EถK|m ๋a๊@ใAู‰บ>xฏ\ฟศฅ6ํxN yอˆฟเ๏KNtNล?ชPUำI\ tuยB<7OฝJูท‡Aข_“L%ซžถIัšญฤ |]19"ด\z๊เ’Ž าฌร…โ“ผl;NๆEu฿)่_๙tN:ผI๑™ขd|ฎํj 17ิ{ฬ„๙๒@่uh‰ํ๓ญŽฬฤ๙ฦู!ชภ๔[HซKนw๖ถSุZวjŽตฃwรs๚?กส*’งแcr๘ึdผ~B1ย^ปบI๒nrพM‹xGฑ7>๖๖๒ค๖‘v]บbHKถ3„สh_J“ฯm2ปๆช7ตค2—gเn๊‰žำhc~ฆ–‘-ะŸY.“ๅJTE้ฝ6…ซฆ=/+ฺท์ฟ๖|เ?ฑ๕`zโ”แ ;~ฎฟ[ƒๅฌ‘๕ซ—ธ฿-?๕ด๊Nฬ~™•%หแฎnžrฃQGŸ}ต๖ฺฐํอ ?xฤ„ …F งฅI•ลฏอi๋Tญปw^ดTRK ณถธSHฟˆฤ0Ž{Pq๚ˆHO พโฤbˆ^yละ๊O๎g฿yl'ไa“›wิO,ิ๒A2ดvz"ภ๛๒ Sม–dp์ฝL”ฟฌชzฦั๋รุ_[~u[ปึ’ๆ‡ฮ 't%y{G๊‡h๎ศฅC7Œ ฦEpƒลใf 7ปNล\๔+า ™ฑ‹B่๔้ศoขช)ˆพ2Žฺ๚lq“`HบยฝงUยฬKม8๐ํw@/‡ฟ๛๚ตฒฌ2}mํFิ™ฆโแ๏ฅž–jHฬ)บ)?ฏ˜งฑW ษ: ฎ˜D6}ภx๕์Ž์ofฺ ถPำฎTAT”›Hชมร๗S๕‘‚ X๓ม๔แฝON/๑…๘9wวค•”im‡วโ๓๑_์ŠBโสีษ5อV‘šชแื&ฝI|2“A๗ื‡๎œT)+ผ XYS’†หะฦงœ-๘ธรยใ‰ฌัฉ๓9MŒ@˜hoฏ๕Uฑ„NูŠR๗ฤ“ฃฤ[d ฟU\HJผ–—rกW'G–X;๙ษ:Q๒ีฎ๗พญฯMแฺบณ@W๔ญ‚}มEกPy0ดฦูŒษ „Iลฮฺฉw‹4์%6๓HGน๑qๅ™ฅฯ !i์ฝาํ๙ศ^ KฒtŽ๏-๒H›ZnถŸS:ฏุฃ‰ nPเVะบ+8yำ้(z.#ิ0žไ?โ]ซFฤcb4‡ซจ&9฿_ศy ธๅwPภฺ!EJzE’#ส&ส‘ะd[|กžชฎIัุ’ฐ%X}7|—:พsๅ„๐šั:๒5HoBV๓ApH%"้-  แ˜b๋YOdขฎ"ค0ณ ๓jOj;ฑCๅSค[จ^ใ4๔#˜#‘7ฑƒำ๏I-›ท U@ŽžSฅ‹ย aQ˜KEเPก๑คQฃษ’็Lุpต ูp6;c :SlฯฮžF‘๛ซกหl+ฟG'จาอๆ1+ึฐ=[ox*RE0ม@ศ‡๑๋ญ๋"!Pข์kk}ิก—w^_ซ๊<~Œr‹ซุีจ;๔ำ&-ศˆMๆ๔nฬ–ฅม11ฮM74’ภ๛#ฉšS+ใ ;6ยษ†ฏว9ถ!# ƒชญ(>จ„gEฦ\ซ๗K•ฺ;ีฮ฿ฎ ง๗C๙nZ?/)ูb“์ey•U”†กบlฆ‘ตX‹ฆUŽฅ{9eใ์๎LK]uI ๗ŠุWzh„9hญ๓ ๕iฎ‹’™Z‡AJะˆ5N|฿HKˆa>]ฤZXQัzฌKM—7ทนK๔คaxT7ศจ:V3ƒn{•“„— ฿ๆๆ5ๆŒ™ฅ&žs/P๑็๗ซ๗ศฎlb#ะร S้‡ŒHHสc—$„ฯ$4๎\vsˆ,๘เRจผCwะ‹”†Nฆ รแยFฐ|+˜๚nแหฑ๒ฯา์bnบ9™Ÿ›ำ]ŽลสคฺHiTล‹ATqO(Bดะ#D *;b`ไหาลU9Vจ๔' ซrฉ๙ศQก๋  WS€๗F๖Z/pฎMvžt^L ’็๗มฅบซ$sณkeจND$Rลส;ชซะ€ถ๛›‚pฤลำ๔gย๊Žฦp,๎ }D”_ั ^ข ฅ}G^ึ]pcQ‹Jบ ๆล<„*a$bท1,ˆำH๓7แZcยzณ 2v+7-Kวฦkะ๊>๛ๅ}ํNฑฏ€๚ไ7ก&…ศพ0๋ฑ h ิ›อ6๓+ป3๑-…๘ฃ{†฿๐1}Pบs๋gเ>sžZ๚ŒS๖ว๏ู†[Iฦญd0อ^'่oq™8าฌ|g๊toYูฆŠJ‘ญ‡Jึร+ื/['๎ ?f80k5xม/ยฤ,ษ^๔^8WชถZM‡Nj€๕zยค L„j‹ฮมxยฑlืhy!๚ไค้ทุ2๐_ 1ซ ฉุ๓ญRผคำ\MTƒk๗ฒmžๅ|"มCSo[ถ, rปืฦ๘WHค")ฃ‡มฅ#ูืBCฺกโ_ผฉž>ฆ…“ฃ8r{ฯgv{ด`๛ด๖ฑ6ศ‚Mฯฎž*r๔ต+ศ?ษDฟ 9jใ‘=(yŠต{ภ%ฝH ฬ๋_‰!{ูล๓g๐฿ฯฒ๚฿ฌ<ใ‹Eœ์฿†kKช•ฦ/ฐ((r)Lศ1V;ึา“|๖๕ฯHป๕ฮ1ฬ%ญ6ฒATEซ-€์:็jา ๏‹ฃ0บธๅ1ฒOƒtBGฒฉyฏgOนk ‹]ํP(๐พ๎๗ฐD฿ขO ถ.2€R๐t^ย2jผ”‹ข[>BาอณธCA#ห%Q3“ัv =ีฬ.šช7O|LioAกŸ๊นุ3ฺCg฿คุQh๙u๊ošmMลฏฺฏญึห{{žy6Ž๛๋`ŠถuhใวๅลT#‰ U*ศ7>Mุ" ษ}๙›7ว8฿๒ั†U?‘9˜ขวฝ/C|–=ลิยc!‡ขD๏๚=Lฒุ๑iAdV–๓ต_{{ปณ๓ํ๐ขงฬา๛8พฐˆลั€UฺPQุ๒ษ„lอ0ฮtUพsฤฆO๕Oh Ž๏_0U้บ๔œi#i%–โ„0ก=Cุ! ฯMŠ;๗InฝฮsŠš้”i“:_ฅึ๙๚ฅโํจ#QืZavำ`4ฦ!๔๕Sผ#ฑŸฆ\Ž Jบ•Nํไ˜@.พ ^bฅ/VYณ~–g–zš‡ฏI{)ช$๙ืR  โฎฦฐำPๅฐ„ขžฆ)ฤนน=ำy=ฎlะาŸŸpท|`žDzฎ“ๅ1-hlอ%‰ƒฺ—ษg8:ฑvŸ 5_\Jจึ๐ป฿p0Œ[!.ๆ๕—๋๐ไexชิŠส[ูš‘—{ฺ๋z-ฺธ™ŒCoOdn‡อฝูน‚R๛›sงŠ้>:9คI0ร`ฏยCิชศย’bฯพ[“ป{fM+๚rKต฿นYt/;ํ์ฅnศ๗l‡๊d˜7Ncj0Oชc†่–l0ฏพG‹› ภN9{ ๙ำ&๖|iฉšIฑPQฺ">CญqOSWVYyส7๒Kw-_@ลบŒืฏำ1๓ฯ+šฝฬึ'@Tฅ๒k~/ปึ*ย•†A}^เๅ๒น8ื ไG=>+Žฝyฐ˜iiบ›#yBกI’p*‹วGBcฯ4Š˜„ยTcก์zCž[ˆิฒ๒ ่ส3พRm!~V่tญe(”๖{c Dำศ>สMxรผ[กžี๕•‹—3™‡–ำใ?ำีข!Gfฆจผ๐rŽย˜ส‘๑{9ขZก\ฏฑhi๓xc ๖ฉ“/3ฟ๏“๐G^q(ฒ<|ํๅ๐๏bฏ+OผN 8็R8ข…หw+zŸp–˜'ฯj ึ=ไ™ษ<ƒe&็๏•%ุ*.ทฦฝ:๘ฐEษฉ ;๘—า๊ˆ;กmlUฎ ๖4า็›ช'>(T ~‡:y‹iH9c•ก็8ง๛Š{hฺ๎-Œ้๑ี2ผYA}\ผB*uŠ[wkไ…ยuŽX คีืK;ิ‹›"\ดgฦ#v๘lษFไ&๓ุณo๛oิช0แโฝำ—“ภลโu#‰M:YYh๕d๎bผs!ูฏIoจS…u0}ไr{ฐqิœ#Œ p ฎ& ยๅ)ฌ7)ก฿…ะทฎ ;tซจc๋ŸlYลWแŽรฅ็๓Ÿfw^{บฺฃตIG1@ ๛]ฑ่&ุแฑฮ6&ู>ดใ`ภ-ฌhพaช8iีvฆ๋yaพลSฑมoๆw๛ุaุvล2๒kๆ€่‚—C็งฦไฎQIฉคtba„ อฉ‘๛๋)็„ลs๗goโไ~-Jkีa๎รธ$‘ฅ-?๛*Z๐ำฐอjึง—ๅH๛ำŽง˜่*๘ฒ๏|ิM?>nพ่)‹CdŸS„ฤHG|ง;มๆ+ŽOw/‘–ƒj’๏ฅ~๗—ร[MพฒHwF…ๅ0ซมD า+r‘ญ>„‰>ะซี}พวี‡V๔ซm๎ฺฦฏSกgฮ ิ‹zR iaฐู๎:ะ&Ga4ฎๅ†?#3าœ”ศ…"ฌ•$wrาฆ}ๆาศ–กŠ~Pืm%Ÿ€ซQwฌพวfjท๐‚ณฐ๔฿7ชพฤูV" ZไดสY๕&dยQฏ.w-(R†Z1า3yิ๔{ [%_ุh*q›F๔oส`‹/ำ_?HฮฟT9T๖๖‚lิฏ%ญ ๖์{Ÿ๊รนฟข0X[๚>ƒIEฺหํฏ๏ร]ูขหญœy็SาGPฺ&ฮฆก๕หวณธ›Agรˆ@จ|#ขอHƒ+ม๘ืปFึ6W?ชlท~2๑ณขฯุบ๗#\ˆฦ1๐yTณ ฌzฎ๕สŠ’ฒ์M‡J“k๔Ey{mZ4ฬุkebู๖/‹|d฿บastลฉใ“ภดZ% Ugh๗๓ต"ฤฏเสh๋ๆฬวn=ฏผe’฿v`๓k˜…%s‹๛kภษพ3†๕!ว+<อแFตKฒ,wnŠฝ“6ผ>ฃศsJLไ—T๚อcฆxฑไg๗;›ž? Eณ ™ภ.qs‡ Z™๑+"ไxำ'^ูฎพ?๗ฮั6%ด์กThzx–โq&ะ๎`(^ุm ์8>ak8S’์๘ู๘ฐใช๔๏๚'Rบฉ"น7ิ?‹ป!ุX๐’]‡กbไ1\ัp๛ฉฉ้[dxฯ}Gแ|ไม'ฟeก๐ยEูำVTม_A "AชOP‡ธ2๓ๅ7oึ๐ต šp‘2ฉlดศ=ฎ("hะU‹l‚ถป˜ฯ*ี‡ถ jl66!ไำู“(ˆหuถIl:[1›ชพ‹‚฿ฯฎึyพะ{เAfฮeถ–:Cโz<]ฟ้q'ษ๗คoาๆeŸฏถฮ๙Yเุ๗้S่งO๛ภ`u[ †CฒŒ*‚8wŸ1& GZๆ1%ี:)ต–Š2ฟNzZXส;^ึ2;q๔ฦ—mไพrc^^'KIผ—"M{จˆ…Šิ๚ื[ซ [NƒŒl‚ฮ‚ง%ร@+ %Fท yjGSห6ฮฟ^|˜เฒบˆZYขจMํ _2…์๔J!>?daไนว–ต“‚$+€x@พŽ*ท/Fปำ-ˆ๛Ž(w&=ฟีyม>๙mพเ‚ษm…‘ํbxœ`ƒa[ุKZกแ€ุ%^_ปรอฆฎฬ•“nชซy๎ู๐ึ)cM&๊๗+ฦมL%„(jf}•‡Šผ๐t8ฃeOtบŠUIน!sตttWฤJ๚eq/ฎำู_,่m+(|*’-ตะฟ*Yืฤ]๑‰๖๊P€จWบาว…–ฏณ# \gผฝYsk-ำ‹?Ÿh๏งฌภ}@Œฺ้ๅ}<fE่็0ธ๗ €HQงZWUฃ•…้ำถoีo์<พvR๕XฤLคฺ์KŸ์Vv'๒ึPปf=”‹Œย+›ิืม๚%G4•m4บ ืLฤOฑ…ฮgต;๏์ |^R ,X‡„BWึฑAคภ>ๅZน,OมIiย3v๏|ฯ๛ๅƒ`แยWฆ฿๒0hŒ3.ฆœ…ปpญg๖dwฝ;ใgˆไ€“หํo+'g•ฌd”4Mีnฤ้pL…ฟ Qค%0V{3G4UŽ(้ฆ๋๎๕hl‹ฐฏZLย …NMจ‚AคฌแGcJุ;ฯฆอ ‘!C\…-อฤbH šaSK๒ [B[‘็˜†4ฃ$ึD๓‘„:ฯJ๛ฃ#ช'dชkžีฌยซใ KR €Cžใ[hQพ-ณบ4ภ้ฅŠฯ-šSฎผkฃต\|ขXdo ๓9ฉŠ.€ำƒ.jม์~ฑซnึ๓ำ๘ ี๒คเฝฦW•NJ2ใฝ™ศB-ศรว2[=๖QFEMัฅŠแ๔>๎W5)7ฎค?–Q๘ ิ ˜#‘%S๕†B$๒Q|ฯ“=3ฅ„ใwณ!ƒrปkวๆ฿ๆึ]g{W€ญM%ก=๒…t่๙,‰จฌ๓’`*๋v5 Wํข…ใฐ'nžโ•–ู๏โ=๓˜้4ํ›ไๅม พซahKoƒำดจ™V$iP ‘uˆา3˜•๎T่฿6ฆ๓\ฒ<œ[‰U^-S|ผฉโeป3fXฐป๚?ส'JทCํ0‹f)#ญสฉปเ๓ีeทงฐั8ุชฒ+‘mบ-bdึฉฉ๑๒R"ส—2–vZ๕…—า›อ?ยdu{Uk6Ž&ูG>‘๐ืทŠำt!r๎Ž@ศŸ๚๎กถŸl~™7Š>o_ขKๅAไำ A+š";6“ปVผะŸฐ๙y4ัอ๙)>y่หฉลnZ‡bl0ฒำศ6ฯค0๑๛ƒธฅ^๓<ท๙ึ๖p5าeS”X๏gปSศฟ๗‘ AEํ/NBzˆ“ฯ_)๚e_Jl(tU๋ฉ?ญF›1’0#lา98)TีพU ๏+””7ึ*ลI๖*็INชด๓เ๊}่(่NืพžัYU$"ชร็gุžzœMjฯ้7ฦšฃrฎŸ8nT๘ู„5|ŸษตZcmค'ฝ9n่(จ\ฑ“ DทSษkw gHผŒ$จเK ๋hพŸย?ญ5kโƒdMฉณหFƒ‘Iฬีotศ’ฟpอืึ/ฟ•็uo5์ฦ›}โwoK ง;œh†LผS ]I๋กšก…lLูำrสฉjนญ9๎%mพศbi)xฟS œๅP5 ่UzšqœˆยYDjีEพs-แดuฦfฝ|SZ#a=š๎ุลuจbx:,ช(Ÿ299!จ;“p๚ฝิA…O‰เภิ{}๋„ง5•ฒsf3S฿า>#q๙๙ค›ไ™Bโ&~„*SQ1๘+้:Eตx+๚นW.›ทEยd๐qOTdQูT$๊ะนุ"ปsโ๔w!•WฐฅูฬEฒ<ีKXใ็Qฌฎ8gAVDS3]~ฟ๚IPeฦ"ิ–,ฮ๊๔lไg›บ‚๛;~•ต›า‚ฮi๑๚ฅf|ฆkžูไ`\pะดkโ#๎่:ก่žกZ“`๏wฟีvEเไ—๗%๛ชบuฬ}ใ)มŠ็หำ๗Hซร๒a"ึฮษ‰W๘]ไฒ˜e19dYU๊aJ3ไ€๗ R8y"Ÿัขaิ็V}ฑ>‹ธV4ฆrpK/rณ๏5๒ว๘eๆํu|Oุ#x €๖yHถ[ฃษRŒ9ข”ำค ‹-ฎJzhZิฟb–ๅ๐?qิ:’ขษล:๕=แ™สไJ๏ผขbน(ฅ๎R๗‹œฺโV๎ฯำ(3Hไ๕ฟ5’ศบแ๔ะฮตA^g ฉBS)bK˜*/ฤ%‡Snศ- ''๏ŠP;iฅศ{๚hF ‰ยผ<šsมxถธ฿แ๙ฯฝSั™q๙ฏe๛ส๏ว}จœ_V6m’'รยJ๊4h๏ถใ๏J^ษrWj๚xฬ๕[ฒฯbฬ•›ํUKŠh’ํY*}HBนขฏ–7ฯฬ3ซM๎ฬญLmAํแ:T*๛ฑ†gช’์ า!ฃฎ ๋‘|da  ฤ *7S„ aปคA๘n@J™™ๆเ`Jป๕ฯะฟt‡หlน„ฮ„?ฌลaลฝภฟjฝฬถRI=์Hฟ๗ฃฺ3€ลฦ_uณ่(€{ ูp‚sb–๛wภ ,คตs์/&฿Ÿ3ะ›ศ/ตช็Žฉ!GLรšV…š๕>ว$kอM<ทxุม‘wื๛จ poฆ<เ>-ใx['zxa›A•6˜า'ัำHฌLs“๙(มE•0า ขuฬฟHโฑ>ำ7w๖ะAสsะํŸ๐AuE%~้ฯษ:๑ม=K๙‹(๕_zทํ ƒ‘๗นˆ€ญH ัSšเ#จ&๘ฎ/7’่1่g`ษ `ีํฟ๐’7‡ˆvžj๊๗$—^ฌ~”`lP๐Zฟ=%(เู›ีึ›NฬแŠ๗โ€]0๓ะ’ด„\ฟ’อฒซ3ฏ|cโฝ ใภdั›‘%:QkWื/’อ๐รiะลชโฤuฟ}3฿…wZ=—lไ๗eข๒Gต//V•Y>N_โ“ฟmœจyฅWแภํ 0๗ฯ2พˆ๖g_8zq ๓NVvฅพŠ„ญ๎VH|g)™๚sV@(Hw‘ษ๐^ อฆhบทF~>ฃC้?W๎q`žฮQŽ๏J@’Žƒ‡J^x ฎ_ฌSุozสOL ‰S<๎ธยโ‚lเซต๖ฬง:‘รpUodฐรัฌณFฤฏฃทX /ฉ๘$Y8A๚ฝ7๘“ืขๅ_9ยแtพ็tYฏŒ€PŽP-๊ช๎"๓๓^๓ฅv}ฃวqฯŠlุณธเd‹ฟ›i๎น๛{›๙แŒ%ํSนƒ๋ป"จug—6ั๙ฬI[{ฯพ›”dะs) ๔/ฃฯใ6ี๖ทฉๆ๐8๙ .ษ๖8ำ4U1’”“v>ฺาN{๏œŽL๚ iHใูdซmnІษHฌำd!hฃ๋;ˆะฯำŸy[๏d}m)eต5yๆŸŒh๕ฟ๊๘ปฑช:ึc|ŽฌHข3:†ีOkชŒาTึ1!ถ๊ท้}?˜4มะ๚ย!ำ6\WŽแป’8่mS์eนวe2พแYย‚_ฟKzn5่Oปม้?่*ƒ:e„ ัตI๙ฦ“ว“๒*[คTแ„ๆ‹๑’ลล ๋ั3]$_rฺ4๗้Cย|ฺำK–X ชศ&ิ,ฑฒgเkdlฒ™๚กตOž”+่๙T:ว*Eย~tY™r -V_i”70g1KeYbน?ๅ€d Uz˜ys>ˆ‡‰ฦบจW๔บhั2๐W‚๘๊C“xK-๑„\ิ nั์C%ฯN‰Ÿ*ไ ฿Gโ^a—'4๐ๅ…•+ปฤ™XT|dฏoPฤห-’OwnW๊ฦxŠXtLโ˜ง-฿ƒ}ทฮฆŽWw๐ว ‹Ÿwv–– ื•LŒ •๙gห†š™งsžกœณ7วฃวะM#งM๏ๆุy˜zx๚i๚emฟด็$5ง๔qxฅj(ฦ‰ฐ\$๐,1^_ลวz–ฯ1% ง_ู/] ฆฃนาชv?ู ำจี6สค๓คOธฒ•๒Gh๋็ๅ๗]^%jฏ;่฿ไe€!ะpคŽำฮ฿7ขพD8Rdเ˜>ฌmหฅ,“iz}oืร“๔ฐ ลJ†5Mqืห&‹6Zฦ฿ฮvำ~6fc๔๏ฟTx`jXŠ…ฬlฆ๙ฃมN๓.ูpสiงีฦธT๖Œ7ํฝ€?เZU๊˜ด~๏ญ)4F?ฬ๗\hoฺปปตึ„์๋4”VA–šตฺุ๋›ฤ)อjปŸฏJ.!โฃฝ&รฏ3ฟCฎ'`ิ*g๐ฎ1๔รไNCฌkŒWฦaฉP{๖๋ัQ›ิ็?-gฒ฿’` yXยD‘ทUฑอ)ฺษำ `ฤzิๅ#ใp Sจ๎ฆW‘ฃฎtD๘๕U_]€>โ†~ŽqๆฦnโฃWq๋์”Q1J๏“(pใด6์ฯพ้ล>฿7็ล็ี9๓;็ฟสo^S|›๘Ÿ[hผอธLฉ‹PฝWเn7ำข฿‘iซr$ๅอไ„MQก–~Žœต ฐqบแคA0vถ=bDร_ฒนษญY ป–“Ÿ๒ถU)ษยoƒ๊P‹]ฬZชm8Lฌ!฿]œ5ด*šพซฒ*f’@n%ก` tทฤRrP „šEิซtTะ๐ก๘uv๗o$๏tpฏK^,W฿ๅŒู|Jู|jญ๏ฯZ—ฎวžŠู‹ว ทŠ~bง่W}ฉแ๖“g@W่‚ษ†ทต&ม_฿9FNโ?fถN•ๆ“pDq[ๅ(ถ๊Šq'๖š –z?f+แถอeปขนY$๓=ิG-ััjอ!ม&(lฦ–5ล๙๙พ&ๅ้Š›V†ธ2ะ#‘_yK๛ปธzฐ*ฏ0jฟ4'ะ@„Ž๖หๆ฿ใ\ฟƒ6๚X† ฺใcยŒ‹๑j๔‘fผ||%nโup๐ c้ฑ–\LๅM‡๗7ช๛n]pํน๕ยธOuดuU?b‘๘\*๑ฯ๘‰ืปvซ>U้A*+ไง๑ืปq˜Dฐ๖ษjI‰Nƒ๔ภfผ฿ิj;ืฒใqป"w๕ฆิร’…ว=uง"mภfW๐ด‚u?๒–ณหT‡๚ช?I|ใ9}ฺvต]Ÿ>ุโt*†žฮu้vu“—'lNึ{Š๑r1Xฤh๒Pฌ8%ฯไ๋ฯส ะจ`พCaฌlั’๘U๒Fd[2a`ำาๆˆv“ฦรภhDอาษ๊ ผ˜งม€*Ar้๙HอXๆฤE{ฝ้มษ๔/Gvข%3—Vืa…1ย!ย!ย!ย!ย!ย!ยgnิ?Av8˜U‰3cไ\ๆjŽ™‡Nฺฦบs~sฆ๓|ั'Hู\ดฉๅาๅ่ฆเํyฏ#๖:๕ฐ € ๏ทา”ม†Oไ+่ƒ™ถฒ†iโžˆwแ™Cฅ๔3h‘๖Rฦ‚œ~บ-บb„P๊’ํQตq.ข;๏ฌ6Vง5_ดฐ3ุ[SUช!?*w,จ‘ฝ' !F(†ฦ]ป5 ฺu) ฌฤYš0฿'ฅๅSTeทฯฺDTPงึ[๚ๅ พ|๎Yp฿ฑม~สำ*ซHwฏTœ#็ผฒz_x"–jbc%ุ๎˜บใร XรoฎMอถ3ส๔็Y/nแ—ณ—+/xpุฒaTI4†ƒ p๎~ัฆลeRŸq9SอN$ปณะถฎ#0Pnzง;,ํืP๏ฌ๐™Sฟฯ๐ว|Z\Ž๔ฆ=ชห๚{ชห†,ฺูฒ‡ิๆH w๐ฌ ฑ*฿ณ0‘™ฐ๛Ž _๘L{($Gว1nWYื”์wี2ฬ˜๋ฅผPŽืYบถษ๕}ม92^พ>#ฆf1yิ1ณำFไตฃยa`_ํtu๊N’%่Pฟ6ปkaeMฌๅ$งตžz8B}>@ไ)Kฬฤœก๓ฮƒ=ŠยWNะTTqkrC7ึX]๖zz!Ÿฑ"f )q%š‚žqKจฎ่l้ภ้บฎา๕ฝ‚๓Wว็K`@LfMเaภถญBอโ ‡ฒทFDHญาำK๒8๙qรbษ๏ํ์ศ"งzsˆโP๓็‡ ณค๓ฒพฌ†๒_ธn™ 3!K+-ฺhฃ0_ =ƒ/{๛A( |$/พXบธ)ส๎'2@๎2KE0C0C0C0C0C0๛Ÿa‚-,^1‘ฉr๖ไ^าล-zOŸ๒nย@ดตย81‹ตฌผ- š1ฏฑxv4Jญึ3๒!žๆ…ษอ‚lบุื”ขิๅNั ?v\ไล๛ซืฦศ์M.ป6เแ\kบU#=_Iฒ$JฏฆH์Cฌ'Y*„yUG_b=_o๔N\ฃ‘1ฒŸ๔นษฐ8วM`‹็%่jVีค๒‡[”บๆ40}ี'm~Nฝ({‡ล3{'„ lิŽ้”†ช’j’ ฺw@€ฆ]gž4พ>ษ ด•r€ล้Uw;๛ฎ`ๅ–)๕ ฤ๔qัs๚`โu฿อ้็ถvพจ!um๏P9/]๕K‘กœ ะผห๘๔e#“|‘_ึ$ษ๗๙e˜|‘_vฦษ๗yธ๏oPKหMSS๑ง]c&9 คdata.plistPKหMSSD!W~p 1 ค‹&preview.jpegPKr%9thinc-9.0.0/website/docs/images/layer-traversal.svg000066400000000000000000000351431461023342500223300ustar00rootroot00000000000000 Layer 1Layer 2Layer 3Layer 4Layer 5 thinc-9.0.0/website/docs/images/schedules_compounding.svg000066400000000000000000000111551461023342500235710ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_constant.svg000066400000000000000000000100521461023342500230730ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_constant_then.svg000066400000000000000000000120331461023342500241120ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_custom1.svg000066400000000000000000000107771461023342500226530ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_custom2.svg000066400000000000000000000105031461023342500226370ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_cyclic_triangular.svg000066400000000000000000000101371461023342500247440ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_decaying.svg000066400000000000000000000123751461023342500230370ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_slanted_triangular.svg000066400000000000000000000110551461023342500251300ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/schedules_warmup_linear.svg000066400000000000000000000100221461023342500241040ustar00rootroot00000000000000 thinc-9.0.0/website/docs/images/type_checking.jpg000066400000000000000000004640101461023342500220070ustar00rootroot00000000000000ุเJFIF„ย]ฆฤ   ฺ๎<|๚$P'อัาeeฐ‰2ุŒ’l๔ฝ&ฒ๗yแ้นซ;<๔พุ(“-€๋อฺเ๒วi&bบbH€ 5ห]้hฝ๏ƒ๏ธcด-}D๕๛นไๅŸQ…๔ิขึไ๏›Jุ^ฎ˜ฐ^—-jํ0#๛Š™ฬ฿ืŠไ๊๔ ขํชžฟVcQา–p9Š้ึU=Ÿืฝติ…ณิeฎU$‡ถแXqN~A%ฃ) gxผฑi)'‚ฒpญซ๐aๅฤo๒ั๓?ะ–Š฿Zoะศt ใtฯ'@t7็F-›า๊ ลุ;1ฆ}6ฺlu…n้6ขธgฒฟ/P|อtสs๏ ๕Fฟq฿5๓ณหญษน%๎ใ/ก* ผJข๔็ผ|ฟฌ๔์๗1]4}ฯo‹^;ชChO_WtฯญฟNฯBˆOvฌ]ถjตžCv?/Vu{Š"ำ8oห{ฤ›l”r+rะ่฿รQ{ฃš{าOMภ SV3vNMพ๕ฏน9อ%N]ป‡ึฤีX<;šุ$ชฎU๖W# ฺgš^ฐ๗ึ๖ิMxQใ}ฤฝก0ซยูะรs๊๚้ท ฏPFมj^ฦrŠ๕–K]FC}Uh0 Cย)ณ-หn+N0Z]Wฺ=iฯ่>เ”๖‡2็™ฏŸถข\้ื’"•:&}TŸa๘/็็ไะ3“๛9ภ›€~?%/๖ไ`>‰ษ๓tt™D™l–~>npัe†ฅ@ๆท๔†มห†ฉูx#QoMuๆํp4ื-wฅข๗พพแŽะต๕ื๎็“–}FำRv‹[“พm8ืน ๏่bqnะซุ๊็v‹œ[ลญ=ๅ‚f9ฆ•Fํ…U]=ๆ฿ƒป†ช๙-ค?›ท>_ทKาwHT5ั ฐ8๕9_’L์]“ใ็™~ฯJด๑cถฒŸŽ๙ไ่†่ลณz]Aธปf4ฯฆMŽฐฃm?ๆผ๗฿โ๘ึํ†XV•๊หๅOŽ~,ฃI}>’ีโE‹Uูซ+„ˆ;๓!ำ=D๛๙,v FyccถQด'#ึŽtฯฯ5ๅT=xฯˆฑผ๏yถ๓ต5MXอุE94v๛ึพไไc4•9v๎[VA`๐๎k`’ซ]ม_พ๋FhYๅLฺ `ฆภR๖๎ศท…[–]‡~่๕oUi™ด1•U้ฌvบฆฮšษขไศฤโฝB›nก๎‰‘ร,Œ๐JlฦMฝ๗a9|Ÿpำ+&ฬd ฟุNl1ธฏ๖_็hWŸž@*๛K]P‘Wีธ‚ฏ%K๛rHำฟ@œ๓๔žฯฮป*6ผ‘๙9้์‘0;๗ฃปจฎจ‹wŽzฺj€Sะ๏K๔11์œUฏƒทเeศื=ม€ๆ_ฅŽQงฉ๙ฤ์žSiN”นย้ฮ‡o‰L๔w5ฑษ+ถฎตษ๚ €“cTjบ๊ื˜๛๏ก[ฆIซeB๚๛W๕+ใ•พณนฐพZฝ๊ึู8๏ฑ|ฺeะใฒ๎: hzีŸฉฬONสภยทด่kš๎ฏ9‰้ซo฿œ‹ณค๏kฃQ‹sษ๛๓;ญ~„€าœฅ_ๅ!Jฝok•?15ึ=`<๖uLทฤฉษuO:–VA ๑ˆฬOบ]ึจž๎อฉพ•9ช่rˆฅ^บ๎ln #a='ึ•ศจ <ม+oฅ^jบ;็’Om9U’็ษŠ]qs๛ะcCึ”๙•Ž?.ฒ1i๓ๅ๓๓?ฐ๖๑(ญZ/ฝพQ๏ณๅ.5frัZดgf1ก:3่hP์~€ีต=v`=|!ฃาQ…zข"ฦ๛Jct็ยธ์p M†ศฐ +ฯ‡O 1zB๛ศ}[ˆ(ฺ๒Tฟท$;๔ ฯ?IเO‘]ต^Hœว๔๖H˜๛ั‚ิWF€ฏ$ ]XฒC›เ™~–9Fœzง็ฒyMฅ:Nๅชฺ*พ%3ัึว$ฌฺบื'่.MQช่?ซ^c๏พ…o๚™&ฎ๔Zี~=_ื๐ฏŽV๚ฮๆย๙hf๗ซ[dใพล๓si—CŽหน่1ก๋V|Jง{O[Oใซๅปvเ;๊“๚€™ฺŠ>กk็ZU”๚›๗Gœ๓ะฅ9JฟสB•zื*~bkฌ{ม๚Lฅ{โTไบงK+ †๘ฤf'ฎ๋T@ฯwfิ฿Jœีt9DRฏGmok_ ้>ดฎE@Yๆ [}*๓Uั฿<’{iศ ฌ—>LR๋‹ŸƒดงฬฌqฯะM<ฮ˜]„๎ุešVืทE{cๆฒeW†SuํูMJ๗ฤ‡๏c๔ญฉ๋ณก๋แ ๗๎Œ.๋ี7ฺP๙ฯ้*’ฮๆพP”๘€‡๐>ภO็๏ M๛๐wXีพฐๆ฿ทึฺฺฮ€+ฺWํก^&D็ญUฃ&G@ ๆ฿ทึsor๔อ`๛Fลi็UvE,ฏ&ฮG*ีฯ}๚ฆpื–้ฤฌ*ฑzH1อพ5oญ๙ฏฐสฃ้O•>ฅนบ๚‡้f6ฅ‹ฅ›Ÿœช KH฿$ตCบบ‹้S1อพ5oญซ5Ž่ฤ๕Ur^ฌt1ใi๋ฯSgrๆฟ๕V•zi๊]฿ถNุc›|j฿X so€ Q๛€๐7@ีพฐๆ฿ทึWฺy‡๔ๅzฌso€ [๋Pล฿(… ถฦจะSm้‹ต๏sšร~ฝ_B} oT6ุŸn}๗Fยข๓ฏ๙็ ฅ์Z’‘ฟaาe’IlZ’n๕Q?T|}ˆ/ฃๆwฟJบํ#RmฝEพ} ]B๎ว29zบ.~zQฬ่.|eC—๙#\ฦv๚๒ฏะ‹rKKmฝฑขฒ/S็๘๑งฺ๗k^ฮcn๔ี9%˜๘Qf:ฯ๗I|so€ [๋sะ…{sหี<๋šฦซื ษชๅน—|mบฑ-/ฏ^Ÿ6ห“ฌหไ˜Y•ฮซž[๘หjดNn,J+ๅyEมยบ•Y๊ั$ฯฌ‹‚ดฏ7˜ผย;X-ํ4- x8f]$`ฆ๘ตฃิำr฿vด‡๚ฆ๖ฃ่'ๅฬ๎Qฏ๕ญม๒ู้84nีRm8]Wำื[{B๘๙๊K.กษ{๓ุ'™ธ1KLƒุล7เ ฐีM“Aั๙&$ฝญ /ว6๘ีพตLE๓ฉฌฯš.ถ(Nึi2ๆ็Z‘}t „ํฉ๙\‰ งไัT๗XํM๔ชุว2ซfๆiฮีkศ๙โตน1maท#๕ฃำUฯี๕o,B…๗g——‚ธ๊Vd๕ทป'ลqฺฑษ‚ๆšยด7ฝ๑ร๏qPR€ต& b”S๙Aูง™ฎญฆŠ๎ ปm^Œบ"ฮ๋ฏzjmอถฬ้ญ๛€ฌIตฆฝxXeyOศ—น๔‚ฮผษMŽm๐ซ}`˜dถw0พ@!ดษ ฆH `็€"ผั4oL๗@ g&c›|j฿X so€แŠ€๐—€3โ1gั’ญ#ปดฆšš %ปtŽ๎[อ๗hk-›กwิY;4U‘บ‹}h]๔๐™ 3โ5“๔Eฎe7ซ‹xŸž>สHญ ฃพฺทฒด`ฌใฬ<]9๘6ฆnผ=myงฆŠqบYยฑดก|พวตล๑๘L๑Gณ!–ว๒sฟOojm'๋~ฯ‡้žึ๗4พ ๑ฬ$G–f†ห"๛Z Ic[น๙`]ฟัoฬOฟ|_ๆก๕F;฿ณ\๚้b;>ๆ“๘\าม’ุ\๗Wห7ดWๆรcะ|๚gฮ‘fา๋ย'พm่~yf?า‡>โััŒo›<_D J„L9›น/+b,ฬeQ™'ฺ็vtsrxณ+5ไ่YŸ3r%=Œu2@ป๑„ฯi}œs๕๔d|หบ^iฝขป6+Ÿ฿รJNคFgๆ›ึฏ…๒Ÿƒsf}/๗‡ฬฃ๙ืวา๘€+ตจ/ˆหX—D*/ษ€_``ฮnฐfo็เNดv:Œ่ŠSญรฺีœ@ภ%ึE%ัOB๓เ fhlฒ/ตข%ั+ณ‰ˆO >“ฦฺงO7sฯฮe๑žcวหฯ๋๋์c„vฃVศๆžm่0นœ*YวฯXิพํŸ1ŸF๓I.i ๏`ษl.{‹ซๅ›ฺ+๓aฑ๊‘ Fตvym\บr฿<ๆd๕ฏ;๎g‘๑`บmํcากfฤnKสุฟ&h ฒ ‘๓$๛\๎ฮŽnSฏถefผŸฯ 3ๆnDป2@ป๑„ฯi}œs๕๔d|หบ^iฝขป6+ก “๑๚๙5wธฮY๏/ทฅะๅรญลทจ_vต%๑ูk่…E๙0mJ*Q^„’=หฉEู)Ž -ธ1eจ@๎เอ@wsง›Œีะย:ุ51ณmsาศ˜ฬิwไ“ƒo{•โ๔๘ถ9ฉฯ^+ฑฬ๋kไไw! 3P]™r;ะษaBไx9 ณSŸนฅฑัH!ฺ f ปนŸ& ๖;ญmฌYmม[-ทoOo}mฌX@อ@wpf uะฤ.๎ฬิwๆj ป—Zญ าดทYZ1•กrาดญ+Jะพฺ.ฅ2cญ ะ[ZV†Le๔ด าด2c/ถ‚—Ps5หญฎ\WZ_Ž‹ิป๔ฅ๖ฎฦeฅZฎ\t]fk.ฅ,ญ๖ึห•ถ‹ฎฅ-2[r๑ึ์f\WึฑฎญVdล“uัV<˜ืR•ฅึึ•VญบฺจVœอ@wrทฺท&;์หŽ‹•ฅทึ–ึ•ดพฺญพลหoฒ๛/ถ๛iUึึฬธฏฐพ…ชไฦษe+Kฌ/ถฅ(ชตฒชา‹…น,บฬธ•ฅUตZhขดๆj ป€V€s5ภ9š€ฝ7= 9ฏ iฺโ๖ปpงk‹โZ์แ‡6พฦฎLภ5sโุืุม@Žw๊7ห8HŽฬ๗ศโR่›ใg?Sn๋lถ๚b้iฌรณฑƒ_gW-ฺ6ื‚€ ๏ญษœ๒๓haไ๕;ุqึ5๘fkฉณ‡-V]‡%๘๊ว’–ฒใ‚€ptภWxdd}2]Juฃเ3H#&ึ๏ ๓.วˆ{—ž๛H๋๖กภ,ผv,๎๊ๆ็๕๕๖1ย;QE๙ต้ฝ8ŠLนYmำมฺฺ๓kืผ้O๊g๔4๔Oั๔ ŸDฝ"ท|Š5#ˆqfp $๛7๏sป:9นNฟž2dมMนฤcฃณืะ็๔ตi ู๓/W๓ฉ’ ๒ฯะAํ?ทiุœวz๑I—ฯข3hTๆ1ุิ็ณื๋ƒ/ƒE+NไหkK๋ŽฟLdธะฃฃ‰ัžธ)ิฦแๅมMœ9pSfEื๓nuทYL–e2[๋‚nธ)ณ‡. lแŸ€1ะ\˜€(ฤ@?ฤ ฺ =กษ๊ฐI@งท@บ>Vขฎhฮ’€"€Jy๛O๙ฉ์ฟYy/ซ„๐ฯˆอ็-fห)*SฯC~"๗๗ƒ{Cะ^ึ๕ปk้ฏW~pตx๕#XฃYššฦณฌะMfอIDฉRัf๐EฐHทVณ8๊ษแฬ๒&wไาณ)๚•๊ฯ5๒ฏZ๛cวzฟ๘๋ฯœ}FณX4ฮฒVฒาVVเฉซk;ศต51SYี—‹–\€<ฯํoœ~Ž๙ฏู~ฏ๓๓‚j&๓-อ‹ฌต‹็฿e๚รึ~{๖ๆ๏ถ=_๏? ๔ี฿!ฌhk)McyKๅ)sฌ๋:—:•#Yซฒ—*%฿_@=กษ๊ฐI@ฮ€ณฝ{ั€w~ะJM ่gq@๓ฯฺอOe๚หษ}_๔'†|Fo9k6YZ‘5›ๆฟZ7>ม๕ฏ“v๏—ž-๖ืใ?bœœtYึ(฿9xต?R?-Uฟ,N:ฟrxใ๓<‰ฤน5)3ผW่๗ฬฉ฿ {“ฃฟ๛ำไ฿ท;MใYึ5eฦ’*rfใYบ—b€๓?ตพq๚;ๆฟe๚ฟฬ;wฮ จ›ฬท65’หš๕ฟi๕ว้ย‹ฟ๔ึ๘+๏?Š{]cyMFฒšˆo6Mfห5šJ;ฯfJ”y25` ็z€,Pฅใฯ( >ๅ๔'อ~๖๐]fuŸฯ=ลศXlิ\jXบอ”™ึ3หฎ=ใx3ฆฐœ<˜ไใ—\ใod}๓ฅšอ—Rใ|{ฦ9พ‹๔งบxพy฿B๑t^ป๐n@''&5›kqsซšFธ๓สšว'&,ึmล,ทœ{‰ผ7Œm์ฐ]๔ปYถพ=๑็ฏ๚ซา^ษ๑J+ุž๑๕ฏ’ฺ๙€ฬุ@ฃ3`6‰@“@ไศิ€3๊ ิฉx๓ส,9ญ€ cyณQqผุบอ”™ึ3หฎ=ใx3นฌ'&98๗%ฦื8ู_ร้f๑คึRตวg/ๆ๓รปลสNN>Lk6)ลฮฎiใฯ*kœ|˜ฒ—ฒrq๎&๐1ทฑร๙wาํfหbYssนฉg\| ,fภŠ%› …C[ฦUใี  P”q` s.05ฮ8ธ๙/&r9$หW›€ื8โใsใ“uใ|Uฦ๊7ฦฦฬrtเนภ๙๑พฃƒ›|<นรyษeพ=๐เฎpลวกwรผีeRๆฒื8โใ\เ‹k˜qq€ฎpลฦนภ‹ภ*……Bห,ฐฐฑe€ ฐจ–ภฎpลวeฐ lPJ%D(,ข(%…,fึt–,šฮฆฑคบ็\tK) %K,ฒ€ aD(JB‚(”…’ฤณXำ:*,บ็\`Xนภ็?N'X:n—ืGœผ_ส<_ล}ค๑o)๑o)™ 7เx7€^ธt/ q๋ฏ/์>ว๊{wG๖?ฎ<มผ›้ณ“Yโๅผ;ึ93วญใs›Š[ภ—ฎ7KใพE๊~า๗ฎ"๑๊นf๙zฯ,.’iๆM็Yh `/\7า๊ฑปุ๔๐J3iว็|พJใ]หึ"jYวญi)3จ๚ ่_‰ผEsษšอ^9์ž฿ผSฟqgด๗~ี฿9q๋นไลkฤิใไหsHึ_A๑ˆอใJอ8็๔=ืข๏^1ๆ>1฿;๖ผ๘BšŒ๒q๏:ฮณ™ฐ๛: ,่'p์x๖_—/kํHฝฌz!Sพูะถฮ‚w ุ4็>eั๗vฎปฃ๎:ํ^ ใ~๋ๆ๋z^ป]ณญ้zํvฮทะ#๙๋บ>ใฎีืt}ว]ซฎ๔ Pฒ€”?ฤP R"a! #$012356Qst4CP`u%@ATUp‚Gq…7BSr€„ DEVd†ฺศ=i_[ˆeึ`Nฝ˜Bี N\ข~~ฮOฤฮQe9ส0„1™Nb0O ‡žฝ eo]QNมOfQ}‡ผซZภ5fgtœbb7•vLฐขlเวWฏ,=ฆธฎยฎ+‹fํ์โHQ<† ล ~YฦQœc8K„ฑ‰F^ร8šูฤXi`JX๋˜เ^Œ@^ใ อSG/ถ3๖qๆY็ถ„ง<ืZ#l1^P!”Ÿ]6ฯฯQ–%J?n%ŒK๛ƒ4ฒ๙„Nภ"~Ž>ภUฑbZก5‰<๑ฑ4ะ\ญ5> =ฤšNญbฐLœห—ปŒŸ์Ÿ“ํฺฎทฏท ^วจ€ฅˆ>ำk„ง4ฐ1s)g[l…ธftฬ1“ŽWฺ’J˜€d]ei—/’l๕Lt‡wำบ"…โ†’uœŒ๒1oๅ ชอs)rYีn@[;5@ฑแŠe‹ n˜Aขง_^ีฉAืีE๊ึฃ„ป@2นcแ)ฃZู"๐›1`“๊-ู่ŠฏJ#Y๏f์พ: ฑฌ…SfR๒๖ฺงญจ คฑv0™๓๊>‘๓Nzt๊c็ฃ›เiŸ๕/๛บd์“ถXZถVK€วŒƒsUeธk๒ek9Hx ํb ฟ!ไฑZ๙ทฬrœV™ๆก9ทš{eฎ’ƒซwb9”†Aตฝ…†Lฝ][–›์1h๏TฝZF_.ฦ๖X๎ฏJ๑kฉzีฐc>(๗2ืE:™\ศผพ3’ช๎์UrT™cg#'*[ะfฑu…cuD<ฑf๎ไต›ŽฑปQอื[Mส‡,,ค<๋[ํ๊ฬฝ– I ิW+Rg@ ึต๛ฤฒีฐ”กๆึ๊zนŠFว,ู๕ด>ฆKNฝุfAไOUปŠ ุ›*‘sVฦr:ะ๑:ผสีธัฑ9โkา-t"LQŠใ[ฆhฉืืตjPuมตQzตฟ(แ.ะ?Lซ๛ท็0R็`ฯ0ฤZิ€ๆ>H`‚gw%2ฬื{ต‘ bฒ›p†ญsฟฦ’พซูฟ#ทU‹ ๔ฅDผxตธ5]jpฮzื glๅIbญ^ัฏuษ๖k๋๋ฮc2z0ึฯ1ฤ^%ช"ญอถMีŽ๒‚อโU/,‘WdPฑ๚:ฮ1Hsž˜ล™ณœหzr๋ฆฐดUyt+t๗)ซ๊”ฬพษv_H"ฅzSU%”œฬe%ฃƒ๘"๛๛๚วnห›Iิ€F ุd…โโ๖/๎d:CWฺH&1อ}u  แ&16 ฟc[ๆ เG…;ฦFq{รฒL•๘ดมq„ฒฟฉๅ๚๏™Fm/Cdzัๆ]ฯงf›่ฦลiๆKfžs-๑9DŒฉAdอxปปžฉตVๅ8:ฆeูœๆ†wึภf•ีyหBh๎ไ์ญฃXขฬLrษใ‡~โ๓qส”ฑ‡บp^Ÿžlห~กื>bl1หœ(ํ๚u๕Kฺท‰ย-3๑ผSl้l+bXภœตทRก>ฦs!|1lทOฝ(์Fjท+เย฿ณCeตŒล#E~nฃVฺ ำโใ”a•Lื ะ๏R›ฐ—Œ˜;฿็0ช๊ถ‚๙๛๓—j^+๊V๎†a.3ฝ฿8dชชธ"น่ฬฉ7—q6ฎสูํeOeึๆKDjฑa`|wมZั&^ sิ๖5Œฑรงท’บF–KNszœOธ7่0ฆHดุ๕s$1ซMส:ป0Ve&# ๅ็ุ๋ไกL:‡fสลœ[VนแYขณมฦp6G฿ˆ๛sžŸn~ฬcํฮMพG’š5•/Z|๕šซ•/“j๗GงxสŸsšบ๗ฐZฒhŒยQWo๎5ฏเn1Mfฬy—wvไNฐu5…ฉT—c9กj๓Ž*ญญ๚uoฏ ‰(ฐZK}๘8ี‡ญ1*ะอx}i1ฺn•ชญAXp<ม‰ฝB๛ิyฐ /ี;Y†eฎ_๎ทํฅG๐A์พ„ ป้`HโqศT๋u์–!ำํฯfถne Œa๒Eo}7•๚dqน๒—์ฦไws๚.ฦ*ห๚‚๙kbฮ+V๕๔•ฏ๘์k~F?WK๖cเa\ร[w๕ G๘zฺธพค]}nฯูOๅ๑ญญหf‚2Ž3ฏi‰ใc๒หn]D?ฅษYโืัฤ…๎งaŒวŸสDยLWžYqžฆ/ฺ!W๖`ดI.ศhEฦ3q ‹s๗ๅอญี…m,+ีŠ˜ฮี,Z†๛j.g€ผไžaค˜w็๛ึ1}!f2jˆb้๊๙ำู฿ด{Ÿ๙ƒลฏํญG๐Aญ๏๚—ฮNิํฯไt‡๔ญ๓สฦถ.c๎ƒใฎ;ฐ๑s,mฯp๎ ญ˜๐็ ๑็a๖เ6Pฯุฦ$V๘๗ำy_ฆGKŸ;๗๕rฮ้1ภJ-ฦ0†.‘ฟฉ3ะ5M๚ขฏ9/nเฒ?๙GOํ๘Tึ๎ๆฑŒtw8๔บปม>ฅmฬใ๔X4น5vE~ซ;’?Vก๖tฟ๔pZqีkร–4@J1ษqgมT. ๗b$๖o฿ึ;s๘ฦื\~{*?๖sน๕๔‰๚Œ?โ@ีผcœg้Ššใๅ—ัจ๛:็ฆeษชU๗ jzKZจก•x๘๖๒๘t/ณ&มbถ2g‡%ทuŒ<ำ#](5ฃีo?ญ๗ฮืnBxฤก2ส2Ž1ˆใŽ1ใ์ฦuZ๐ๅ‡ ŒrEY๐E• ƒ}ุ‰=›๕ ฟ๒ ka q ใโdaž๙ rแอฟ>่ภX)บโฎ๙ิ$;Kสx%)Š\›ัSฅท่!0_K/NBnB/จไ‡!๐M0z}cฯัŸู๖\๊ รฮฦ๎๏l*Ÿ„ณดpIl๋ˆ‡ฏ6egk่๎A๗1ใว–/&ยฬ"p3ขซ.9š2ฦฬั๐๋IIมˆๅ€ัำ4พเzษ‹4bBศ^ฒ๖„ฎŽยžัu.ๆKญ{ธช๎ชฝŠญa้>ใ–พ6๙'๐ร…(๗}#ส?๊Xuวw32ํฑฺ๘iu_๙>’๓w[3๖jณ&ต‹ชผฝ๎8<ฝ˜zeๆ *k\๔™ฏsืัƒ๎,ฦ$?>bธ๋—คVaKc่๚–ะuตฑˆnห‘๎wแV๎๒๒ยฤฑญId‰ˆSŽ๑บ‹้œ็Ÿ๊ไZืัื๊6ล ซฟฺ?เ+ฏคฟพพ‘jๅL%fcg3ฬๅ๕ซ๒๚ซ>ฟพฆ™jxš+•’เ๒„ฅงถญ{Œษธ”ŽNน,ช้Qง„๐ฌg™“๔งHH;_ตย๙yK"P&QีDgฅ>a%ฝฆุhเ‚4&"C?Gิฝsฺอ ฃืฎ!sท’ผ มlญ*็9mชืนNhณ3@S็™‘SSb“%f*ฤ  Ž้บ๕๕–z๛e๊ฆ‰’ฮ$!+๊ืญญ…X&i.8ž-” *๊‚@ลๆ–_ู.ฐF‡6ั!ณœš4๔ˆQ‚AJ๛ๆq“๗o'โั,ญ)ศsMA"ข้ƒฏย€กง6}{Oฮฤlพ‰อœไ๚–ฮง๕ ฒ/TนSโ้'฿HQ˜`2น„ใ]ฒ๊ะv/ไญธaKธ:ปส_zoTfร้yป5Ž้ฑ๙ถว],ชฒ๊ร2” jม!XจTอ"ภf์๎—ิjฎฝ}UŸ_฿๕]vสฏ‚Mzพ๒SฌWาฑ”ฯฬˆธETฎˆ/อ"X,ั ปDฅฝ6dYƒŒCชงNœ2˜žy3‰ฏmZ๗“p#)rYUาฃO แXฯ3'้NึฮญqƒฒV,13–f”k6สULแ าO๛]I{ˆฃP๏ zuา๛:ตVศูฑ๎\ร4!์rGl‘ด)‹8c`ˆฌ“aศ‘์œ‡JŒjaLHI” >>‘ุ58”q6ฌสด%฿‚…K5๒=C้๘ุ• Rๆtรฯ`)iขTŠ)3d<˜–Zุ•&1 นC—๔ฉฆF•|ฎ๓ŒK=ล.~)ฅ๙\ถฮฉถฒ4lอฅXxณ˜$พcพ€ใฉื ˜ i2s<ข ะMdƒ๚5ƒcyถัฟสาpญาเธ†ฟัอ'Uฆญจ•ธT 0V„5็ย_่๎›ฏ_Ymื๗ณถjกjRฯLก0Q‘ŠตูซอDๆl-•ฤทz*ืึยฆ็R8๓‚l ™N\MXฎKบk+R‚hfฐ Ž”&2 ]“Xฉ:แ›-ษ‚๚ อต_P้JLร'ว•ๅ๔yM,๕หvz๕ี.Jˆ†"งtู<# c}วSฎA0าe๘ๆyEA šษ๔kวถ๋k!xภุh๏ Cˆƒ`T‚,ต๊"@‘ล•bvหIGEศ,็ปภฉ‰!"ณ`ศEžฐY๚ดฌQอ{"ถ8„Aฑ*B3ŠGx๘(ไ1ๅJT”ชล7฿—a‡,-ฑ*™3ฬ๑‡,ฐิหQซ$ิ™ศ9Gฮ]ุต œŒฃ“g๏ฃจฆF•|ฎ”3Ž์๗ถ;2ญ๖ฆไา,9ษeKทซจขOILล๛ ษ๗ํ"ๆ0'๛ยR zฏ•Nเ๎ ฤณjืiึZฑ๋s&Ss=;˜ฌฺUีอa๙ท‡ๆ๓nก}aฎQ”G–ลจ˜B)™ฬd‘dษฉU=ย—s™๐า`’โ€vโ ๗็iZ_๒๚อVW†ฉ ผ‹0ฏ฿ู-ฉXr\\ธ‡$eฉk{ƒม#‰r็๏ซงF\จ๓KฎHJJ่Da&FI’$ž‘ Nพษ๋@‘™1aห“@๛2ธฎ•ะณbŽXฬคqchิ ๕l๕+^ถฺU๗-ๅฦYฐ28ฐกrŒฐnืจ‰ใ P&บทD#8iHB…อw™S-‘‘๚9b๎๚u๙ฝG}G๑9ฦ%ŒฦXฦcœtฮ!=กลฝ{ตธCยฐ!G=p1ใ8AฏZWึโu˜“ฏfตBำ—(ŸŸ‡ณ“๑3”GNrŒ! fS˜ŒรFa็ฏBY[ืTDSฐcำฤู”GŸa๏*ึฐ Y™ฤ]?gพ์ฬ.ดq6แœ๖โ_—ํวไe…ขUc7I>ศhdGŽXษ’Gไ๛s๖c—"8O๐F†3™{d๚0/V'๎ŒxRˆษLAˆqโ.๚.uยŽชึc๙ุำ๖)ึี%ฌ`Ÿ=4ะ\ญ5> =ฤšNญbฐLœห—ปŒŸ๗ฺ’J˜€d]ei—/’l๕Lt‡wำบ"…โ†’uœŒ๒1oๅ ชอs)rYีn@[;5@ฑแŠe‹ n˜Aขง_^ีฉAืีE๊ึฃ„ป@2นcแ)ฃZู"๐›1`“๊-ู่ŠฏJ#Y๏f์พ: ฑฌ…SfR๒๖ฺงญจ คฑv0™๓๊>‘๓Nzt๊c็ฃ›เiŸ๕/๛บd์“ถXZถVK€วŒƒsUeธk๒ek9Hx ํb ฟ!ไฑZ๙ทฬrœV™ๆก9ทš{eฎ’ƒซwb9”†Aตฝ…†Lฝ][–›์1h๏TฝZF_.ฦ๖o+ใู,$็TฺP น'จฉวq…•Šั${=Pทๅ|Z*@1”„kอย*YคLFุ|™€ƒmนืจฑI/ยเ9ษฏ" c ี/ืฌi}้ซ[d้ำหญห<}qว‹"%%z'–07\ฑQIbr~ 1ฤ๘ฌH~ฎ;nำ5lฐโmๅ@เpL เวฒืp&ุ‡]ผ๗ ิyษฦญnY€บdyเo5๛S4ะhk3<Œ!น"ํ–kˆ‹)ฮP‘V—ึภ๚‡ีŠ,”้ชw0lZ’&Tศ9Œg8 ฎแi†œgž.1˜ซ_นDำxAฤุฌrฃล์ชIˆ{นฆ‡รอ3หz%…@oLyœดฟ*๋‹Šญฆ0ๅtY๏7eญD …[ŽโMLผซ—'\ศไ,˜#.Eฌ็ฦe,๔Œqœ็- ‡รiนใ™cถเxƒaƒTยฬc‘{๕˜7ศdเ”rฑช๎Jr%&้ใ†Yuฦ 'ฮ๚ภุ์าบฏ9b(M•ดkY‰ŽYัŠ๗mž๒ล2•@ว฿RตkmหJ‚าdขdฒ”๘/ฏิ ^b3) ,ฤ ๎Mม›Z)‰Šๆ๊ฯ–V(aC๚ŽŸ-นบ/lท5€๓œŠ cŒ5ถ]๕๔uวฮzฯภ ฌ๏ฌ €.อ+ช๓–"„ัษู[FฑE˜˜ๅ“วูo_v0pš™๎10@AŸฎiNษzีึ;)ภนทัฎr5สื9fG‚ไ4๛จ6Nสฑ”˜ฌฐŽ3,.}ฤ5oAHuงUˆd ฿฿aข‘ไsq 74ฟXG ฐย„ ร*๎zผˆ’• •ฉ„p6mฃMJปถฝ๘]hv[ง”v#5[•๐aoภูู?ณ5฿็๗†๖าฃ๘ ๖_B๔ฐ$q8ไ*uŒบ๖K้‰v็ณ[ทฒ†~ฦ0ภ๙"ทวพ›ส28Š\๙K๖cr;9cnๅAm‰ตฑg+z๚J‹Wv5ฟ#ซฅ๛1๐0ฎaญป๚†ฃ=m\~฿R.พทg์ํง๒๘ึึŒeณAGŒืดฤ๑ฑ๙eท.ขาไฌ๑k่โB๗Sฐฦcฯ‡ๅ"a&+ฯฌธŽOSํซ„๛0Z$—d4"Œใƒ8E„H9$~ญC๙์้ะ๘Cึ๖^i3Uธืว฿`acHf;xšฦ9ไฏงโผทNaแถไLววขฮs๔!{กXK1ๆห๐ฑผ"xืm“8Œ`ฤ๒ถญพvดฐฒผฆยโœŠล8~ซBฆลเ†"G๋ฆ ๅถ‘ษ๒.ึฆ>ธ—ฝ๊•"แ‘qถXแXOŽ&CŸพOBs๙V5ฑ?Tณ"_n์wะะX้2‹าJ)บพฎIT(Jถว–น๖พฆ“ำg? ].G๏๊ˆœ2๓˜๋}ฦ3ตž1(LฒŒฃŒb8ฤcŒF8๛1^]\XงKไยŒ๓ฑท0ฤ7ต”Z Hวงgž{ศ2ญฒง€ว่ีWK๕ท^Dชaิ–เ‹Rย"Œ}U‘ฃ'G@ม\๗แ4Mc.“]]๋ถC๔๔˜ ป๓๔({†=sฒu~=Pฃง CXบซหํรƒหู‡ง๖Z9Š๚็]ฯงXคŽถ๘ทF+๗mZงkห่๑™ภvu&๘Jซ6!พใฺํศO”&YFQฦ1b1ฦ#}˜วา?๊ดŸาRTb„Gฎ‘v๖ัภJ:a""ฎ.ฆsx{๒ปXอ๖ใผ›๑ษ%ญื๛ช<'†#ปw5WgฤjAt๑vาตB7Œ๏ฤ=หF†]{Jv‹ฑb#w› ;ทถ๓…nX์)ฑนพvฃ’‡ม4ม้๕ฒfkฟ๛ฯ๏ช ๅLกdH ๑ํ”พฃU~_Ugื๗ืา-\ฃ „ฌฬlๆyœพฃU~_Ugื๗ิำ-OErฒ\P”ด๖ีฏq™72‘ษื%•]*4๐žŒ๓2~”โ‰ kโVธ_/)dJส:กศŒ๔งฬ$ทดย F„ฤHg่๚—ฎ{Yดz๕ฤ.v๒WX-•กล\็#อตZ๗)อfh r๓"า*jlRdฌลX„มั7^พฒฏ๏_lขฝCTั;ฒYยd„%}Z๕ตฐซอ%วรฅฃR„]B0Hผาห๛"ฅึะๆฺ$6s“Fž‘ 0H)B_|ฮ2c^ํไ๏เผZ!ล•ฅ9iจ$T]0uโXP5kTยนQุfC๎ม#*ํ™[X่VS"๙–a แyV$,j œ‘โ/ภl๚™US &‡cMห-1ีwํั’1˜ษ…!8 bSมธณ28ฤ,HJุW)hดิt\ก—จl œNXœฯXฌํE}‚XฏexๅXbP๚…]๖v6ำW๋…UX ฎ%Vวฐc๖gcUg๒ตg'ตPKีqฐ๔ZfDš.ฺDตkิHญ๚e“ยdฉ\ถซๆf๕+ „*ซ—ณปkฑำิ31’งmกRY29์ห5ญาOส&ސbทm!\W‰ฆฟ{mบม vLเๅ`8ˆถU`H2A›.ฃœIŒgฮ:gํฦ~ฬโ{&ฆS” Wม‰gฏแŠหhfR‚แc]R-zธ–lฬŒB/60!@"GŽƒเ8a ญ_[ !ฌgp;@ศ'‡๚;ฆ๋ืึ[u๔ดjัˆมTญ&& ,ห่๒šY๋–ํบ๕๋ช]ถ• EN้ฒxFร[6ธ๏•๑3`‰™IˆPจ‹‰ผRฑ“’๒ฦท•ๅ^ฐฆžd[ ฤ€6ฅVji€วฑ“๕iœ\m ถkFzโ€บฃšO๘ซMYPWฺ"ม;Œ0GbTaYฌCผYO#!E šซ(<ห#T\yฺ•‡%ลอ๋€(rFX‘๖Zึ†" ม —0ฬ๒‚AญMtW๎แZส›u$ญ™ธZร ๒๓_G”าฯ\ทmืฏ]Rํดจˆb*wM“ย0–ุต/4รFjฯdฤ<ใSดซ้›ร‹3`B`smžำBษ์X๓ธ‹Ÿ&V6M3;C๘^ๅฝซฏYค–dv6Dพรฉ’rlะ์=ŒขLjโ†บ๐qƒฃ—x๚๑0ถภฆ bS•ืqอ …bviอ‡ิ้ำุ•!ล#ผ|r๓W\ ”C^ผ‹0ƒ“ถ_฿™*ด‹ฯ%ม#cงCjkฎB@คfQ๔ใ/ใ r ย(LŸŸ?๖,ชถKฯ•ม“Ÿ~b"ซx!—ItŒV, ้<+Œ5”qภhYnŠวYSgd ึDIใ๑7ปกjrEH๎ุ–8Tฺ๛‘๋ถ_]ล@ถSŒ~ฯธ–ฆฆซ#ภสH0ฤj๗\\ zูˆgC—าMnฝ–B๚\ฏˆ}ย&Dcน’}›‚;คu๚๋5ฎYlŸำํ-)๐ำลๆ?จ<;๏LU้ฌฮ ไf Ldฃฎh#g-าุโพIf—;$แ!งช-์ๅ•ขฉ8ขภx'?ๆ์ณfมŠท[ฒงtNฦ฿Gฐ|•ฉabYŽ5ธn,QฟกIV8ึtซE‘ฦsำs๖cnr†iซE—"‹สฐ?โm๗Kbฒ๗5ฐ~๊lี๎ว่:{๊๘คษ๚D3ึ๖ธฑง]ืฑม#ฑ&m‘zภ"‚6ฅชœ ฿2ี’-Šw.ฒ ›ˆข,ฺ[[W˜ ๋ๆXŽzถ๗‡ปš๗Woผ8ีฝ๑\?}๔๕ไ๋๘ซ๛W‹`ฆฅ'ฬใ™ฦไ@ิWไญ0r Qใ%eอ๖%'[ˆคIศb?ไ๛s๙5๕š๊ฬ็ฦช*ญ.ฑA๏Pณ ๅ;๓ั…โ็sŠดeŒ๕œป{Wฺ๗ํ^z๏R*e|GW๗ะฅ{C–\nY‚ซฯr฿ึH%ผงQ4๛yฏO1]ฒญ“{nยส+Œใ6ตฟo/๗B๗๖๒‡๙uu,g1ฮ1ž็ฦ$ี='แด“bฉ{ ฑŸbากฅž$ุเ.A‰ํพใo6Y’CžNดจฆKอำgmษ<ข‡P+์VบซojJ๊Š๙ =ช๗๕ตถdฒง~8Ž1ฝi๑…^ฝƒฎ ยŠ‘ย๕ป~ฮ๖ขธวบ2‹ล~ะ-้รษdCษเ>(Ÿe~พฟฦŸณnํปzปvq่cำูฟ?gOยบ%Cฒซฏe7ตNณฐิkบนˆcตCHั%๗Bคทถณ˜ง$WŽาดlL\Rพy5๎œ›!= i๗qตฑฐpคv(๖ผb๕'ยฬ H•‘ํฏฉำณ2รŽผKm๚Zงjหdำฐน&Z]“ฌSWXย๒„ฃ 5?ฌ”ํxฤx๏jž“๐‰Znษฑmิฝ„ู.žฺ™ล)ยI-‚lฦN›ื}าสeTน8eถๆ[ญลmw)“)ฏ,ฎ”bพจL>ว ัฯNbํต™บ-n’ŠKฉิ‘Oภ๛ฃv3RFฬฝ}|'ž;z๙ึn-ฎงซ3`ƒ)๚y}ฦ้wะPุ—้9‡ำN ํJ‰ี3dศัCฺ=รF.ฅ !`ฒฤ‘E๐n‡้ซ์Oีˆ,7Uถ็\ตšๆดe฿y ‘O^ีF๊ฏฎฏy‚ฬƒ„ฦJMบลS†u‹v,ˆpHRรีาmฉ_nขœ–|#ุ6,ŸU็bM‰)‹+’eฅถฦ!$ณัษRะๆ[อ์NาOะQวท86SW‘๓๐ŒYมZW›จVมวUUเgฤj฿r#ถฦฬึW0ŒฯญใO๎dkืฌฒœŽi@_๎ื"้:u&:๖"ซYฬ; ๎ฝ>_U+ู.Fัศ:\—จ็์ูดป›๘ฬ๛7F ฅึ,, h‹Ÿู3”๖๊rœฅ9r5๑9š฿Œ$'Nค พ#)ษRํ]ีTบmดU,ฆผ ูi’)G7ๅY]ูพรืํึาko\ะHฏฅน๕Šƒพ๋ `ฝ[•Pํ"น3_ฝ`njrธื#,ซ›ฤ๖ฺVv$ปฎ^ะชNอ%\ฉา๔’lŽg”…ๆ„๎ู>าˆ' p,&"ย$#˜NHŒMGŒHฮ#ฉJ4๖ฒ็bฝฮšmผŽ๋ซณ`CYš&Šฟาั‡ๆฬ๐‡—'โ>aไ฿GwU5y๑๏Z(K๓"%enžrŠ๓We(ชส‘R{fR• ^e๙}4cซมทีว๖eฅ&นฑฯฐhฉฆvBฉ](ฃŒลWนv ฟซ6รยC=:ฮฟwSeŒื3N„ยหวoDศ.Zำm3ณe#Oฃ[-[†Ÿซrฝ˜Frษข๙k]F๙9`f˜ฬsต+=ืJจฅ‡>=[mh/ฒFnซls2Jญปcc‚}ZehวŸฟolN)VฃฐdfŠฒร๛nั`ึS›mูŽฮ7ฎ๎Ÿซ(`vั(ๅ9’•ปบw์๚ณhวผ'™qจiฐชว(dฑ ‹ํMฬป`ตRbN.}ปัvก0V˜.Nถp*ลฃ„jf`๖ฒตhmส– ๕นWeQุšC*นฺ๋–ฅš^์1&ฉ๖ฅ3ฐ-ฅตจธถ‘?ง%ฮาeฺ้Rทb›นrา)iโ๛ฎขeโeหžFะv‚๙!ิf๊ถว3$กJถ68'ี VVŒy๛๖ๅถฑŽ,*V ฐpl'0EํฏcmRฒ๕dv’‰๘šŸจ.?รฺึฯšช 5ป’vโ–พ 54!,MฆoveLj›]|ข๐แ‚Uv6U๛]9ฮ๖\V~‹)TนsYokiณllY๓แ๗›>ๆ๗Ÿบฺ๕<]๋ƒ—1ฅ?Vmบx‡ฅO\าปŸDลC…k[z&Arึ›i›)}ูjุิ4[•์ย3–M๗ศYbตาr์›‹0๕ถk=ีLขาวCJ>กZJ๑๛‰žสŠาลLXช•nโถ3*'=จ๊ JPM` =ฝนฯtญyฌRzม#e›[ปbJvึS=– ๚4oSŸูึVึสฐํ‰!!rเ*วูพ`++’U“@ฌไง-†ษค๗{^ลศฌLฎMดี•nู6 R๙ฏ>bืrไซ๏ซ6ารฬ=2vlณV[ีดซƒ{n\ณธSฝ๚ณm *8CำTY9jป=cU†xว1NWUฐฺํYผCu;aK:{็—jฐVRฬฝf๚ึลm๚ฑfน˜C:ู5๒Rฃี›๚Mก2แ%บexผ—%]›t๊<`Kqฺฏ…ิหyUฃ˜8ศู#|–ใฏPDpŒะKญภš&ซ„f."-โ'‘ํฑฏ ข“L๒$FLร9ฯิj๘‹Tิ-Nižq!ysŸb&นฃปบh{zษ่6ห1†iฏฌ์›๔ํํ็kล2zหmfHYSƒoY02†ํ[+D9ถํœaฯ8อ์$็๚@›ž‘ŸGรำีndœ>ๆgŒ˜:y1ท5SยธOp –,๐(`Mขฝ“ถ.*๖€ี.=aทบ™š‡™lN„ง~›—h„๕›lตแRhุปt5JX‰๓‚q’บหšF,ฯณlวผ ๖ฆiฒช์T†ษ5ืฮ(ทฃƒ7ภฆโJฑZ,ภณคม–-\฿aL}\ณWาศฒีm›w^ญG้ฌ –”s:ใmOQ\J†,–‘๒U˜uฮล๋๛@๚cทึ[้q;ท*V=tวูzฦhณc:„ m,Jฤซฤอ{n.์+Y€ขnฬrK“ํ๖ฎhฒ๎~ฎYต๋$)kqึพึj๏kมœผŽ2)dํๆๅ *ƒHส™a–ŽšะIEิๆ.‡_8ฝาp?4 ๚~o๎ฆvตฅƒหš๖ิn$กฆa)ฬ๊ƒyFS6g4€™ลฌG‘ฟsŒ Q”a๘‘ํkGQซ๛QพI"…oนฑFI0‰A ˜vNu่†ต%ั_ฏ๐์Žaถmํฮ,mแ*|;–Fœ#ฦ0†1B8Œc๗๔เน‚sธพNLJฏiWิฝ‹ฑ`v09‹–ฺ+ฅฝ3ฐ—HหVWร“ž8๖๓}ลๆูKp1TgH~สฆ$ฤ๛ทU๕ซoPยธ.;dZบด้ิ‚iฐQ๘ฅ/ฎl ้<+Œ5”qภhYnŠวYSgd ึDIใ๑;‡rๆคหืคฏฎดoฆFo šึภวT%@ฦ~ร}ฦไต55YฦR@†#Wบโๅึฬ@C:ธ(v–โkpE์ฒาๅ|C๎ธฑ6๐ฐช#ศ€Dƒ์ หฏืYจฝrหdŸhุนiO†ž/1Aแ฿zbฏMfpO#0R`ƒ%vเณA9n–ว๒K0x,นู'่ื =Qog,ญIล›ม8ษ๘—๗้lYฎขฆๆสyฤNj-าหถ3ฆถGุวฬ}›†โล๚•cgJดYg=1ื?f1๖็(oฦšดYr(ธะiซ&฿tถ+/sQก‹แŽฆอ^์ƒงพฏŠLŸคC=ok‹uั{1‹fูฌ(#jZฉภ๓-Y-าธงrแ‹ ๚ ฑ๘รqb JฑฦณฅZ,๑๎6;ŒKด+E&vิํญs;ห˜ฬฝY~ญ™U๕w•๛์ท๎ayZ'#Œ@ธฮBะฟบ—ฟท”?หซฉc9ŽqŒ๖็8ฮ1&ฉ้?•ฆ์›KุMŒ๛• ,๑&วr Oh๕๖๗yฒฬ’๒uฅE2^n›;nIๅ:Xฟbตึเ}[{RWTWศ i์…Wธืญญณ%•;๑ฤq๋OŒ*๕์pfTŽญ๖wตฦ=ั”^+๖i{)`)M|g05ู~น\)YYึi!)ๅงฑŒcฦ?&>ฬknํปzปvq่cำูฟ?gOยบ%Cฒซฏe7ตNณฐิkบนˆcตCHั%๗Bคทถณ˜ง$WŽาดlL\Rพy5๎œ›!= i๗qตฑฐpคv(๖ผb๕'ยฬ H•‘ํฏฉำณ2รŽผKm๚Zงjหdำฐน&Z]“ฌSWXย๒„ฃ 5?ฌ”ํxฤx๏jž“๐‰Znษฑmิฝ„ู.žฺ™ล)ยI-‚lฦN›ื}าสeTน8eถๆ[ญลmw)“)ฏ,ฎ”/ถQqฮผyดฐ2ƒ{™ฆ๎fP_๔–“ฐ>่Œิ‘ณ/__ ็Žพu›‹kฉ๊ฬุ ส~ž_qบ]๔6%ฦzNa๔รำ‚@{Rข@uLูฒ4P๖pั‹ฉHX,ฑ$D‘|ก๚j๛รตb ีmนื-fนญwBภคSืตQบซ๋ซ`ณ แ1’“nฑTแb‹"ฐ๕E4›jWจ„g%Ÿ๖ ‹'ล•yุ“bJbสลค™iwm…1ˆI,๔rTด9–๓{ด“๔qํฮ ”ีไ|ใpV•ม7f๊ฐG1ีUd8๗1ทˆํฑณ5•ฬ#3๋xำ๛™๕ฤ๋,ง#šP๛ตˆŸ๚GถฤNIŽฝˆชึsร{ฏwฯ—ีJ๖K„‘ดr—%๊9๛7T่lฉโ›ฎ1&ฯ฿_ถ^าฮำc&ฬืfมKห\พฉฬ ญCe ํว ”l‰eN์3ลง`}ัปฉ#f^พพฯฝ|๋7ืSี™ฐA”<ฌสLo๊‘เ“ภ๒u†)ึใ$แvปตฝญ[PhW"\€๖eœ&oฉ '5šซบhnภƒห— ิีŠ+ง รฮุiRGึึ๎f‰v@vŒํiาx9J9DฦคX,ฬม๓ภaW:k.r๎K›0Yd๒์อ*š ˜…ดฎŸQ 3๔vBน’s&pๆ:gm”ฒปฎ2$ๅNรถ"\ไฺคธอƒธ26}‹:ƒlฟ๋Z9๏=ฏคCL[^Œผธgฅ…ื!๖@!กm_ผn-ุ”?C๊๐ฤcำฐhฉฆvBฉ](ฃŒลWนv ฟซ6รยC=:ฮฟwSeŒื3N„ยหวoDศ.Zำm3ณe#Oฃ[-[†Ÿซrฝ˜Frษข๙k]F๙9`f˜ฬsต+=ืJจฅ‡>=[mh/ฒFnซls2Jญปcc‚}ZehวŸฟolN)VฃฐdfŠฒร๛nั`ึS›mูŽฮ7ทน/NqW"›ฦญ Vs]weTดUKdXˆqบX“2๋˜‚ศPˆ“ดอถ U&$แ็ฝaช`‚ไ๋gฌZ8Fฆfk+V€8ึฉ`Ÿ[•qvU‰ค1ก๋ฎนjYกu๎รjŸjS;ฺ[Z‹‹i๐jr\ํ&]ฎ•+v 9ป—-"–˜/บ๊&^&\นไmh/ฒFnซls2Jญปcc‚}ZehวŸฟn[kโยฅj ยs^ฺ๖6ี+/VMทi(‘ฟ‰ญษ๚‚ใ=ญlูชฏเ“[น'm๎)kเฃSBฤฺf๗fTฦฉนีืส/ 5Wce_ตำœ้฿eลg่ฒ•K—5–๖ถ™6ฦล‘>yณ๎oy๛ญฏSล฿๎ธ9sส]ร๕fกˆzP4๕อ+น๔LT8Q6ฐทขd-iถ™ูฒ‘งัญ–ญCOีน^ฬ#9dั|ˆี–+]'.ษธณ[fณTส-,t4ฃ๊ิ๏7ECญยฦค–kส–ฅkหย๒3ฌ\๛ุlgทท9๎•ฏ5ŠOBX$lฃsk{ทlINฺภƒ gฒมŸFƒญร*sใ[:สฺูVฑ$$.\X๛7ะ,…erJฒhœ”ๅฐู4ž๏kัฃ˜น‰•ษถšฒญ&มช_#5็ฬ@š๎\ƒqต}๕fฺX`y‡ฆNอ–jห`Zถ•`pbQฏmห–w wฟVmก…Gzj‹'-WbGฌj ฯใB&)ส๊ถ]ซ7ˆnขgl)gO|๒ํVŠสY—ฌ฿@šุญฟ[ถ,ื3g[&พJTzณIด&\$ทLฏท’ไซณnBวŒ n;U๐บ€ูo*ดsว™$o’u๊่ށรบ uธDรขupŒลฤEฏDา=ถ5แดRižDˆษ˜g9๚Qcชš…ฉย@-3ฮ$/.s์พnๆแฺึqถญŠโf]ดท.ฺะj‘ฺฌ ”fd]—vb›7Uv2™uFำถ,ถเ*๋†/€ถณœ๗Jืšล'ก,6Qนตฝถ$งm`A…3ูบำฑV๖ณp"ก]๐ =ร+›าR7ŠGWŽ|D{ส•ป ฆๅ|yญ,‰หs๎W8UGn0ณ}ใ็.ํคf๊จQ!—•œO๛๊ย@Šะูy๗žcู’%A@` ฦใŽL 3#ลsIQภฬDrศD{/Q็d‹™Œ‹ฒฉฎญoย@๕ฅ๎‚ิบvฒtŽ?ฮhไ)Y๓qิฮQ๊๚ถ8ุฮฉ”รRณŒโณฉ9+ ‘8จฬ จ†ฅป๋giDะƒฬแ์l1ถcถจQจKžณX €+LO!"{$7ฝ๏ 7.ฬ€‡๗c;Zามๅอ{j7Pำ0”fuAผฃ)›3ภš ภL‡bึ#ศ฿นฦ(ส0H๖ตฃจีจ฿$‘Bทุฃ $˜D„ †ฬ;':๔CZ’่ฏื‰xvG?‹ฐ6๖๎g6๐•>ห#NˆใCŒ!F1๛‹zp\ˆA9_'&%Wดซ๊^ล€Xฐ;ลษn›oง$๔๋ษ zŸช๛“ๅอ๊•ซ– _ฑ%™dy'๛ต(SBม‹ˆสซํa;jU๎ข!6v๐ฐ็‚IQŒa(Dbcห;3†>ฬส8ื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pื แฎA๙ร\ƒ๓†น็ rฮไœ5ศ?8k~pอฮ1’—ฎ1Ÿฬืd&’Ÿฏฤ ЁtGŽeนด๕ต '=FAภฝืจา $s$ฮ–b8ชศYvลฤศFa๛^gั$œž•c1วEo๏ด0๗ฆ๊R D–`9ฮ1ฬๅJX๗ปชdXsmดง4ปaŸ๏YG/๒อดฟ๖{v๔อลuตrk@ฉึกaฒิห๔ฐฒป{ นdtTฆภฆ-ลb๚๔ะดชœqำ„ฤฤoป๏ฬ๔…ห˜า[ป๎]\Oว฿Œ(ชๆ๒ธ[6‰ฝEฅ’ed๖๕ไ๏+ŠNศ…เfA4ผ๕6•ู้‘cE™†YQwI฿ฬญT]ZูŒกrชฃoู™`w1)ฏŸQต?gชƒ-n&l”ซ)ช…’ต‰ฌู7V#[ "o3&=ปฉyn•าว็š œZ`์W™ฆzโ5ฉฉ ๗{^–c )(%†ำ›ากlZ;:๖VŽG–ฒข[oŠๅxwษฌ ŽF„คuหHย-ึ3ž ขุฺ…p฿ฃ\ญ–ZUอๅpถm%z‹K$สษํปฯ~%"x K“…‘!๛'๑ู๖๔r/์฿๋Kgฒยๆถซ"ร์แ|›ศตดnซ+Yบ›ญ`hก3ฝ-[^บพu็ Wz|op/QŠ่Jถั๋V"A•ŒีIKJล`ภšH๚;;3ํไอ>๙uY’mึซRๆ(1ฎ:oซฏผ฿}7฿‡jœi6ํ\] LเฺฝบฌorQผปX"ชe_PZ๋z๋^_wณ†8;9uป7 ;U6 oฝฮA‡j_U{พฎซี~ู!๐]•:AL'ฤt–รบBŒSYฬrฑ๚ไ%ญษXฝnปเว๔ว„ไ๕~ฑณทvต€แ™อลน๊ฃ8g‡`1Œ๕McึŠp—*G‹l@›–ญญดUDYIูิ|ฉJก^ุฎช wdc#7ีŒืวoพ›๏‰รตaN$›zฒ.ˆ&pmo;ชหOu๚ฐNSศฺฏปซต™ ƒXbBŽ$Lz‹๚9—๖o๕ฅณุส(น–ำUฎฮฝš๗%/ขฏDUb‡ำp‘~G€5ศ,)„ *!๔ƒvRจBRฉซๅGต*ทูนsq[+้Lv(ถOTั9˜ฎHลฮzไ‘โ>(Ž#ู๛’—QWฅ’I>Hขส๒v๒jTี”ง:ชูฮyฬฅ!Tี€‘(+P a๖ภ‡\ @d#8gำธ`\ Š X#a๙ฃ๖IEdฤ’หษกวดl˜dy ล.ยˆ…`0โรŽ"EP ฮ ิDlgฎ œbXฮ3ŒgวLเU`ๅแฎH|๐อ .บฐโX\]s.3ำี4Nf+’1sžน&8†#„Eˆ๖q{’—QWฅะE<สJ$ขฒž:K?ขŽ_ๅ›i์กฟห๛7ํๅ/NŸ๛š๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ๘พZ/^ฬO๗fZ_๛?่AG/๒อดฟ๖qqœg๒gw๖คงcฌๅc๒uฟn?ษ๎ฮ๘w็๒Cุ_ัหฟณญ/žอ๛ˆ$ŒาhสสmN33œ„9ฯœˆyฮXeu#ดa€0โ-น่4WdYgถ1zษศ@1†IvB\ศ๙{ใล˜rwฃdœ&TX‹#ป%#๎z•อfผK๖ห8f1B`ฬ90P๎j& 0ศ)งŽทฌaน"@fก‰fA๖?m[Wˆๅ๖ฤทๆE jLK(6&{?>2ดB/BถLรOะYปD 0Zฯh!}}_\ณซ‘คi.=ฏบQ…Tqqm๘g9บ้หjไธะภ&?C3๎:Eš๔GฑุฦqAท”@ฅณภ ๋๒๚ีpงฏๆฃเร<๚ซ๔>๒๕ƒ๔=ž [จฆ&mg๎Nุi4,ใ9 ฬˆๅˆฯ>ฯฌ4ฝญO6ฤR– ฮซํซญa)ืด6q๘~ฺถฏหํ‰nฬŠีถ˜–PlL๖~|w^โMZ๗ิZรŠึ<0€่w=^kkฤํคd‡ฦ]AHํ` ?8‹nzอมdYํŒtMีท†n ฺ/ษจส3Œg bpž1(ษญหD‘ฒป6@ฃžู@ "ื$ cบwpาื›ปˆ฿gQฌา๎,*aœ3า}aฅใdพ๐rŒ•}ตuฌe*๖ฦฮ!ำฟรsฏฐฝMœขฤKŠวPิSZ6"+…กฦญu\c7ุŸๆbพ๎ชื9Šˆ๓Ž;ฒ=๛Qต˜WPtdoะยษ|ณ฿วูuD่‚&ฤ"d‘ึอZ n›ฤล™ไK9ฮ1Žน๛1ท9๚ำทนธ=๊ท'^c8ฮ1œgฎ3๖ใ>ฦwE†ศd–9ํ”Wevร0ฮฑ#๗ี“ใy๐„ฝ:๑#i_gIยฯg็ใูcqW_ž‚ณ0ณ(ใfWืฅ!o๏\`ไำˆ(ส๊2ฬหYŒWw!ฺ๔Bฑ^l๗vbZ![ล๋™‚๙”Eข๎:0ท”Kb3‰vJพppรง‚แฬ๑ nช5=|อฉล๓ๆ๊ฎ(ฦห.ฮ]‘a]ิ ๎ทˆ[Yโ— ่พฒFฬr*,A‘ย|r—ณynTุซŠีV8™Hิ"ฦ6าXOคt-=Ÿ๓…฿ธฌซํ๕๎ |ฯc-+์ใ) ุ™ฤ??_ำ |ฌใโใˆห#-0 bผฬ{มŸห๖๛ดBฒ#“์มh—9ˆ๒]วH๒‰lAq.ษC9ฤq™K8ฤqŽน–7N฿ษธ1jท'^šeตำšd˜๐้™•gำmoXณ*ฟra]ีSบ'!5๛wwP%บซๆฝฌ๑OF-้ z<“66rG$๖๏ ฐ‚้Y@ฎzนe์ฺŸณี_หi๛zฺผG/ธ%ป25๗UvฝุAั1(cฌก+Z๘=ูตฝ?ถ ธ๒•แ๕ž ‡ป๏๕kz\;อฉ‘`ุ:๛š…ณแ`YF–{c^Rธ>กำลp๗b‹๎ fฐiลyลq๒žIX%d9• ศเLŠS”ฑสrฯHว”ณ‹Z์ไXรc๊|๔…`™ฯ5„xLะ๋8ณY$@h’B$Jโภ ยRฦ7N8Iๅ"|ญ#ย&Œs<ม{4'„ษ๖9qhฑ…2hแ‰~hŽภU‡)ษCฎ1 ฤ‰!ž่N8”rด}๓`f๑"Œ๘–ูŒuฯูŒ~\๛โณ3ใ๕‚๎๋ำD(ย9ฒฤGu”รh็ุ&‡9t”บ ๅหžภ1\Žฺธำˆ†ะๅ9็ถ1สฒŽ28ฮe,ะR]‡fŸ€ 0ไ XyNฺธSศุใ8K1œd๚p,&ฬNฬ@vต๘tร๘฿-Kน}(_ฅŽr#{ ๚9—๖o๕ฅณู๔“๚พป๙ษ้ะ๘#ึ๊5 nว3 ิF`่šๆฏX‹ํฆ)ปcVhJ๏k@y๘ฺzญ‡19ฦฤศ๛ ฤหIRํํx‹ฌ๔œ‡•q;@๖~ฃษุ๊Y(›้XชpŒึ†ใฌQmั@ชB‚>T๎อ~งซ.’x๑ —ูR๏+ษู ,แ,œ` ฐMผจ็Z(ญ‡xpตดt?ญ๑๚ใl1nJฺ๓ึZ8dื#Bญk#ceSีปI7^ซ๕,G“้1‚5QŽ:F,1Žๆ ฉlยL#aqภะiำGhฬนฮeภ8ฬa?:=lลWsk€ l,1œzส๙oวสkๅ8ฌVQŒ ’กV3ฯtใ์ฺ(&๕ฮแ๕‹œŒๆฆ๋ทํŠjใ‰|€Ÿzฉnw•ไ์…p–N0ุฆTsญVรผ8wตm|il_ยkแษ\๚ญณKRZZถ‰\คุศbL›ูบH$›ฑฬย๕˜บ&นซึ"๛iŠnฦ#ุึใuˆlุ3—+JWŒคค4ญmไ๐d…2ธค FŸ(ถƒฏไฃHุvuKtQeด€ัš+„ ํ๊w_หœ 5m‰ใา2rm“^™†IศๆฮRล++Xฝค+ฤ˜\[2น'ฌ/๒โใg`\cXฉ๚@ŠจG…fC>@o๚ฺ๕k@สษฎ–ส8)ซ)jDZrc0mภฮบุjฐึ๖=ƒRd์4ฦQi9ฆผfถ๓Mธ๖ุฅืดคๅญ๑KVฅ@šQ5ิ0Y๑*sŠšร—9ษL‚„&vฯํฆๅ๏uฟ*๔ภณ˜๚–ฑ20ภ”pH{5™ฬ‰วฒรgภฐZศ% W1D(๊y„a98ฤ#fyUผH4 จๅ 32Dฮ~šิ9ฮ{ภ%ด6เฒฑfƒ฿สถSL3ฺ๖}วฺ๔U~๊ดศ~cuuฏฮ$u%šœ#ู}Šใ๘๋kxŽ&๛l3ุ๋Yจ9๋~ีฃ^ฝkH,ห$.ฟHYษCœ™œุฮuปhjAทฺ8ฏ ฦ{sPB็9Ÿจ๚ุ~ร่i๋hจณปUถ0.Fฅว]Y^M๏f”ำ^J %ศึQะ„†’มV—|ฃ์฿•Uจึ*TัYbM๘ยSซจซ\Iด>œy็ก\;ฆ‹0มฌฌB@x"ฆ฿8ญWย๗ฏK4–/ๅPzุแฆcn€๘yฝfqห ‰{๊œq$ฆ{ฑ,{ณpยX้)x฿2~ะก๗กhม๗Gq<ัฟ\(ฑ^ยƒˆ ’Kฎ7d,ฉf/า,Hฦzต'ฝ[ฌ@9๛ัcหขcด3ภ๑ำดRฤ1ถ:{ท์ˆ/vท1f:๎ุuว1เ9๋#ฤ๋4(MใฑА–UY๐็แ๎ข๗”ฤx—ใวQฏ\š˜$W!‚ใ&,T/!…เA‡ปBฎJฟ:ซ๖!ž:ํล@ุšiก ƒMŒว9ฎวคจฑyร9์๋. รเR3๗ย+PŒxXศฒF~๖n}m฿ฮด้๚?YžฯaG/๒อดฟ๖{7m wสชศฐไศฒฬj#ŒGตxฤqŒcW๛uชสุI โีBS+ปp#%๎,„‡ุEEJ‘ญ ๖‡X†ฃ5ช๖eUๅ฿\ฃyฑ4[TNฌuŽเฐ)˜๏จ’ฉตJh๗K!อE{๕๕าVyษdคๆklo]Vม‹*™ถŸgง% 7}Oฟ\Qพ๎/Kํฑv"ตl 4x็ /]ท,‰m ฝยุhฦ_qmทฑRๆกๅฑๆ.m}มbอSฎุ$f7yเฺัqFT&sˆ4น—–R๛ฦค9Rถฺฎ*เ“œ5๔‰฿Š๊Œ8‘pi๒JาƒtุGุถZuฬ3‰3ท6ลษ˜Db†u๖ๆ้๗iชฒNลrˆULSU f–4๓+]ทm›นR<ช์qcJภˆุผmVห™ใ‚^อนทจ~ฆHดแ`N๐เ;}ม๎ฦorEฝ!…ูุํปZฮ๏o6š/Q๖‘ }่„VTVต^…|ย<~อีทห|ฒ˜ะ I’D๛†๑/q`Œ$>ย*%ฉ™bƒ4๗E ง‘๐D J-๎ต-ำ๗ลพ ˜ีธมl1L'(v๎๋งมTคตSะ™”5GRzฺจ๓คฑ!e9#›Ž”ฌGnุซ่XŸ'งกฎดF ’ฺสOฒั0YCl/hfw *‚ฎ €4;i๕ํ yvะ™~q”GหI๏๊๏Iเ% ภgX†๑Y…"ๅakร†฿oZๆ๐wิฌ+;1Šรk฿:tญsd–nŸ^—ปnย๚f๐ยใยQ•†ฺ๗ถvชNด%๏๏ดRใ (พeTธ:ZWk๏fล{*˜6็จ!๊KiI๎rภLQๆdtPFนkt}1ฤ#ึ*TQ]SดGJvษ0ฒนึŸ^ฦ@ฯU4ฆข%ฏVยถู'จ –6-dMฎJ–s)deญ ดม+ญึuv "๑ัmืUฒf๎ ฑ`ฤ3฿eส๛˜วhEP`] อฏผ)๐lWูT‡ J2.ฎv๛ึ7T–B*ธtี›ดM฿*จ"ใXษeŸค(t ๅ้ฑ ๊ืo๎›?๕y-–%O.%฿aทีi>,a๔ๅ%ซ-KvIลAฏฤฐถๅi๊*A™ fO™Jวm\F่๗TOชนZicL+ €ธปif˜ษzŠ~ห}นป๎#ภ•Q๒`ย‘=ะฉ๑‹gะa/ฦ1=ถ์ึต5ฮmuฬึ%๊ีช๛ื฿—ํ…งaี…น)๗%ผ˜UGซวRxƒช๔ีบท).K*ฬึ-8เ€๖nํพๅ๘SdXy\…œ๕นj˜นช*+L0,ศโSัonฏH์ใ‚`Cž๛เ+ฦธV่แHวŠ eK5ฉฐ’Mม‹‹ชlตใFสJฐr^ ฮํดmkPยV…T"ฉoถๅƒ–Šิ6\\])ธƒ&=๘๊mว8งวฒ๎—vฺ๚ลqcY๎ณ—จ—ฃฉuคIvl+gTฟtfฝžถ๗ฟฉS,#ํฏ|หIฦอ<๓ตn5ฯR๊๏า/,Ž๋ฅœ5nnฒฮqUฮโก๒q'Ÿ*งอN๘fM›”ฤทร‚3d |ืภ5.oC!ฦZSlo[mๅฌช`หฒœ™%|`…‰Dwq๚‚ž( 8๔๊AิฉZอ8ซ๛มอ2\ศตฦš.โBโXsฦๆภฒŒ ฿ฺ`ž:ฃSาW‹ป|7฿ษฆ2niDEศKลิdลE‹n๖Œb_=cโ&ศฯ,F ;ณต•ฯCฮ๎™ŒโŽแ€๐ฌ_‡์‰xcฝจƒ่ผรy{ ฅ๊eŽ™šฐฐŠณ‹F ๛็a QxfDูK'#อุย%ล‰€|็8ใึ*ฌ)ณTภ0gป†ฎฎjอด\ฦ?>vUW”dสž›‘r"วึฒฑWŒ3หGโŠ๙ฮ>ึ ๗ต…N–QJ'้‰œ˜ยŽ_ๅ›i์๛ซJลญิ’M๒pฮPžuSG_H2 f<นฦJOฦQฅx0nะNS‡๛U]4ไpชsw=(ฬ฿ํ6๔H๚o[อ๘,ง1`[ํชณ๏sๆApช Iq*จ๐ =ƒโ%F„ฺ“d„ๆI“1ืป—๕๑๘GNžวชTฐœว'QวทFธ ว๑่ฑฺa ฑฦzใ“์วูŒ~L~+ ‰ƒH"ษc๙ฅ๖๔r/์฿๋Kg/่ๅ_ูงฮpY๔ฮq๙บ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wหสZ๏—”ต฿/)kพ^Rื|ผฅฎ๙yK]๒๒–ปๅๅ-wK?๛ูอc๔ฒ/c–‘Q+…hฦองf@q2ซ"Ž %ฝ–adฮa’b3 ;t๛ฐฏZL’$c!รฒCๅYI๔y็ˆพฦœยฦHY†e๋ศ1"ๆ หˆd}Œ0ŸuenญWฅ๕}๑ƒgเมxU๊ยฦs๘บใ๎y๊๘=4ฝ?งๅ๕šƒุ‹yฦ@ฐไำV2 €@ อฆ ,ฑ-ฆ!‰"๖Ÿˆfฤช†อ‚ง< ๗ŠCŸ เOษ฿ฯฅ›ุญHฮศy.ว๐h`๎พ—c”=/Yะf?K/๒๖XแฝFKซ''๎ๆฑล?xr9tสะS)ีฒ%U€๔ซถขV๒ฒฮXไๆณk™GY0ซฦป^ฐtEก3‰๕}&*‰+Xmฌฬm,I/ํหืSฮ1œ2—HณKN‹_„ร9ฬ5 ํีฦ!ไๅ]‘ฎขpท๕ญ8Vนp๓kฏ‰ฯ'ทrSส%‘—“<ซตญ“6ซ ๓˜50yฟ ซ=$&`ฟฅFลD‰AุANZg฿™ฺ๕J’ฬชฬซ๚\Rุ ฬeถDM“z!ฺ˜Šใ#$- DjŸฃny–E่ษXมƒ‹KฆSjf๔hฆฑ ต>H-๋yJeั*ฒZVQหถศี”…yQ— ƒั_ฒจŽy/Š ˜!มg๕'—’]๊—฿0rใปำใฺั>…T_ญZฦo9 6E}ฃ์กp๕%ul ๒+ U†0’FŽqษ“’นBnจ๗ยy๎ฉ›yะ๋ณน™ศ.–8แ5Cวฒห6lO%ZูT ]fผo+ข[šdv6€hฌฌห 4ํฃฦ•1šX๔ฬ4ภเSCV^‘›‚Aทณ(.Dื;1ซNฦs?๚š€Y4H๕หๅ`€JตOwŒฝุXี ฆญะ2kV3ฏJY๕ฦeœโ1n’ฆ"*’@นฎ1Kนธ>xEGเ0ษ,Uk0ิœƒIฤ๓aขคฦ๑h?ฅ ี’ ่ฮ}ึ‰W“,ะV?K/๒๖I1ษั=œฯ” "๑Œฑ‰c1–1(หฤฑ0Gฐ~ฉ๙(9bPEชมฐl3ฒ›<|Y6jสSG3c0! ršh N๘ศ‚ๅqtๅOŸ;ZึปKD,ฺ‹>‡โญ7ถ#ก9ป%zๅฆ(,‹mVปๆ€ฦBไุฬ~โํ{๓๚oqผฒ]ผง[Bู๗m•ณj,๚ศG๑Nnห6lฏuฐ{*wD์mิ{ษQj–ฑ†%˜ใrŽุลญKDมว+Tูฝgม๖D๐๘ก๗฿ำ˜่ฑ!ฮP—ฎ_ํ5yึuษBารถ๑รหท•/ึ๕๙ยิ๒‘W…%๗Bคทถณ˜ง$WŽาดlL\Rพy5๎œ›!= i๗qตฑฐp_Iม*ถ\˜รก‹ซ—ฝูVุ๋ฦ%%ม™;hปŽปฯzถคi+ช๚[y•ฌ[รฌ &๑อต(}๙Jxๆ—Xv์ยmฟ๕ญ[E‘ฐGร›*šyผ๏ทA$\–Y]}‰`ฤอiXFคโ๊gPŸnŒฐดบ๕๏ŒฐVGย๛s%ฅ9สr๕,ถXi๘4ยแ•ๆ[ทฝคหต7%Gขqฒญ`AD๑Fš๔Vฅ‡\OŸฮอ Cถ๋1๑าฬฟ.ถงํ>ๆ;ZบXฎ8รc๎ผ™“vซิV/้oฮk!–๚ฐ๏6 ฯส.I = T๎›Fo]ฬW j็[o–ฏmนpฮfcœfwGVข#ื๛>ROŒ{*ิํล๊๖๕~‚q๔์฿UฮŽฦง :ใhจmืAg WnLแq“fK๎@„4B๙"“[+๖q/v๋dป฿ฬj๐fดใ —บณ๐ๆN[-OVผฃ,ฬf‡~ฌF{ค3ว2‹ฒHรT๛‡ฆฯ#ไ—sกš™ึูๅช.5"็ฦ๗MธHแLŠภคŸถ=ปA๚ๆX๕ž๏$}3[‚ชt6T๑Mื“g๏ํฏnฏi gnŒ้ฑ“fkถล}P˜}Žฃžœลk3uธZ%—Sฉ"ž?/ูŸทึยฮGิqื‰;Y๑~7สฬทI*นู/ฌธMนnญถฤUb@=†=MQอcฝะ]{)ฬA=Cื;]rิณB๋†$ี>ิฆvดถตา'เิไนฺLป]*V์@sw.ZE-1ผ_uิLผLนsศฺะ_;d:ŒVุๆd”)[vฦว๚ด สั?~ถึ1ล…Jิ „ๆฝต์mชV^ฌ›nาQ#^หz%.ฝ?ช#๔ฝš๚Qcคี*…Afr!ู ๊ีYื8Žeู๊C(Fu–ทq/to6ื™pฉ’หT-fุฅYผ ; V“งdmฌuI›#Oู้8ตฎแ# ฒผ nก%(Yฆnภ{iซg ^กkoฉiQธร5Eภm3,๓๎K{.–U ํ๋†Uฒ?ตl-kฅIvๅŸa้7J“™๚@Yฬ(ฯฃภsŒตปRq›ญบUิdโ ก“มL>‹‰K=0าฦvวs[:v1ฤ9ฬ๒ัชฮ-TีฆK™โQฉnโฒาฮว;nิ๑™gลบ—ฑธ๊eO๒ฆPd&ทฆสufhL#mฎF%PธYI„HŸD๛ญ`wฌmตฅฺ“๋7ั”DzใVใ๏a"’Rฏ+|3ฎlJว#$๒ป[.•rฐ๕Zี“!sภ;ฦญํฎgrิ8ฎ&eOpๅ™ iœซภกF{‚ู‘YT‹mุLsฬืƒปfสูกP]ปa๓ๆwv“oXู/˜แ€ภQ_[%๋‹J1Y\’3„!ฒ๎ูบฟM้iถ็ๆ๏ี—4๏Yนณlx“ฟw+coทำ"ซ$๎]ฦhธฅสUป^uไ„BŸj‘‰S.‘a%ฺŸc๕ŒŠฒฌปSณ}V๛Y@,Všณz ’pีq_กm†ึ–FYๅv๖๎]*ๆa๚ฅjๆB็€wอ;Zฮ6ีฐ1\Lหถ–ๅB R;UB2Œํ%xฤฯeEibŠฆ,UJทq[•žิuฅ(&ฒ|hฒ๓ฦ ๆ]62%Zฆn1Œฤ๖ฌอใ„๚…๙ฝ?8y๚uเ+ ƒทœแ~zCD ล ณ€วฮœ รเAหํŒฤภ๎เ8Mูžู๋ิ/อ้๙รฯำฏX\ผ็{๓า!(d…œ8tเH ็_lf&วwยnฬ๖ฯุล fณธศสoCณ$ฟ;:ภ~๎™้=sƒ—ƒ˜\:๐”เo1„.๔†ญpฦPc ถ$OาmQQL šๅ๗วf๓0ฤq๎แ0ูž“ื89x9…ฯำฏ Nv๓B๏ฯHjd€ฃ’q#๙ำ„เHเƒœI }ฑ˜Ž๗p˜F์ฯI๋œผย็้ื‡pะฏธฺ๋ัุ\98อ).*ฌโ\Caํcป€แ7f{gฏPฟ7ง็?Nผapv๓œ!๏ฯHj fฝHเcค8  š๎๎ยภv3 @l €1ภp›ณ=ณืจ_›ำ๓‡Ÿง^ฐธ;yฮ๗็ค4B Pษ 8 q้ภ,0AฮพุฬLŽ๎„™ํžฝBŸœ<:๐Yั)neˆ๑Z(U– qŒcฦ1ำ๛1๚t๐ฬ‡>v— {๑{•O€vปๅ๕pฉS4ุ็x‡‰ eฃ ๒ๆDฟ\ฎด้V–KˆๅภybgVu*ๆC"กX'นQ๔๘a๛ฑ>_W •1#MŽwˆx๑ศฆZ2!^dK๕ส๋N•idธ^\–&ugRฎd2/๊ แล‚.ผ <’Q‡_‹Gฉ 3,ไร๐‹|เ:™ๆP‘,Ohp`=ฌwb|พชสbE™Cค4xไHR+ ผฏ0%๚ไ ฮYd˜^O,HหNLศsจHƒ‡'๎480ึ;ฑ>_U e1"ฬกาุ~์O—ียฅLHำcโK`OKŸอH๊‹ฟ.ำRU”๎H๔อฮ%ไฎ๒ใa‘ูVœI]ป>อnIหา๚ดkจ‹bB๛ท๑ญ:น‰ณ”ต…๒ๅGฅโ]จฉŽ9ํอ๔ศ๋gGo•iฎd'uUh์Fห•je’2˜\ล+Aู n„แJq-ฺ `Oฦ“.ˆ,ฆ0ฒ๊d@ฮS8ฅN๔mo‘UงศDถ6bธ#›~‘T–โBว—.`๔>˜ั#ศ\v‚ฑ๙ใo:Ÿž*ุ6'n้๏ขฃ!ฬŒtt†8นf๎:ิ฿ดฮmTฎ\ดชวƒยฦููO{-พ$ฯ!9อˆFฮะ=0๏#็ ณk๒ฝ๊y ใs†ทCjV {`›+†Mi?F"†ืณ๛ญNืnส3‘~รฺกป๐ฃPicSk฿mบSุ•หธม‡0mZppBฆฬUbmใkTยฮข๘ไ0฿ห#นนฑฐ jXH฿vํbฆ฿ฅkxะu œY^;๛Žฉ‡ฮ_ำ๖›ฺaไฑK|่em,)^yยvwฺลyƒMS|] ผ#๒J‹%Œฎ1Gร+T–โC [โึ๛มญ";bํK+"ถ+ะmฝHCX7uัลฎ6ฑฺกWDผ6G?2๚^ฆถJ/ŽJz๏ฑุZขV๕vŽT"Df zsžgE…3#๒`-J(vu "ตุ๖v๋Uู'ˆุฦาD๊ถฤ„๛r๚\็rลtš?IŽ$ ฿ฯ*^[i๖๒ื๓ฏฺG_jOูฏ ~อk๊œ๐ไHฏูŠ๛sWํVพฐ:ฉ”ฟฝ: oซ฿แ:‰๒ธk|๋Mร์ฮ[ฺU:“ืญ6Dณs6Tา›ซฃŒ•ญbศ๒หภ—‚q ๚Wฤ[็าดห„.ฌฒ:oฎ’ฌ yะ๏€๒D"ฝผZ๖๙๚?~ศ๛rืุj๛ืฝuฑ4ฝฬ›YxHทNvฃ๔˜โ@ฝ๒ฅๅถ‘๏o๏-:ƒR‹ุ๗ื๎๋้ปP'ฅ.ณ2ท่Š2$แ฿ช”Vำa๓ฦีc๔T@๊Vุ‰”ฌแพ๏C™๒tYo*—Mฤ™$-hรฤZUฃพ1jก‘™ิŽ–ฯ•~มซ์Sู7tmJ+`ุตฒ๓๔O~ยZ๐(#eตs<%YkS้r1ญฑ–9›ฤo•hอัฐ„# cโRิัJ๎c@Dนs?๙W๎้G“+j"ภ )๏l›บ6ฅ ฐlZูy๚g@ Ÿฤd~"ๅ r๑b%ฅ้๑ฆƒ‚นe์Šห็I|“OŒVฟ่ƒBุ]8!?แ^C๙vๆ‰ถ,ขE ะ็ฤ?ษ้…ญ็[gf‰8l[mZn)ฉ7น‘Sฉm๏ืjดๆYษยสcใZPUัๆละผ~ํ๐ฟฆVํp๗fr q7B @จ$i8J๊b -—xฃส็[*ฤW\}˜ฝซ์j๋็ฌฏ฿d พJนฐๅn[๚G3์ ยฏ… d fีฅแเ’o•ึ?~|๋๖T9€ญZI$๒๖ŒhึO<6๑จ0ผปlซ๑ฝ~ภื๎ฐืยiˆฎถ ุ8ˆ|ป%ฦำ…Sํ+'€ r+kํ๕kSƒด‰จ‘ค‘dภ(๗ˆๅQฯ‹ศ.hO๚ืฃน›ŠธสาทR4๚‘๊Œภาข(ฬ|~wฆ‘[J‚IBcLo~ฮฎU๋_รุึชXค)ศcรEจใvHย!Lฬฝัwฝฯ…}lF๎|ษ๚tาย‘•^์$ทํQŸM‰(ู  _Ž@,ฒFร‘4ั๐UฐPm๐ตGุ0๐๖กท,zๅRI๔มอูเb๒สีจ*dužF•๒hย๕mฌ*Yc1Fา&\Bnห๎Z†Ÿ7UB/จทgยดฒ …ฒฌŽฆื๐ฝผชC”ำ0ุ๘-Z9FcvFsึฤT์f^x]@y๑ฅ‚"2ฐ6๖•$1ช\)~ั|+G Ÿˆ.หจตkepฯ,‘@oPY7y@‚>_ ใBg˜$Œ๑žสฒ+G๊ๅH.๊W+๛Cษผ)ž/gลโe๊ึMพ•ปูtฉŠด‡‰)”ไP(ๆงูฤผ•\l2;*ำ‚‰+ทgูฃ ภc‰9z@VubฬH_v5งW16r–ฐฒ\จ๔ผKต1ว=นพ™lใจํ๒ญ5ฬ“ค๎ชญู่rญLฒFS ˜ฅh;!ญะ‘)N%ปAl ๘าeภั”ฦ]Bฃ ˆภŠ{gฉญ๒#สด๙–ฦฬWsoา ’HX๒ๅฬ‡ำฉ V ฑG;฿JŽ!L"ห"Jv๑ข๊ษ=ฃใ."R็ๅj‰ีb—‰` +สb7[\ฺืฺต*Pฒrโ˜Ggว5iๆ‘…ี#๊ฬกpลp_Žฤํส“ทฤดB?ฎ-Bไ`9ฝฐฦyฺฅC˜Ÿฌ‡^zey4ปrWztฝ.ึŽ(8‚ ~ิ฿E‰ โปัตOู3FAŒDทŽuต“T๑อย8" ‡Rjc|ฑ—pค5ทฑง`w#ฟ? jด›^มˆS๐ธขฟ >ัRฎึ>คefD๐ฮG๓้ต&F88ศ{ฒฉ๎๕ญ:ฑE&^ฒ๖ฝ?~3"eรo1ศ๚@7&พขษ”—๛ลGฦฃ๏ปp8ผ๓ฟfตM‡ 5BๆBŒ j›$EŽมZ๋P!ป„.3Qp/G p#2AเmตBฎ‰;๓ ็็kx^ง๏*|Žอp-M"ฒฮ\ฝไ9ิnจV๎#Bื๚ฤํ๐ฅษ$หr]_pKl.maสธ%ŠHซ‹oi.สAจ์Bปนศ๒ฉญJฟS๗h%e[จต~๊ฟ’9 รN~XฌฒW^&›ุ1?^ต ยธBใ5๔qท3!dS3๐ุŒฃf^ถธ”ฏ& 0ฟ\/ฟ*ำฃฑžG;1?%ทj7หอ”ซๅ\EแฟN‹_พ |i+ฮL๗=iJธ+wŠC๕—ฃrํZ]cjฎ$๑{%ฑlฑฦึ๘R[‰.ตขํฦฝ9ฅ๚]I€›[—:Oํ—ะยเ;”๎+ 6์ั๚Lq ^yR๒Hˆ๗ท๗–ฟ~า:๛P๚~อ~๐k๖k_T็†฿"E~ฬWšฟjต๕ีLฆ๕้ะจ[|ํ^ ้ะDO•ร[็Znfrะสฉิžฝiฒ%›™ฒ &”]dฌ ~มซ์P๗?ผป่~"ฝึ–ฯณ#€ฆ๎ š๗๑XˆG–โ*u%~ส>MทฦŒ%ูรฤห7™ต\,(ัห};{B6ไถฝฏŒ?ดUky •่xค0ถ้ตวง๗wฏ}ญM}Mu k๛Vฅ๚รˆฯ•ฟปต7[คe0ฟ๗wกปu)มฟฯ*[ดึ|Eอ~ศื๎ัzzๅฉ<#o‚–4าE๋.ฏiึ`8ใ}—g]xR๛xฯX|ฉ…ิใลeธ>~ƒษ•ต `ฌYipย “เl-ฐ๋Zuย“(‹bฟ~tพ๒ƒ’_๕“ˆ„+š3ุฦŒพ_I'Irฤฑล^\y-๙u=ฬแnA ๑]๐ฦ~ฦัส“ษัฦ,ฆ“S+ไ3ˆŸฦด๏ฑษB๖๘ˆ"ษx!c"ฐ)1ฉวN๋"๑ฦ๛5๋[นฉ$‰ต X ฒ0L}มอjVC5ง‘ฅ{ฒจุณZ–›,Xpี6ฺดฒ ‰หนมิฺFU+g4ล{นฐท.€ Tดถ); cv!ฎวฤ๕คldŽEุ:7ฬŠšx#’ํ*ฤ_แษlœ†ŠN-ฑ์๗๙๔ฃ\๖Š3๐[mใzauemsVฆ™ZuCูศจ่2๘ฎC#Ž์‘ฐไEK<|?5%|-I์๘<5ฦ3 ^VSj#แํำน)y๓Oคอง ฅ–ฦ)ํ“GŒcตถิ9v.lํ…ญํปA“€P‡eฦ๗ํŸzฃ8ห ƒ\l๑?CZ†RP7{ s๊Miุ$ธย›‚Uชpๅ.1%งSzำษกPๅ๎Cฃoฝด๘[-ภŠ"*)ใแฏ๊๑ใNArฑ&น฿mg‰ 8Bƒ>*?+š๐D\TSI1ซมŒbลs6ฝ๋ึ4ทsZงŽF.=žญzฦ—๐๖5ช–) r๐ัkE:ยฒC|I๖๕ ร ฮƒฏฌ๑‹^ฃqzแK`๎ษ2Iลตถ๓๒ฎขI{จUqำษฆ){m$lz๘ืI#ิE‚apึถใึิาEฦ‰#7ร’ชzํObๅ!A—+a}ทฺงใkO/Idท%ลA๘๚t์‹!แฟ-ไVธ)์\๏rฮTrw;QxฝX๑˜H๖\2๏ ปี๋_รุึชXค)ศcรEค›MรW•ณ!Dv๙ึขh^;?=’55ข•b2b05ถธจ๕ึฆฬไL๒Jญ‘๙W F‰ข@dQaฺ4{รJƒุ}๗-๓ยx๏ฬ฿o" O*pฌ9จ'๏ค์4E;ˆ้•I$Wำ7g€aˆsห+TลZCล”ฬู 9ท‡๖้กŒหท/hE4‰cqƒว็R4W{›œ˜s†aŒหถรฺZะไ†7u์‡ี™@hัฒ, ทK๛ตงำ้ยคvLsเฃ_ณำ๓Q#s6Bา[ญน(&ข‡ฯˆQ•๘„๒ทไห–‘๑=ย*<ฐfต๔ธไIํ’Ÿ:ƒ‰ฺใg|ณ'๊G ‰ ะ.^๑ๆ}/ o?ฐ‡9ญœ-ฮฦบแวe-ˆฦ /ycบฐฏUWIŠ”โq;}Z“6จฤภ–Ul,]ˆ •+๑ิื1N-€ € ์ m๚ \ี“Fc’ๅMปCsq๘ื โ 5ข&ํศคŽฯŸ@L$ณ61๖™ฑธษ2๓O~gŠYJ๒&.ๅQfซ›}dr๗ ศ2ท?G rU@Gำ+TP‰Œ‹ธddฟ‘JY–ใูน|17รRaไHๅแ่l-–C/ฅ์ืถ[^ฝŽ\+๛<_ฑ‡๑ีฏ๊ZQฝว้ nM”ำ>๖ษฐI่-Zม%ๆe๏ใร!vพโ็ัฉlxŸซwŒoะ\š7ตฒว$ห}ŽฬไฦŽf2Lšื>6@~U~.ye™?V‡ผEfถFรiš๏ล์}ฃ‹๕ฑฦ๕ฆk:eŽ„y๛ๆ—lg๘๎ฟG[dyšถ8Ÿคย7฿„ฏฬาR12<ัw๙›oฝHฤ– ู$e๕ะฃึMยfท6 หบ$TNSึ%‰๘LI๓77#–ยฅrฏ;\(R@๊9 ม๑’cงtำ^ร~M~uษ%ํ+^i฿5ป†ยิQxข>e๓ท•~๘…’W}C<–IQภ฿รำ๛Z^้๕h3ี_ฬvŸํ ๎ฉแ6ก’?๘T*$"=ฒล๋ษVิๆ๏ยำสa•nwท"ทๅสดฒเbr32เโจ-k k ถX‚ปจ๗ญ๓จœงฌK๐˜’ๆnnG-…Jๅ^vธPคฝิrƒโ+๗fฏบฟdk๗—ฎธฑโหส‘๓จ50ห ‘œkปj„›โ๑ญ3ฎ9&ๆ๛ิŒ๒ฮฐi๕ผ1ยPWถ๖mz๚9ใธQŠ/๕kTํ#Dณhi%มl ˆO•L›ฤัๅป๙Pี&พ%x†d~ศx v&_Wžแ๏ถ๖5#’ฉแJAn„pุVMร$Ž0^[F.|ฺ‚(’v_ฃNฮ๎๑้OีKxoB๘8ค„ถE™ ิูตกQ‰ไ[dปท—ไ๕ฯRx7K|ช=D'PฃWะ9]pŠ๕ง!dฎฒฒฉ>cZ—i^$‘ๅD[]๗ฒ๒ท:pRH}›ฦ^2ฬ๛๖ ึศ]QๅYป"s lญึฆF&‘dโฮคิลชงธ žฤx G•3์9t`ฌใูEH์รณyแ —่ๆ‡ฬRณyก6€๋ล'ไดแ„7พ&^vๅต:ใล:g3DซๆฮrทE็ฝFOmŒm<ŒรญvAญYW’ 8c.ˆeพญฟ‰๔}K ‚€ื}ฌy*เ๐ฉฑโ=ี๋O๏ํ่IB้มZึฟObXฮ[ฉจ˜ไ‘Ÿไฐ_‚มF้ฮตf_ึ'๕i˜ุlสmQ’ฌู BWศพmฟ*–S"ดwž๊๗้pk5‹ึbaดbRF—‘ต6 J!ถT}๏•iX#’ฆ&๗z&Iu&8ไ•R(ฌหl๓~–๋RŒ[ทnอฎ฿ฦ1™โฐ๙Bดเ2:ถลYM(ฒจ;x7m้[3?p้CฯEงฏษมxฆ0n>v๒ฏœี็๋2ถ_xอ—ฌ/ฎ.>]G~Љ๘R๛๋ํ๛ว‡.,ื`ถ\C>U๊๚ฆ2pไwฟ‚-฿๚ตชโ+—}?ณ™KขdyฺฆางWช™N(ฟฃฑฌีƒ์ยค–ฑส๗ช&…–7ท๊3ฎผIลยŸี\WๅIH$‘๘ฏู ุูฏฝฌG[ึขซฮ7„”[๘X นๅา Šybบฬš‚ธว๚ธ๗๊H๕ฤค$สสะ์ตi๘ึˆ†ถ ยŠJเjโแ^c-ณเต๙งพp;ฆMไบ๒ไ)ดฆ†Eา9ญพOฆYnpŽๆคR$‡8#ฅ#ูฉ ’<าC:๑aโ•ฒjัซผRq7ว4V๘๘๘Š๗ฃŠi าๆ:\žVดส๘ปสธ‘U–ฬ-qอhE)า†qXSTT+‘สใ$\i ’Gโฟd+cfพ๖ฑoZˆZฎ?8Qoแ`6็—J'xฏฉƒBคF๘฿๋SCฉ‰"Y)vSูyžี~ศื๏/I ฎผyq“)€ฦ๊‰ใึฃ›Y;พ ‘ฌNํrVเm\โิpžก 3b|kี๕Iมใj}bู๐Mํห•{OZห‰‡น•๎ๅzพชโฺEำ_ม๗kSšศฎaดS]ี<ํSiS‹€ซฦีLง_ัุึ ๊ม๖aRKXๅ{Žีuศภaฮ86Euใอฺ`TY>Uธ4ฅ์’ฦ๙eอ_mEu+š>@ุภ ๑ณ2๑1โฃรbsPภ‘cส„sNะDš๐อ.ฑีŽ๑<†๔|bˆธคW(/3y๓|1A,‘EocDๆ&๕๋ท&uKงaœฎ็nTะO ฺˆg•[ูd„œK=์ง•zพจผj—โ๐G๊ิผOXยทE\฿Nอzพจ—ว=๘ผป฿VตBLŸ$ฟxˆœซี–d#‘s0*๓ใP+œF$ิฤ m๏€}ไfโE—ˆ ท้=ใ๚ E฿ํVOฉŽ=ObๆFิ"=อ๖ฟAสวzUี„‰Kn฿๓™&ขVwUฃk„นณFm•ถ<๋…>ฃTไฦ/+ฤˆ0N‹~~ฑ้„ชฟaณ,๐ฎ6Ÿ*‘›,Bm‚ฏ‡ฅ`ีF˜zHฒ+ˆžเิฑ†J@๛HPo†9ไ‰ณ@ูชคF๖ๅฉ"ิEk<ล๓uhน jเK๊ื“[lyํฮข‚Y"„/๒€v2ศ‚หaพ๕‡œcศGน7Vถภุ‹ึฟL\Uฬkb:s>UgฟตWlฃM์๊1ฝถฃฆŽ^งŠœโำD/‚[็}นU—ึtห๖’>่๗zะำ๊ขแ`๎๖ฟฏ฿ฉ/ฤ…nb{ธ๘Slพถฆๆ2Xธ๛KใI|ๆxะฒฤถvๅสธ:ฉณโcทะญปต?า‰}›ฦผHฃ่kJ$ฤ—$G็aฑ๓ฆธxะ‘rศyX*ช฿~u$k(เˆ^IN-ๆRฦฑy} ‡๚€…>cำงใ`ฎ]”ฤxq>โภ๓๋\T<>ต๛ิnd+™P.ืฤไs7ญWDผ>ึ%ภ|ซฉมm‘๘๓กผr๊Ÿ5ฐ?o๕<ฒฑลŽYˆ€]ถ็แื๚Rฬศุ๊C)$v-ฑฯๆ4Œ‰>=U]ีญฝไ–C–W๊Oญฟ๘บ”!rภซtฟปZ}>œ!ŠGdว> 5๛=?5พ(ฌุ!`ป’M์ฃใzƒ1€ธป๎๒+ใ~ะ“.XZGฤ๗จ๒มšืาใ‘'ถH^|๊'k๒ฬŸซ๙(F$,d{@น{ว™๔ผ1ผยๆถpท;v๋‡}”ถ#€ฝไuŽ๊ยฝU\Y&*S‰ฤํ๕k๔bLฺฃYUฐฑv ‚Tฏว๓ZีdRO" ผ`๎’๓ต&Aขq ไv{@ไAŽ/ฤkDM‘IŸ๙>€˜Iflcํ3cq’eทๆž(ฮ9ฒ•ๅถL\สขอW6๚0ศๅ๎en~Ž2ไช€ฆVจกpศษ~5"”ณ-วณปr๘w… ๑šัvไRGgภ@๋e่ฃฤ๒ฦ€vDำubz_ใแ`AƒXด`’6๋๕~ใไ?ษjพ๚˜y์ฏ๏3VวใcCT˜F๛๐•โ‘๚C!เ*F&Cงš.ใ?3m๗ฉ’ม;$ŒพบzษธLึเFมywC?ฤЉสzฤฑ? ‰ fๆไrุTฎ_ี็k… HG!ธ>"’Lt๛ฮškุoษฏฮ Y$ฝฅkอ;ๆทc๐ุZคUส.ฮ,สํ์‡#ฉ๐lŸX๙o^B–I]๕ ๒Y%G |Oํi{งี ฯU1ฺด+บง„ฺ†HแPHจˆ๖หฏ%[S›ฟ O)†UนŠ฿—*าห‰ศฬหƒŠ ตฌ7๑ฌp2ูb ๎ฃท{ฮขržฑ,OยbH™นนถ+—๕yฺแB’๗Qศnˆฏšพ๊‘ฏ^บโว‹/๛*Gฮ ิร,‚FqฎํชlˆฦดฬBธไ››์oR3ห:มงึ๐ว A^sqต๋่็ŽแF(XฟีญSดอ Yค—ฐ,2!>U2oG—lf๏{ๅCT˜F๛๐•โ‘๚C!เ)ุ™}^x{†CพุิŒNJง…)บรaY7 ’8Hมymน๓j“’ล9์ษึiดTp8dฦฤ’H‹=7ปT-ฯƒŠH@;d]น‘ฐญM›QๅxžEถ@{ปy~O\๕'ƒq๐ทสฃิBu 5•ืฏZrHฺ๋+*“ๆ15ฉv•แโITEต฿{/+sง$‡ูผeใ,ฯฟo๐ญl…ีU‘ ฒ'0ถสjd`2iN ,ํแjMLQ๚ช{ˆ๐ู์G€ฤyS1~ร—F อพ=TTŽฬ;7žน~Žh|ล+0Gš`ผR~KNXC{โe็n[Sฎ†๛ื “Oํฃ1แไ6UพšŠBœr’pณุvศuฐฉ\นำอร.$ ๎ธ์ฑ๑จ[Ÿ€vศปs#aZ›6ข4?ส"๑<‹l€๗v๒ อ์หอi—/iง็jS‹คJU1Vฒ/ฬxVฃต‹๏‘sG$ฆ“ฒัขฆSU๊๚ฆ2pไwฟ‚-฿๚ตชโ+—}?ณ™KขdyฺฆางWช™N(ฟฃฑฌีƒ์ยค–ฑส๗ช&…–7ท๊3ฎผIลยŸี\WๅIH$‘๘ฏู ุูฏฝฌG[ึขซฮ7„”[๘X นๅา Šybบฬš‚ธว๚ธ๗๊H๕ฤค$สสะ์ตhดำนฬŒž5aฐใ็ฝ๖ซk ศd•[sM|กwLš&ฝท^\ฉดฆ†Eา9ญพOฆYnpŽๆคR$‡8#ฅ#ูฉ ’<าC:๑aโ•ฒjัซผRq7ว4V๘๘๘Š๗ฃŠi าๆ:\žVดส๘ปสธ‘U–ฬ-qอhE)า†qXSTT+‘สใ$\i ’Gโฟd+cfพ๖ฑoZˆZฎ?8Qoแ`6็—J'xฏฉƒBคF๘฿๋SCฉ‰"Y)vSูyžี~ศื๏/I ฎผyq“)€ฦ๊‰ใึฃ›Y;พ ‘ฌNํrVเm\โิpžก 3b|kี๕Iมใj}bู๐Mํห•{OZห‰‡น•๎ๅzพชโฺEำ_ม๗kSšศฎaดS]ี<ํSiS‹€ซฦีLง_ัุึ ๊ม๖aRKXๅ{Žีuศภaฮ86Euใอฺ`TY>U GXใNAU‘_c๕dํ_ญK’ส๖€ร๘ฑ็‘bถ้P+3/*1Œ6'5 <จG4ํIฏ า๋P๏ฯศoGฦ(‹I Er‚๓=ืŸ0ฯำษV๖0๑dAabo^ฑซrgTบvส๎vๅM๐อจ†yUฝ–HIฤณสyWซ๊[ฦฉ~/๔~ญKฤ๕‰ +tUษํ๔์ืซ๊‰|s฿‹มฝ๕kT$ษ๒K๑Wˆ‰สฝYfB9็3ก ฿0~5ฑะ้ฤbM@@ถ๘qGFn$Yx€ภ‹~‘ฃ1Ÿ ฟฤ]ีh๔๚˜ใิ๖.dmB#฿k๔ฌwฅ]XH”ถํ7๙’j%gpUZ6ธK›4fู[cฮธS๊5NLb๒ผHƒ่ท็่๛˜Jซ๖1bภ ใiยฉูฒฤ&ุ*๘z}_U'ฺฌ›7[ป็Zก-ฅ$ุช๑#NUBi4์ฯล"ุถ8’Fโฤuฉแj๘๗ูข%๗๊๋tจ™—‰ฦš†‹T#šv‚$ื†iuŽจw็‰ไ7จUมŠF,($FถVฺธSO8ย^mBข{5>ๅ๙ุšฺ๒ฦุฑฦส”ีคฎ ุํชb‰oวzษ))„ั#?ท๐งะL—ญ‹[ฮด฿AงyXฟ๚>‰†%ป*ฯZ}!ดํ๕–uRร์ณSiรภณ…ผ<ชษ e์q8๘ฒเย฿ณึธ.žiVX๚ด’<ืสŽ–Xdส.ฺรlญฑิ ”ฎ˜…Žโvฑหกนvƒผ x”สu}ใิDธศง๒4z*ZM:Hฬ๒ป๛?ู˜โว,ฤnภ. ๓๐๋2…‘q8’*๕ศธ}–สุˆ5X‰ฬ@]ฎ๖7ตฟ*,s •อฒoสšู1พL๏nฌnO็#‹ฺ๒8E˜ พ'ะไชขภษัฬ!rqฦฬJถีชž9W็ษขG–Xฏy;yjฺ๑jL๎‘˜ีD]ถn ŸŸๆ#xFV๚[ƒ}๛,>๊‚DŠASq๋œษ‡฿H1TEUP?๏g’+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d+!Y ศVBฒฌ…d?ซO๊ี…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…XU…[ฯ๚ท์ Ÿ๕oู๔iฬƒƒ…ฑ „oฮ๔gใ2—‚Zุ~kLาGYธ ๐&๕ ๖ Žเ_ร๒R5hี$r€ณํPจw8Œ™ฌHุm๗ำ‹6.k๔ๅ†|หใ–๖ฝผ+‹ฦ๚>นโฟระ9นQpฃใZD‘en๖9ภ/kk>ีฟgำ๛Y๊FbGุห‰ตํ๑๓จฃ +–ช!cฝX[/ขSโ(ว3๑ษ)oฃS๕‡:‡%qŒฅg8˜R5=9Žwญeษ>ซ•คฤYททรฅpๆ>ฐศ–PN์(G*cฤพJฃ๊šเjWทฑLฃˆศlOZเj;๙ด–โใ‡/าค8ไ๏สําœๅ‹ง;0็้Žฆผ]l}ไ:P๗Dะฤส็ส้k๙ะGโ-ไ @Fึ5ึ8๕Sธ*฿รzXฅ2#ฆ“X›[ฒฟ*ข‘fภ|qต ๕(ป9ฤย‘ฉ้ฬsฝk.I๕\ญ$vๆ,แา„s&๘x"ส„s&*M๖ช?ต?๊฿ณ่ิ้โŸ ปุ๑ตz†—ถž$hq^๊ˆฮtค‚5Y?๋ป_:าขภง6ํฝข_๘S]=˜ˆศ~1฿ฯขM4Lํ๚์F:U0ผฑภmj๕ /mi Š ๑๎็ร๖นต6‡Lฬฬฦๅ˜•จดzxไSส๊๊ท*Ccquj‰"฿se_KCิ"๎1Iˆศ ฯZš5–6ฤไ2Gž๔จข!ฑภ ฺึ้Q้aVSโ„ พTw`ŠM4 Iwฃan้๊ผช’$นๆpŽยคำDฮ฿ฎฤo๓ ช#ร–8rท•z†—ถด๚xa,F1ซ๙VŸ๔๓ญ๛5ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ึ๕ฝo[ืฯ๚ท์ Ÿ๕oูย๋F`ฃ๑ๆC/๕}??๊฿ณ่‚FŒฒ๐ฏbVผIZ•‚(๐ำ‰aษบ*ดส ๙oNลํ–=jœ-–W๐ต kถX๖€กฤ+aคŒ3Hมะฅฏe $ปปœUEลFู•รgน]ถ๋ฟฅ‰25น•.ว๎ค$H—ไZ7ณบปY‘’ญศM•ไ9ฐฐ๑"”IฦโIX [ญ๋Rาษ'Žี6V“ณ–ึsล๔’P0_™ฆน[ฟwป[ใภ+Ÿว•v๐ฯ,-ส้šQฅโ2‚V/ืฟJLป,Eภํ้9{7,P%ญนธ; \•าฒŽ@}ิฤ™สฦ—c๗R$K๒-ู‡P๑dn*ปvภฐ์_ญKลiLฬ๖š2ฐEšq,97EV™T-ˆ๑ƒ{o2Ÿ)YX\2‘J$—๐sk|๊6 Œ<ˆฎŒ—ๅฤฮข`ส|F฿ยป~อ‰knN'aK’บ_–QศบดฦX#e๛{ึฺ๕ํ3iธ}ฑr9ำ›ปžฅุ…vฃ—ญย”ทซ˜-v‚™9`ณ?ญ;ข•วตšตHArฑ๋QW"-ฟส +ทยฝํ๔๖รช‚Q้A,ุทUf…X™จ˜:Ÿ˜ฎ’€yŽฤ|้ถ—ๅ”mธ๛ฝ'<๐=Œิจ4ฐด+9apฤ๙ำe”ฅ฿†ธุxํ] ฎฑŽR0c๐j|ปem1G#๘Rดซฆ2ฺRK'^iฝฉ2์‡๎฿ <=-$~ฏ–ฃTฑฟ`%ํปU๖อ1&F+]C$”/ึแJ[ฮิr ืLลญหฮž๖ษน ฉฯ> –B^QโFบyไi๏l›์ั%(๏ŽLาXsจ๏`เว"+ภrk~ืk–๛oB๏;GๅBเฏMมญ๒{œEญ็FโสˆXž\ทฎา“nxๅkจ็lถฆ๑<†ีโงpwฃผrH9ศร๑๛ซ ฺรำป๘ื@\อ๊ึ0ฬ6นวำ:‰" ฺ™Ff&์“เH๑ฅู’๕X…๐•NกใQคiฃ๖gm—๑7็P(HุMฉ:i l.ฟˆฟ:/ํชŽ3ํ9๒ฺš2l๙x๚bฟI^หbปZแฎmฟฉ๔ฐ้Dˆัทฒa๗=แz๑ิ"๑ฎKu๙ึ#ึ„“.WŽnc์9ySHาH„”ษ/—‡…Lนบ„”ฦซื•๖ฅสอ2ย[‘ุr)–‡tถ{’ฬzงbq5’085พU:๑!ษๅš๎bnษ;lHzธš#;(จkTq*ศแเ•&'zXPHฤ.๙xิzวณ7tใB็Gh…:$\N$ญ ’ชEต™v4ฌUฑ}pS‹.ใใZxึ,ัมบษ{ฦ็z<ูYพ|๋๗๔ฅ4มวฯ งxฎบฑ-ฒ๏vญ~[rฉ‡kี์?–ไ‡กปกป^ชป๏ŒSฯv[\b6=h๛ญ"2ฟ\>8‰$“ˆ„Y$ฤจ์v“เmEฉ‰ถ!วaฝณญ๖็้š%ช๘‚ี๖^*qๅ Zฬ7ฆaศaฤFl:ฉ,ฑrคP%b๚…๘า๗žแx๓ฃฬฌh๐Q_ฐJ™CฆKฌ’ฦฦŒJaB+O™จPFฌึถD/ฆ•”้ไlIbฃ…Kษ œไŸ฿ฃฏฺ‚X>‘ ฑ9ว 7“aน้NฉBExžEŽ-ฑoใ_กฤโ้หyบช"™2๓XƒญQ๖s๕~pฤฟ๋›|ฉษ‹vฤŒƒ&บ฿™็ฝjะ9ใEุเ๕๋Q;Cฟ” ยยฑลz(?ยƒHืจ\ฝก=ฏูšทดทhc—‡• ‘แศท6๋็]3๏ฮบf.‹o๖ฺบ5ดwณyT@ &&Rง๑ฏัห8ษ๙ํ๓กั_๏ พผ,ฝ‘^v๐ฏะลž฿…Z<๘˜ํ6|๙ิย๗ˆฅวแQ{0Wี™;= ็Wvฬ‡2|j๖ฆub-ึk9ฐถVํŸ*™VOt96ohwTโฒ/r)T{กc‘ง’BฦKe•ฏo•ฝGฯ๚ท์๚5-")S=ž=`ผ†รtฃqงžf‰FคkฒN*าF3จSn.ญศฟw mฝ๚Tp…n๊›ส‡ัPลn_Jุ|/]qakƒใแZ•๖ฐไr'ํ๐ŽถฉwHไ“pˆ[ดT๗๛บWด\8rqSฐบkEiW-—?e>อน๚u ๐eฝฒ €๋A๗ฝiเลkโI!{ท$9๏zšแO ‹F๊l๏bฑŠขY–EJฑลฺ;6Lึ่9 ยอŒ‘๗ิ‘œษ~dๅูR๒/ภ‘๓ฉ†ฎ›คs๐ฃํ•nื3D\๑ใ~/—๔š๙:Šๅฅf(ไœล’ฦ็ฏปส ghํ#ไ,dU?…jิคD!%; ิkZUลV<{Aฝœ}}0<ฌ๊8ฯ'ด‹๕‡"h<พฑVHw\1ๆฟ^ต ๐eฝฒ €๋A๗ฝiเลkโI!{ท$9๏zต๐xไฦH๐ธฐ%๘๎หvำkำ.\'šฑPHไ6ญ$mร:…6โ๊‹๗r&฿ฅioŒqลoUeษWด–•–xแcบƒรf_ฒ๛t59$ศฒ‹2 ๎.๕ฉ[M\อš7์Ÿ; •™ใQ ณC||oฮตƒตฎ.Ž6eq~ข‡ฝภ;๘€ฉี_Mซu๙ำๅ๋.ƒม–4kก~ฆตŠคHŠถธXุd๖J๖™’^3๖L@ํx „Z'lŠ Sฅฝฺ<ฎษˆฝe'ท#๚๘Q-ฤ&ฬ;ึ๋ใ@๖ฎๅสบN่?j\h๎.ง˜๑๛V9ZึฟSฮปa–`ysฃ๕Wwต@z9 cฑˆŸธ|‡s(๋a[๑V>@_ ?:Ÿซ_›lใ]ฎXp๛œ+r๖b๋์๏ู|ซด,–‘บš„X๏์-N`๔ถว—/uA7!on{tฆษYWp™รฮขซ๛›๐ื๘ะšCฐ8๘ 7๗~Bรั๓ญ๛?•`ืŒไป๏NฦIdวป“ƒ ž…ยฐฤ฿c*Y‹ฃ3 6๏Ÿ้1Hwต๒ุQAผ5ว,ป[P่>'Ÿ™?™g๖ys๎แ่หฑ๔|.๏ระˆต๏ฝƒั"+€|l฿œ1ฉ‘~ฯำ๓ญ๛?่#็Z?VฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjๆฎjีฟgัฆXšษbฤ๑|kW ^8๑Rฤ†[ํp} ใ๔ำ,7ฟ–W๔Dป4ฒึู9ŸีB‚‘ปฑ๑bfž€๚ol-“#๗z ห่%1ๅ๓ทๅ€0ˆฺ๙หs๘TX—ั‡+ฑฉdฮSœำzฌซ9RCม๗๗j3|%รึ5š„Sqšlk๙CSืCฉn‰ i˜๗‡ณ๒ขI ไๅ'Z 8PเึQจี8hผ,ท“ๅZฉำiโ2ร …ๅ๏‰&ฃOฉšA บ‰ฤ2ว$,p฿+ฎ [ฅZ๘ทฉฐcแฮต:ุ%‹[6ิqใ:‡‹•ลv@฿gัuแแ+$‹^๛xัv Šm@๕a‹dฉห2ฃข—ตiQคŽ๗ (pภฆิาgจ–d•fอมๆTtจส„ิDy&กX˜ตFT5แJฝเzC€๕xธIรxsนญ$หS1g*สlวฉ[T/…›€–็q|ฎ ๏ฝjไY81ทxDT ๕<่ฐว4’๑ณ‰ะ b{ตช•XBญม#U=I‰N ๕ถ-&&ึ๗ถฺ[ณ้~ŒIqหฦ฿…BณŒช#‡น“T˜˜ฐ‚#U[u{š›PO่๏І`ฝ1@ึฑซฑซฑซฑซฑซฑซฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ฌMbkXšฤึ&ฑ5‰ญ๙ก#2= \ฝใฬ๚^as[8[ปuรŽ>ส[Œ@ฬุ:DYMpโŠัฎž' Œ!G6?ุ‹ำ้;7๐หo๖9p,0โzฟf๗ฟ.–ˆ;ฅ8—~x๕๘9’kPŠ๙ฉQ€[ว'$0ฦผX๕e1ข›|5*JบxBœZ๊,๖นทฮขหร˜ฦ-•?'RŠKใมร(คๅฺฟ*X`C‰^91"“หฏๆฆนŽ๊qld_`KoะRๆจ๘ š3—*mฺ›ลปzm^7“ูŸxฟฦีึ)Wณ,GเทลMฐ~ขธซฤณiRฌฃณdณRท3m๑|V๖จ$THD{e‹ื’ญฉอ฿…ง”ร*๏nEoห•ieภฤไfeมลPZึ๘ึ8lฑwQ๏[ฝ็Q9OX–'แ1$ฬŽ[ •ห๚ผํpกI{จไ7ฤW๎อ_wฅื.&X๐ํูn]ชเ๐ฉEƒฟˆระ{ฆF์EดE+ "แศaป)๓Sฒca@7s€qFwํ๕ˆฅ(ตMๅœฐ9 cŠ|i˜ถwŽTRํิ>4šˆข:XŽ๊ žึ๒ฦ™‹๖ฆ#ƒ6๘ทdQสO–›MŠ‹Z๛ใพ๔์X๗MFIแฉM~!yekโz๋Q v“9๘3ฌ˜…b ›sกอKง!๐ฝxดณณo+ๅ_ภึส;๖ีœ‘AกชV2)๏2๐”r>gjˆ”ผ้Rชใ๕ป@ mหN–M%๏ใ’\jWcxแS๊้ฟึ7?:IJ 2”แ‰ถฺ‰%ฅำฑdๆwฐฦโ5ฉŸณ’N˜/ณ่oฝpู ๖ฑ”ฦ;นฐ[ํตFŠผI@ZGท2|k๗ทฏๅญ”,`๖ีœ‘AกซW2)๏2p”r>,vจ‰K๊#‹9Qq๚ร 6ๅงK&+lฃน๘ิฎฦ๑B„i“ฎn~ีG)AฆQฒ0a๐ mฉ‰-.‹'3ฝ†7฿*ีOุฮ9ำ๖} ๗ฎ&ŸFcย;ศlซ}ป4D“ฒvwv็ˆง๏Jx>จถ๒X๛ว๋|WŒ iโyŸญvฦ0Md0ยุKู–@,งqฮค…ั$YaฤœYญpvญปล'|sEoˆฏz8ฆอ.cฅษ)ๅm๋Lฏ‹ฐ์ซ‰Ylยืึ„R(g•…5EBนฎ9ุาEฦ’ $~+๖Bถ6k๏kึ๕จ€Eชใ๓แ%nytจwŠ๚˜1$*Doต4:˜’%ย—e1—™ํz`xึlrห5oช+ง ค นคTแ่็‹๗ฃb<ช+BโW2(‘รnIุ๙mPฉโhH‰ฟlQkQ นCฅ…C… ถ;ิ๐KJ=bSxฺ@2ๆ9R้†กZฤๆยyAPญ{–:ำ+6‹I™:ฌxชธุ}J'xOฌi,ช‘q-cฺ้Oฆ(แMD Z.Kฬ๖ซ/ซ&H–3{sจ`–Tˆzฺ5ไtxืีโฆ!พ\้ป6”บฟภSๅ็Z^%แลE‹๐ั๙ืซ๊“…ฤิํŸ฿ร•vธ๊ฆ#ุ)`Xก=Tฺtำ—hj-1#'f๑?=๋RŽ(Š%ไ ืQC’ธh@†*ศต†๗๑zZขNฏ๎‰าวŸ?ช:๚พฆN7ตWูธBฺิ‰m)&ุฏ4ๅQฎฆDuWฺeE†ฦ๖๚๕"jbHืQ9s##Ck-ฝ2‡YงXฒy+าBแค_g!~ฑ ฿ ztผOaรว๘qฟ{#o…zพช>ตim—฿ฝC#:‡ำ›ฤRภฑŽ๋o–ี64ๆF€Œกาฑไf๑?=๋Rฬ"‰Oฌ*ธ“{|ฉษร‹Iหม5TPD†.ฃPAลY๖ฑใ#จๅj†>วO๎B[˜๓็๕G_WีIฦ๖ซ&อย๎๙ึจKiI6*ผHำ•Eฎ )E{#dฑพYscืฦQ]Jรฆ60(|E^ฦG'๙ฑุQู6ั}๛ฟฯqnwแ๓ฉdH๓> Ÿ:‘‚"Yฉ:0๑ ต‰&มฐๅ\Dใ[๘|๊Y<ฯ‚็ฮค`ˆฟjFŒ q‹nwแ๓ฉdH๓> —:vฃโอHม•‡ˆaQH’b|โ'๏ร็Zcvแ_ ‡*โ'๏ร็Rศ‘ๆ|>u#E๘ณR0taโj)Lƒaสธ‰ฦท;๐๙ืD๒~hยไ฿๋qศ‚tฌ€ใ-ณWYU”๒+/็žฑH๕ญ๘yZตœ)Š฿Eขชจ๋ฐญCคDoู6ฤว’ๆฦีงtM<ฆญฑ%r๗ฐazั๐ใ&.‘ศฎฌคx\mY<๕๚Gฌ}oรสีฌแHDV๚(ีUG]…j$‚#~ษถ ถ<—66ญ;ขiๅ7ํm‰+—ฝƒ ึ‡1tŽEue#ยใj™ณ•ู7yฤ’OขPC/ a๏)apl^ดœ(ษ‹ซซ)๕พ?๙=ป฿‡•ซWยr"ทั EUQืaZ‡เˆ๛ฆุ‚ุ๛น“jั ฿ตถ$ฎ^๖ /ZNdลmีี” Šศz฿๏รสีซแ9[่"ชจ๋ฐญCฦ๐D}ำlAl}ษต@่HoฺW/{ญ' 2b6๊๊สG…ลd=on๗แๅoษ†UMรuRยเุ0ฝh๘q“HไWVR<.6ฌฟžzว#ึ>ทแๅjึpค"+}jŠชฃฎยต’Aฟd[K›Vั4๒›๖ถฤ•หม…๋GรŒ˜บG"บฒ‘แqตe๓ึ?้ฑ๕ฟ+Vณ…![่ฃTUUvจt’๛&ุ‚ุ๒\ฺุด๎‰ง”฿ตถ$ฎ^๖ /Z>dลา9ี” ซ/็žฑH๕ญ๘y[^ฏWซี๊๕zฝ^ฏ๙ซี๊๕zฝ^ฏWซี๊•zฝ^ฏWซี๊๕zฝ^ฏrหฤ/!1AQa๐qม 0‘ก๑P`pฑ@ัแ€ ฺ?2๛!๑ฃ ูอt๋นณล๙#]จŸค@-\dž‡ษM7šI›&aoึญ—@คd‡สGฌ"•ูย~60ค&q.‡S๒ฅ€fจ …แ€ูศ้$Kึ๓๎ัhๅ&ซ)@;ๆ%้‚mฐ‰R?ญ2™y$+มžไ€&๙C!ุ๋bMถคIษ…)ส2ย ษฎพฑ TyฎฟิCฃ๐บy[‘rm0๘ นgUด{็JYŠ(ฦบ~ 3˜rW ต“"‡JŽฤ„F#๔ฑI 2ไ#จVŒ๖๔{6จบ๘q|Pb‚œฉ5งpขvvส5฿)QดรVด๎—U2กs฿‡้ฅเpl$’ท ถx^R(ฺlฉ$ฐ๙U…›ˆ๕ ฎIZUO_L!idˆกv•ๅ๎๋šB^ู%ถีI$škh2&a8ต ฎไห@guบ@:ˆทH0ร…ฦ' ‹อ%จnณJ กญd๛"4„’FAย—€45b™ด„๛I'ฏ\IX~jx:FJห0ฉ@HIปˆ\๑pzˆAบg|PฑP„๓ษโŒษi|˜,v7-„Eดš eดQญc—wฐษก“ๅD{บะ`+M= กl*ใ(ใภDฤู”Œgฤe ๕ฆ1™๏ถคK‚ฦNญZำบ\Tส…ฯ~ฆ—ภฐ’w฿ED!ึH5จ5™แRฦ1ไฑ‘t๔นK[โk๐s๋pเA1ธ}๒ฟ>แŒKฏlb Hjญ~ชเสŒH ๖…K.สม(ž‚CŒ9œ Zฐn.2'„\47ฆUผ…ขžh'I7yฮวzนQมพ8็นFช˜@P.๚ฆ8”$ข‘฿5กคๅDณคbฏ๊˜ง;ฆค2้ผO‹ข8ั œษŽc9สญ;eข™๊[™&†ษไ.Dte|ฟaT"aYฤ!˜ ซฦN ga†VปQฒฟ  hฐ\ำขbอVW:้๙๐'3 X#ุษขƒNโ \7o๎ˆ™ละ6D%๊ถแ.b!ˆ™_ Vk„„<cดา%็่ฑช.ว๚b †‚œ*ั‡ŠผF5๑E“M =๖D็ iฌ0FP“—p)กp–‘ T๚~ำ,‘KdมxAํi†ๅŒMมY,I฿9ถWตภfsอ+๙‹-0YกมœAฉ‚ิ I›˜nFยZ”ฮŸ€€ ชนrงwญฮ ADดDA0Gํป‚ษหZb<}Zดค(์ฑbŒฦ๗agLะ^K›(เโต%’ซึจ„Dง‰ม‰6เ€•G|{โDšฦยy+\ ศเ๊‹าŸุชเ1tF0›๖รจ‹ุT้Š;CFฝซ๕ฒ*€ฌฬยไA๖~Bˆe98๙8ฝบpฦฒ3OภA๋›ฒ๔๋ชร#@’V‘แม'œMะ๗bR๐(.๗FW๒qปIขˆๅˆ9ฯ` ŽHฮึT ™สfถ…ฤ›—=E_Šโ„’H h<ด~˜—นัุฃฺแ‡?ศLุ๐๐}3 ยษ"CฝaํซDLษาP๛1Ghhรต~ถEP™˜\ˆ>ฯEJ*…ˆJ้@กไPะ[K็ ฮ.Zhํ mEฬ!แฝ<เ”hงdอ‡"a'บdIาyษkIjาศ2aช<๙Iึ{Gะขท‘5รงัŸœ่อต๘…ˆ ฿ถ0๎Lช ๘ 8zxพ‡๏•ฉ;!6ัzโวฑ’งญฎ‘5พ(฿;ฃ.KŽpŒ`เฅ6y);ุฆ†‡E™ฐV‡ฒฯ X|Ff _ˆX€ญ๛cไภJก žพฏ็ฤ“ซฌ0A?-มbaสKhGะdล68pฒ๏9fฅฺแ้LB ;ณเส$Yฮบื\–P๐Tฉจ๖๋„-S฿– R;v—yhฌDฉ&D๊]p๔โ๗5ล nC ๙ <8N@18DลŽ,ข_yฒRงีS^š‰่ธMโ[t]zสphลคIŽ˜ษ’4[ฑ้&`/a‰ ™GBFpญๅธFว ƒๅŒVPี๕(Uข•XOว-มzถฯฉXเg๋๊“๕ร:)ีงณg๖0 ๅe๒Aซgฮ`๛๋[ƒ๊I*๑vH4ฃ{9wะ+$+๚ฆq6Z-ำ๏ฺ.Dเ€ค ัw—fgเŽdฤKMV์]Ty๚ํฒS3จฆ9ž+2ี–8รAชศญ g„ p๏7 ศƒฃ4dจีณ•\ฮbAิv(ฤ–$ณฒ#yhวฆ ู›๘ˆ'K\ภยPภะT@“%ฉ\กํ 7I}k;Ycดh ใ7๚ำ”Šธ0ทxซ& ซ4ฑั–๒3ๅ” ฤลŒ๕<๚ƒv?์ฝiข5#เ…Kd๗Lž:d๔HQ$ ใำzีf4Ftลยฅ1๓›€ซ9ีงœ>(ฯXNำlQzป—"WฐศŒLภ“X:uถ[i(ข0I€>UฤูhทOผ hนw‚@'E\:#๎๑สิฎzิ5)ฉชฤ"ญค๋รVpCN}`i Xm-เQQฺFSrณnHh p0ศ่ค๛%*_NฉโะHdoy%w&Kี…’/€ \qw^Iิ™oK€afูH P‚๋•6 ๙ห๐hG›๐šมIH_rใ‹!ง๏Wy๕V ‹{‘่(ฟH๚Dจ^Aฝู|็‚^ศุt.H)—าตๅงlšZนEิื๋y a4 โOพ-1ี$ฑoเ@)งbB‹Zฌ#๑?f$!$œHษId…glส4[ 7ฌฎ H่B๛—|Xq ?zปฯฌ‰สฐึHขฒ†dฎ„U)pไฉฤ‘gJ{pˆฆฎRู™'๘ณถ ”ุˆคdcา๑ขโ“ฅ€œ&ฐงไI‚W$โ€œ„า@ฐยŒd\oป!N๗^5 2–ตฒp์เq็” 4เท&ฦOA~Š-ขฮB€ฌภH›ุ๊ƒนI ๅขคชล@ Udธฅฦ!ดU•ะ"วUฮ งxHX\6CœƒKdึƒ ŽDณ?€v*ฒ'eยCaJUซฃuMอข#{ฅ้:]าyภ๕:;„Aฌ™O`G "xล˜ธัG&๔8ค7†่‚X pbญP€ค@ˆ๊8ํbJ*้‡๋‹tฅ ษ”า่`‚–ูิ{ร ฎอฑๆ)…tR๒อโสn@1wŠ'Vฏ อ๘kฤิoMT็๛wด๖_ึjฟ)่(๐t!ฑไษ๕iน2แ4_๕uUYUีvช`6๖|hมvsFcz๎l๑~Hืj'้ W'„แภ2SMๆ’fษ†@›๕„ซeว†ฟะฉ?Œั ๘LL ฐ@  DdGHfŠะBlณ?aBŒ”D%@ F6ฎ6BC`d˜F?H}๚ึ‹ŸสดH๐|ธ๑Q ฺ่-้SGS฿#ฃJ•o‚Pภฟ„๊น จ‚6oI,lM'ไย๖ภfแ@๗อล~ Mป๛zt๒ท"ไฺa๐Asทธ5ฯ๎H น๊ฃ=ฝอช.พ_$7˜ ง*MB)(ฒwวŠTm0ีญ;ฅมLจ\๗แ๚ix[ $ญร-ž”Š6›*I,7>UaAฆโ=d+’V•SืำZY"(]ฅy{บๆ—ถIm„ตRI&šฺ ‰ทNAํFkน2ฤnขmา 0ภไ!q‰ศb๓Ij†์าƒhkY>ศ!$‘†pฅเ Xฆm!>า@‰๊xA๒Fมไs(„ "ƒปก/ ‡ ึXV7ฯ€้oฆ"h)b๕1€ป9ฎ๋•ซ&ภจ,จ+Œ›™"่ุ9ฦะชX I…โ๖•ๆ=ํ"๖ชpธ#ฝง‘-(}hb†ๅ2ๅ?FOP;Z\)0hะ†่jQ0ฆ nฺ†;ดrPง๒์™0u`u?5๘‡`อๅ ่ aLE D›ฺ™ฅ(LPโ่3/ช6ฐBKง,S:pฦ"ำŠpม๚Œภ^•ˆ๏d YEึาa"ฤ`C6่฿ก๘จp9lฅ?๎…OTเdง›“าผ„กฬ โ2 ช๒€ฝNฑf†ชภฑ“ˆุa•ฎิlฌf๗!%๗หy8Zญak%$ฌŽฏฦ4”‡.„กย๐ฬำฎ "%œ;ถ๚š๊pjัV!‚00M#M›ผโ'็ฝัเ2I1๘K“š“ื๎]ฒ.๗น†`(jฌ 8†ZํFสศSJฦCAVAช…S,ะญ†:ๆฤูิw…‡!ฌ่่ฌิ"uธใ฿ีค๊6ธ\๛ŒบAญŒƒYP”7ุœาr1ุiJๅ”ื"€€Lง(ต˜r^ซnแV"‰˜q•pบ#M๛aิE์*tลกฃ ^ี๚ู@Vfar ๛?!D2œœ|œ^๏]?ธcYงเ ๕อูz uีa‘ I+HŽpเ“ฮ&ฮ่{ฑ)x{ฃ+๙8๎คัDrฤ็ฐPG คg6pผ_F7๐“•—ฅœ๛ญ˜‡๚‹' ญย –ˆ๋ผ”“n0๗=™%N๐Nศ^รขิื‘นŽqศGัค$าS„RสC`แำั0ๅ“i]ืส๖š™?ร๑ F^‰ƒนฦ3w„…uบœF0(ฉB๚฿"อ'ฅ’โ ๙ฯ;ี‰l๕€๐ชล์ภฺ”พฟฦ+ I % )อชฎDŽะธ(ษ™XPี0V‡ฒฯ X|Ff ‚<x๗สญึI ‡ใ%ืsซ/rฉิCท#ัฮŠํ1<+ศ๋ภ3@ื,ขค€-ณแM˜H%ˆ7]ต๖ฒ=/ ษ~ตœz$%ท@UืชLหM๙…ๅeฎ>Dสณnซ 5w^๘ก์๓ยV‡ฃC?oศDTipa"ช"li‚ ซc๋Oฑd‡^xŒุ“ิ”eะ^wh๘ษpฟP8ŽZKlตcAœ&ฬPnฒฌ2ยˆ)œL‹ณRํp๔ฆ~็๛€“‘ั‘‘ฎV_$ถ|ๆพตธ>ค’ฏdƒJ7ณ—}ฒBฟชgeข>๐€ขไA Ayq6f~ๆA\DดะEnลีGŸฎ%=ใ:Šc™โณ/YcŒ4ฌŠะะa–xBN๓pเ`จˆ:3FHQ{9Uฬๆ 4GoยŒI bK;"7‘–Œ}สj ™ฟˆ‚tตฬ % D‰0BZ•ศฺาt—ึณต–;F‰ูพ2žืE›41`Hlล€ิฉQจ…ppห๛่รฑˆ ยƒ“#’าภวM[ฟ”˜บฌ6’PๆŸ8]F๒9L'ณ"˜๚โ๏]๐Ž>ZนHจคJย โคA๖|_œ‡ีฒฌจสส฿ฏธลฟ๗’IG ฦNฮ€ป ฿B8ฝษB‡ช!KตŽ+จNs ๒ฒฐ]jเ$เ๕ข € ขํJ I‘ยetซuPZX&Kฤh4žณ็.ยv†Wxˆ )ฦหSzqE๗xxa๒รขภ/Cษ™F 7ฅ”ๅ๚Ciดสถ-๗ฮI*Q|ๆ*ไ4c๊9#้,ฌํ™F›ซa†๕•ฤN๑ฮธูƒภee“*ฐP1sf๒งข‘$-r%ฝฮOฅ%ฎ=ูฉะ็!hงfๅ่ฎจ๖}8 ข้!˜šlา*™7`บฤอ–ศ"4ถL๎งฐ@ฃ…‘ภ\( {oŒF4R‚lธ )ƒ”6รใ<)ถƒหุ†F3mอ๎:0‘๘ธP' (2ม%ฺJT`„–7xK€…:€pกƒ‚2ม&ๆ‰ฏ&A1๓M,ฮฬqะq,ฌyš”สS่ฎ™PXž>ฆ!ึฦ๋Yƒี2 s แะซj<Šาw1ฑศe1ฟVก;ยย>)’2 ด>กdO=—k ZHัทฏ่ส๘โบฟ.! ่2บั๓@ด€ว]\“ฉ“‹'Hˆ^ษ่n% ู็ˆzU F•hฒ ฑ<|6LCญึณชd@ๆA๔฿ๅ๚๚ŽDัณ฿`z/แ3 tZ“’1K‰‚๙!-า,@Ž 6dkฤvK=ฺม%•/La –ฑYตะ๋V”ฏฅฮเ!N (`เŒ-B 6N๒ย lยถiพŠไ\O•อ6†ฦ—ณYŒ2CsaทพP>ค 5ก1ฬr8X๙:Šฦ#ฑ6 ซPAเ†มุZๅ›|7`Œ%C8–†hœู“&ŽPฆxeคฦr brำิo!d4k lD8=๖#œyŸ%ซ>า๗kื5[ัไaD…‡gˆฐjึจ0ส๓ ฎ˜7 ถลLdฑBๅ;›tT@ฦฎa#%eIWœRฌีณ‚bทZIงฑ๘‰ qW(z&รป๊8˜น#"ไะู๊ฦ๎%Yƒ&D‚Q8ซ|Aด,0ํ  Hf}…ฃํcพทH์,B5paŠ|€ะ3W˜Œ-‰ด5iศฆXFพศH+คฎ ŒŸ=Oธa†โ€ีศ:AmKOcTakผ่เpฅฉiTy"œภ—Nก“#.๐>ษขถห&fh!ซA๓๘b.ฦ€ŸUm†Z&“ljหสฎู9†ฃภิำ’3O๐@ล| ‘ลวํzhuu"‡X:=`IKืžุSmbPวฉะ† #xzฎๆ[!eฎDด๐ะื7”ƒX^•;ข-ถ\gอ•คิSบรฺ>ไ.E4TฬCIx>q—ธึย‡๚F)ŠRฯแp's“ถ๓อS@ฐ)Kด๔็ฎถXซญงั ฅซF T๊),D;HUƒิี04i5–์b;่‘Iจ๋VE8ืMuมฤtLโPตŠฬJe+xฉYw^์ลcฬˆไ‚๑+”7ุ “ุ@รฺ>ไ.E4TฬCIx>q—ธึยผ˜ค–)ำฦO&ทฏCb>=NDAัไ"qฤ“ํส_ #"ก9ˆร}‰]ุ‘O8 —ษ“›p๕มh&ช†ทแใœ‘อg๗Dต๑ว+ฯจWฆ7‡ช่๑`ฒZไKO syH5€ช>l™QฎO:๛ฮ‘—ค๙วโ€uก0mN J7Udไ\R ,ฺf$rะ–LCดdj‰ป bzถ&ž์z•oฐ#พ๒ญ:๗๒)t`๚ลท”HŠ€แ‘A/ฏ6งž›ย๐ IGKฦ"๗Sลfฝ+wตœ+€šชƒตฆŠ๖ภž“ˆ–Œ”ƒณง “f yลฐฎd4•c,Sยcˆ* >ฯ#Rก{^rๆ$zใ .มตŒ่:6m–ขอวเ;พ”แ>ห๔L…“ถฉ"ตฎ|xQ๏8ค‹qwคNeๆว ๑ •†ๆ7โษลอฉ?บัฤ][ฤiˆฉ^F„ไกra ฃI90%ฝด‘ฯ-ˆƒจmฉ{สHmSิ;่ร๔P>uทึ"nฦ;4ัฌฆ”—Dๅแd๛eคภฅโ๖R เฺ์%๖B0ำžฬฎv/v๐ทศ’ 24พุK<จเ AŒ<๐ปผา‰!R' ม8W?ฉgf ชวชh๚๊7ฃVฏ7J๋๎สu^dFŠะงD„(In฿ษDเี<๊‹Iพๆฬดh+j9ัdช<'๛Pธ&˜ัh D[<™Dกฅd~ฒ๗ =.ร๒ƒ$&vz๘ˆฐ"ั๕ Iง8{K›๙„นDic™…มบฤSบ~fwSwrฺŒ’8X๕ืqQฟส‘#คDy5Šธ.wภVวre%ฅงไ T็าํHv&K(‡ คq๕ัึlQeีถK'TŒ่Rข)มnzฅTPกSิ‘แ  žดmอ d{^N-TB\t9HปC้xฤ~ ฎ•{ศฯิjฅ]kL๕ู‡ถNถnฮเ:zeosDH๕ฝษฌทaฟV20ัŸดaN๕ๆ~SmซR"iค0ๅO^วญืtNiyซ‘ุj*#Pภชไจ@ฎ์ˆx“๒˜Jƒพbdไ๊|๐•ภLฆ้Lึ{๓‚๑“œaVๆc%ดแ"huเ_3๓z^jไvŠฟ_๘^X&๕‰สไๆtฬA+ใ ฦ…ูยฉ(ท/8›ซ คb ๖ฒT`„–7xK€…:€pกƒ‚2ม&ๆ‰ฏ&A1๓M,ฮฬqะq,ฌyš”สS่ฎ™PXž>ฆ!ึฦ๋Yƒี2 s แะซj<Šาw1ฑศe1ฟVก;ษHˆ๛zR๊qCํฮ{๎ ลpI@ะ 2D๓ูvฒคz๘Œฏ€n!;ซ๒เžqกC/๛ญ1แ` หH uีษ:™8ฒtˆ…์ž†โP ๎x‡ UP”iV€+* วร`tฤ:ุk0z ๆDdM_ฏจไM=๖ข00วA…ฉ8#ฑˆ/‘’"ฤเฃfFฐLA๗dณฌขYR๔ฦษk›]ตiJ๚\แ.๊ย†ยิ ณ`$๏, เฦม !›f›่ฎEฤ๙\ำhlirษล-(”ฐ์คฐอbคะ#~`๙ŽBG 'AXฤถ&ิj<๐ุ#ซ\ฃso†โฌ„จgะอ› ๒dัยJฯlด˜ภ.ALNZzไ,†``ˆ›มปมฤs3ไตgฺ^เM`:ๆซz"\Œ( ฑ๐โl๑ Zี[dภSใaถุฉŒ–(RงsnŠˆีฬ$dขŒฉ*๓ŠUšถpLV๋I04๖?q!Ž" ๅB$ุb๗rC^ถส9 ]~ฦ้“F ฤฌ’6ืfˆ-๗=ck0*C1ศHแcไ่"+๖ฤฺ‚ญA€c@œาm(เP@O{w๘ˆ7ำp#œฆ2โฏ "ฐŠฑq&Žณ"CลŠLcํ vษMDซPP8kฺS้_yiค_dศ$ข5จ4ตฉ€:y7^ำ aใ <%žl[UU`ชbํVำ„"jื๐a<ี(Cƒมœใx ุ๔wโ'BZก์?ต บบ‘Cฌฐ$ฅ๋ฯl)ถฑ(cิhCผ=WGˆs-ฒื"Zxhk›สAฌ/Jั.3ๆสา๊)aํr"š*f!คผ8ห‹kaC#ล)g๐ศ8นษ ๙แˆืมา˜ŽŽ'[E๚พฤe,&๔ใ*FR5ฃ*u–"ค*ม๊j˜4‚šหv1ฦ๔Hคิuศ+"Œœkฆบเโ:&q(Zลf%2•ผTศ,ป€ / vbฑๆDrAx•ส์PI์ aํr"š*f!คผ8ห‹ka ^LRห้ใ'‡“[ืกฑง" ่๒8โI๖ๅ/ฟ‘Pœฤaพฤฎ์H€'œKไษอธzเดUC[‰๐๑ฮHๆณ๛ข?ฺŽ๘‹c•็ิ+ำรีtx‡0ู -r%ง††นผคภU6ฬจื' }ˆgศถ—5๏ม 21ึ*ค‹bำดไ\R ,ฺf$rะ–LCดdj‰ป bzถ&ž์z•oฐ#พ๒ญ:๗๒)t`๚ลท”HŠ€แ‘A/ฏ6งž›ย๐ IGKฦ"๗Sลfฝ+wตœ+€šชƒตฆŠ๖ภž“ˆ–Œ”ƒณง “f yลฐฎd4•c,Sยcˆ* >ฯ#Rก{^rๆ$zใ .มตŒ่:6m–ขอวเ;พ”แ>ห๔L…“ถฉ"ณŠึ:~ถม0ฯผ์ฬ.pณƒ‰^ƒ‹aษฮฒLP&าmy‚ 6™‰ด%“ํ7P๑ หฒครฯ œ’มbœ ๐ั‘^(‹:tซส0ธ <ย“ปแDรIแิ ฤ์]ไ€xjรm…ะŽณ+ˆ“กo๛ูศฟ–‡ึ๙7ŒงXZ๏ู9Iฎ>๋ํฎฦฺฝ‹hชคฬFa7‡ญเ'n๐S7 z`๑”่ฑB%4ำpCศงœAF‚LŠ ฤ๒p8ฎzุ'wหFษ=ฃ>_%ม4ภ ‹E"฿๑ไศศ%5+#๕—น้v”ˆA!3ณิhŸฤEˆ'จJM8yรุ2X„ุF฿ฬ%ศฐ8๊#Kฬ. ะv"ะ+๐ป3บ›ป–ิd‘ยวจ–ป๘—†,Iฑz ‹ย ,ศ6ฟ๏ .[ถY #ฺ๋wดฮ[4pว %P)NNNNNNNNNNNNNNNNNNNNO–”$†ม?ฃ5,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒห,ฒหค‚ฐ๗‚ (ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ฆ0ำ`ผŸใZ๒;งัF ๑ฃิ๚&5ฮ#ynฑ„พ๖๘สา(u0๒E€h3”8ี๘`ภ“่d[ 3Eฬ๗น{‚ฯ "@เn~พhGเ&Qำ:อ‰yz'’ฏอ`†๔ึG ๎ฯ#ท๚yท๖MK%จ’ด‚dณ\x—Xฬ–&ห๛ZบXZcŽฬ)ขบkœA๚ z“aDช0โŒ#ื/ด Gˆ2๖ต84ำฎ”DบY๘็ๆ๚ฝhฑV&‰’MžcXค‚:2| โAฒ(Uชž>Rˆ” ร" ฉฃๅlˆHฝndœ–we]ฐšโุoตeวtIฑHŠ*;แ ๆ–…2ภMษIGเบ"Lไณšœ”ฺDนบำ%<๛c`wqลGฎ_hg๏a๛ƒ6TDบ_๎ษyฟำ่๓สBุz1ษ“\ฝฃ`I xู’“กVŒx5xP -๔‘ํpEMลฉ'๔มธใƒ๔ทฑx‰eมTHุ๛หี๗+์–คซœDฃ\๐Œญฺ๐œ:‰%ฬdฟ์ู๑ž™๚&ฯาทxฉฯ=1*็8ษ๘“ฒ!f;sƒ™t@Ž฿ƒญjกล~;น~ฮ๋ SV}Œ‹๒OZ|@&๎%ๆ๕kฐ๋ฐนฅ' ฃตŠกlA;ฝP๏ี๗+์–คซœ{dฑษ”!•ป^=lT7gฌอhฎP-๔๋๒;งาไ4„ ๏ ˜๔ฏC•‰\aว๘.อฮh#,n$ฯ*9œVฒฎ" œC-Œ˜‡๋`๊ะ.i Gฅี^๙ 5._?HJซjใmน<‰ กŠsผไ I:90ˆพฦ Zหี๕ฃ(ฝ'ฎjด๚ฆจ“x#XQQ Tˆร!y @ฮlsU1 pt_prduจ๑ไ,bldฤl?[ @คb“ESานา๗ค™Žฯ๗_‘5ฏ#ท๚kัœxฦย๛ `ZิคDหฮ๛แณม!:T€CtI ‰Zฤ#ฌ,ศ,้——ˆKก€u1[x€šW ๙i๗ิ ยถฦ+ฮ1q"ส“ŸPy๓;t:๎ƒo,๎dm˜ฺ3ปQ+ ิ2ž๎u ‹สDฑ2uGศdฮDFXgn\M}ำฏ`cฺ;ฎlึส‡&‰สณœๆrˆYโL„Vœ[’:’  ŠฦkคhŠyl{ฬญ’ †o$%œ @9hศn๑ฤั ‡"Kn6)ต"ƒeo;๙ัWŽุ‚T dPภธ(@-Uศป๊Ÿ#็˜โ ใี”HL'#IG8HžštQคliยฬCฌ"xผ^xŒ›Q^j\นACi`๎ๅyฒ(H“ื๙…ุเ๓}๏ฮ1•<0ฺ †AŸp์ฮห฿€๒ฐ€Šภ, ใตRแฉ—.ณ›DณCƒU“๖E1†ธ้๊๛ฑ๗bฮภPD๗ Uุ]ุฃ$๗ งาโแE0BMุKŽT0q„Xเ@โt Šโ› Šูoq™ŠGงมsVRcŸเ]6d”๋ืTŽWนยpB@๖cีa~๋bL!Dรn~,5 ƒมปv,์Opล]…Š2A@pล$“Mฎํ‰‹็ท#&_ฌฺŠ๓Rๅส Kw+อ‘B@์žธ=Ž&่ำขLm^x้ …ซ—คฤลงtœฐี8&ld๋ ˜˜)ถjnbUยAฅฺ ˆฐเปy ่ฦgภ„<œ$C น ำPแป‘xhฌ K$ฐ‹พ6ฟ™KyคCํ= 3ข$VbแไWณฤ†u$41ู–ภlค‚7nmLท€ดw“3‘้XcNNึc๐ฯช…? !‘๓ฏcฑ๘ๆGaืD€^x›รๆ”nŽ"x้'๛  JOํ–ภไu\ ฃbื"๐cz#AD๔ด TCRฎTฒ๚ฎฟชฉ #&%œpชฃ&ๅปoๅ!TM~˜ˆอฮ๗นo9ฮn •gก>ฯv๎/“าDƒ์ส•๑u„>ฌาทไิ a็ฦ€Djhพรๆ34fMณีœ>W˜,L!/ฉ &๗เ{r {@Z•Vo v(๕8ฮŠ’ฬ๛C อ๒aub?6นiP%็กYYี*๊๛Sภ}๊ฒ1H2s๖…[v]tจล๓>คA!ด๘รT,@M\K†1ลŸ/2LHบ%… B๒Qชไ*…๊>ด๋\`๏9วNเม-Ž= v 52ใ%†`กˆอขณ6Vc7-฿บึด= &‹๔=a’tท่ˆฆ[”๚ฮ‡G8๔ ’ศฺท#Kฮ’!๗ตvu๐4ฮ#ŸEPโลนsฮC๖5ีอ†ฏœํฯšศค*^‚ ƒฤEห|Ÿ'์รh ฮe[8hbี์ อ’uZษจ†“งžูi‰>FIaZ๎๚ไR>THwc7ผx$žˆFล 2ฅฃ ˜‰ม.h)–0,:ƒ_2๛ใ˜B]w-เ็)„P †๔!้ฉชฆท8๘๔yฟำ้ถด˜DH™๊Š็‚\รภ‡์b‰ูญ–›'vŠทhŒฦ“Wไ็ˆ4๐ุ?๐ูมฬณุˆmpๅQฎ‘ฉ|™Y4ภฎLีFz…ร‡ึIซฃDๆฬMฅร๚Š๖Žน๔ชส™ WฑอhTˆRผท›สัฎM|8I2ป์Idผ†Eฑ‡ผ‘ƒสxSy1สK0ิ8ำ)”QšHl.น"ย@ฃจƒ7‡ฝp:QŽึฬ2"ดห4•1gฤ–ro*‰จยศยhf๎E๚"rด๛๚–ž„"ƒเฦ๏ฉ†ัฤ$kLชส™ WฑอhTˆRผท›ว[F๐ถณฉย๒)›!1?/Yล,€Lแจ‹“e†&ษขญฺ0ภฅ^์—‹œyฯฺbbT€เฑ ›“ฅ$R@/ศ\w™ยภ๒ฒ/าภK‘ไ+ฒT*ีไ†(ฑ—8e2pฌb†š๋€I/E ฦtW$ทัuผ๋฿d4รฑ!–แ*าuว฿+L๛สKืQ$$ะ๙๊ฒ‹ 5_ซ2žัs|€Ko"ษ‰ๅd{๕๐8=๒วuc…ฆ&Œ! Cฒ[ขNrฆา%ญ•9UAƒlc็™ŽฝCi๔|C5K๕Šd ู๗0ฟCUuƒ ภ5ธบl'—Fโ&‚Q]0ม=ๅ„]š„eLž‘j%I:+Olะv ดvึXกe2ใ‘ิบc๐ณ0˜2eไ3šŽ[ีฬyƒWตPPB ^*อb๕๊๊LKด‰ คบhจ:/gIฦg|šง ผ(ฯฌถ@Uทฟฎ–ถฎ†•‡Xใ๗umถB๘9u‘`ฦร "I๊_W>๙Q5€€าŒ>F#™%ฮ,˜ยŸVณ๐ึโฎcณโA9 5ธƒKb’Tๆื€ฅจœะ4”>=($ษก:@Šฐ•.ฺ…์BDญ80\9X:qB+ญN}Y_๔๕tฅธ$&Iก๛ธHMWชฎBV+๔สํAeUfH žvป๏œขfำ†-$ทCฆpษƒT`๕&gฅผƒัFDเ„ๆบiณjึั–ช#SนdP:F;dSม!ฉซ๔ยดeฺญ1ๆ m ‘Wำณฤš’6ีษx+}ผุลTบXขส?K!o๘๑’uœไ้†m &“dเbฯฐว &์๖T ‘ฐุ™A6 ^‡ํ“ะ/๎V˜๙zDำ6a;่ง^Apกจ‘ฦ!#บˆ LQ"๊ญแำs=เc 8i๑ู|ฆง’ธฝฦqC›–บไํNฺOยฌ1ฑŒ–oบ%#‚๎]ฝEG ฒjEŒภ0ฎFxฑjฒ›L๙ชd"ฯa;ฯง‘NดตาFrํ“V๕ภA๊†Zํ;ฟ™5rษXB?O๙=2ึ‚Qฑ%๛A‰๔Ÿะแ4เm‚N ฝ•Cป‘K*%mฟษƒPฮDฬu๔]j๖ํ่(œƒ้พ๐ –Rปjํ[} ะล๙๐(ฒะ†>พGo๘ึผŽ฿้ถะZIรง๘!ฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšiฆšh*tRM๑๛}"t„๊8k/,ฅQ]B ~ถ]Llƒ่#ฯ™gDbDฟcกป8๊ซRR\ฦ= 9Rณ :‘๘ำจฉฑ$ก๖ฦ|`าœ:z?cื๘นx๔›1 S ๊O พ็ุฐ๋B‹=")๏ๆ_~Dฬ๛แ8,“๛ฺ—มฮY`Fีฆ1ืกZมฦŠ‹l~฿Mว ใjSาg เ…ญFB‚NY๊”gNƒ?S! †ฆ-Nฃ&žGร_glฉ`๑๔–ปูEล ึด„๊\…= @%LRYd†รฒขนX€ผސธๆg\Hผา4คศด~xค…‡ ‡oฟตK‰๋P€(œ!ž์ิ]&ฤ2f˜€[/สš4-  ~ม๘K็๘ษnz(ฃŸ ๆ0‹ย~\๏b๘”@fฏ6Yำๅ>M@ผgํaํ˜$ิ๋ฦhศ\Y)dhdฦิ่V›V๒dƒ(F๑Eฒัโ.‡>ก้ฆกwtmฑ3Rก/M™mUHฦEก\j,t7,ถผส(`ƒx‘@Šญ‹ๆ$ำWx:ฦ+u้`ฺ๊ฟด(s“3k”Xuด"ฤc:Gb‚!ตกะc‡"&ž;ฃa็)^Š2๓p‘ีฒ†!(YJ]˜?ฏ4&ฅบฯr5†๗’(7ฮpn=฿/ฑุฉฤrฺcิศัา Lš’ฆ๛๔ศ฿่|Žแaฒˆ๐7้\‰–€ˆ๘`ม๒M‰ผฟ%๑y ฅ”้ุiุใต2duภB$`‰E›&W๒F+ตXฌLนL*d0„ึฝ|้ Iไ/ฆ8ฮFุ–'ง›ฤฎ•D‹ฎ NVJฅ๋™+‚2๋…ง ๑[D๐อๅnป4ฌOv<‰qกW}็eไยWH์Ÿ€฿€ c"%lŸP่ รMopC๓&’)B—X rhธ่– ั‹VีGƒ‰0ใQAœฮJ ฆ!ึฦ๋Yƒี2 s ๚o๒}] ฃ๏”U่฿ข#—+#_ิ‹ณษ2 ถฦO=๋วร๖ ตŸ%,๎k“ I)่ปฐญฯIน.g%่H๗g('๊ƒข;%หบต*MDiหเจ>$…๋.FK5 CnฅE๎ฐใ:o (œy5ฆ{1฿เ[“๕ ยค’ข7ฎ๖o๘๔ ›%6”ฐ8ฏฤๆ๐๛ีอน%aœaLศGZั๗รฆฺmไฬ{ฆ ž7ยฆœoNM•5ฬถแ๋ว๔ก๓ดm Tฑ ฑp0ŽJhศr็„m,ธ๋้(ษOZขฉ +j2–%$ั TWผI› ‹r †qง%/^ื:`ํ๐nPรธ`ธ%-ฉภ้“€Zล€ยืŒ%Aฺ่@ญ„xe r„@CFC—_†$1บdเQ‰ูฌฦ!นฐ฿จŽRะ˜‚‰"4ˆใผ‰พ4|iฝฏD %ŒกีWต ™Qฃฅzคื\GDฮ% XฌฤฆRทŠ™—pEแNฬV<ศŽH/นC}Š =„ =ฃ๎BไSELฤ4—ƒ็{€ml!+ษŠ@Ybq๘ ]hLS‚’ีDaOบ K้์ dฤ–>'c ิ|<บลฬdmึ๑ฤฏF”‘bbXฮฑเะดŒ๛จ†น—g5O.ฑsC๕ผq+ั€ฅ$X˜–๓…,x4-ใ>๊!ฎeู๔…1ุถ"๑ฉณํมึฮ}^gสฌ\ฦ(คy.ฦh$ฦิu็#๏‘˜Bจ%ห>ัฬa์็ีๆ|ชลฬb‡๗๚G’์aY้ ๆ& |แ๚ฎหQ๘ฯดsX{9๕yŸ*ฑs?4ศฌบƒ4x‹ํภ?D5ฬป9จ๘*yu‹˜ศฺญใ‰^Œ ณhภช:ŠsI๛a%ห>๊!ฎeูอGมSหฌ\ฦFะoJ๔`)I&%€|แK A๘ฯบˆk™vsQ๐T๒๋1‚Hง)6–โแ€@๘$ถ)ฅ8ŒไฬI#Dtแ3ๆบ82ฐชิwYJ5muŽvฦZ<5ฌ,C•2›เฆ+8Œ>ฮvV“#Dtแ3ๆบ82ฐชิwYJ5muŽvฦZ<5ฌ,C•2›เฆ+8Œ>ฮvV“, =ฺลEะŒั”S๐xEŽฎโ€ฉnศ้2ชQ#ู>kฃƒ:SQ๊ัFญฎ(ดHฉ‘ iVยว)พ+’pตwKvGI•Rˆ๙ษ๓]าšˆวVŠ5mqEขELˆkJถ†?๙M๑\“…ซธ *[ฒ:Lช”Gศ๖Oš่เ(\โl`ฤk2q}œ 6์ญ&F‰้ยgอtpeaUจ๎ฒ”jฺ๋์9ŒดxkXX‡*e7มLVq}œ 6์ญ&F‰้ยgอtpeaUจ๎ฒ”jฺ๋์9ŒดxkXX‡*e7มLVq}œ 6์ญ&F‰้ยgอtp‚ล4งณŸฮ3๙ฦ8ฯ็ใ?œg๓ŒqŸฮ3๙ฦow้—ย็๓ŒqŸฮ3๙ฦ8ฯ็ใ?œg๓ŒqŸฮ3๙วแƒKแs๙ฦ8ฯ็ใ?œg๓ŒqŸฮ3๙ฦ8ฯ็ใล—ฤ;!" 1230ABP`#4@pQ $5Ca€%Eฺ๖Gรแ;8๒pˆไ๒phdpิoˆpศฤ\m๓๘ฬ$^ ฮ™ู“๐ย8ฮ7ฑ๐ฺฯa'๐เ๐ศมจยr|D„๑/โœg#โฬ๎๖i#8ว๘+x'Xง,Sต–+4ะฑ;HงŽL•˜า97! ษƒผRŒaจl iี‰KDxา>7’hJณ๐ |ƒ3šœขlำลจลJ์„Q4—U#(€็วไ™ฎฑVXงk,Sต–+-๓Nhหˆž8š” RTธŽฯ้fŒ๓ำ[\ •wชหioRXŠฤจŒศ฿"๑๎ัy„Q๊=ž`”!kรฑbรG~Iใ,๔ึำ้rŒ€๐}งาRFQ%ณๅq:b๕ น ฌถG•BG#ฦ;K๚qฤRž ๚s5ฆVญมv—IM‰bํH๖ผ’ฤP–$49I,ฉFอฮŸฬ(žU 5ํ$z‹gีg0xอม๛F๖I"(Oช‹Pฺ๓@Pกฆธๆs@QsPร›dีM#คŽœคQž“ฃ0 ผผหภืาพฅxม๋ ซ๕Py‰Q๚๊X”_ฒ%O๋Šจาซถธบ๚Œ่˜ฮœœูู์๚1Gฒใณly์”ีWกqผจ|SyW๘EโŸม๚P๐ฃข๑B$o`! |K…๘ษ๛!T^ช‹๗k–J๐ดฏ”๏ฏ3 ‚)ปิeG้Ÿ7ฐ>%ยXUcฒขถ&ข’;วHLS4 [–ฟ`ฅgช›n†๕ืีDฦฮฺ•O;jM(ผ ย˜bยR† "y!ƒฒก๚~ศัุU^น-)0ฯŒ6ีึ฿Y๊W๙…T~ึ4QE3หSmจุ<์ซฝVQ~ฬี ’ฝึI๋%{ซี๘ณป={*Šr…ฦ9"ฬZRiuV๚T๕๒4จไs=G–b™๎AW ถ*YNWนC9Cๅ"s,œjŒCKgpขศNฎC37ว}*'ศฒแเฒYsบฟษxง{:wบษ^๋'NN2~#1 oธl๒žฆซo$Y“hซ$&RสSD5’3Yไ”ๅ{ž๖U-Aฬ8•ˆ“™9““๐Šs†๘๏ฅQฬQMพ• AŒ+4Ž2j#ŽMGjู>e!‘๊9UศLคœๅ {*–r›อFโ$ๆFNdไ"จ8Zย๕ฒ;Y…d[%น„˜ฝdฎ๗E)šจซ$u,ฅ1dCW(ตžINWน…T€8ฉg9ผอG+ตัาJ›วS$cŠ’คฬpQNp๙w’้ฅ&‰โO9พ Cy7ฉ‘š!„xdฌึy$9K"šb™๎G9mตQฐโ๛™ :“ˆqญšศf!โhฆ(oใ—{[๐+บป่‡ยvqไแษไเะศแจ๖g//ฤต>k&g~Lเcๆ@#โฮ/g๎0™y~$๑˜๓$"ไ๘‰ โ_7‚uŠqฒล;YbฑใM ดŠxไษPy‰ #“rผ˜;ล @๘ฦ†ภถX”ฑ”G‰ #ใy&„ก{? XX %%; 9ง๔uš^[บŠๅ1ูปย8สRฤv—ไgƒm๘ขล๘3šล[•ึ)ฦษ™b™ฎฑLศšมvtแi4่฿†Zr„r}Ÿ+‰ำGจAMpฬๆ€ขๆŠhZfА\”3ด ์ิ๒๑“K %3ู ‡Nkดฉwbv†8มT;-Ÿ+‰ำGจAIจืmฉiนผt๙Že-;ฦ:‚ะ9Cชะย๓š)t ๑ง9อ฿Xcี—ยŸNfต_๎ ๒๒๐o/_J๚—๙ใฌ*ฏืuAๆ%G๋ฉbQ~ศ•?ฎ*ฃ๗Jฎฺใz๋๊3ขco8Frrggณะy?‹ชGศJ?ะฅมS฿jvกพซช[g%ข8@๎ +๎5B๔ณžh๔คpโ+ๆพฅ๔ง๒ฆ๒ฏฅ‚o^<ว0็32"งือ๋Cnข๙"ฒฃ๔ฯƒลQฑK=ถƒ+๊@๒~+Fกๅๆฅ˜Xt`ค๔Mš‹ึSzคดคร>1Žfยฆz}Fิฎc#Q๚gยƒิtorwq†1‡V^‡ฃ|(อฒxjrC“d4๒œ๏ง-+ฮbะ1nZ๕ธ/ศrWบษ;dฏušฟwgปoeQNPปธว#ฤY‹JM.ช฿Jž F•Žgจ๒ฬS=ศ*ไลK)ส๗(g(|คNe“ว!DY ีI `๔ฐศๆา5Tš’๒งๅJvzษqล”eฝlŸ!ภณmแ๘ง''ศธdฒu—;ซ๒ฒ~Lษ้žส๗L๖Y? ŸŒR”/ฝ๎Žคไว-๔ชYŠgนoeRฮSy†จุ0}ิธธ=,2fาช™5%ปERq#พ•วๆ;ษ2ปdNOS#4C๐ŽGˆณc'2อสr(ฺ'สฅœฆ๓ d€8ด•'(โQิ˜šjนYA †LcY&rbัLpฟIVสํf 2ฬ^ฒW{ฉ ไ<฿๓œŠึแwn_`ษํoแฑ;xต`0หฏNœเ)#๘0ำ”ญ’จ€"fq๎AK&%634cSรkq8ฉZFแ์TธƒxงvnI›'ลMH˜ฆŒAŽyฉุR5@p™—t่ฤcwoƒ8แซ4”มงซ คˆ%wอน'ถ7nะŒq‰ฒ‹ Rm,Kเณrษ้)'ฏชJj?`ฉ^:฿M ๖'fA๛Eํณ็ำฉง๎v/ฒ๓vœ๐ช๖ซู๚^ยะฺ๛=ุs˜{1์j รุ&Ž฿6BูŸ–^Zu€ัศฮLวฮ3Z*aPฑG(<j$ฝM9ฃ†Gfปฺสฏั„๓ว$lยึM+i‘ฝ@็ค*YถๅฅLb์2„า534a5ถl์QBล ๒Aจp๚ยซ}d>(ผU ๅ2#9ภบ”ฃ H็สF‘œฤฉตNiš[!–^Zubัสฤ5Lฤ0ฯh Pฑศ๘4๎ั@ิ์งฆiGฉ…งๆfBๆ๕%BdfNาœ“ๆB์ฦ2Sนœณดƒ‹ฒโฺ5 -‰ดถ–™ฅgด4‰ฒ.†+SS้ฝ; P<๏K.ฉปบ๚8ฒธงทห…Wก yใซ๕#Fฤ๙5E19SGhždยs‹Œ๐$Žaqž)tž๊rŒMๅ“TฒEๅe’Dm,_้แหZgุ‚'4‚~าาPื๛G v_๊ง๗5ฆัฏ๕ หBปฃุŠ๓gi(h๛~…่=ง฿ชao'โ,E‹€ฤ0ผH„"T๖7อชศ%hค„ชdิ• ŒะดjQJ ฮา”๑ฦNRดQี(ล(ขk‹O8ฦฯ Gašๅ!u•ง[L†@Šก๕ฆQฐวญHฑฉJ=ซ ŒะดjQaสGจไ'‘‡ลŠฆ!Ž"5 Tšฉ FuคคŒcXฎšฦ-พŠqฅe=๓jฒ Eค7iโ*‰5%rQ้V‚6$๔๚DQย`€r6TฦL!ยภ22 นsl็:ŽN1< (ฤdม„b$cตฆv•˜‚ ฃ–qฃ|ฒ„ชฯ)1j}Ž่ ๚žœภแxŸJvu๔q๐YบwฟhฆˆEๅ†0Œฦุศ๕1ฦn๒ถCฒลSต9ณำศภnป•!‹1 ยCฺF„^G˜b•…‘6$์"ฉb ๊c‚Ogi;ฐg]งู”}‰ฃYูฅb{[งฺQ๛Mฺ}ž›ณ”Od๘v7a๖wiRผ๕~ะาv/o4 ฝšํ>ฯฅjฎมํฬก์/f'.ีžถจ๋ชไฌ“ภFh›-ฤb0๗@๐,ุอไ'7๘aQCะึ{''~_ลgทyฺ฿nC บ๔้ฮ’?ƒ>ฃ9–ึ)๐w ฅ“’›š1ฉ€aตธœ@ิญ#p‡n๖ชŽ\AผSป7$อ“โฆคฬ~A ำSˆ†ฌj€แ3.้ัˆฦ๎฿*qรVi)ƒOVIJ๏›rOln฿€แ3/เ›“5พnึลa™๐eๅงX ŒแTฬq ใ5ขฆะE rƒษกาKิั#š8dvkฟƒDXžI๓ว$lยึM+i‘ฝ@็ค*YถๅฅLb์2„า534a5ถl์QBล ๒Aจp๚ยซ}d>(ผU ๅ2#9ภบ”ฃ H็สF‘œฤฉตNiš[!–^Zubัสฤ5Lฤ0ฯh TCฅจ้งaˆ-OLา(R ปN9ฬฬ…อ๊J„ศฬฅ9'ฬ…ูŒdงs9gi eลดk@[im-3Jฯhid] Vฆงำzv y–]Swu๔qeqOo—dึศ็L Yโš<เี0ต=3Hข=H$%6ศQณ8šคŒIฯvลq’’&’NกyH๑9ƒNWCkตไี”พR*ๆf6ด์ฺงv้+ฑร (x—•ฟb,\!…โD!‚งฑพmVA(ดƒFํ ผ%S&คฎ่Lf…ฃRˆ€*Qv”งŽ2r•ฉlฬโ #&f{4๑ำŒl๑๐คvฎRYZyดศdชPje qสัT‹”ฃฺฐ˜อ FฅPFคz€ŽBy|Qxชbโ#PีIจฺ’gP๊AŠHฦ5€๊้ฌb่งŠVSุ฿6ซ ”ZAฃv"จ“RW%ฃO(ถqS่y0œq˜ยBๅวๆ‚)ุx'5j*@ำ,x‡ํIBns โ&ี0xกdนFb๕.ดMฆบ˜j™Ml๚'ิra:xฬ/‘Faๆช_M˜ธ1๙udWv{ง2~n=e๚’˜ดm&ร+VDไEๆิ‘9›๒vwgป;ป๓~=ฌ™นต฿ล<†ํgNf.๎ค6๐Zฒ'"/7ๅR๚o๖ุผล/ฆm ไ๖๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ—R๊]Kฉu.ฅิบ”ทม๏๖ศผล/ฆm‹ฬ_ั๚o๖ุผล๗‡B_M˜ป?เ|๘ปฟ/เ“w[๘,›ป๒๎7—y—ฯป๒๏“po็K้ฟb๓]ฯ—ฦoนท๑9|Wแห๙ฒ๚o๖ุผล/ฆm‹ฬ_ั๚o๖ฺFg#พ"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠฤV"ฑˆฌEb+XŠชะถาy„44o+ฯJp Iฦž ฤบLฉเ*™t…่K8ธEจ๐จ‡@๐๏นcโ๏fฟ{็ยํยํ๐ฏn๖k๐ฟ;~5W่?i<วย˜c>ฯ‘คถ!C”:ฅ ะ‹CF:%ฺ1ผ5‚ิั 0๖_๎ฺ๑=%%ๅ™เก‡Jižaa yชpิzบ9Jm0:ฬŽsŽJbีyฐฎŽ†]]zbโ^,Ÿโ%gdสหภฌฟํ/ฉ0ฎ‰์\™ฌฌูฏก{๓\ฎ‚{;ฏฆ๋ๆ๎ผ,์R{x/กำถ<ฺ๖rug๙~1W่?i<วมฆ6้ำ;ณžพGน(ชŠ0า}ไญ>บjƒhเ˜ฉไิsฤ8W‹ G[ตษ™Uฦษ`ใ9ถsig๚<^ยห:0ฉ=็iRาลMิ›ฑฒf*ช๊qฅฉxCนยืึชŽ0(ำF ว<ิ์ฉม฿“qEฮdฦล’œutK6ดฃฉŒ]†PšFฆfŒ&ถอ€ (Xฃ”H5XUoญลญ๓ธ๑ˆ5$`RT4ค@SณวS6”ผซzd’LFฐร#SฮํŒJณ”ศ1j<œIช`,‡ฬลV~เ—iำฉีˆNฤTฒUT•d}ฆเ๕T?ซB=กOh $sniIกกํŠP‰ยx่ชZถ ^Y๋แ:}ด=ždUัe๕๏Uz1จ]šKผe,ŒฑปCSe,๓X5Eคจh„๕#| ซ†ฦ0ษฌ‘ฮ˜ ƒNํ Nศ8ฃ!nBCท6RHฬ8ศT> ิส6ใ•ขฉ5)Gต`1šJ" Œ9H๕„๒7{,฿ŒgฆljHแœตX๔†fาฌ!)Yฦจ€ฃ Jใ(ณว1G, h"™^ค#‘Fb“‚ฆ!ฟส?ญดuFาUEIQM:์รงคฎ!’3ZฝZŽาjง(แจŒจ‡ด$Žb ฺกN0ื–โ 6hขฅฅŠHี]$Tโฯ -,eQv=,ๆuBOfCwk๑Š1’๙J1H*”‚)ˆ]ข—)*-ช๎! ผ-PBn'จ‚wฬ'มžมลฉbฆ= ŠภpFยไ›š?่ญH๓ำG$q๚„B ‘‰ 6BG'งฉzhไŽ?PˆAฒ1!&ศBHไ๔ี๙YV~เ“†M|S“7Œ' rฑิU๖„sภ4ิฌL^5๑NL7fๆ๗gๆฬL^5๑Nื๎„‘ษ้๊Gžš9#ิcŠ7ฮcฉ ca€$ŽOOR<๔ัษ~กƒdbBM„‘ษ้๊Gžšgท๔Tัf์Mณ‹OM (]สAคvศจล๑*`ป{8ด๔ะา…คAglŠŒ]฿ฆ ฑG ml ง Ži\๛6๗dฒnฬ‡ลูฯง์ุ|GZษป2๗d??vBŸณa๑vAkweฆi 0]Š=œZzhiB๎R ณถEF.๏‰Sุฃูลงฆ†”.ๅ า ;dTb๎๘•0]Š=œZzั|•™Y•™Y•™Y•™Y•™Yธู•™Y•™Y•™Y•™Y•™Y•™YปถefVefVefVefVefVefVo๖YฤC !1AQ "aqฑ๐02`‘ัแ๑@BPRpกม ฒ#c€r‚“ขยรฺ ?ผโญซJณ๛๔1๎ๅ+Vdฯ์หูYk‘4ฌ’ฎฦ๋RI6IFผ‰(กี1’ผJ„ฏ/ฑnj่ฌšฝฑ™$ฦ฿J-ุ๋‡ • ึ6IWc2j๖ฦdา{Y$วูษ•‘ก%'dชxยฬI(ึษ(ิษฺ่‰)!ไ:Ptก%Fiษ’Ž๊1L’LS&“pฒJT๖;~F็Œฌ่›Xซe]v2วฅ™ิุวGy&จm่ถ7gŒบŠ"ญ›r๗ถฆถxๆ›ฃฃผฺฤูถถ5‰…ž๋7๘มั,-฿‘ัUถxภโxหูlฬKวiJซqณSQ'ึcSฦ&ข^;M~รฉกƒฉ™K(์KวiCDknขFข^;Lู™˜‘˜•wฑ/ฅ ญดฑ$fPฬฅ˜ูŠฒ… Q‚่ฒ†L๛œฌmะIำs‰ 3_๗tซjร๐E่ี=๔iซs๖ฎZไM+$ซฑ:ฤิ’_อ’Qฏ"Uภšc4$›ฒiฝŒษช๒งว๒nJฃ$˜๛ (ิล1ิtH\ํฬฌw๙?zษ&>ยHtŠไ<ฌU2<"U$œฝๆพสฦW•กฏค:™พ\ˆาž‰า(•iสิื‘ฑล๘ีcหัK=‡Ufkแสxฅ่๊พรš๘{Qใ+8|sdk&F์‘ณS7ฅ‹‘œ*~DQ…แ+#Y27dื#A`‚#_ก…โคiC‡อณS7˜่z›‹*gส\ำAฅั{ˆ8x •3Y™ฮฯZBซขIPึLู!bลL๛ฌ๑™๗HเdŽ7‘tำcฃธK/S/f"ฤw‘ฤคGุuู+ฒG๔‰ฅะMu WคโฏถรLl•ืา;ฬth•~†ผ†< *=N"ภ•zN"ฤ•ใ‰uหdฬขI)3Š›๑า:^‹ˆฑ$คJ์‘;ฬth•~ƒก43)ช2g›ึcfGBt ฦฉA็์์h฿เQฅyZ๚H๓ฉŸฺีNฟื„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B๋$จ:ื์บ๒'_ัŒ"ฌสวWnFV๏๐>๓2*hf•ฃฺ –mbMY›ฑ`eษ๑‘กฉกฉ•lIซW่ำก'๏ฑŒฦวdŸผuไๅkฑุ์“๗๚ฝz!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!Bใรz,œ`“ฆ5๘ J/Xบฎซ]3•lt๋่'%ิ^>ๆ•ฏิU้cฎ ๛ี}บ๑แฝJโฟhbW๏อ9:Sฃ|?5Šปuีm๗ฤœa)ทŒ•rัs_hึ1wฉ‚ฝvF1–77ม-ฝๆาึq<ไจาJ-g†5ฌฏใD฿ญา%Kฑnฉ;ีว]แq:uัยWธwZtK7J`S™ยRว*ัgะq!9ช]บจ๚Wชˆฦ์”ฐXี!+ŒœpX]หึmสะฯ‘งด>17ขฬ›ฏบศF๛๛ิวแ^šSŽt–X*%Lฅ b๑๊}O๏…™Bดํu#ษษbผt˜พ&u๑แŒ#›ปฏYJฅN†ฉLHF [ซ>๒•ฎi๗ำOฏด๋์๗Œ {ปโ>๏ˆ๛พ#๎๘ปโ>๏ˆ๛พ#๎๘ปโ>๏ˆ๛พ#๎๘‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ั๚;ฑล๘฿ัํศศห‘™,ฉNฎดFํ—ตw๔Sน{%ซ๑ฺb•;น*ขฅ}ฉQี{uฑฬxศŠ0ผ%dk&F์‘บ๔1TBขจฑกฉรฑW๊,Uฝฦห๛Nœ่8 pฺุ๕o8๖q{5Lค}๙œเฟr7oๆบH(Z.†p”V๋‡`๋CฃนrผdF๑i•he#จ†ฅD•ะฤฯฌ0ง๙Hส$จ2WdŽ%้K šๅ่N†Cฎฉ;จ—ซ๏&—A5ิ<~cทŠธtฆzแึ(‚๓}+jnISฅง†yE๔๔Nน๊๖&ฆงŽวญร‹]ฟ?ไลงSส|sMัฤ|Jg\ซัใด๒ˆ;+โว‰]พฌ๒ˆื;ธ{ฝoเใฦด๕pัอretโ,ฺq*:ื8ซ8—I^8‹JDาoSˆ›๑ำ๚%{mI%]วD:ขIำbJ๖ฺ’JปŽˆuD“ฆึ๔wYŠฐิฮ์ฯ“Ÿ*IำbJ๖ฺ’Jปžช=BIำbJ๖ฺ’JปŽˆuD“ฆฤ•ํต “‹[xg]๊๓ซฝwœo๓mถ„ฏ(ไ›ม}4ญI]ŒณŠx?ฎด Xsvcฎ๕yีปฮ7๙ถBW”rMเพšVคฎฦYล<ืZP~mฌ9ปmฑ’jบWไJM|\{‰WฎŸMำงไIฎ฿‘*u5๐mq๎%^บ| 7NŸ‘&ป~Dฉิืภ}ตวป“6”ณUม๘่ Xsvcฎ๕yีปฮ7๙ถBW”rMเพšVคฎฦYล<ืZP~mฌ9ปmฑืzผ๊๏]ว็mก+ส9&๐_M+RWc,โž๋ญ(?6ึถุ๋ฝ^uwฎาฯฤ: 0p!#6@AP357`14a "2R€ฐฺ๒ฐฒ“Uฃฅ ๅ!ธ-%๓ภ–sน`๘!œ/”hXืq“ศˆถI‘|†kˆ…ด~˜rลดiยแฐ\@–ฬˆ๑œs—ฎ˜่ข’$%gดหศญ=๎kัGw—๐๑โEฑL“๔2Yก%โ๔‹2ำ๐„ŸฑaOvvv9}(Xทญคš mžํž๊-6๏N#;B2D„ฌ๖™yภUฦh_Jถุ‡ศ‹$ฃงภุeซPiV๛‡ฒ_lวํ่?ำทZ`‹‚‘X‘t๓-rt›eฉรBฅ็ป่ะ u#๑œEG;ฉ>f๔ํtq๑ G/RŸษiบ้)+๔่ี}]๎๔คPt›eฉรBฅ็ป่ะ uัๆวฉฯŒB๔u๑ซP~|๗ม๚๘฿_”๚๘NซัŽ~Xวฃ|YSxลJ๊'’๏ล ใึT1Sบ…ๆ Xึ๎7[JวดKM๊))โ%OMซdO&UAีภWฅOหลศš%๚$๚ส›ฦ+ถ’~—ดีƒ>๐Ž"Rq“จถีš•๔ แไ„๛‹๔nถ•h–$›ิRSฤJžฑ้]ƒQด ฦฑ‘›gฒu ๊)โ2wฏๅต#B๙X•) ฒ’cย๘ิXุYI‹ชัาr’๛T4”ัTโˆ€"‚_ึฝ๏‹ณ†ชเsไ$[$ศพC5ฤBฺ?L9bฺ~4แpุ.  KfDxฮoH9‚KืLtQษณฺeไVžwnต่‡#Œ;ห๘x๙M- ฤ๊\"[์ฦฬŠ่๙ืภ9M"H่‹K ฐ๎6_*wG!•คม้WS ิ’บ<ฬ˜^Q„™D่nบOG’ zF๗†าภtํv6ฑำ—’C’; ›:#ky ๚vซLbะR+.žeฎN“lต8hTผ๗}.ค~3ˆจ็u'ฮ๔e๙ษ้‡ลAจ๏ิw๔ร๔แํj๔ฎ๚:)V‡ฒััหหน“๗ตฺ่o๔i๙B8ำ?3ฎสEj% Qฟ˜ทฎ“<ฑฯห๔oƒ๋*oฉ]D๒]๘คzส›ฦ*wPผิ ฦ๋iX๖‰bIฝE%ฺ฿๐ญๅจ์ป†Z๎ซฅ^ ฯซ้Eศ)งvBฤ๋ด;ญอmๅา15$๛ฅ œกฯบE‘r iฑ:ํŽ๋s,ฤI !1"2AQBRaqกSp‘’ฑ#@มำ 03sฒย๑Tb€‚ ขณัใ๐P“ภรฺ ?ูK–็ลD kWฌ›v’f"wIๆ>ิฐสคpฯ ’>_šAZน$}ย„(`Aฬa.ฅนV่€N9rŠำQ+Q:๔ม0ฎฯ}"4อa"o+ โ‘ŒจฤฯfUฅทคYมฑ2zฒ วO!J* (O ็แสดฆ๔$9น~frฬคc฿1ย”—Ywuฤdx๘sศ็Zci."ไN๒2mจ๖ๅZCeํใ#1ฤƒดHใ๖‡Rศ\ํซtBIว,โ+้$;ข€nJ ฬ\/ฤ‰โ'็K ›Jค‰ส?ึดถTญw ๕ฎTฤงคŸtำษuฝ0€‡ร‘”œ6kMi–เBี…ส3ฒ”• ˆว"ˆZXใˆเEiM่Hsrฬๅ™Hวพc…).ฒ๎๋ˆศ๑๐ๆ8‘ฮดๆฎZŠ3Rg…pสKa Rย  ™๗]gZ[kR›P‹…รŽ=๊ำู›sW"้•*อํ๎g์+ฎฟ“~ƒi s๚ฆซ)ฦฟDPจๅ2>่ญโญ‰jˆวezฏนuี_ษ๏ด๕—๒nฝRiฏ]๗ท\ัฦฒ,ฆ>%ื้ฎyภkkว*Bฃ”ศ๛ขทŠถ'๕ช#•๊ฟ}4J”VฌO}zตี๋ต{ Jlศ ฤxม:gG๘๘ด†าถbA 0ซฑ•3ฃ ZChีศ3็*W*KzCH&mไ`;gฒˆ F๊!#ๆ}ไาึhษต"i๏mฯR>C˜+ ปsk ใ฿h R˜ ’œRSŒฯ3ฃ Zm ่oUชf้‹ๆ||)(ี้*นF ภแปต8ƒIHFŠใiM ษฺ@ฺ•ฏ(%ฦิา ซฎ^าy#gฅ8%<ใ34–๔†‘บLศภvฯeิ$BGฬ๛ษฆ˜ตค„‚Rน€#pSM%2 ก*๕Ÿ•*ีฃ{ 2ฤ:• •ฮะ‚Gึgแ์ดมฒณอD“็™.[ž@)ญ^ฒmฺI˜‰'˜ฑทy@“ˆโHก A ŽD`Gๆ›Sg8P)1ใ์ิฒ;j ว.QZj%j'^ƒ fย9๑ฏคF™ฌ$MๅaผR1•™์สดถ๔‹86&OVA8โ)ไ)EA% แ œ9V”„‡7/ฬฮY”Œ{ๆ8R’๋.๎ธŒc๋Lm%ฤ\‰QโfMฃซHlฝฃ\dbR8p6‰<~๔ซ7ฉ;V„ฏ้W4นqืฌ*=e..๗™ญ)ต<ศ”ทาX€f'c‘ๅๅ@:ฅ,ฦRฃ8v{-qJJr’pแlอ9ถ8'‡กTฎ๘Uํฏ#๙*oŸ๛่“t็ูmBs4๔ฌs๏ฌวฑV‹ฬ‰”Œ' 8Ž=ต๔b/๗)ƒฃ 'Lสคใ™แ๖ฎฯพบษ๙ำšฐ"น๑“‡*ไvป~Bœพเซป6kŸฑP’ดฮ๔‘ˆŽ|้ฆ>%% (MปOฎa6‚F<ปkHBฎํ๗<3ย0N†ีƒE‚s?’๚[3‘~๐ญ! ฒxƒห๙ร•…๑๒๓ง‚เ`๑5า3ญ-™)Nq{k่ล_๎SG@N ™•Iว3รู˜IZgzHฤG>tำ ’„”&€@‰'‰W?:fึโ” ูŒ‡y•6โqตb sวwค]# >@* ๑1ูM8อๆXฯ)ใ้ญUฝุ๗zB”Ÿ„วฒ–๕งVผ$#6ี4 „Mวญ$Œ8eM’Rก˜"๐4ฺ›ป+’S=ำMซUืด๑eMฉหsต$ว|eI+Qศ$๘ IJ†`ˆ#ภำjn์ฎIL๗Oไ!HœฎOtำjี๕ ๏ส›RํฮะLwลฅœ€}ิXเDแHR'+4ฺต}h6๛๒ฆิปsด๑I*QเŸu$ฅCภ๛ฉ Dๅp"{ฆ›Vฏญ฿~_”ฺ›ป+’S=ำMซUืด๑eMฉหsต$ว|eI+Qศ$๘ IB†`ˆ#ภำjn์ฎIL๗M6ญW^ำoล•6ง-ฮิ“๑•$ญG “เ)%*‚ Mฉปฒน%34ฺต]{Mฟ^ยฺCจr$,ำ0AIJ†gŽ3nฎ>ชฮฅ_>38ิhศlิฎฑ%JR NTlญ๗’ฎ}"wJภ™ฆuฦ„!ลค•ง—H[ัผ*('IBอะ์ฎฐ!IP<เมใDD[ซชณฉgWฯŒฮ527ต#kฌIR”ฃร•6+w}ฤ$…ซŸH„าฐ&iถqกqi%iๅาV๔o Š าPณt;'kฌRT80xะซ‚D$ 9๔4า‹Sbิ’T™$๕€0L‹Š }*7C—ฎ`…88๑ซb-ีวีูิฒw|๘ฬะK AธmuŒจ’{อ6Ks}hI W>” ้Z4n-ฑ ZาJำหฅมQA/ฅF่rใตฬ A็5lEบธ๚ป:–N๏Ÿš a(2w ฎฑ•Oyฆinoญ !J็า=+Bf›mลถ!+ZIZyt ัธ*(%๔จ\vน‚<เใฦญˆทWWgRษ๓ใ3๙,ดฅ56-I%I™<ยL)น*ƒA:Jn‡dํu J็""\}UK:พ|fqจัูธ%ฉ]bJ”ฅœฉถู[ป๎!$-\๚D&๎•3Mถ๋C‹I+O. ทฃxTPN’…›กู;]`B’ yมƒฦˆˆทWUgRฮฏŸœj4d6n jFืX’ฅ)G†'*mถV๎๛ˆI W>‘ ปฅ`LำmบใBโาJำหคญ่คกf่vNืXคจp`๑ข"-ีวีYิณซ็ฦg๎ณฤ/!1AQม๐แa 0q`‘@Ppกฑ€ ั๑ฺ?!VŒ8ฒ6 …ฎ gษนK๛ xrปt)mสทCVh h้มฬํr)อ A้๒ƒฑฤ%oฦษ ‹ถrš 9ei ‹#๖eiน:˜ซ@ปภแผUฑซ„"l๙ํ;มูf› uแwyx>2ซ2Tng&Iั/'ฮœa๑ส“z „T,ฃไฐx-๘IFฆœตBc"R1/้]โฤ9๕…ุ๎|ล6aทนIํNV่ˆŽฝjoยํfฒ• ‘อ› ภค0ชC๘6ฅ??ขะH‰SŠ$ฝษๆ € ฮ› QดXOfUBJtX๊ ๎]ด4;o’ข‰.ี๒R†ถ-ๅอ‚ทฏิU ƒมณ๏b4WCผณฅๆฐ’ีR็Œ็(๏!„Smjกz}ปSั_€ูึ/ิB„’ทา๓ƒ™ˆŠไำตเ๙,_[ตž–e  w ะข03ธฤŽU2ศQ*๐ /ต ๓Œู€+Updฃie๛6รY.jชำKX1e #โ[bDƒยูปถPoถ›^ฺำภ2`่fงฆPTคhมx†ธ‚เ#ใ‡๑)ฝV~N”ฝๆ#u, „ŽจคƒL8ฝŸฮž‰:z3}˜œ qc'Fuภ3ckืสด0ฅk ๋Kป็?ฅ ต[Zก.ส\ุ๒D iมณ๏b4WCผณฅๆฐ’ีR็ @ฺชz}Mzฒ$Iฒ`๓omSธล("cŸ~Ÿๆ๙ๅุ=.†Nˆq*Euณ…๊๑mn U‚”™Lใ{ŽMšRgJฮ้ะ๓๐ย4VHู๋2,eZ๔Gฒ˜@m^2bจฌaสN๐`˜u‹#ร8*_ขRฤพฃ ๊•\ป โŽVwcฦุe:เ๔bO๑…ด …ฯ.—Ba0๚ &ฦ;~๕<ฃ๙บdทcฺไ‰aญœAph๋=]d >L† Paฮ๓’็ใLE"ัิธคึ- ƒหj‰ใ๔๑S4ผ-ส+๓†วD Z0@&gfหกฮ5A๒W Qหรq”*ŠJ†ฦFรน_ส›F‡"ะฦยซฐLƒ`ช@ำv ‘e"PI:ณyผOP#vชฏW”…= ๔v &-=ุOใ?x žd๎“Vค›๒RB็W๙ัf9hฎ‰Iา๑˜๒S|๗ฅƒฆศ'@hภœaิฆ7%SDsVp32$ศ”†pMณ/CI#ฑฏะโพฺน6 ฟํจ๗c',QQ"a•ัฬฉwไถ @Gมงd@ฺศ.Š˜๖ฃฦ&†บMœฐฆŒฆก ฤฮะมบยู๚TวQ ฒฺUNฦ`+ u%๔Lท๙\ว๔0}6%18(TGฎ Rำ†k8Cs.„i†๐žฎ0ขหำ MะŽวฟ‡0—๋ชณไู‹ท]‹]|Pฎพ3?†tF2ฒุ]†ภฮฦ##งmพ๔ึ8ลบ6ร#Rี?’ZำQ๙cmงRษ–{ื‘ษศ!๊ฮchQL>-ะภ'#OJFฃiตวQ4]Tfฒาy%ผ้–"cV|ซf ŸXj{ํฟฐ RIfฒึ฿๏’`ฑUzšh8qœQย€4 <5œ!น—B4รxOWQe้†&ฮ่G๔๔\?— IรณกฅByoO๒n๋P•ทpN+ฃ่€€ฝ\Y๖jซ๙ฅ“ุ˜oบMภ๊:๑Rpฏ๘ฒำqm„KCัฬคดL“\JัjงธF!๛MุN“ๅปu๐#bฉ\Lmข;ค P”NŸ?๗าฬn”Nภ3’pนณ]เk5๎T:QฎŒžj˜PYถฎso|ๅ’{ฏƒฝB๎ต••[Sธ มค~b|ื็;žBŽุ`โH(ะ ท_6*•ฤฦฺ#บApี D้๚?๋*&ฉข…ะk;I~„s ฎlI G8s!จ๛„Œq๊์”›v๘MqŽฆ„ู?ฑเฎB๚GเMดƒบ,ayฑ…2ŽนฟฌˆนณRญะš‚B์Vง9D้1{ภPผ๘/ูภ…W7็Šู!เš.าด™hแ\ไ–ม6†้เ(:บฯย‰ฑs่๗ถo๋ว3€šŽธฏ๑ž๑c"W`ฤ/ถ:ฎพSคNะํ 1บ2>ทGKYrร3v”†๔hhhšŠQ“ฐัธ0{Zงแ'๐,2๎๗|(ฦฃ*ทก!ทNPุUป๓œแฑ$"„ ๕Ÿœ ค+hƒ่aYห+ภ๖‰ ะb‡šCผeา ฤฦšภ<ะ6 f.q€ดtqš…P.>=SอกW˜-nK๚$-wศมˆขcgึฮwฤ8(ซD HšŸ2บ9ฬq&บCux๎๋œซ'ธวฐJ,wฉไตยe็yา๑้*"< โท€%Sัm‘ม7nฬ!ˆฅฺ* [ kUฺั[w5$›jZ<๎ธroB–ลA&ฬ0์ล*นD•/dXภkโ๏ mlsz-ล†๗กfฌdส4น8šC์=ฉ€†"ตด/ูด ๑๕ๅ๎๖๖'Zapทจแ๚รGSU4€ืวE๘ฌCตนvB;+˜_ฤ๏Lฤืภ๐๋ฌ้ ๚ไ๛Mฃ\ะ6u’2fใกท4๔ตqุCช4ƒ(vVq%]กจUใใี<ฺy‚ึไฟขBื|Œd๓œุ TฎO&ภHิVŸ‡!™๏CށHฑตแvงB่&ธ\nN‡I?œ&y›QใN™ฏ1Nd‚อ๙ox ฌ RอS๓ zยQK\rคธั๚‡ไ$!€jzอพJš๐ -รป|Šเ์ZHd";*4Š4หจ>ผ‹,กฒ%‚ิN+?HTYSYเ1j#๒สZ—_“nฆUึ+Zฒ8อ`ฆ€!ผ?$sYใuพœER๙ฌว็จ5ว‚Jศ™ƒŠ5ฉqถ f–"๗FvI.eˆHพอ#Ad@ @หม๕ฐลHq? ูWi7๙ว=R ฆจฑhtหจœV~"จฒ:ฆณภcิGไ›HI ฉv4ีืค๊aถึŸศํ ไCฮEH]&Hืพ$œF— 4ฃK่LiAรb†yŒ ซ‘j_ฅm 0ะ‡มไPดE†๋ณAธYปEฆjฦ่เ7ดา’’•Bฃ๙V{{ษธ2žN1UวQMขtHื๔t2Vฮจ“R=ฬ:R`”"U@ส™ๆ์6ธk๎™R[G{ิ˜+๓•y‡IผดdไภmUS4?†๏๘,8ฟฝ 1…ัฏกเึซมi"V4Jพ}๏ฮ/>ย=sฤH,ะh‘็†ถk ฑePE๋9%ง๛0ืL๛Vจ o Ž€ํิa!ทแ ว๑๊$Wซุศห+ช1jBLZBXbtB@nฤ`ะk*Oไ4บŸำž๎Izบโ~ึ๕;ตเB&89Sฤช ]๎๊ษปsp`zd '•ฟฃ,ƒ@กk‚‚A72nRยฎส@rญะร•š:ps;\ŠsBz|  ฤ์q [ร๖3ˆฦ1lOG‚ž@า'๎x< Kด๐hดFUๅ,tc๙“ T4ห‡ซICMŠษฑง่๎Œบ+ธ''ํ•+ัf าึำLยค๘N43๓‘›ะ๊ๆถ˜หŠy่K๋๔า‰ ฉภDQํ€€ ข'์ด๐sซ˜7Ugแ@B 7”๘ฺœญะ5;zิ฿…ฺอe*๚~ฃh<ฐ&žฬช„”่ฑิAปhh*v฿%๛E]ซฝไค1 lZ9ห›o_จชƒg฿๚ฤhฎ‡ygKอa$3ช0ฅฮ ฮQCฆีB๔๛v.งขฟ)ณฌ_จ„ท %oฅ็๙3%ษง๙j9ม๒X พ ถ5k=,ห@ถ๎9ก;D"`gqˆ ชe(ขUเ_j็ณVชเษFาห๖m†$ฒ\ีUฆ–ฐbห@Gม|ฺJบ˜•ส"ว„ง ๋l`คqcต@uo"๓]ฏC“›n[b{s…e|Q €\ฺN๊YIฌZvะบต2“3HŽ]ˆ๊<โp–คอำ|’ด้@("-%ธร…/jณN่Œศ|4tณG’ูYขSTbRXRC8Š:ZyuˆhZฬ]‡ืงรs&9ํ{p#ฬz๓rา1ผััT<ตๆิ$ํ€.ฆฐ๓‰^@ะvภภvค๕…NศEป›Zัhoqไ?ดŠ?Ž! ๔CHZ,ฌชเฎkำ้ฅ2Š o ึdvจจ†รฦ9ฏ2›gQั]f๋๎u C ณ’็ใLE"ัิธคึ- ƒหj‰ใ5jn“‰วKv๐่ฉแปE[Ž&ม>ซxu`˜๋AฦEชGUใาq๐ฦX‹ปqฑลืi&:โœt‹ฏล]Š™8›RFHฌฤ—๊ภส๗™xํำ้ศ;ณ“š&ฏcKื9.~4ฤR-KŠMbฺ<ถจž1ทy1ซ"๊7Tพณ,๐!Knำ:: ณ‡P๋i+nX@Yฦt๐รl;๐xs\คD‡&นv?v๋๚€ Žฆฏ๗}Uๆ7~~h~์:6ศ Tฺ0ค๏วำbSณ‚…Dzเฅ-0Yะ่fณ„72่F˜o ๊ใ ,ฝ0ฤูเห๘s ~ฟ๚ซ>M˜ปuุตือต ๋ใ0เ#๘gDc+-…฿๘l|แ,b2:v๏Mc€แ|Yกรl25-S๙%ญ5–6ฺu,™a'ฝyœ‚ฌๆ1ๆ…รโ r0pบฬfซoˆ,$ฑห8'PuQช—๗J„|ภ@Š5&ฌQญๅDxWึ๔5ฑผlญ -%  5VปเaLo– ตrภ‘ˆ 4e\bไ$ํ0๖๏ฝ฿|UCiำฉ/ ห็ร#ฎศ%m ษ๘s@ฐ ฮฦ]๔nึ0Siง/เร๓วศฆ#Ž้qู๗๘ณจ๚[‡F†A…D*€ฏ ๚*๔‡้‚tภหน‚L^tงิํฯ๓NI฿๘icdีkฆณ7CฌณboๆๅZฝ’ิrbUจฬร"ศ#`V`07‚แAAฝั*p9VAŒ;#H๒V*`r-๊†๘๖p๏9rฮUJๅงฉK๓ง่8๗ หs‹œi k๛นP๎พฮฎ–"็bIตาqฉ/ย ิ"„q)$i0า่ช3Z,If๒ปอ’ฝ›H‡šโ่บัt*ค% ]]ฃDฦ˜สtLDา8r™>พ)Ž '\3E๐ฐ„Pq๐เฒ‚ˆ ุูs‰'K~ฤdM ๖ญ 4 ˆš‰๓R=$ผช"๕ฦOรvUฺMqฯT‚้ช,Z1OQเ ึhnI"†NเีปN˜~qaถ Yฃศwส‹A'9๙)J8ีkฤƒzๆฃqๅ‚S†*9GŒ—D=N•R˜lฑเด‘Fซ %_.รชม ุูŠ /NSa”มฦฮNƒช%|๚k? ูWi7๙ว=R ฆจฑhtฦ[ิฺ๑ J็'๛x.ณ/Sณ’Ÿซ€RDหbะl UขณCG๑สคง๒ธ–ฅ08€๒v&ํตบ ฑ…|ำ:xฅ€๙ตi๙$VฃK่LiAวu๕mผโ  j\ถดhญƒฉฆฝ>9z่)ณีeGfv+Yภ์ถถป็yKถ @?ัฎิ ภ •z็m๕X'40… n๔ืPS๑ษ]Sw]1ศ?gcFQ:ผQHฑ/JRชปช ท๔ชšŒ$}ฐleU\ส"œXLYธBƒŸํฦๅท_ nW•ฎ<*o๐Oƒ๋*’ŒR ๆ<กึ :ณ7ปีฤั’‰บ]5„>%ง1ถSก›๒0ํ><ร›Pฺ๖tํQ@fป)ชu‹ภศ"APฒูF>จ,ฯฃ yษ6!ฌแ\ฝ  ฎ ธิ)Q๚ำ?hkฉใ’Žท YลM›ว๐AaF‘z็ ข`ภl[Iƒลโค7k,ไผฐ: p฿4kแคh๕O?ยฮ:A‹‰ผŽ_ดํš๕# ๓?ภณดMอrp^@5‹6mาำVP†AOจh— :ฦ) ษ=6ฌ6a:h%ฏ่ž๏uD,|ัF$yภrฌbฬ0(ลaณฅ‹z|L(& ŒIชB‚QBH๚pLBญ‚€ะ?ค…R`o.0ณะ๕ึVˆ€Cฺ0r*นUeใ=PK U<ๆR๋\‹รฑuล„uFฦศุ™ํปuสไฃ8zเฬ;ฦพเ#ถƒŒ้ฌžZNXU&,“›ƒํ(=z”ๅ๓#ฝq)Rจ€6FรฯmฎW%ร๛ืaุ€1๋‘สng Ÿ‘4๎fญฐ5KlKา์o50Hฒ,ไลฑ๐ะm'ป๐ฦุ๎cเ:ปส <จณ๋หF@(ํ๒aๅh๘ ิ=ฃ5ถg.’<—PL“ษ์ƒz?8ฯD8๛Kพ-หถ&ธ 4ŽศBฐฬ ส(บƒไ๊ณu1zเะ\›ฆ,ฤN๚7ั๛Aุ๓Zi๎ย M‘0Nๅาka:Œw qqGm’ษ าUORธฃฐ•ฉ%้๏ฬACvซŠ ๔ธ{8ฮf๕าAM`[”บŒ5bชZบ@–โฺQ๒q#pร5ฎ๓๊“Xu^ูd3_Eๅธา2ฐmSะCUฤmr 8eฝicฒQร^ ภ‹›OMุม4Q๙Gnzs๐ฆ, ๑šื<’ำ !๊KJฉฯ๓*T4o๊็ FดNB๊แำ็Aบฬ๑ไ๛A‹tธ|d4^J>^*2ผๆ‹iแซถึ"อvษuศ‘ŽIฌี5,l˜•ๅมป1ค2*Gด่-iผ{ธฤฏ8ๅU‹กู‰…8OP0~o|43kbุ†๋๑ฎYฤฺดo๒ ฌวˆ=๒จWŸาฐxlก…gว๋/€b„ฑn;ชโˆ่ปŠ#)KDk1 Y$ฬำ^ห๚Bฯ`Uน/†ติC:tอnย~—fัRกฅ˜h€o›โะJŠm๔์˜ nฦžB0บOO—Yยๆ}…x3๗pฌบ๋Žัฤ™€ใX€9f„Rˆข์ห|ใ†‹ST.qJๅ‚tฎh1ฎK\่๓วไ้^ฐ๋ื๛Nณูต’yKผnฤม~ู์ฺักฮ\หqึฌภtดฦQv&CLญƒ#&‰\rฉษ—\ใh„LNdt=้›ฌ๔ำษŽx๔9†ฤ๐eื\vŽ$ฬภิฬ๋4"ฬพB2<๎ขฎใNJ ( Aฏ/r7ฎ^o็œE$ทพBฅฦ™~L$|เถ๒]$‰2RRZย[J๖q”ษ๎ื™๘1.w แถ‰ลBษF๓C‚”I †ˆึ๙พ-จฆ฿Nษ€–์a่ำLœ€D—‡[Ÿ๛hb์1 มxŒโ4—Cq‹ศ2@D5L฿ฮ)kto•y1ํณ`.šMฆ"ฉŠ„\ฦlว ฦKdGWวภ$ษฏฐ™‚๕ฐcุOขคž‰ทCั๏เฟ:ต4E‡NสI'ƒด้ณโปVั9ะŽ8‚&!์์iODปjธพขง=2(ฮ0ฅีHฒ"อ๊:๚)ะฬ7ฅLหhP๙}๛‹?<ฌJˆmnE`จDWค$O#.ิธงโu!šH่ไ‘”ร84ต`ƒyฺ~Žd๚ฏ|6"Rืn~!ฆ๓(์”ญE6๏ๅผโ›—bภ"`๓M;ไ;Eา [๊ๆ$Nฑั+ธO&ส3-มšIAัn™c; MKๅญโŸ$  šฐ๏๏1n“-จCH˜@ลObเฆ  คe๚ดชฎชq|jุ=+,%™Zw๋กVƒฟ;ํ68อ_ฉ œ({ž”_พีหํกJsŽ—O็ป&ศฅž–Mๅ_๖ส‰ยp]โP …!ˆP žหมกgr=จPšอF๓eฒG> ƒ) บ;~œส#TŽ8/๋กวบ๊qษ‰๐e€ำoFฮฮ๎›.ง๙}Tฐ#š;ฏ‹้CZ(Ÿาก–ฅ„‹ฑX๔ศิ6Ffภ/G)‚y8–ฟด PY๖ึฆภ$)โ(เฉธ์๋ข๔$$J@5๛š/็ว‹‘ฤ%แPท้…R# าmธ*1ฬpvŽ฿้T –ะาภ"W" ช ัuBz๔t|ใhดv'๋ฒ9jจธd&Xn †€ \“šB‡7zkจ)๘ไฎฉปฎ˜ไณ๘|%ุˆXฮชg s๐z3)ฑุœ'่U5H๛`ุสชธ ”E8ฐ˜ณp…?หnฟ@ฏ+\yบT฿เŸึU%ฅAฬx)Cญ@ufowซ‰ฃ%tบk|J-NclงC7ปไ`+ฺ|y‡6กด์ฺ้Š,'4ค#ฌยš!yฦTดŸ๊'K3่ยrMฟHk8W/hkƒ.6๕ T~ดฯฺ๊x๗vไฃญยึw1Sfวd?…1XQค^นร(˜0ว`๑xฉ ฺห9/๎D้f}[ฮIท๚1eNvง,๚G\5VC$‚s m’Pีณ๓@ม8์:ณ[ฏ๏ฺJข้hU&๒ใ =]aๅh๘ ิ=ฃ"ซ•V^3ีฐลQ#ฮe.ตศผ;\_ศGQtll‡๙žท\ฎJ3‡๗ฎ รฑk๎;h8ฮšอ้ๅ dใวูQ28ไ’h‘์.j๗Jc}9œYฬ_n๑^ฦzKฺ…Znคศ3f O@\j\฿ 81Tกซ‰Emะuงน ซ‡Ÿ,*‰ Iอม๖”ŠฝJr๙‘ธ”‰ฉT@#agถํื+’Œแ๋ƒ0์@~Š๕ศๅ73Oศ‡w3Gึุ ฅถ%‰iv7š˜$Nูrbุ๘่6“]๘ ใl?๗1๐ ]ๅžTYuๅฃ v๙0๒ดG๊ัƒš3—IKจ&Iไ๖A‡ฝœgขœ}ฅ฿ๆฎ๛(†Fk\:เโ.๐!ะ๖๚\๕Y‰:˜ฝph.Mำ ob งGวŽh‚ ์yญ4๗aฆศ˜'r้5ฐŒF;„ธธฃถษdะ i*งฉ\QุJิ’๔๗‹ๆ กปUลz\ =œg3z้H ฆ‰ฐ-ส]FฑUญ] Kqm(๙ธ‘ธašืy๕Iฌ:ฏlฒฏข๒iX6ฉ่ ˆกชโ ถนP2ดฑู(แฏ‹`Eองฆ์~`š(Ž#ท=9๘S P๘อkž~i‡†ค%ฒชรƒข7ฤฃА0ิrcW-W#tํA†:วฌนอะM5Y‰:˜ฝph.Mำ ob งGe๊W ดrt0ถ""„š?'พ!ฆฏื00“* ๋้ซ‰NZหฮjฆƒHjLูTย)„^ช+„ศL๙1ฯa4|mdŠิ ถไi~K–#‘ \ถ๛ 9r&ฎ q๋c‡ึ ป†rЇ™‘ย †ฐฉEูฉ=.0XSฮฟจLk @w`ม?ร฿ไt]` ฌ†ๅœา‰g€0*—รZ๊!‡ „:fทa?Kณhฉ ะาˆฬ4@ทอ๑h%E6๚vLทcO!Š]'งหฌแs>ยผ๛ŽธV]uวhโLภqฌ @ฮณB) ฤQveพqรEฉช8ฅrม: ื ๑“อสค ‚mZำ‚?z‚‰– ณ|ฏ๎ษฌ“ส]ใv ๖ ๐๐๖ฯfะvrๆ[Žต`žฅฆ2‹ฑ2`ํl4Jๆ•NLธ:ๆ็D"bs ก๏LๅgฆžLsวกฬ6'€Dh+.บใดq&`8ึ gYก†e๒๑‘ไup—rPYA y|๋‘ฝr๓<โ)%ธ=๒อ.4ห๒a#็ท’์i$I’ช’ึฺWณŒค๎Opžธฯม‰pฃธO ดO๖*J7šไขMฬ4@ทอ๑h%E6๚vLทc็Fšdไ ,ผ:ูCa‚E๐f2X{":พ>&M}†ไฬญƒย}$๔MบF๙ีจแข,:vRI<งMŸฺถŒฮ„qฤ(ั1ccJz%Uล๕9้‘@พpู….ชE‘hQืัHކfูธ*`[B‡ห๏ุt\๙ๅbTCkr+B"ธล!"yvฅล?ฉ๔าGG DŒฆมฅซ{ฮำ๔s'ี{แฑ–ปs๑ 7™Gdฅj)ท*š~‡ 5;Ž›m๗!ผฟค Sj#ผŠไ-–nูHณ„ฯ8ฅญัพTmไฤsถอ€บi6˜H’v3…’Jœ3/ƒ˜jฎS›‘PไŠฬCEร`ฎ]ž( (ำ;PBV%‚ำf.ว‚ภษทEฌ8yซ‡wโ“;jOัััB๘_ป@๎๛ \๕ื]p่วZ9[ฃ!—%๙rมžp'็]ๆjบอไๆ฿ศCW17ั(๋๓ชม๋ํไ้mIŸล‡3เ‹5F๘/0วzซฉ›ซq๑‡ฺฦ;A†ว+Šำ คฆ $ณ!ข(—˜อิ*๘ไ‹’nXžmFธฎ*B9คF๐8S;ฑ [2fกu!‹Yฝน Uษมg฿J;ร/ฐ!ัเ8H‹ฑษ๘๔AzSบึ2๑๒fวnฎๅฉeF”ฎช๕๓›J…Cำ]ip้p7_ด่i(-skฦ๑:rlcๆช;เ8 ภๆธ;Qa4N๘$๖SyZhดWYมtDš•m tส$พZW0R†oฌ&.๔ฅ7ƒยพkฆnqBรนฝิศ$ นฤิแ+ใ7^0*h!0Iยg ผดh„๙Ao lkฉ”Oอ.า4฿J๐80ฐ-k'แ9ึ%-€*ฑเยX#’ภJa™ๆX๊‡Fˆุส,คGƒ6ฎธ*q๒๋ฎMOาQฑSƒ!ตaฐJ/pเๆT"ึ๑ƒL3ข+๙r”็ฑ๔fW4Ÿ™๒๊k|b!W๓1ueไmOญ…c‡aeมยฎำ˜#ฦZAทc ใbŠ'U0 ไัฉ๙ฯwฎ\!nผ2ีชฑี€Fธทโ‰A๑ฝ†ž'cKผ‚_TยHpธร๛%/ร/Hcฺ)ฅJœ.Oฌฏ #4 ๋…ฦŸ4;‡m4!‰Ÿ>œํCง๏ ว’มีXผฅŠ •ิโœีณข_ฮ:,น}า {9(้Šซลi-JkฏSJ๔=ณŠ๒*ฌ’ƒQปgJŽำ›ย ๎ใœ8ม๓:Y › าˆŒ‰.฿X๋ kญN1`คTaIฦฟ๘ฝ /'zเˆ_iฐ"!'ฦ“ภO_๗Š๓L‚ี:ๆƒFYดต€pm’„ฌN@(qๅโ๖๗šใภLง%DwGิฎ๙–ซฅ\G์–JKฑพ ฮ”˜ยฅณ๘ชjร๚๔kLUถ]ิ”r”บ็8iฌฐbK9ฟฬŠิu‡“ŸดรNX๛6฿ฅ‹~u$พjธา8ีXe]mAตaŽิ0`ฎSฉŽ’ฏ– 8A๋‡ˆŽซCŒไ’#‹ๅ@‘„œ]`ซˆpd>œ“y/ใุT ฦ$Dส$rแrฑiท*0 ˜<มภธGOฃ”TZ‘]บรi‡ 3_นๅFร- QึLZ~ะ 59c์~”0 ‰;ฎ้r ภŽ๓•กL|สๅx๓๒ฯ Hฅmžห—‹k2œดึษ>ฉIฮ์ นW๐fขbล‰hq7ผีศฦ•q0ำ@ฉ)ี\Žยซ;`fC๑E–ั$qq.ปJ็Z0ŽBีfD99เๅฝ‡๗7ฒฌ๎PลˆX)ฎ’m5เ ลฎW!บš฿vใญxะI=‰Cu (๗ŽจดK’•ัB@@ฆเ04ฐau„K=Œkf)ดมื~pฃ:'wj#ฟ‡2('ธ7<#XRึ#aฌ•.qขฒU#™ขmณaฦ…’30ขชู}x6่ l-GRสซhผ+K)ฺ=)ภ:ทฑ_‹P_ะO๒กฆฺJ ำiฌ™‹žฆกล€#ฌ ร_งำYQqๆvํ „@a nน'p:hžLt๛G40Jซ=ทG๗ิ@ๆใฆ0|ุ@Ÿ๐mๆู™kอถƒ ภร0พFšKv๎๕ญj U“€ค๊—ฆ๗gW7ร์อะ๋cVh?šŒTˆกธี)“e]ํ05๎ำv'ดDฐ๖’TyFpฤฅ๎–ฆฃ๕bK—ปE–˜Ž๛ส›‡]กร ™p6•ข]ผ๕lฦYo <ฎŒP/2ฏ;โ=>ฟŽB#Lฐฺ0ด„pฒe๔€o"๗ฃฌใ`รษฦ” L๕mb{Dึ!I$’I$’I$’*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*TฉRฅJ•*Tซผษ\•ๅk7J›เ๚สคฃจ9€ฯ(uจฌอ๎๕gขG<Ÿั&๊&CŸaตฒๅเX๒kลxแุ๊ฮq’ฟ—> _“"@ Urœzฟ œไ&D2๐ๆZ'ฆdL{Ž›โ0ื ป8W&๓‘Iนึบ=ูฏาšแg๘" ป\>"่ขJŸGEช( ืe5Nฑ`ธH"ช[(ฦQ!ŠEิ 2๎‘S๒jt\;ณTย—jฟœ0‰ ฦฒ๔Kธัๆ—ษq(ญบด๗!Up๓ๅ…Q!Bbษ9ธ>าƒัWฉ@._2;ื‘5*ˆdl?ฬ๖บๅrQœ?ฝpfˆัCฅNืค๕O=1IศN‡$H‰5…๋-ค(v๊ฆา‚dแkUvศณ&‘น๘ฒ,ฦไ ŸKๆ›ะ็ซกp(O‚ ุฃ#พgภ,ฺ€!aฒ—8Ž่๎ศx(ุอ3ึT LKมŒม˜:oq0€คโ]ZJQ–~ึ_'Y[ ๑Dษ?รK€ฆ8VDrA^‹ƒ็•ฤ†—เีf‘l-p๕ฐฯaCVoร‹ซškAพ,ผ~๛Wƒํm7G๒1~ด{ใzีเtญB„ำ”wo๏ภCกฒู•๒Wป กมP๓‰ชr$ิ`ŽšEQ‹z๊ลกrgฬทi๖?ฦ7B†กท„ฒฝ15\ƒ\U,ถEšญ7~Hผ@8{Ÿ”น5ธI„ำ”wกรฒำฃเุL<5!-•Vพ%Pไ†ฃ“.ุšโ€า;! ร3xP'(ข๊’v@๐๎ Dา8ˆย‡๖๔‘ƒEฝ[n{CF4Š^pฒ?kim{กณ4?…๓F๑Žม‘“DฎmนTไหƒฎnqดB&'2:๔อ๎VziไวNจxแL”I^i&e{2Sว[ h‰ รErด?>ฐย ฐฉง่rQณธ้ถ฿rห๐:Aเฤ7โ3ˆา\ ฦ,{ ษี0ุฟฝ9$้ะธ๚„๐ใแป‚จฃpใ–3x„•ห๋แŽWf <ศ#•Bฌ9;ฬ:%Xr&้bpืมFแว-f๑ +—ึ#รฎฬ๚yG*…Yบrv ˜tJฐไMำถฤแฏŸฟ0d\ƒ} R[ฤ้รูŒ^ฏx7rŸใoJ<๐ๅvbknญ^Wg๙มุœs]KB€{"‘‹ีใฯƒข†โNS`อโภc  Gžฎฬ.lhค*…YตอุอœTvฐ๖E#ซวžE ฤœง๘ม›ฦfŸ๎ลฎW79ูะ็๑๓๏n0ไMำถฤแฏ‚6รŽ[ อโW/ฌG†9]˜Hj&+ณๆธ™‡$ขภ9tํฑ8kภเฃpใ–3x„•ห๋แŽWf <ศ#•Bฌ9;ฬ:%Xr&้bpืมFแว-f๒ wฃPบ$ข Žต@ {Žlุฃฉbฉh(ฉ.ํหƒ$าี4CF้$?1ฎPr”@—‚tcฑฌyทผzฃภื๗ฎKnT—vๅม’ijš!ฃt‚˜ื(9Jn KŒA:1ุึ<=Qเk{ื%ศั8L๓~ม\2"ร^7ฝ๏4ฟCDW %$R๏ฉหƒ!เgใ] !ฺ A$ทLlBผำ"$5sฝๆ‚ะ!๗่hŠไคŠ]โี9pd < kก ƒD#›A("D–้‚hWšdD†ขwผะZ> \€”‘KผZง.ำ=rฤ๛ฉŒTxใ^๕ษrส’เ.ธ2M-SD4nQขC๓ๅ)Mิ qˆ'F;ว›{วช< qฏzไนFๅIpn\&–ฉข7H(ั!๙r€ƒ”ฆ๊ธฤฃcอฝใีธืฝr\€ฃrคธ ท.๘.k๏9ก™๛vYe–Ye–Xชฉ]ึฟๅ๘ v๔6Ye–Ye–Ye Nภ?มา๚ห,ฒห,ฒห,ณฤ/!1AaQ‘ัqกฑ๐๑ ม0แ@P`p €ฺ?!๖@dˆ3~ ,&ˆ2ฦู่œพ๘™ภk๙XD$๘8ฤฮcศ:.ษ&ศƒ x€IdสiLgOฎ>cน?‰‹`8ฦk009(์lฦ:?/ฏ€bS+bย€ๅ3AAwRภข”*%‘"X]9Ÿ‰$น(œด.jP[l\๐ัGบš2cz€nˆฒ๘S(%โขU"ุS Ž<[ a1\€‘ฆl๏ีˆmแQ5งTม!nผ@rษˆ„ม8dๆwEญu๘๕ปฉย#”T๋7ฏ3E .ต+ัO๘‰DAFER›s”ูX๑่ฤม  2รdช!ี๚ 0ำuŠhLๅ๚บ,ˆ”E“q@“)5(ฌ&-<ฎ  ไl๛๑& ฆ_sN‚m"‚oุBcฐ๛โ๓,So #;กˆdมใ œSฒŠŒ…7ˆ๑ัD€แžlๅำปฎ‹X๖I ฟ๐b='OD™DฆOt|oฤ W.Gtน๗  บ‚""mิคก˜3 [ฒๅนAŒ e$๓X/ DษF$a>$("$วB!.HTŒAXDอ” 1ŠsdกHUฏ\้้า™pยL"S ศ "`Dฐi๑๎„ๆโEi”[€14{ ห3;3"}๕C€ะ๐โƒอLำฮุ&ถJ ผข„4SJ'โ4ž™…๋N่ภ`œ^ิค  Kู5-ฺ*J •ฝ DAoฺu€XŽX ฦaZ -’€lr‹๘ัM(Ÿ‰ศ‰หล๗ุขุ๎žรI ~ำšอ ็q’ฅะJศ8€~ง,SBณCย†'šy0` N‰ E๐อ‘œฟ้4-€S830P€aฃPาzlฃ 0N8ฺศชiรDAA`ญ๐mLำฃุ เ€ุ{( —ลา&:† tฤCเŸ .่ะขุ๎ƒP๊wฒƒ์ฎ–ยŸŽณTๅ๘8dˆ3~ ,&ˆ2ฦู่œพ๘™ภk๘0ส?”Ÿ›เษ6,[๑aสœภŽ ‘ฯ˜ฃ™โโ1ศE@dPฆ%มภไฃฑฐ ห f‚‚๎ฅD(TK"Dฐบs?Hs Q๙9h\ิ ถุนแขuน4dฦ๕d๐ฆ0P>KลD&ชDฐฆx›RH\aA9๓@ มQ…; ธโQ(ไล8€ฆgU๏ูL ๘ชHว-?Hยpร‰B&ฤ็š-D€ฆ4SXEb“ไ3N"Q‡(!็๖‘ค|ๆ„!นPศD’ฬFิŠgง…ัLย’?ฐ‚‡‰" ง† ๒ลE&F!]{)-eC˜1จnฎฟ฿โpฯ๎`นฆ๚ลDmAHฆzx]า์CตBl€–ฉmัฉาๅ2F(FชZ(ศฬมA!˜๗ž"2ิ7ฒ\๕'ศŒŠŒvŸ่f๐šG ฦŒˆO?฿€บaูtpWR]INฑF=จัdƒ เ้71| "€G๋e0q๗๔Sƒ)ใ็& เกฆเพ‡'k-เI์ฒไt>๘†ญั0…๎?w*ะ™=Šj1S8A?‚B:EF˜€ัlู@tฟา $?\‚Œ>Š&ฅ;น(Nด!มžuBซƒ9ฑO•ฦ>h๗@žฯ ›3Vq๓ฏ$ใๆœศNฒ๋ิ๗›ฦ๋”`0`5ฤ€d`฿cบ" 0๚(š•ั„Hข%œGc‘w0„•}:{ษภๅ.ฮsFฯ„่ฌผ$ฉญศะ™ห๕uุv )่™:z$ศ‚%2{ฃใ~ PˆBนr; D ฯธPจMิh็๖ }% ม˜j่—-สD`0h{(|€'šม|…&H1# ๑*๓Gภ๎  &~hฮ}๕FI€‡์DดšุขD5oฺ|๗_šฆ&ฃr9<_‚$@ไ„X$Dม‘A‚{Œb\๐)$†ฐˆฃ™FN'ึ6P>’‚ฐ๖Pษ@ภ6นA "LtใH:bO‡าhกuN๒ Ÿœ_u๋N่ใ˜Eฐฉๆb‰9:ข ํn !ŒQ\ิ!˜ฦ/ ษ@ภ6นBŒา;ฆไ บ€˜ FIˆ4%+G กะป๋ฒvๆ “!rขi๊ล ็q’.špไ฿๎€ข›เa ส๔?รe’lรฦŸVL‹ึ‰p™ย็ฤโ9“็tw฿`ฌ#$HุW฿Iฃฏ“์฿I››ๅฤฦH™แ3 <ŠŒAFŠ ™,ˆˆžO/๘ฐƒ@x{Apุ(p–‰ปไP…ใCฬ[๑i๑๓$เฮŸ–b์H์ˆ่ ฃ~Iogแิต๗ว๑ …ผ๖x‰™ Ÿ'(๗@h:D'Xฐ,่S P2ฐOคcU‘€‹9h87ฎ์ศ™ 0 „rR$9˜ ๆ ‚ๆLะ“ˆ=ศ@]ƒ ๑I`^ยC$อšEŠ8นก˜$ฤ‚„ิฯ๙ ๖A4K‚žjg˜(:ณภ๙bแ&นว‚š๋’h Q]“จ๓ฒ#ณ๑ฌ‰C~ไIๅ! *ฬ&ิ]ะเอ2rใ/‘@ฬ๑faถHถfA ฝPސโๆ(Ÿฮ"๕๖ˆ‚ฐ$CU5ื$ะขป'Q็eเ1]€คฉษผา=บงJ\dbม!ร>DXดƒšฌ* ฏ$,<ไ*ฬmำ(เ๔,f zAลž9‚‡ผ}ยSว>ศq ‘๒zญ๏ัศ{ฟF@`9ฅwว }"„'p`Xด=”ไw™่ฎnยณ่†$ภฦV!ฟ ุะจเ ระ@–F9รํEY0ัRa๊ล6๋บ†tฝ.œฬ๎C‡nซแบ`ึซร๏ล€ลXDG‹ฆ Nฮั@ป#ุ|”0rV‚”<๒fN‚zhxY ^Iข 5ฤล…)จ„ฮD”Er@ @E (ฒIrI.$˜’ง{ทœใ`Lˆฤ– ธ•…๋9|I€›นh8‚๓˜(จYไหhZ l$C]˜RyฬPTD?ศ ฐšš'^วฝ”ย%นสe2ŽฤŽ@U\!Š;(†€[ฆB$msึz&๛‰@`ื˜"๔ฤฯ"1๚G"3“คpDฬZ=Bn/8/A˜0งAW|ฉฤ0€ฮ QœKwLCCิ…แƒ>่’oW”ฆ&A๐~ำd–6zลจฎzฯD฿q( ๑๓y<๎g็๔กๅ‰82อIS‘๖C‡€ร™E‚.pซ ฐฌG)โ›#\EƒbฉดLตq‹ษิ#€‚H็2™Gb@ว *.ล”Bมี๛๗LDค9 Mมศ‚{„(ฮšPp˜# c€s‚1W q™ŽœH 9j[@ฑ2ŒดBอุ.z‹ัะ€€Zศ็Nkšโิt.ู@„'n‚ถC8๔™ค?h4'ฯ,‡f7$,u"8Fฮ\$Kูๆ( `)ฤ๖แ๗โ œ+“qbสs ๗Gmศเqs?ฅ ๊ d9"ูจค๑ศƒจ bR ผxS๑”ušฅsๅ๐งs€ุ“S๔…ภ,1•ึ{FWฒž(ำAพaS(œ ย\เa15๎งควๅ’:Qูv9ข‚S€Dสภ @AW‚b,Iแ`&,a‚๊0ม‘๋S”h<)ก`9์š~al„ศภฑt ?œฎไIDเLทC; Nฟๅ@ำDฤฟ๑มb่’ƒ๑ขฮ_฿ศรœJu?๑ง!\Hก?Š)ธS/๑ ^Ÿ€.ˆt ฌ%แ3…ฮ?ŠไQ8ธP}๘Œ„d‰ ๛้4u๒b›เ #3s|ธ˜ษ3ผ"aเ&`ม‡‘Qˆ(ัA‚%‘ษๅh‡<W‚‡ h›พE^4<ลฟVŸ2N ้๙ aภV.ภTŽศ9€š7ๅั7K๖$ni;ฏP{ š%ŒมOH53‡ฬYเ|ฑp“\ใŽมMuษ4(ฎษิyููxึDกฟr$๒„ŠnLTจKซฬpF)šd6ๅฦ_"™โฬรl‘lฬ‚ zก!ลฬQ?œE๋ํ`H†ชkฎI 1EvNฃฮหภbปIS“yค{uN”$ธ> ศล‚C†(|ˆฑi5X&T)^HXyศU˜ฆPม่"Xฬ๔ƒ‹ x1เเยŸฦCเ/_ภีเวเะ๘ŒL›ฺwึ๖\๘ ‚d™Fhอ L‚*ˆH๐3BhA*Œ#!ภd‘Bศ฿ˆฒM<_รๆŠ2pขกTSpขUš-OBH†๘Eƒ€M ก4fม7!ภ&‰/ฤML€Jฃ5sภ|hอSƒXŸทช|ภอ ช๐ง‡จ.ำธทฒเ/ภ '8ม่Sะ Sมธ8S Bxบp๎OC๐%ีะง เใ ฒppqTQขz(ž…“ฒp*‰„>.ก‚zƒ‚ž_€0เแ"ž ~€กD๔)่jฃn"่'‹๑<]ํ€dHOBง-ฤHCใฺwึ๖_๊๚ำธทฒ„vว๕ฌ•ฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš+MฆŠำEiขดัZhญ4Vš ฅ,ทษ็ภO ใ˜‡$้<ย0› -#‰‡๓™๔เ41Kน $ศ0P‰ŽA€Lธ*Nš๘ืDQ4๓2˜™‹็G07มฒ Iw„˜Dบกฦลƒืcูo“ฯ€Cฬ8ข2PvBcS&ฑH .EigM๔KL60 ศK„์ณ˜  c,Pƒลภba[ล ่Šส DT‡๚œl Zq3”V?}ค\ไ ภfMุDSˆ ุŒฐ ค ‰ƒ`qQษ:I4eก‚A†ขz"#+ฤ‚CD`ศฬ3BharCยŒ@ฌษOYf(ƒrI'เ €ใ๔ฃ2น:!๙(0*ๅ4““†ฤี–เ€ ู~ะnˆ๓๑ŽhBนhย 0ฆH_š„ฤ๒๐ K1บ'rLภˆšฉ<ั8ฤๆ’ฮ4z=ั L1็ืฯcูo“ฯ€Tc5p#hเ€ˆฤ(hŽ>อ…Pr•€$ L ‡ฌb€ Œ0˜"@šฮn„1Ž๏Œn๋1dฮ,”คF<อ'8ษ€R/ำแภ s'Hbƒƒ)1fb‘“ถ"ภ๊DI-A ฅด$ป‰'ne 9$˜Pแa<^‘Žˆ3ฅ3Fx;็๐ Cล)0‚T#-5 "ุ&ฟ+*[ &๓…‚gE.1แ “–ม:\@D ŽH`€0ำ`ไ–D ‚AQ“q0ขk“Šhฉ‡๙žวณ๚ุŠ!…ศลy ผ…^Bฏ!WซศUไ*๒y ผ…^Bฏ!Wฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnฝxz๑บ๕ใu๋ฦ๋ืืฏฏ^7^ผnŸ็-1pqทฤณ: #3s|ธ˜ษ3ผ"aเ&`ม‡‘")"Bซ‰วแอ8ฌปy็€03"ห8อ๙i๐ HXฑ2~# ‚H‚ไฃ+ฐะq˜ฤ 9cฦFnต 6ฒp?‹4‡ดโ‡`ธมŒ_HใŸXโ… ะKeูส™‹ี้.b‰โ/_hˆ+D5S]rMŠ+ฒuv^ุH$Vg‡ „Tขƒพ;ง’A ๚rLdd‚'0 3cัเ„ั,K็=` ์žฑ(@ภ'ฑ˜~‰“ƒฌœ tšผKยฌzใ4„]ฐb‰ศCJวไ๖Q˜1(ษ> „ๅ(้fdš่> ์ƒ “krC—Š…#6AZบ Šฬ\1ฌ ŠๅQภฤฬKF)๏œ9vบO–้>+&Ÿ0lŸคเL*ฉ ผ๔๚Lภ‘œ'ีวC-ฑAbŽ…Fฐษ;€aฒ>OUข๚pคร„้–ม x9€ศH’/R‚b "ฦม ่CทA†&๊z ิจำw3ภ๓๚Pkล@ปgUIใ%ํDฮ 2(ษซa˜$๒ฤบํAญฉE8g6ป พqLzi†s,f‚™p$LLLCuC-๙ฮิ'"๚ w.็T CUฟA˜(|"'ๆ/ำ ฦ6“!vNoQ …ห ` ฤDH-1ม่ง€ ’X`q2DQ8q‡4๋ิ&า๓ˆรšˆOํA2h ฮฆŠ*9’˜@รฟฺ(_œTใทG „ฦผžfœ#ฮ!t,]0hu(ZnD!Ftะr€I‚ X) ๏`:&™0€~O4R&I`3( "H‚เๆ1nlปุ‰ฆLเ“อ€ ’X ส’ ธ9งLDเ[›pax–)”มU…•S8Šo<์vx‹ŠตTภ*o‹G$ฬนไฆP[VULเ>(€ใqย™AlXYT!b™ก๐tฤNนฒ๏`:&™0€~O5 uœฐึC๘  ]๓งLDเ[›.๖ขi“8ไ๓E d–2€ย$ˆ.iำ8ๆหฝ€่š(Cตb@@ณ† „ฤ(ฐg๖Qš€X’ภฌำบืv48ฤ )ลGE4„D0H`แล ๏เ~ส3A @๒€šwZ๎ภ &‡%!ุฑจโแศฆˆ€ๆ 8ข!e\’I$“‰%ฯ ห€"ฑPd† q๘ภ‹ฉ9%ล& "$~”wF3f1ชฬ ศ1 &ใ๑/RrJ3ŠL$@D2H0(๎Œfฬc๛U™Ab (Mวใ,^ฏŒ11ถ0Œ 8"šB"˜$0pโ‹w๐?e ‰ y ภM;ญw`PCŒ@’์XิqpไSHD@s†Q`ฮ์ฃ4!ฑ$!€X งuฎ์ hqˆR‹Ž.Šiˆ` มรŠ,฿ภ”f‡,‚šถฐญ…l+a[ ุVยถฐ€˜Bถฐญ…l+a[ ุVยถฐญ…l|Lยฐญ…l+a[ ุVยถฐญ…l+c_ฤ0!1AQ a0`q‘Ppกฑั@ม๐๑€ แฐฺ?!๖Coqฒะ^‹ฟh—žป+x=ำ๋'ฦ;๙Wมฆ*ฤ@ @@aศŽษ๙’โ0๖ฉv“~สr1ใภ„#xงษปu๕w8่=็™e้^yUึ/ป ขŸถ•‹H%2"w\ฺฺฐ|“ฑศJeฟำ‡€@ฅM,B$<ๅถฃs1•ืLยWqS^•J•*Uฦ๙อ)8{D๘ ํ#ดฯmT”eh3ฦ!T$=f ฃkk„RJาข,  p…ลKยO^๐gY ฆข ถหt0Xป-sTS๖าฑiฆBร$N๋›[V’v9 @ฦ0a‹lฺร2พณJRมEฒT—Z‚f้ฮฬ้–|ผOโ^ไyeง\’ณsน\TeMCิpNฆๅq\W+าธฉนYŽ^5รRฃŽjๅNฆๅJ๕W q%r๑_#^ด”คฐยk๋fะ๙%็๕™บžaคฦ\จ[Pzmš{้ป:Ÿธ๚~Žแ ๋†;ฃ๋NกรืฅNG"๊ใPบjเ๗,ณ๓%ฒทธ yฅ—฿y™บžaคฦ\จ[Pzmš{้ป:แณ€–น๖๚Dอิน7;วHิaฟQฯP„w1ณQ‡ซธ๎๎;Ž‘แŽนfQ:„ฺx›z;Ž๘gSใฉโ3จ|‡A{ญ&L๔ 4ีใ ะ7q ฅหM }เ4ิ๕ n.ำยชPU˜>ภ ย '‘8ฺ ‹[GE‡;Kc'=-b,เุขฐเ|+๔๗พm็ป—/7อณ|฿Kš—ฮ5ก(ธขtา†k้ฆฏcฎ3G6ฮี5๚ขšZูCศวkyŠบT$ๅด>ง7{€„kย›*ฬ @@ึฒ…‘h0PU˜>ภ ย '‘8ฺ ‹[GE‰gA@Vณ@_Qซ6hถฌ†ณ˜หSV"P‚คG‡%UaAFลE๕อ๓|[ล๑qฬ=Rๆฅห๎w|[ล๑sp๔-โู๏-โๆๅอสeK—5.u/‡^‹f๘น|:ฉฏ™ะ2F‘2"i:f=`ฏ–ฒใฑึ๗- ล่ป๖ˆูะi๋ฒทภ๚Agลั„ตัwพ…ˆYฦฺ,{ˆŸZ่…\J,Y,ี‰zฑ…ษq{Tํƒ;Iฟ e9ˆ๑เBG‘ผSƒdn:๚ปœtsฬฒภ๔ฏ<ช๋†QOJลค™ ‘;ฎmmX>Iุไ%ฒ฿‡iรภ Rฆ–!rQน˜ส๋‚&a+ŽธฉฏH•ล_ลq^Œ ะofVฅSWœŠฌA]ฺฃฝ‚RfIนq”-pˆถม˜‚,…l]0<$5ผใ๊Vฬu’ฐ1ุt+1Mย&’Uาล[6 ฐLั’^ahgk‘( แ:ฉŠŒอ0ย็–A’ฏ4ฦฌิผณๆ'ขนฉผฯิi4ฯฺัLธy๖โขJ•+yธ5 ธ๚™RฅJ•{อยVcฟ˜มฏZJRXa5๕ˆณh|’๓๚ฬฦO0าc?ฎT-จ=6อ=๔๎O}?Gp„๎uรวะpxCP†/3ชU‹HrพyBพฤๅ๛ิQn‹nบ๑yw,ปพฤQโ๊๋=ฑ{ึ๖Lลุ1?ใJาqkจัjฌลŸO!ลฦเโŽใจxŽช—ิ!;๔ต0เ฿์๊&Ž๐รpw๓์ ด˜!3ะ€ำWŒ03@ฤ*—-41๗€ำSิH4=ธปO ฉAT`๛(ƒ(žDเ_h*-mbํ-Œœ๔ตˆณƒbŠร๐ฏำ๙ทž๎\ผ฿6อ๚.[aฉoลพb๚Dา่C&ๅ ณก\‹ฌ`–Œแชt.UP๗„็-Rhšฒ‡CฑF%หมvP"("Rฅฝr( ี”O;กfญขU‡(กณXŠข$ช=]e+jฆ0U+ฮqธ้2&ฦ ฝ %š๚‚ ฐ*p*ืoลห›—7.[1ฬิพ-แืชๆๅณrๅฐ#5/‹"บ]>‰EŠPฦ:วฐฏ„า+1=sˆวš๘Uๆ'|Wชพy•฿qฌวร:๏bUถตv.|ั๐Kา ?\˜ํมzิๆ@^zษ‘๏>š.{ix:๚ำ่ฯะ;=Š ๓๋7๗ฐuำผu‡บีGน„r4”H|ฃื๙Ž ๔Žกโkะื$ธ๕ฐGฬิ๊}#ฉcจjๅ๓;\s.1๓4W š=D๎jurๆฮ3ไนื!Œมพ;ไ"ต๕’…}4cฯ‹ฅ๒ร์ฦ๚ื/ิgSeภฤแ7ฟAธ0ดDํLูะƒI˜! v็พถ๕<๚a๖Ofซybึฏ‚ผฆฅ๛ร๛ฤ+•Vณ_~ฝฝแ\ฟผw๒Ž*งqŒ#7ม+พ7ฦ+’1๊4ล๊4ฮฆ๘ฎใQิ5 Kฦง|iŒaใŒWฉƒ‡’[;˜ชใร˜ๆ…J๗…T8๏JคL์Nœyq>กD/]ฎฬuฮ๘๙CPืิ#ž;‚ิ"ด•“๖}bk*ฟฉนEต๎ืtชJทฎ‹s‘+SwืาพฯyUฌk฿า  Cถ ึบ b‡jA๗Mะp๋{7šฅ#ขขมำ๓=tณkI๗?๊w๒ญ๘rพ๘ชฅ‹_ฟ๒๏๐‚WH\ฌฤ๔uฮ#kแ}eq^ช๘AๆW|ฦw๑k B7 ซื๙Ž ๔Žกโkƒ5ษ.=Eฌ๓5:ŸH๊w๊†๙|ฮ็WหŒ|อ๛Mขw5:นsgŒr\๋ฦ`฿๒Z๚ษBพš1gŠลา๙a๖c}kั}Mj:š8๊เeใพs;Œguรษ๒ฎ*งqŒ#7ม+ธJใษ๕b๕gS|Wqจ๊†%ฮใSพ4ฦ0๑ลช˜ฉƒ‡’[;˜ชใร˜ๆ…J๗…T8๏JคL์Nœyq>กD/]ฎฬuษŽ7ฦ*`„(ƒ(‡ฆผ1›Œ๎yŒ3ม๒อ๘rพ๘ชฅ‹~ั๘เo๐ื๒ ฿แฏDฏ„&'ค.๚Rž~ฏ› ๓ค+ธ P3LฌิLิร)”ŒF ซส^cWŽMM?YV๐2ฉดส0ฤJ๙ถo๐ื€z`ฮaผว ฤcw- "TธŽเ[ŸDm†า แ˜ฆnๅป"=ึo๐ื‹ฉoอ๎)\-โ-– xท‹xถ[฿อf " D5ˆ7๘k๙o๐ื๒ ฿แฏฮz;๔šŽน๏Ž๘<๐๋าo๐ื็'\wษ็โ>“†ฟ‘ " ถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒุ›7๛๐S^…ไจlถ๎ญษf-9ๆฒj ฏyฮฒแa†I ดm๓1CIjž.†ฏ“OTnป_~œk ฝทjup๘‹โฑ ž์ž‘ฉhทลโฅผ[่ท‹slผผดดดถ[‹~Y฿๐ฺ‚“่ฯs๗Os๗Os๗Os๗Os๗Os๗Os๗Os๗Os๗Os๗Os๗Os๗|๘ ?†#๙'z็๘Oง›&฿ี๖c|*,m๊(๖zqO…^bw2x7:Qk|อNงา:วŸq8ผƒf^G๖xPwnโ[O7Xแj3=F_Q๊lŒ'๒?–7๙Œ๕ ส฿TZฎl7‡๕,๒.ฉZ็๚BQ}ทๆฬตฐŠg๓ฟŸƒฌวs้‹๋‡p|๐oฆ/Qฆu7ลw็่g=ํฒ๏ญw'ัqB๛WีsนŽฃธไ•|ฮก:„ท[พฌตท๊ก{คM513 ต!€ฝjขALbƒ ~ฏ๊&‹๕ิ‹ฯ๕ ๋Ÿ๋ำSpšc:ใ|ใษ๙Gfฎฮ๊ฐฮ๑Wธ ฆ'๓CLm›ย›} +๚LIdxhOึRk—<ะY๎J;5vwU†wŠฝภ]6๑?šcl้_าbH๋#รB~ฒ“\ผiๆ‚ฯsŠฬ_๒ส5n๐Wš =ษ๎bปอV9^*ๅ–ฅx+อ ์บ Ÿ@+hโ0}BคIFญ ๓Agน=ฬWyชว+ล\ฒิฏyกฃšใ"“่-fŠ‚บค”jเฏ4{“ลwšฌrผU๚ฉ5หฦžh,๗%šป;ชร;ล^เ.›xŸอ 1ถo m๔/้0ฑ5‘แก?YIฎ^4๓Agน(์ีูV*๗tฤhiณxSoคI‰#ฌ ๚สMr๑งš =ษGfฎฮ๊ฐฮ๑Wน_‘Wสเศ„5P€ลที:ฮqŒH6M ะภ ู%V•…ั,ไปล‹žเfฎHํuŒKR^_*‹TCŠ7o๛ชuœโ mšก€ฒJฌ)+ ขYษw‹=ภอ]ผ‘ฺ๋–คผพUจ†+Mšuแดe[x๐-h”ีšสฮ1‰mŒO,vจŠฅ—c๛Bฐ•๕‹mฝXอื า์;ๅ›๎ืgEvง{,ึ1-ฟ๑‰ๅŽี`1Tฒ์hSฏ๖ข~ฑmทฃ‹ภฐ:ไบ]‡|ณ}ฺ์เศฎิ๏ešฦ%ท1<ฑฺ  *–]ํ uราbธŸ2์าฦ1-Hy|ช-Q (ฟ๏ฉึsˆ,bAท๚hV†fษ*ฐคฌ.‰g%,\๗5v๒GkฌbZ:๒๙TZข Qป฿Sฌ็Xฤƒo๔ะญ อ’UaIX]ฮKผXน๎jํไŽืXฤต uๅ๒จตD0ฃvฟ๚งYฯVtฤ.!1Aqม๐ Qก0`a@Pp‘ฑ€ ัแฺ?๛  ฑAX๊qทฟgC ƒำ๚6ฎนcด[(ใณจmŸ-A‚&NEฑ๙€ŠDข uฯzึ‰TPจ|6%ธช่Z5‹0ๆMิาๆฬYBRq› ึคZPˆสตh'EH5IniDh7?4AŽ)v๚-ฌ „ด~OM้Q@ิณนz>1ะh(t๖1.>๐ฦOษ,AืาฆJ‹(Šนป'แf#์เC‘ŒR/บซ ขปR๊™?ฅ”mภืหาŸฌp™v!ิOึ}ย}เBดA!QJตฤ#`?ฉจล›๘จะ๛I…ฐึ่ฒh ษำF›”๔2ฐ Tห@ถฎ า(@: ญbŠธRแ„TœำS 8 ‚0K0^๘JษeG!6ธฒฌสa$ŸสศWš @โ‰ฐa฿@qจ:ภz!น ฐCร๕ Z]ร1Iูh>kะ kํฐ[) ข†ฒA:ใคฦ๑dTqŠc!ฏ!T|Jpฟม ฃ{&ˆึŸD์ฺข`W๙ีค–{โRP`๊"ร็ม0v“ฝ“ภ๕ ท€sืt๏%ดำš๎๙o›_ํa๋ัร๑ชbhก“:จใ๗x=ภ{—์–]ฦโ2 † hฑฦ#ฌณนธฌ@ฃ+Xศภ๛0€ˆฑšAวŽvป‹ศ็$๒@cxVDTœำS 8 ‚0K0Q็70ถC&่P\?]ฑ์T =แเฉYeชD_oํsบ k2ิv ภฺมSZฺฅ๖Tf&่ƒ-ณ+ภ”ูฮยฌ๘%ญ”ŒT]ุอ<ภ%H฿ƒซgc)7เKTภ๚ฐT W๛ๆฯฦล ถu-•๓ฦอ๙ห Uผ\Umซ:AะQ๚†Œpจ‚}˜อ?F—›\6zu)Fก5 Oฉผ2]TฆW๓SY["N;‘X–9•"ผูdย9pi๕ู{่œชดXKt%k €@ภCCQ่ฉ$@๐„ mษยT‡’da”ฆฒฒฉeR•lfpฆน"๒O์ B4†~ซj…ณ–3์L9ฯ)†ดkgผ$d€V๐}า6_น …"(iS4gฤๆŒi฿Dํp๑ืB‹)ใoW]‘ูชœๅˆฏงwo#๕[ฤHก้#1Ut6ดA—็ษ๛^n 7%#›)I]ชwm๏*…X0ภ€ฅJจ8eบvค]ด€๛้็กแ๘@ฌ'ถ5LZ,Šญ‚LE๔'•0 *ฬCj2`m,œภโwษŽr”2ยtบQ@ท—~~ฃaa JCอรg5—ึ๖tk!๐†ูe„/+ }ึ}^™Qkแwe๚e]B`wpOใวม๛“QJiท‡ืษBS6šพObรก ’ฝๅ4mฺ†๋Yฐ_Dg%โะญ/Uู๖ย"lƒ๎•~Pˆขฆ่WกฟŸnีศใ€xข‘โ;œjAมzt4|ำๆdฅœธ๖€aญ˜vpDโร""ดิ ”A ด Lฺjฬ170Hcฺแๅซ ˜฿ถ)qนlา€ฌฎืำห๊“vึ)ตˆ้QVŒ•จˆš[ทื C‘˜@&ศ2{;>ุ@( ื]jน8i!I:†]‰HBฬ-D5™ณ#%{สhต ึณ`พ‰ฮKฤ:/ม•๔ฅAๆvชA< ŒpT+ี>†ํ…ฏุSŒฮd่๗AœP๏เ„“˜ƒXบ๙HUJƒœ0 f๑5cŠจR|(Gapƒาปํฆx๚จ€ฐม{sิฏ(9wปg{€n๘๐0ร9,๒…d กX €lค\*^นU>]…   +๐๒Z…’ด& Zภศ:UำYp/ฦ€ ฉ[ —ฯsฎ๑บึ๐s๚)ฐ)T ุŒn qสจDโˆ‹ม•๙ศ~ึ”ŽJ๖ด4qZ 0ฮK<กYhVเ) —ฎUO–้นr…=ƒvโ3,„฿4๐„œ#ร”๒Ql฿{ๅณj!กฤั\Dtี†ํA‰:p:Š่ —ฐะ“9ใฐฤW[ั๒แๅ@ญ]%อE—ื5It‰d"5Uิ8#>8P๕‡l„คฑ* $mS๑ว~1vLก่ฤG&:k|Br๛hทิณเT)อŒ^+$.’DU%โ Po์”ษ „1C์ˆI๖>ุื}ะ฿ฐ#eำฎ 1T๘ใ=“ห"้]เ†œฐ#(ฆb฿ฤŒไษHลD_ํช`กหŽ๐:xtึ%ศUy%cงU‘'J„๋ไ^ag$rQกQ๒6@ชโตง!?a&ึศEI*!ธฐ…BBVGซํC+%ต4Eี:”$H๕qUฃ c% CูChYฯฌyVrย สARXN\:ษ.ัu`มรศ-์aฉU/˜ฉหฆT๐@jเ”ถฑh,๕Uภ„.YIQฉ* †™ส(hF๐^ฑ<&6fสภค@dzธ;ไ-[&Tp๔–Tจ4ฌ€์ต&“’‚^ทOถ;K๕mุฏ† eนFใแQํEฑภMƒyลAบŸมUTณ-L(แ ฺ–ve™ฝS@่ŠG iฮyใyN,Œ$ฮ7*RuŠ@rฆ.มสัnฐญ•2”ชตwผD๖Yๅฺฑa\บพฮ†ะ2a!+รีอ''฿]”ญฐๅฬGฒฝ‡† .Wี˜–Š‹ป:Pi N& ส‘ญตUๆ+e  Yg>ฑๅYห0)Iaˆ[*-šช*ฎ’฿^‡K„๏Bhp/งฯTr|๎^_โ€cj์ๅฎiฉ—ๅNฝฌMข>’nŸ ุฃผ-ผ@qRpำซ, ฃ๐#%^T‡eXH_žˆ๘ิ>+น_ธ้SแบbYน3มpw๏๎ ขฤฅมึyแๆY`Y๙cฮ&gมo˜F)ถว๙wห‰Iq`้ผ!Œ‚าŽ๒˜‡e)p0ต่b๛หฃ5ภ. Ž ไผญฑ:™%–Œจ†€ฮ7มซ็<,-iF#ูธ€เไgฐ'ŠUi–pม8fˆฆn’บ๓สt v„้%hฑ/Œ๚ม๏๙cฮ&gมo˜F)ถว๙wห!‹‰บešภ&็บIเ3FzJ‰o#w‡ˆj|4oย>i{ฏ3/๒ฤFz๚า๓@๘]&€ฏE r๗Rš.Ž^ผ$ธ้†ุดิ…ˆ8๎:†จ 4บฑwœฯผศฆฉ—าTsญฎยZฑb: โ6อ5YฮŒ— *0^˜}9„‰=„A*ฑ๘'gเฤ [ฦ › 1–Aถ0“ VI๐2(™ใR{“#น:ณMฺ 2c:E4‡ำธนb*™›ค๔กˆ]๒ ื)…๒‚:$ˆ่œ„ห,TิZxอv?;Jล‹ยgLb AXญ›ึ รทตŠjLoถ:†ไ์อDEVำ๕!ซอิ/ุ"ฦฺ`-จๆDกSญiˆ:W$M๚P๚ƒ*g บOWฤ}W๔zณ’~ชIˆโ=@3็€, ฺํaูศ*Uซท๚*ุš Š(๐ฯPX ฌu8Š฿ณก„ม้ื\ฑZ-”qูิ6ฯ–€ ม'ขุภE"Q†:็ฝkD‡ช~€=๒ญูuา,ข >b'๕ƒg๊)2PศYฑV่คs"ฌะ`ก๚(ฆ)"*06เ+ 5J"?=1Pีฉn‚nฯัo’ เ€!T ธg5QฺC๐ษH์น/”t5ั๔ดRšดFฎžฑ๔'ูีR/ไBชl_๓<""#๔{EbGCซŠฦ๊อฑ{%€tR/บซ ขปR๊™?pJ6เ8Šด˜[Mn๛&€ผ0๔iนOC+Lด‹jเม"„๓ ชึ(ซ….EAq™อ10“€ญธ)ฐ3๏„ฌ–Trk!-๊ฬฆIฌ…q™ ภ”ฎ(›๐dƒฌ๗ข’ฑั”้_็ๅ€€**n€z๙๖ํ\Ž8Š)ฎ!รนฦคก—@Gอ>fA*YหŸa8ู‡h๗N l2"+M@้D@คอฆฌอำs4†=ฉQjฐษM๛bว$lhU8THแ‹สCุถึไ`„ปX›ง{กa‘๒l ณ ชF)ท–…๏OฺศUMศf‘mด=\จ$ํC๕1;ฺs[Hyw•บl Pu@f#ร2‚Kบ฿DL ‚ดŸภƒํ„ ภAฐ๛ฃ$[aิžq๖สง5ซ•ฒิษะ/H’„Jีำฆ ˜‚>N’_›K-‘  h๑A€rฝกJNMSGฐŠ&–์5Vk:ษด›Oน๋@!i&๔ะ4U7;กๅณX~@‘พ ะ_œ‡้ฝiHไฏkCG เภ"hMOH๐ย6ะ'ฦ! ฦ>ํˆ$”‘๑`่๋@๊6Xฤศu‘)ฺiq ำๆAJจฎbp๊ *,6ุaVน'•tช%fู0/๖]1๊เณO‹ส]มข™:ข๋ƒ๕&&/ิ '9๕€•Jภจื็!๚@oZR9+ฺะัลh8>$…†bc ฬ*ชชธ@•(๑E N'd5&๊ำaว4 ๖АŠj)Gป๚ษไ*ลGจ‹U& ฉ Eห๐ว_T8dฬ>hv@สธ&Šโ#ฆฌ7j l~เพ›X{ Ta$จ†โภz Yฎต |ฌ”BิัV๊PU#ีลVp%Œ”) #e  Yg>ฑๅYห0)Ia9p่$ปDyีƒ ทฑ†ฅTพ`fง.™Sมจc€zPVฺล ณีWนdI%Fคจ€fg(TPกกมx:ฤ๐˜ูš@+๚‘‘๊แ๏ตl˜!QราYR าฒF7ฒิšNJ z>ุํ/ิiท`Fพ3–ๅ…Gตว6 ็y๊URอษ๒7บเ๎ ๘*@ีAมP่๕˜ยะุใไBํเu@จ฿ร††ตDDŽ!่ˆ t– 9z= ตC†<ƒn>ุฉ[>ํจะ๊Ÿ:"๐็$มAX%ใL;.ทTOkTํ๑ฌ%า”ล.a†3ฑู ฃ.”ภๆชฒ6{ p4ณKร]ุU ,gฑb8/ช แ๛iš๎h;ขฮb ( (h–QมปๆวcIรRA60๑ุœฑ\€ˆขLOn฿oฉฬ2*bฎ†์ัfˆ(2ธ>ŒƒTnภ%ๅั€&พธ0„†ฝZpzHฬศฐ˜ ๐๕p$ญ3หy&ภ5œง@ืhN’V๋๘ม‘ฌ€๒๐I yขY‰c_&ำย-4@<h]๓hยหฬ๔ญู KรŸzอๅ_s€h›žlDฮณุ#‡7ผฤบหšzž๛*} Uผฆ€.๙k”ฦยภ๙9ฯษ|ลมฐถŠ อ็’œศ0U–๙ค—=žsสt v„้%hฑ/Œ๚ม๏"ฟ๙B=“ฃVฅ|ดvD6]Qcญม$ชฤPrณ”xo0ผเFšๆƒ&x@ณพ‰X†Fํ7ม$ฬ{ผก…>ฏสpฟ8ล๎ “ญ/4€าhs๒น'๐ฦ)๚Aวัz$šOŽa๑i;ฐห$ฟช๎‹ee%]W๚0U๐†ภ’๔Gๅ]Žฮ(T  @V[I2B่L‚๒ห,j๔Xฏ้Em)#vƒ ]wญyhฐ๚+:๒yzyX{ฤฯQžย ‹)ศfี์ื!๛ๆอ iตD‘/Kœขœื4`Œ9ๆ'f4๗ถC ๑S ” 5lใ6Œ"‘ฟ๑ภูฬฦด.dฑจt๏\wอ`3\น3๔SEOู ฉๆŠ}อ™ˆี…ษ›๑“๕WเกuCใI`e ธญ( อฬ€6‡่ƒ–•LงQ๊ง"๊ พBBD|NSผWอ’๒$&uห@}็–Š—ฃณ๒jถ๕‘Rฆ %[5ฒzะ0gีํcX‹r< ค)๖ธื’dq b0๖}่ N!,ห%R9€€>`0ฃnrฬM๚g๐Pg าc8GK_I%ษค‰าฐŠกผึ(คJ]TˆฅuŸๅL%B5ส/9Nา’ฺ8้แๅื€LขฯTึจ;าศภโศd˜;‹"ฯ6\ำ๏ฌŒณGฉมA,„€ (žจ๓คุ„b!wŒ}ใRR2tๆๅa๎Šุใnจ:œ`ŒWฆKฯqฅื- 99!0บV{NAcZ>6}฿๔๙;฿|ฉ๙#jCx3s๑ข7จิN0๚6Š ”pM 0}ช9ภt4|O้ฌŸธvg+elFtƒภป™zpi”๙ต=ใ*ๅVœ“\4ิ ถซ2๏๐ใc™CภสฦeAˆhฐD/ฎถุ_€Œ์6Q™,ๆizu™…t“ฑŽศ%อด๊aฏฮ]h ภb๚'„[ €=-ส xฉ ซ+โKฃ๊;ธ-/าths‘”฿„…5 ำใภ–ฑนƒ•“ช!ฆีRโูกฏ๕<๔ƒฆDe Qแ}ิ์—์๔UทณิWไม›Bu5 {Zฤiะบhห๐O บ68+>ู฿S†˜"™‹ฮฝv\"„ั‘๑ช]Ÿ-2คŒฒy}X"฿˜(91ฟ5๘€67—Ž๘4เQก™ๆN4ื€0๔)'_…๗ร™<†ภ|{”8ฬJต*jญฯo‹pLฃฯ‚a“ไ@Qฺฎส๔ƒาJณ.๗›OdฐCw;ฮ๙๓‚ๆฑฐฎ๎!!nีุส’ศ‚3B7"tJุjAF:`'—ี‚-๙‚ƒ“๓_ˆcyqณŒSŒv9xฉƒO5ฐqƒ'ะˆ๘V0๛บ๕ขุw!†ะ๗น‘_bmlถx83$˜ะSณ4ฉPฟK €ไ๒มl; ˆJ๑ฦ`ฺณœ‡ ด0๘@@ฆวg;๊pภ“S0m๑YUหMm€96FPฉณ|ฉี7ใ“dภ#Mi†ž[Xฎำ๓b‡3)!ฃŠญ#Nrฤธ>ะ@‹๋„:ฑ็ศKKผรข‘.—Qผ™„ฦ ˜บ“LM!$! Š{€D'ˆXบ?Š็ผ4งHฃ|$— ฏ)ฟ“A‰ืฆ6lเAน^‘ยTฅ%๚ —-$h™ลึ#;(๎ฦM#s@< ฉe_bึ8hpU้ฏBT3…ฝ“ฒdo{Œฐf฿xฉฒฝ">ภ1‰!ฅ35LYa‘"!B8s๎งษฑ"รฑี-A•XEฉ•rqŽจ X๎‚NฉRˆ.‘tBรยฤS'\_!_€6ป2ั•Joข`l”แ๊h:–!ภืW2<‚แpHฒฆ๔7;!k็mNีฆฺ๘>ฬกึTรC€f/M—ฺi 3ฝa—๖SFw๋“W–ง+•ฝถ๎RW Lโ†eยอ_oชRฒ™9Š ช๖๛lฆ9J %}0J–ญLC๑ทบ ด sT5ฝ8"ˆ๒ิ/ใ=—ผfg –'@‰ซฟฦกlž*5฿้z๖<ยมn๑%ๅX„@}%1ถVฝE+ขฟกณถXl‹.กฅ\‚ๅuร…หคT๐Vฤ_าLบ ผท2หฝ+๚@๔รŒุhฐหฑ›ฟe€ฌ!„ ((‰ศy<€ฝผ‰ฌ=โgฮจฯaล”ไ3j๖?๋๓f†ดฺขศ—ฅฮQNkํš0F๓ณ{!†๘ฉ…สถq›FH฿๘เlๆcZ2Xิ:wฎ;ๆฐฎ\๎Š๚2ƒlรŸ‚Aีž‡๘)U“ <™ฟ?Up.๚T>4–Pภ+Šา€ฬศฃh~ˆ9iTสuชr.ช ไ t$Gฤๅ;ลqู/"@2g\ฐ1ดyh _้z8๛?&ฏีไอ๘ษ๚ซp๋Šฦ„šกแ$AฃƒนaิZ๗ฑึXšถีเ0ปP[`eง[?๘0Ÿตjฒ1ปคฒ: Rdx›6bk8฿FูจSqG๘}lญาœอไษำŽ๙0ฐn%œ 9ํฅ˜เ(ฐศฦ:,ม'E-!B6ถชไI˜ืฅภv—+7Y๎ข๓ะฑA’}Q ำ =ƒำ(งต…c๙อ ึz9dฬ๖ ˜“{"!ฉ์Mภ\gH9\nนh,XSเรษ–r‰ลม‰^›จSฏ ปp–s€็ถ–c€\ข๚LŒ`ŠซPา‚jแตฦาม82Z๛ป‰dr=|ฦ3%๋b .R0ฅ€ฅI€z๙YCดงg“ท…งƒใแšD๕ขคx›6bk˜ู}๓1qัb—;œIช’•็๐#œ"๘!D*Qq้1ๅ‰eT ‚ๆทxTW!แ่อL)j P,โ;ทศฒ.}yฌQH”บฉJ๋?ส˜J„k”^rœ ฅ%ดqา!รหฏ™EžฉญPwฅ‘ลษ0wEžlนฆ)ท฿Yf"S‚‚Y @Q=Q็IฑฤB๏6๛ฦคค8d้อสรฐ ฦPu8ภ ฏL—ŸใKฎZr rB:atญ๖œ‚ฦด|l๛ฟ้๒wพ๙S๒Fิ†๐f็ใD$n#Qจœa๐4› ว#$R8EemAใศ™ภ-„กด๖iฎฐฅ l„D9ށ L)j P,โ;ทศฒแ๛า†.ชฟภaฐคจกก %ส๎ง๐ม่lŒ้H๖U๐^ภุ2ๆ]ฝmฦเข ;J 0พC0˜ี+$:}๋้$WC[M€‰`๑ไฦ],R=”าˆ dฦ่ง@V๓ƒRผธ5‚#ณาiDœฒ๕F<้'฿5Z €}Žuห6 Uแ h5๑P4ACUŠA?iขญฝžขฟ&๐. ฺฉจKฺึ#N…ำ@6_‚yะ)ฑมY๖ฮ๚œ0$มฬ^u่{ฒแ&ŒR์๙i•$` “ห๊มมAษ๙ฏฤฑผผwมง ฯ2qฆผ‡คI:ื"FมืaO<พ+PEƒ™sเ@ถhzผ&QŽgม0ษ๒ จํWeznAi%Y—{องฒX!ป็|๙ม๓X€ุWwทF๊์eIdAŽก›‘:%l5 ฃ0 “ห๊มมAษ๙ฏฤฑผธูฦ)ฦ;ผTมงšุ8ม“่D| ซ}zัlŽ;รh{‚ศŽ/€16ถ[<’Lh)ูšTจ ฿ฅ@ry`ถ?„ฤ%xใmภฐmYฮC†Z|   Sc‚ณํ๕8`I‚)˜6๘ฌชๅฆถภi™ึKฉนf๙i—ษฝศ’แด~ปOจขทฤฮธCOอŠฬ@ค†Ž*ด9หเ๛A/ฎ๊ฤgŸ!-.๓ˆ>Dบ]F๒f.b๊M14„„‚)๎œ!b่+ž๐า"๐’\.ผฆM'^˜ูณๅ{rG R”—่‚\lถ@‘ขgXŒ์ฃธ๓4ฬY4๐‚ฅ•|A‹XแกมTฆฝ Pฮ๖NสA‘ฝ์ 3vม›}เฆส๔ˆ๛ฦ$†”Hฬjtี1e„BDˆ…แฯปŸ$:ฤ‹วTดUaฆUษฦ8Z |ixพ้Rkp๋†ชญ"U<(mง!‹๘~r๒ึะ&+^(ร๋„4ุกฬฤ HhโซHำœพV–YฏXวะฎ๒—๑฿;6]ช2N๓ส%ฏ*z`มBC๕nผšJl^'H•ผฎ9cีนฑ‘ชฆเ๘งŠฟFZz!˜™ฤgะ ฬ‚ ะลอน"ช€%ึชไk้€ a\ฉ ะมฮ๛hาe1^tฮŒดœ€ฆrb'[‰ู‘4บ๘DูM\ฟพ-ถดH…ฑ–ฦ!ลพ๗ํƒ&JZขแตwก?5d๓} Zอญ๘พวฌQ ‚฿า:ํ%๑Œ:๚งˆยน่ธ*้ฒŒๆ7~`—ฏƒ๔า*เPvIํ๘:ะ้{ฦa†z btšปjษโฃ] ๏]›๋็"yื๛ศพฯsฏฟ๓’ฺsN฿gฬฆฟ๛>ž๕ูพฝฮr!วผ์ว:๛9-ง4่๖qศฺkฟ๓ํษ๏]›๋็"yื๛รฬLrtPqอZ๔Tศyจzลlฐ ธPZฤ๗ฎอ๕๎s‘<๋ไ~฿g9ื฿๙ษm9งG๏ณŽๆFำ_ŸnOz์฿^็?VDค˜lค\eฒZ/;ฃ-s ฬZpŽEรj8ฟk฿็j3บoOฟ๑ฦv~sณ๓Ÿœ์็g็;?9ู๙ฮฯฮv~sณ๓Ÿœ์็g็;?9ู๙ฮฯฮv~sณ๓Ÿœ์็g็V˜(d@ฅ"ก)ย?เ~8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร‡8pแร๛wมผ&XY๖?ภแ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @&้G๎ภ(ฃ?ถŸk†~?Œั*Oฉm›g#?บ ฬฆFะ‹๔”ฉ"^Aง ™๙๊%๑ =ธ}[JŸ”ฅ! Qณtอยb,†ฏlฅ?@ š+0ตษ_๕O F:ส–ปท&:šว๕จฅสแLึa๖”2ฑ‘t๐ศgใ๚:Dnภีw#*ˆm “ฤŠุ•tdษ—’ƒ43ŒV‘” ส15sh‚‹Vสก_†K) ๔Uฆn5h1’f]37Ž6~\,ำ๔CLa๕— i2ญข‡EBT_†zฉ[‘cpaฐขiฐฐ= ฤ†ย ๐฿ฅzKb๔Oีxb["ฐ$ญี’ศปIฯิั(P๊cI ๙iM6+ๆ T3ม(=•) ซRjฉฅœณ`ขdฒŸEZfใ"๎  $Tน†x3๑m’s€H#|(,™?ๅ ฒnห]1#็ษ‹0๐”h‚’nณ๎ฑโ@า• †ะt ฑฉFšH%`รWiLrCฯ+ฎฑฃฉv—$ิPK๓˜ hy\-d ‰ัใื2O3 ,แ\ƒรaึญฬ‹V˜๑n@&m๎ตฎ›Rพ}๗'มฉส‰ฝฺ8rฌ/€pN!ศซฅ๛มfคQ?q€ฎ+Sภ”nH(sQาPYzัศ#]คH1ษ<ฃR็๖tโ›Sฤก๖ +>ฺฝi๕๋… l3” †?ฦˆ J%#QฝhลBวNแ0B$bg*'„1:ฏ๎ฯฮ?Kพr~%b@ฎ4& ƒฐรi:tฬณฃ_ …lถ7?ึKนฟ[ฏ฿๓r*ธษงคeส SQิ*$ ๅหiปQ j/ยE„8 QEฑ!แฅ›0†Q‘up 4NฑŽฯฮž Yฟถ*ชึฅว์็Ÿ(@ข#š>๖ฤo*\ ำ6ถวBะ)˜V$ ใB`ัŠคฆ'x"้ะฯ…Hมึp>š6 ~?๑ฎ< ุ:y'๓nwเ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๗เ๖‰มI9—๛i๘ฦธgใ‹ŠฤsPฦงhฎฮง๗Aณeฯfj 4เyuจ›T MŸฆPŒE*Eะผ๗ฯว๑†๏—5ฎP2๓›ๆv`ŽQฺท&–หœข‘€&Gฮkฎ"๐L„OJ€ŸwZฅYlT๎E_บ™.2:\๏เใsัx์หd"%ฤถ9 ๙1Wณฟง๓%.;Cyิ. ‹ ‡วต๑i:@•แ+บPง๒dKบฐOŠxศF’ฆๅv๒…UฃXศ฿ ะืF(e’ ำP๋ฌ_ู9ำื3ๆYฆ=ทuฦฒจ#v`’qWฮํVœฎญaa[<sบo}ฃ`>้p7ใภd!zญ๙}กฟฺ™๏~่.Kkุภฬ๙€Hqฦํ|ZNƒ„Pฤ%xJ๎„<็!ะจ@ค63›วตdj |L+-—9E#LŽ œื\Eเ(ภW6.ฅYฆลa"Y)5ุ""8ิIq๑ค‹jR6ท#1˜;ฑDฒlFAห฿๙Tซqš:Q02ˆf^ฃฟปจ ด|ฅะภFJ้ส 5ภxyZ{i\ ฎ฿‰i  8XœZฒP; Pกฐsƒแ5 4ฅŒ์4 jN :ก[(ึ-\bแ(ตˆฅVมL( ณ.06HฺHวTขaG5ุฒ""สm‰Qˆ๔cฃyvNฤ/๎ ๖ฦ˜๚ศ…งy ">Kšˆ‚ฺปณะ*ว,pฏตšG)e–w๋iถ๑ปฤ๑วŒ„โี*Vื=kp‹฿Z•5T$k.'พ+€t>5 8 ŽiXํฤJnE"ณ๗<ีฒ5๋ €SB&>ยnะ๘Rz(ภฟฐM;KL™ะC*L\y™=Mซท3‡8๏ำ รDA.}ฑbกค˜์kjU™|!ถ้‚{ั๘ :C‰ ืภ ฎ๛Œ:‚๎(ฃ@U)ทฌR!šƒLุQฏ์x^‘นตภถ'[ล”ŒะUaAPก*q%สฤา^[5~’)m7,l‡ิ JŸผนJ#‹ื!FคCีS€:)HCNค•@Tถœภve )ˆ H9aว v„izยZฝดฤCQ/2pภŽ nช`Hง&ˆG' †* Bฐ่2ฤทอ8‚ดค2Nณ‰ažŒ’Jภ’๔อฟปN:ฅšล๊ีmฐะpรMฆž’ ปึq ล› ไDR๔,ฮ บŽธC๗Œ—€š€นLว;gŒ(\[‰๒fืฝฅเIkR(ึ?DK†CF์?=Šrtฤอ@๕๏ร€^™N่อ 8Tล/oูฮS‰่ฐ‘ๆ<ใƒuรบ9๚~ก DTE„WXฌNผาใ^ัW$@[*ณ1:ะีโj ’„ู @W๛pgใ๚>หำ$บ€Mบ งz๔ Nฟฃ~pง$E5Vn๑โ+b*3ณœภุฤœณB2*7ศX <‰Fณcกa†ศ…ส๔žฺ‚ฌไ ศ˜บ‹@Q'HN7สฅEฬŠŒ€LGข๙Dฤ $bภ"‚‰—ช ]|FaปศใSฅKฆ8‹ฉ8Bฐฌศœลc๖„€ฏ^๒๏บ=^nฎฅUอฟๅฮ!IbmqิDNŽฑj่5ย€ &I†๋๊kœ*ด41E |ซj5=jฮ9Šv™ โƒ k(Š.dTdb=ส&! ƒg๋† ฎmzf9“ ฅ„๔0u๒^Ÿแ%ิmะe;ื ju๓†Y5E|GT , €’ถkM%7ฤเ gศxษใS–็๛ *๘a3ม“a47’3‰W=„= ’^*‡ž+N›ยh.จ3๐‹จเ2Y)‚)ฃL5ํง5ษฃV์0๚4Xผค'E+ผ"ˆ"ไr%dA~xฐyŽ%D7†ปšก ๓๏€ฒK„ˆsŠฃŸฑ๘/‡คi]นฬูxS๏จ๗บ!\ƒ๙ๆๅ‡jh…Œ8ใ๋ฆ)xฎฒ๖ณr-ค(ธ้•[ื5ฅmQl",”ไC สโร™_ค<“ร๏‘-\_ช9KJ9ph๘@ัŠt Ksฦ2ึšS๗‰!"Kwi[่†/]8๚ •o ‘ีฯ“ฆฤRฌ๘0ฃHๅ }# ฟฅg8ูฎNรศQ๛ฌjTR.mC,\/ซสฎ้๓‚ู.๏+*%ขภˆmCN‘ป9™ซCWสํiช„ุb(ฅถRีI‚ฝr•ๅj๗8(จxZXทๅk’พ$€ภ*ฆบถ#W฿"O๚^pmยIจ…ๆุƒวฦๆn@๊Ld•๛ฃ^ฦฮE๓ˆะzSั‰ฟึ'œตฉr– wฒ] ะฬ‡;Œ ‰ดป‘}‘เ@ถ๔vCY_W้4]›]šฉPv "ศํGvีQ.:๙ๆฺึญ–mb๖ลH?'ษธฤ7มzJQ9ˆRLL€šbi…๙$Td• ศ9Fsƒ{K4–๊ฒิ๊ญฒ;69`คœc5คIR‰ะ๊ƒ ไฤ“g™†ตFnเ—-พŽ]Pภถ ๋^˜หำbฑ‡†‡๚๙ณ);ฤ‘ ค๊`Banr๔‘t๗ปแณภ ]7/ูคš0Nฒz•‰ษกฟ ะ๒สiจDฬ†รFˆข…  F9ข๓‚ $”5ฉG~Z }KอŒAœๆVำ]ไฤWฑ A”๘ ษ-2M_ใ๛xgใ๘รู‚HCฑ„nฐy๚Œ U]ใ๏A@|(ฅ‹l๏ฃธๅW็Eมs~`‘r’”W';X  $S 1'•{Fsxbุมwrv“โเ€@้๛|=ขึ{๖ืbพƒ—Z`ปไภeญโ~๛็zถืUล๛ฌ's€ช F'ป๐ฎzVๅพฺbn,ฟ0๛XFF9อ•ั.ฐAธฃซwQสณn9ฬasqR>ู๓ย>Œภ๚ภนo(ކ(2‡[>‹ํ †”*ข„0, ั7่F<แิ,=aŸ›๓ิวฝPp€$ั…ถฐmFO4โฝ@[kชŒbึนภUP#๙…œ2‚หAf‘`[ศn @>ึt+x`PวใณพŽใ•_*็dฆaW๑P”ฎฏ/:ัไMคxŽEฝล กถ#ๅuฮ๐‰'';‹OแfฃGYผˆœSๅฤศJ„Z€฿ฎfL™Tำผ7?ฃผa—“ฐƒ R๙ฏ:YัrใŸฉUp6N๙—ีหอ’ ๖ใ๐ŽŽ(*๏์]ซP~ › Wpะตwงt3เ0jฎ๎มO‹แุฅญ7ชF€โฒ?!”f๒ฤ 0–ฑหา,ด@.อ80๋๚(Š …1ธ7@D|ฒЇWฟ๓8ดฌ‡U)ใqV ศฏ1๎ง|Ÿ๓๕ภšฟlฬษ“fๅ–RUโ "”๐\ั ๚ฌแdG–"v ผGWส8b‰ธ bัย˜‡ว te…เู‰ขC{—ปา—Q!"๎>Žฎ‚ซus•ูำ๗4\+)ร4ิ›ิ๘ฬu๊eห๔:งฆอ*_06‘ฃ“ฤ ฐCƒณW-xท๎.bhต๊\?ฬช ้XBYŸ "๖รญ็ขNmีBoํ– Œ#3๓zfV‡/’cธฌ๓ฉน๎jœ`ทPล‘‚<๓“ฎฅ‚\bคฅุ|h›Yrค ปต“ฮ_›๔0อง*,(ผ%&ิฏ[„ `าอ-พe&†,ไ<ณZๆ์ฃ€Šห‘}โรšใFƒ=Zcp8ฃ ๏V`ˆโ๐(„ณภปygข$ํ|๐{*๛uˆ˜+00`๋Bๅ•“$ธˆั‰ค”ฦ}พ+5ค:&_YbะŽ``ŠˆJเ †ฅภ(i$0r`ฌ}ศWbช *€็ส“7fุ› g*ึXม ฮI„’Œ3T!>จ%ำQb:ณฃ„€ใ&$1^ˆF3ล)ุ๔ฒ  ๚pฆ[@!ี๑Pใ•ะ้ฯ7:+yŒmjทฃLjI3ๆh ต›MnๆT:*8Oฒไ`ผ๎5B ;ข4้5gX>AmMVe๙ฺ1- 9Mรkวuu7]Tวœp0“‘ši‰JX‘…_‘&‰O๖เฯว๕oฑRแt›ดี9ฮlu์ฬb3aN็่FE„ื*็V ?xR๕ฐ๐Qมห"M6จdศ5˜Ž*่ด๊nฟฏqžc'šษใฤชP ีฃ[ง่%ไMไยขJ5e…i‡_)\๘_๛๎ผmc์&ฟœYฮขอR L— `ร ใ Xธuข—q ำะฎ#0hๅท†~?๑ฎQธ}ืee๛น๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๕_9๊พsี|็ช๙ฯU๓žซ็=Wฮzฏœ๊ถึฦ‚SŸํฟŸ๑^5q วจ 1ฺ:ฤŒวฯฮฅ%ฏœ\„8ˆฉ๚*743H‰นMุ ‰M6ะุ–ปSs\Bุz-3•ovฉฝrO]}ผ?โคkP5๖!  งั“žหฉแ‘ทํ}qะๅฟฮ๋ ๖ๆzๆrr(ดP7…UะYนMYลc˜Qิ`5ใต€!˜ฅแ]1จต๛ผ"‘ฎ c2‹์ซรkŒสะ˜อNdฃœัห5™R๛š70ไ“iฅ๑Dฝ๔|ฌ๕P‘c€าB_ลƒ๙บ$บืฏฃa+6L1 ‚D•~•  —`สG`œ๕'บษ•e  yz๕ห ๚ร bfอ>ฏ‹ #มศ]็@Aฤ๐3BI˜B*Zเฦ5เšขจNqณ๔ลฐณ…,ฎHCVหC2z(lื'X‚็xˆtxbจ~Uถค&กษ\tลค †๔T>}™๚ตฬ -C฿ช ฑRhั๋ฎ+sๆธ7ฐoU€‹L0‡€ˆคJฮๆO[ยžMำ`@ฬJ›~>** EUนฐ๖gˆ\I๔`Œ,#ฐไg‹7Žษ๒ฃาตฎ™ฌน=%‚2ฑฉ@X+=x.i)๛cฏทƒ๛o็Qฯ›%A(‚ชก –-กbน%(ะŠ$โ=7(t7๛$rยญˆตล ศ เ๑%I–ะp์‘฿B?ฝG„ฅ Š5Eโฆ–ฆ‰SL๕ฬฤ้ำL(ว ๖‰๑ปšธxรัฃ๓?คpGๆญj#G6$“ ซnผkัธhBHพicC'ร0ง Žตฏา2ฉซ%็s๙2๔™), ภAtN8†4&๖:#Oฯ>ัหUฤ~“,C%s หb„ฝGKDt?THํ-‰.L๕ฬฌ4ฅถ$˜‚฿ณ"ฉไj 2เฬƒŠJR,L›๋ณsณ+ฝฒมฦ…uŠn_ฅ((P[’<๏™_Aฆ›.พ1ป5{Q4ฎฮฑ„“ฑ Š3{ฐaงํEฆฆ\๋”e4ž$ุT๐๊ส ๖DAPVัๅฟ™“ oฉ1๕ูƒvกˆX๓Vทšั•แฏ๋๗@ าM?dh/rงš)๗6f T1 |๔ด(ฦพ\‡ม๖˜จG๛แฎ 5‡๒h0ฆณ`4์V8$\๒อี™ด†Cฑ7q ๅqบๅ ฑbAN?ƒ&Yส'%zn DNพt 6ํยYฯ๚žฺYŽr‹้21€?๋ฝ๛ƒฯb7“ฆธมއ,F23J)#ก<ž:ซ^:ูY3ํT€nž(/V์ุd%[ยdฒเE,ยฐQŸT๗‡•ึCฬhด"๐;ซf”:0"22 `ะ`้šy฿าฏซ B0’cฉ“ŽY„ฃาญฅฎ๔ำ7Mวำ]-าšk๘|S @\A–โๅ F‘ ‚ยณR+‡Š{ณmƒฟิะ+Jมฬเ?น™%&'ฃุEฑ๎พ;จpOjh๙sซ พDD3t‰‰ ”l9Y#mQ†Sษ๚hฃ/ะ$5 beEนRค๒ศยฐ,ฮ~‚ฒํƒ๖ฝ)ubู)Kห๎X_ื!hJ1แูฬ…‚w๐e๑ุ๘p3~}!OCIบ r2H#„VVิ<‰œนฎ]ำ+ฅR#TS…Jช9๐้ข๖ณ5#0uๅณšš…ฟ|6ส}}ฆ‚$"๋ฝ;H -ฌ่Y!„Hๆฑฐฎ๎!!nีุส’ศ‚3B7"tJุjAF:`'—ี‚-๙‚ƒ“๓_ˆcyqณŒSŒv9xฉƒO5ฐqƒ'ะˆ๚$„ี a‰ื€Oƒ^“(ๆ…‹ธD€ล*(3œใ,[`"xBfœQXEฅŠ.ะHป2ะิœิ4zฏrณƒQญ[u"ฃ8ŒX๏KE|m#็2ัศปฮ ขเไD€Lฒจ”5ƒj‚มv€ƒื’ก ศ์้ใ™.ซbˆ‰งRศs /4D‘ฏ10g*i˜W5hฉ|ฌZJ,ลfQ๖™išo Fณ เุข`wศก/}9ŒO…U8ฆš),ลฤ ‰ค|y ฿ธt"ก05ฬ…ฅPˆ ๕Žgผ๏ั*Ž6ƒrึY๐tŠฃ*‰kืV”ฐlT้ญษฦ๊p‡ฑ-๓MRไPƒ๒]ิๆฺ‡๙งแ ˜จEร=๚p4{‰๘ [hYAฌ8\‹'–kLDวะY!ฬ7บถ‰ฌ๘c†M"ุR(พŠK1yฑ๒ขˆชW+˜Fr€ศ/ฯ*C-cŽpีUคJง… ฉี7ใ“dภ#Mi†ž[Xzึ‚„ (Z1ฟP‘ `F‚t$ฟ‹;”ฺoถฮdF‹๖f=%X[‰จr˜>’vํm*ข]`ฤ;ˆ ‚#ญ9ก%๘|Yฆๆำx…ถp‹"4_ฐ1้("ยHEC”ม๔“ทkiPฅ๋!ุD@dแiม:#ฃEุวlขt€VŽนมWEซ œฺ"ข„ŽC„uง*BO“ ฺุo[† 7์ฬ\7 สGo˜a7,ุ,0™ฺ"ข„ŽC„uง*BO“ ฺุo[† 7์ฬ6๒dˆ Pๅ1h(ธšƒ1iDบภข*(Hไ8GZrค(ิ๙0ฑMฆ๑h'H5d ยGซก๗nm๒ *’Utœ•มˆv8GZsBK๐๘ณนMอฆ๑ lแDhฟ`6b'bยง+y†€๙VNา ‹ศฤ;ˆ ‚#ญ9ก%๘|Yฆๆำx…ถp‹"4_ฐ1้("ยHEC”ม๔“ทkiPฅ๋!ุD@dแiอ /รโฮๅ76›รj\ฦฆs*ต1๐ฺOมภภธyึ้ฐˆa|สฮBฅzรZtล๐ฉŒyมฉšธRีQˆk๎a6ๆ๘-^ิ0zี๓+8 •่@w hGr=ำยฆ1็คhbแKUF!ฏน„›เตz4kPม๋g]6(ฃ)>ƒฆ6า<‡็ศีุชนว.5kaV์hBฅ:^RอPฅืฉ8BzืLKOP9ปuอน๚ปW8ๅฦญl*€MTง@ สYชบ๕ Gย{ศ_ฯZ้›‰i๊7nนท Wbช็ธีญ…[ฐ ก ”่๚jLะ๚ฅ|ฏFj=j๙•œ…J๔ ;†ด#น้‹แS๓ƒR 41pฅชฃืยmอ๐Zฝ5จ`๕ซๆVp"+ะ€๎ะŽไ{ฆ/…Lcฮ H4ะลย–ชŒC_s ท7มj๔hึกƒึฏ™Yภ@ˆTฏB๘+rธุYYžŸ็=?ฮzœ๔9้sำ็ง๙ฯO๓žŸ็=?ฮ<ี5I .๎5๐paEwsผ๔9้sำ็ง๙ฯO๓žŸ็=?ฮzœ๔9้sำ็ง๙๚Nฌ(ฎใNwžŸ็=?ฮzœ๔9้sำ็ง๙ฯO๓žŸ็=?ฮzœ๔?๚Yฤ/!1AQa‘ั๐๑qมกฑ 0`pแ@P €ฺ?รๆฃฃ&S]WjิๅM๊dข-ฤN2?ฒn–di”&Pีำบ™ฒG$‚ Œ^ ฑAX/2 =เkYต^E#PdHOqฟฉฑ”โุก๒ซ*Mษ‘ ฒ&ขrQx-}bล Hื LƒขŸณ„พฺ๊ถBI# qL&ฟ๙BlT"Kฉ>O๐6d€nฌ:Iqฯ๘,buก@_^Tโ ๎8ฅI6ฉH‘ƒฝFซŽด)นI9d๕sx2‰ฒI˜ฺไ. 3œPว์iE”–r๐!•ฃt6ง#น(*75#9ฃะƒfbBไ™ธ?ถง(Q-โห๕J0$'จ@ภท^Qต(‰@Dยa9#ฒ%+g.ำ <Moj €$0>“S#๋~7’‹b‰ย€๖ผ’I|—F(รดŠPw >ฺป!˜D1”ณ๏ซกtโSrˆถ€ลŒ›*}`›ญ-]เ๋KŠm vLa ้˜n:า$`๏Qชใญ[ ๖ฆjDQ‰lU่zฑ๕๋†< ๑3๑E ˆ๐#๗Aด๛@*่๐– JIษีm2ผ์ึ xเ:&Uุ/;\šA+HยPสหเ“ตึจ#๑t/หฤ“iจL\ภ๛œจฤ€…มZง฿๑ํzL$ฺ7.^๓๑FA€6bหก%9Œ,RIยozD$ฑcฅœ0$ิษHY5fะ์ไq ">Fซ้2>ฺดฆั!œ"ม์Fฑz†]E‹. †]5i48&„วJ๚ส ‹[ฑjT–HCฤ›็฿๘ฉว d$Y˜ฦJADฏT˜ม›• h `q ่ผ๊wtร/ฬi )ฐ ฎถฤojว๎๘-ทd`s„ฬDร<ษ! |EIฅKUฐผ|ัคH#*Gโœฝะูžวฝช$0:šš{#Nฟf‰%–ๅC!Lด^c=ฮษ…๕GฤJฆ`›ฤ&ฤqiIแ2่4X2ภณFB7fv๖กQ ภ ” [ฑฺEwฝยื‘HHป D˜u‘เbด„š_k&(์Lย“๔š๊Y\X63šW‰’I1:z๖ซŸ…๔๙ ฿ษ}ดc?ปิ„ไŒนCfัJ๒ค3%#ธะrUุ bฬ;Z๛Jึb‚?ู+ERWVฅ•ลƒc9ฅp8‘‰$“งฏ|šฅ K4”u, "-โtRช‘žชณ๐€ไ~IQZ็ๆi จ)†T8Œฆž๖ฝ๘ขDd8- qฝส"๙mย่1j(สฌY\๗รํ9ŽB$ :ลœ=Uช ›-ะ(€Ÿฆล‚จล’VcฏMrศ—้ฉ‘ฺใOว่แtU%HN ณ›cี`T™แฟ \$1๓<๘ิ(bKๅ-sแŠVอ<ษ‹พtฒ"…Kํชn ฐl๋…ˆพั๘ฎ๋ณะR%~0ฺIฅpOฯZ ยีม?=j.Pr„ใNฮŠ” ’€ัปี˜’"hŒ:nฬ๒'โš• ‚,ญฃs K‘ข?švU@F๐ฎ‹ฺ˜Vฉะ€QจบnยiGะeเสธ ฝ.B$‰[อหึNา,#c‰๑.ญ_ฐ,ƒวUU฿ลHB"2 ญ‹บmDคH”Y`ทboฦฒ& ม์8ถKIŠีœ}’จD*]@zยตJ6 6tj๋Qn”ฺF/ฟอ4ี˜%S9ฃฐt Oฬ”51DKXศท=j4ยD-œJหโ(EcเKณ{ภ^†‚คWFคFHผะJD‰Ae– v!k"apœมc๊ห‚™€ดXตA nยEชJ!gQ5Qค5’2}ษD๛อศ2ทป&้ื]foHeBม‡Hf'1zžbtA@ฎ…ลF๚Z‡ขข@ส ‚ะd’ิ$@XBuT฿z6–bย1q&7‰ใW์‹`เ~ีW{‹4  `,i#ฉ‚Šฝี^+ํภ‚TยIE^ฐ—!k7กึœd&์"9ั“…-EศD๐YmํฌำT`$˜HD~oจมCฬo@f๋3ียJ0M ฤ[‘ืโƒดป๖8๐+„rH,Jธ7ข–ฉก,€Rrสœ๘h6ข๓"OผNํ_)0 ƒหซH2(E2อๆ€Ž@สยUุ/CZ€‘aC N๓Nบ ™bMฌ† Z‰+(eโีC<ห ชฐชช9dŒb มb'ธๆว{Nฉฦ3๋–ๅŸธ6’]'ป๐v5Ÿ้4j˜๊ธVง(ด๒oS%n"q‘๘๕“tณ#Lก2†จ~Ÿ่–T&ฃx&ิ‘g๛ƒ4‰g๚ฅbG๐•V ,ฤAฏ๕ R`_‚๔`Œโแฬ=1cฌHXอะ~h‡Bฬ# %ณท๑ำJ ฺAก‚งJ๛ฤd อI๚8 }ิ9ตl„’F$โ˜Mศ ›ญ ๚๒งoqล*H1ตHสDŒ๊5\uกL…สIศ“'ซ›ม”M"Lฦิ๏!pIูœโ†ๆ?cJ,คณ— ญกต9ศมAQนฉอ„3$อมต9B‰o_ชQ!=@สบ๒ฉDJ& ษ‘)[8 v™เ*k{PT!๔šžูXัสฤ…RฤF)ฝJf%0Œฑ;iG ะฅ/#P”IAM]6~7ก›zบฬม3ลE:Œ<พาB rถ•๎fญท6าeํp&สU๘‚Ch‰™ฺ]mฝ5ฟพฺง…)ล†RO๒aฌHO:†Cu๛ซภiฝ๕mะF๒fำ ณHฬฆ 'ต–ฮIงำลม*p>Qt"๔5%‰`r‘6‘odก9rห$$bศ๖PB3&`=๒jdฌd†ร†M‹k•ู22Zแ91wiจธ‹ฎ#Šฅc๗|ฒ09ยf"c‡_ส๚=qOั้’า*Aไ็_‹ื๘พo้WlใWKSฦำ๛Œ1ฺืcฺŸž4ƒยAย๕= |BŸฤิ3้7>a—ลczNw…t 4ฺŸฉ b=ิ(ƒPˆไK%vJว๎Ÿ{ฎ8=–ŠฒQ†ฟ‚{ดdๅlŒใA†b‡i`๙ณ4ƒนR๎ƒิดฑ Ž}ขtฉ‚Qฉ e†๙fิje7'เฅลjม”"ๅ'แ฿>น}พสว4~•๙]+๑?ฎ•dใ๎ป‡บฑ\สลJSฺฟy๕X=พ฿Yุ–Ÿตฎh4ษดB’ฒZ์แvๅXkศป๐อ7สศYผ_วข?ู+ERWV”รฅ! BYป‚/SหA)F_lpงo4บ8y@=ฺ I(๊Qใ๚šjฺ›บK,gAwA™ƒด,๏ใซ|ศ่mˆฬฟฑ1RH0Iฬฯอv๔„ฉ ย!`ึslzฑ:#ํ7~ i๗ƒตฦุqs ‡ตฯ‘rค~#ฒVŠคฎญ~&†๑Mฦ๎ZJƒ„j‚ฮถY’ ]ต(e๖ณyง๓5tตภ6๙ƒŠโด a!ไ‚žลย ถ้”% ดŸBVษ -}5›ฉา›๗,^V5๑…ฎ~g‡V’i\๓ึˆ0ตpOฯZ‹€Fิก8ำณขฅ($ 4n๕f$ˆš##ฮ€ณ<‰๘ฆฅB`‹+hใGภ@Rไhๆ•Pผ#kข๖ฆช@๔ j.›ฐšQ๔@8ฒฎoK‰"V๓r๕“ด‹ลฤ˜โO†€"Lม|๊ชโ๖($ด˜HLKฮณฺ*1}ธTˆB$ˆ่›XtmPศ‘Ab6Viต๒#‰7เึhHอฃ|ส@งษC"@”จI ป˜V=ข„B~DิMGปา๓'>๗D๛ษย›ฌS&๗2™o๏|ึe*{qS…Mัสฝวฏ๙๋QฒgปะT H๎(ฅงc๕Cสว ณlึ<šA~z๚{๗ฉ&งฆ6pV FH)ษ”Weจ+’”‡%"‰ˆ๘ฌ+T’๔`Š›อAR+ฃR#$^h4‰ิ1iโี‚XิP"l„)ฃสEภB้ปlqขm>ฮ†_–S„UC ™cbiทข”จ*–b&lแ7ฬผฉ+ `*i{Kj:bRฑ2ลํvŠZฆ„ฒIห*pYซAKถFauจ๕šXมคฌ‹ด8ฦณ pPะTŠ่ิˆษš!•e@‚P฿{3'ŸŠ\ฏ0„&๑d’oยT~ฟ‹ƒๆ๙oDœLH,Ee–kโ…ฌš[๚A๎HhภJ๗,N‡ y%C’์ะsqŽใฎบŒส…ƒ ฬNb๔;„rH,Jธ7ฯ๙ิCภ”_6˜๔[š ้s๖ฉ$ฦF‡— o2๒ฒซษะ)/ช5)š ˆ b(โๅNHฃLม:ItZCnฤDŸโœS ฑ:‰NCHNpƒ†"ƒณฅ–ม~ˆr%ั; ถฆtFOํHฏ2%nฬ/ๆŽ@)ACmgV;P๗X*0#d)8A=Ÿิ€X ษฒXบFj|l ย“a’›6๙Š”H\ˆXAฝ๎?ฤ%ƒ-LVœ%ฐL1“&ฟีsห%x™G,ภ%/Šžยม˜Bบ‰ŽM@VรWqI9ดTZฉ่๊‘ˆ$ู็y๔…ๅ~3ˆc‰‰‹ฤล$ฺG๋๚ฬZ?ชz่มปNเ,y$KขL@@cŠขŒHtชุบฎ ViY๓! †h2่ต;Bฆ "/ieูˆ\œฐ. AlพƒVแภฐk˜„^Oศ”)ก0&œJkoธp ะด9ย„@โv ู(ใค;‰4P“m๘SAg ”ดฃcมFrอŒ`[P&าo.ด„0ทำcไ*4ฒ0@ศœๅโD\ ˆ Ievฃ”‰‘DอBๅQฒฬRQ?€ษล9•%‹๏vXฆpCe&ํใฦฟ ้'ง+€ˆ…Y๖-vฝทf‚Isƒโุฉ”nIหpฏฦj:H ฌด‘4สฬพืvAˆํ9/™›้ั†/ *™V Fำฉ‘)‹ฬฆbo3š"ๅ˜ิlAK+ตคLˆ‚&nฺ*–bปถฺ๏๘ต๙g๎ปี1’ ๗-๙โŒ๕๙€€lP%๖ ฤ™&aฺไTv ’.G%ˆeชอ5ซมป๑Me!L‚L ภๅi5ก›ห#ด) ณ…สZQฑเฃ9f๔DBฺˆลํ&ท0 -…ตภฃฑMฎ“›ธ8Bฅ|&ให{ Kjุใ'ๅภฮLI*]หŽ o%ฅปq-L์…ึ์็+U๒d}ตฝะ>h Fษž๘ˆl๒T  ภ$K…๘d๘ค*‘  ”ฒ\ฬD^คค.@ลŒ>ZDขP,ฃ( ั๎Pุ-น?€Ii๊’๎ห Xˆธ"Bำt]mGxKf$aฐิ$I"„›"{49ฑTโ Noดา K!›"^‰ื  ภ KB@Jบ^-D]AfX‘[›อฬเ2˜dฎฯš={ฯI;‰AWxืj7@‹Kiฆศศ e”K(jkŠ๔„DXฤสMฤ˜๚%๒จ$" ฟ]bKF’F๖สฺฺยY5งปห0ณ5ˆmปdˆZฑœ"„LโU4ณลปVBใ9/jYอ,’Fซ3ฑVศT&˜dด฿๊œ>]i›๔๔EแA$ฆิ#ž(7UUปQั‰™๎ช*ย้kHYฯฉ–ฆ 3'‰ฤเ‚฿ลbญี‰gKภ&=8ฦแlฒ_ix›ด>5gaV1šะ๏C3ส๔ศหhี,่@@œคZeGแaSุNxJk@M1?$v~ลZII”Fก-๎ฦ …˜๑'%๋)s‡ฆ๚ IArืบ.DฮŸศ"BQ0—„mœึBษc€p๖PƒM– b[I0โิ‰ๅY]ื?ลลษฉ˜๒๘ขำr!:3 Iข*โต๕าฏ'@ค8พจิฆhH. )ˆฃ‹—๕ป%BX›Dฌ์ แS๒ g0e”YD'๐N)„ุDง!‡ $'8มรAูาห`ˆ „?D9่†[S:#'๖คW™ทfn—๓G  กถณ+จ{ฌm‘ฒœ žฯ๊Œส๙บฆ€บำSถbf$–@ู Gๆ*Q!pB!a๗ธ– ต1ZpX–ม0ฦLšUฯ,•โeณ”พ*xnC a"๊&95[ ]ล$ๆัQjฆ?ถQ!pB!a๗ธเ5™กl”ฮฉขมฺœiNž฿โอ$~ะYยๅ-(ุ๐QœณEcิ ด›หญ! -๔ุ๙ ,Œ2'9x€ั(ภ†ฃbY]จๅ"dD3vะนTlณ†ฤิOเ2F1NeIAขฤ {–*XบA #Žh0&๊ฮฤMํRKซI้สเ"!V}‹]ฟฏmู „R\เ๘ถ๖*e’r+๑šŽ’(+-$M2ณ/ตยb;NF ฤๆf๚tFa‹ยJฆUƒด๊dJb๓i˜›ฤLๆˆน@&5@’สํG)" ‰›ถ…สฃe˜ฎํถป-~Y๛ฎ๗ตLd‚ห~A๘ฃ=~`  d=จ1&FI˜vน€$‹‘ษbcjณGj๗0nSYHS “(09ZMhfลฒศลญG็Jh,แr–”lx(ฮYฃ}ถข1{Iญ๗ฃฬ amFGp(์E$kคๆ๎งD2VK{ฅไ‰\€4›ฤ0Tป—@KKvโZ™ุ3 ญูฮW๘ซไศ๛k{ |ั@“=๑ูฝไฉ@€H— ๐ษ๑HU"@+)dน˜ˆฝIH.\‹|ดˆ!D YFQ:ฃ กฐ$[r~()’ำี%!—@ฑpD…ฆ่บฺŽ๐–ฬIรaจH’E 68D๖hr%bฉฤœ฿iค–C6Dผฎ A€–„€6•tผZˆบ‚ฬฑ"ท7›™มe0ษ]Ÿ5 z—)ฝ ‘lR5vHn ถJล๏ญ“MฤฦLH…•&Š‚0Eภum “(‰0า—rใˆภ`IinKS;auป9สาA^ ฮบ@(C ลฑจb"Ee”ร ฅ6กa‚ าVวฐ#pจจ—`8บ๏‘%\Zศ„˜ฺ`7"+4๛01<=ธ`ถI/มJ„ุ•พ—†IV๋J&…%›ม๚As+š"ถก )6 ู่Qzฌ‘ EึgฯŽH ‚aUWQดหA{ ฟ_tสjz\ผฤŠ„^(ฑe”8dคสฑ‰'?#4ผบ)๊`ฤ๋H,ํฤฌขWL6คkDคG)I’ศmญrƒุ pฐxอิ๒ํ_,พอYๅA` ษ2D“"b*็ƒQผ\ๅeล’ L‚้˜ฬัaห•/X่ ะ‚ Hสฉ< Kำฦฯˆl1๚หzŒภฮr๛ั[W ‚2ฒมmฃ๔]@ฦ์Œžฤd„‹dบ4ฝDP”Q‰„ฟ˜ˆ€a ˜‘จvC…@#x Rสฺ Kไ’HU#0ัM`•คDfฆกฬ8jฯ* ^I’$™W<โไo+.,”9๛H2ฒ”˜ช&ษR… ็_–~๋ฝํAฎˆyLฃฑฅ ๕"B$A@€aošลจL K&&xQ^\๐(ฤ็-q…[:#N*ฝ‘Oฝlg0fQ.ฐ'ZA`/n%eธยaต#Z%"9JL–Chh!๘1{B๛ˆฉ™%!อŸ•ภABฎ่ทเ‹เIผX›(bฉ–๚ ˜II$ˆ27ฤK^ทdTรe`-_๒tPiq•Npพ0ฏน๊ธ@l—ลO$fเl_:S์ข^IคญEQCญ…~]้ศะLBWXF็๔ฉไ)tณ๒qฝ1(JฦpฦCฺขปuฮ‘hถjฦ&.8&mAต5![์„1ฒˆฮโดšฤ1= PD๚สญํ…‰ปvH)ิ Yfฑิ `(0คจ่‘0H&$‘ถต;F n1ณใ5หา“๊ทS‰‡œ๐ฅพคM!–3|R*4บR23hฝ ฎIยn„ศชป2!๔!@10’’Idoˆ–ฝnศ"ฉ†$สภZ‹ซU ,"% ‰ฦฐั‘ เA†ฬHอ&ุ’_aบ[Ijษ%ƒ“fา&ฤ0Zฅ.KสC“ษŠฮL8ง}$M๓—R4›บx1่–‘$†จkœPK0[(/ž!M์ถNf ร|]Š—ลร`Œญค่y%ขศร8mJ 6ฦ-erำญ‰แงv“@K†ฯอ;|ี 7Z-›๙๏๗2าJLข5 ov0L,ฤ็‰9/YKœ?๏๕7ัJ –ฝะฑr&tD้‰„ผ#lๆฒK4€@p?ฐ „lฐKฺI€'คO*ส๎น.( ๎MLภ๛นๆ{๙จต๗๚๘๖ซ˜็็อCฟ|{๙ฉFq฿ช…ห3฿อEฏฟืวต\ว?>j๛ใ฿อJ3Ž๛T._๙žj-}พ=ช #IฤK‹คดm]oๆก…ู\D16ฺกrฬ๗๓Qk๏๕๑ํW1ฯฯš‡~๘๗๓RŒใพU —gฟŸCฐฑ‡^t๊’]\žิฒห—8ญKcฟ_‡`ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ซณ>ฉๆ@5ocมZ‘ุ๐} vYyœNใš!ขเ"=ษ™ฎP`>ฺพแjๅ†1‰-m Bข 6ท๊ํ•X/ƒ ๓ษฌำ*ŒHวชฮXJ&%‰‹O:•ำŒฤg„ฟฟCม!;qฃ–@ภวผ[?้’;ฏ`ฺฑ%1l]M5‰๖พ2ัMษ™าb ค–ถ)ˆฬภ…<€ล >ๆŸฺŠ˜l*ญื~'ๆˆbo7˜† ฺ”ญุ๋qโoฌ”š‚“$ฅปcZ—@&ฑ`๖๛จแ@)yึ๖4 ๓๔UฎC–  ถŽสตศ0ภu๓ู๊ษ`gูGเต—ค๘วฑ๗iIัœ =๏}"ฃ ๆVส_ ๛ยlาฅ”l‹ž๒{MŽยVฌ่ ยฐp“ฏฦh€†!`๘yˆ`จu‡)ฬl๑7ิŠฯ2v<CV:n8สmROpD›ำgB‡e 2Š—@ิฟต) ฤ€NP][ ลญM๒ํIš†t˜q๋š‚<ต|…๘™จ•ฐTŽ5T็ˆŠ~ทลg–ฑพ‹อ‚Kษ Œgvท‡ลฦb' นPฒ‚ฬ–Xฐอไาท_„&sย…ลV๐5ฅFฐDด =N์ำ๑{ึ€ฤrC#฿/†งพ•‘ ็๕šTI ป๖J7ต`R˜feฑžซC‚Nา$LิJุ*GชsฤE9%[โณ๒kแญ๐ธฬ]…ข* ้ำv<DาC2KปC๎ง,ฮ 2ๆ๙พด)ํ{|Qกm‹ฟurๅ†๋+6ฤง่ =‰ทล3ฅr™ผ๏5ฺu`ฤœฤฌLP ฐ:v‘a๗(ณ‹รOุ™V_QB•ู2mt˜pr(j ข|—ฆF)™›ฮ๓™ใ\ข‘๗ฝhQ’ษYQ$•dย_&Žjv๗’ผฺเ=ฑ6๘ฉ๏ฌฆf๓ผๆkด>่@‰!อำv<๕ฉ{|ฮฮี๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ต๙ตฑ&pๆ๖<๕ฉjGcม๔"ร๋ภ [ˆ–j=8วิล"Yฎ>€จ)&ลBุจbt [ฬW๔‰gืH–hล"YคY)CN œz วช%š—‰šฑHŒ4e๑Pฤ้BŒ•p>–'๘ใะ‚‘,๚‚ฐR[คzCฅุจbt [ฬSoH–}UaฅlR%š`ถ*QณำQ6๔แD๑ฝ"Y๕a‚ฒP-ŠDaฎ4_œ ฑXอ"YŽ>บG๖ 2R#<Žวƒ้‹าSบณฬา†kฉ_žธ฿๒˜ศคฒRœ๚ุ\ } ณjhาฑR)+์ฏฝY2ฅขญ฿TRMlฎ’4J๚ฅ;ซ<อขš ทคŒ0Rซ-FbสBI ฌ฿IฒฅˆขM…|ิe๑IหัรๆฑTๅKžก\ฟฟI‚์žขŒžหโ’สฅำAžฐSKi7าญ฿TทTฑ`Bฆ›aF๋Š”B‚Uk็ฟีBโ€Jๅ™ค฿Jท}qVJ$ุVซอnำ‚ี“ฒ”Itฤฺ”•n๚}่้6ŠาˆฐะK0ฯฆJมVี๓LMซ๏Yอ…g5)ฝEjXGzฟ๒;ขi;;็@งJ,ฤฺ–้%า”[U˜ฆ4๕R”คTD=บzผ^„zRอ4)‰ทฌhŠœ8ะB”ฅ"Œ”ฎ}HจฐPฃ%HสRห5%า–YฉฏT-ซR#B”3Jส4(ั€P‡eYšdฉlฅ,ฒ๚ซvk9ดRผัก๊Fด็škฅqก†O@)fA‰ทฎb•P!JR–8ฉ ๊@อ3NNQz๗ฅ4!d ‰Szกw4Œf1ฒ‰›R–6ฉTไDฌอ{zMฤV Rอ}ฺ๊z3๐๔eปEฏRgOKYฏค‘ำj™e๔Pอ16 V Ye็‘ุ๐๊Rซ/๗ 2๊Ueา(ษภŠ]_้–#าXAFO๙jD=BูM๕ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗J๑๎•ใ+วบWtฏ้^=าผ{ฅx๗Jไฬษๆ๗=-Pศ’เ6ฃ˜กš๕จL&&R˜็„ ๒ษฺgาK€EJŒ(…ziดค •(3๊;!&,#$j›โ#ะ9€ˆ„ปฎ`{ขv๗กGpŒqc๏๙|JgŒโ?>„ิp ๛ฯOFA9€&&˜Cg~?ำhf7ู๘ฅฝNฒcฌz[?2O๚^๛‡ฆvh€ษ—ผAค09ภ™ูร/@D, ฿HุภB9#า$qฃgb-LฤP@#AEๆ|B(ฝ ˆ)ๅ"vƒPRฆแ‚ใุฬฺค8:่โA3% ”=‰0( …iฉล\เ€ณ0ƒS*K"ๆ๓Ka™i(qฐ†‹qTaK9Fฝœ\S "hฎYC’r{ • a œSIˆ$& +Pะ†สซt}Iษ<ิึ˜…oฝฬ{TาaXRVnฦb)จช2&ํษ‰แSlT11I}fงQศ 1~4.K๋ขeผN8อŒ)นด#คE/๊’ eช"ณฌฬฬ๋ชภว+๎X*P,‚˜6น/พ j‘๚SB-าA๎๘ฟล!ฒ`–P‘‰พ(ลIบยF5ดDVEš2ž%B d—ลฟะส๗=3€˜€ R)˜„คD„FDKˆtซ๒ ิแศ˜ คF๔อฺ(ข…ˆ\งผa$ ˆHTไฐก๕XhI ุขฏG b•…ฐ‰—‰‰„๚,…CX หzgi„ฉ‘ฅˆtXŠeEeDId$ D–๙!’Yม! ๏fฺ'jยBH,P.(gญ"HE^ฺ&๑ฑัฯKˆAฉS๘rr‹ัDษM@‰cg3I‰2สทW@*Ž dงษF๕ygฅ\\wX๖ท) 3Oม<้๙†๏vำ&•C@&yฉLฆ“ง‡ฝ{ด{"f‡™',rŒa‹๊ l„A„ะ}ดจl ฆ฿ฉŽCลุใM ก!™ฒ^E–Ÿ.filPp›ฒ•ฌซyตญE madึ]mต $uIJxซฆ”-H ภ-%ลืโ”ฬ…„ํๆ-6ตcา๐œ:ถ…ฬLIฉ&ดเr€‰ช\D›ž๔;”ึnํ๋HุI!UK€ฏ vK‹h Q"L"Hขฬ„าT™c6[าฤจล‰ล‰Fะ…คฆฬ’ตˆpฝ่ฤ=ต6แ”ฦ œเlฐ`ฆช๙ฉ$ิJ zsฌ2†"Rnฒึ^eT…€ภ@Dh ีผfฎˆC1ฒ%%B"๒NN1@„M๎`Y ๐j @ hฅด@๖จF=e๘Aช*$สnIƒ๎ฒอ[ฑฑเาาส!i'Z.Szน"ุคj์l•‹฿Z•๐›Œ-์1-จ`[cŒŸ—91$ีฮป๗pŠ$อ’ก4W“A7„สYลVA@&jb 5„<6bFกูเ%K+j/’He!TŒรsE5‚V‘šš‡0เAซ<จ,!y&H’dLE\๐j7‹‘ผฌธฒP็ํ สสRcจ`›%J7p[ŸฌŒE๗ฎ —ฆฒืั &70Ÿ$ิih,ฬZ– ZA0ฺอ:CG€™โE&jูyMะTรšธ'ฬฦ V#๒ฆEt!‰ยฬพ๋T™, lฉI 6:ิƒVBl&x~hLž1kตN/Œ^ eaEฝญP{ญะ2PจJH €ฑ91NฦKๅชD่c_ย ‰PกCJ#์•ิืฒhO0 †ouฯซŒCีŒๅŠqF_˜๛ัุ1De† m!$h^Pตณ"  &ฺ-hๅฦฑฦs‡b+i 0'‡ฝีR”Heu ฐคฎ„ฐI+ฒLCซ9ษZลqํ๋ถ.ท)˜œNrQb&\#ฅด…šH/2€ 3L4ญA%(‘jžI‰"ไ[‘:dต3uๆ‚6‘VdW:ฎg฿๎‰่"ำ…ณฃ‘ข๎๎*p๐ฅบœL8œ็…-๕"i ฑ›โƒฉ Š—!Š ฆ๔Kk๏%_eกzีฆก่กa‚N™7ู˜ˆฝ QQzถ•หฏTQ‹ ตฺห#p(œFƒr(น[Hรมฝ tศ™พศผฤE้Š‹ีด„ฎX–๕zขŒ ]ฝฎะ–YDโ4‘EสฺF ขหS%Q ต,ถT2ี” cา1qFcqV?RLดฯฉPฐขๅPKี^fnฆๆำ‚ิESน๚ผFฬ›%i9›—าๆds5ฅฬDfถ1A;หภผลธB ปšz‰X•ค๒j"ฉšZิP๒ั7ํ“}วtNmDF™cˆ„ศตจ‰บ–[€บK ฬ”ระh*”&ฤeฆผމฯv/<ห$!žื{”e8Q‚ช8ตH2ppJJ฿ื๛‰E๊Fฯพ&๙฿6ŽๆำTU™…ธ:P)ฏOะต๚n๎฿}ๆNฌ็47[บฑ%‰‚?#ยQํ,rs%’ฯkฝส2œ(มีZค8ธ'๗ธฑXwu๒41๎Ÿ฿พปฅ!ดทG๙๔9"บ*n๛ใฅ^ ‘งๅ์›O๖tญฒf,ˆ*สองJผ#O^ฯพ:๐Aมซ-ัxใqหˆi]{"ƒ]=๑hu๚ฟ‰ท๓”ี๖๊iะึๆไt”ฅN๑ด๎€5าญ&6‘ažส1^ภฏฬมƒ+CEษาู B˜\.เ#๙˜0O>ค B,€-Ž(ณภUupป04-แฉฺัjร”4yZ(IrJPt$F!Zฬกเ-˜Xˆ๊ภpg|.]ๆใR“;M้c•3•ิDsิึF .ๅ5pุv€ฅ’๕†ๅ+D๑nu+ซฬึ:˜U‚ `p6 T‘p’r‚y!r]ภS˜บ+ฐดc‰ิ’^ 1ฝไŒฐy’6<-ยชฒา}awVEซP˜d›-จŠฅ๏กส่0S1ึ‚ˆฬุ๒lภ5&ภ>D-,ฒต$Iุˆe}P<‚2ฑิ9ECำtฤ’}ˆ66{จ*[ˆF่R๏ฎ๐๊,nP[5ฑŠ ™ต"Qฺู~ข+j%7พ&{มJMlb‚เ๛2ีpNVฅ2JฒU/x—zmจ.ๆ฿ฤqlษL=‚ฉ@"lFZkศ่œ๗b๓ฬฒBํwนFS… Zฃ‹Tƒ'wคญํธ”^คl๛โo๓hํะnm5MๅY˜[ƒฆ๏GvฃŠwfษดไัะ.ษ˜แฏŒใ์ฝฑำห๏yq@ค*ธ๙ ฬญ=ThนฎŽ  &H9wkฑ”‡4 ๔๑ฉ/#ฆ[๖:;่ –็ศภZนˆAA๐กl\‹™Aพf ง@)สR•30๒@HแMMดv”ี๖๋W2oPZGQ/p ‡Œ฿สaDฅฃoโอFtซIคXgฒŒWฐ+๓0`สะัrtถCPฆ ธf ฯ…)‹ cŠ,๐]\.ฯ\7 `' ฑ'ณ‚2ํ#ไฒ;•เว‚@คK|$ิษ!hฆŠญฐขปAGญฐiฤRTKdลPiฤผษ<_~ใหื2U…ฏะDฏ8๕ซZ…ฆ &ูuบ”cuAธฐซd ผขมธง‚ษซฯ`@@‘Œัู/hŠAโ<ฃrF•์bhฝจ‰$ +Šv๔†ม@,%‚+™่๐@Rซ๋ธ€จ‹B€)Œ๊‹”า}$หดซโ˜3เ_ ๕-‡sฆป›ฤI“้-Lว@"ฝพIซ๏๔ƒj‰Jฃ} fิงะ ฿กพหI[ข‡RA\ (}จถˆ„zข&รHZhjโ -pxื…~งv!Q“D Yี)LฌฅกY๘gฌŠีKฆbิโืO๊‚๗wข )}†ล•dE@ผ T…*ญ 3ไ†Eฑ-๗0ฤค|‰L]Ÿย&ุฤ9ฤXN์,Zภไ”ล E๔ttH ๋ดัพะ\h˜โ๋Qา !bึ$ฆvMบ–P^NฬบbD[ตEธAv1)wะŽ„@l๎มฑ~"าึฆ฿”S!†ต["ูAPi‚ฆP8My1พัั” XฟŒl$ธ‰.\,*t†ุใ+Yj้”๒zhtศRm /PอยlUฒฉB*upย„0SG-อ‘4€‚bŒˆไHๆ(ชญ•rฏuš'ฯo๕ื๋ ช €Tษ4เส/ษฟงลcŸ •`92-]>๛ฤv|7X_•๊‚€`€ฒ๎ูdn้4ง๕๎š?oด@ธ-#ฆf#ฐh Ieb3hข/R๓QฎP9‹,ฃn KฺPปจี i"Qป`0˜wิฐ,wxฉF(ชนE›‚โ1 fถŽ[…0j![ธ*Ž* อต(4uฉl;ัฮqบธ—7)ั๕X๗ŒZโT]ๆ#pีA฿ฦŸš่/&ขดE h'\ํ ฅJ‹•ฏLบ‰Eภยฒาฬb,Jเโ wŒคิeธ ซ€ฆeๆฆฟ4งUCฐ UXQ‘น๛่”Ÿ#๒ีwผ<ฒฺฝP2˜นฅnก-า4(์ˆex*D4-ง |๚`avส๙๏๊ิพี!๔,ฐšAm7บ๎น ฃบZ5ŒwAขฦ‚o๐ซ‡๔๘ฟK‡หMอท๕0gไฺo๚T?\]bๅ4ŸI7ขQ2๘ฆ ภxWย€=Kaมฉค.ๆ๑d๚@จะณ]Š๖๙&ฏฟา ช%*๔%˜PŸTฏo่0 Vูม+๐ฉทAv1q€–ป ฐ9%1hD}0[฿ขE]ฆ๖‚ใ@”ภ๏ZŽ• ฐ9%3ฒmิฒ‚๒veำ"ช(ุEย ฑ‰Kธ„p@ฮYZCgv ‹๑ต6ข™ไ5จ"ูส ƒL…2ยkษ๖ŽŽ์ bลca%ฤH1rแaT๋ค0พว ZหWLง“ะDl‰p ฆ`ู)!ณปล†ำFหฺe„„ษ p˜Ž)ีฆŒEฝ*m4&4M‰ฤํ๋ฟแMโVˆ7ปฤbฬฤb i"Qปa ฌFm+ทq k.šp๊ฬYeqXิ า…Fจh I„ภ›พฅ`๛ธˆ;ภ€ฝJ0นEUส,๏ˆS5ดrฐกจตšเช8จPƒ6ิ ัึฅฐ๏G;n=ฤj๊เ \@pฆCDTิuc1k‰Qw˜รTe~k ผšŠะUL1 sด.•*, Vฝ`w07,t‘(ฐUT(AˆDeธ{สXฉ”U:โแF๐D.#TอDQ/{ํฅ ‘Rบm†p(O+๔ฐ(|ดPC~MกF…vฯ฿฿`7๋๏๔”Ÿ๕”ส•?y€฿ฏฟาR}ึS*Wlๆ~พHaี๖”ฬd๊ฅvฯ฿฿`7๋๏๔”Ÿ๕”ส•?y้aฒY5ทB Ky–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2eผหy–๓-ๆ[ฬท™o2b_๑ซฃ๛|-ต1ณw๔ดŸŠ‹"išz…กฬภu ซ~ฯโอ:กNX˜+  มŠ"lฯส รู0 “t ‚M:บฟ˜้›ฤ,ัc6=ฅP0f^๑;h฿VO‚7@K[ๆข`ฌ์"hCZ™bm R๓ู1ิ฿๓ˆย=ˆ๋™ —hญ๓*ทŸๆ +; HxฐZ~+ัพ.๊žF j)ถeC}*ำ-ปžF*ํนๆb˜X5’-ทึฺจ)ฉmS ัMฑWrญ2็‘ŠmŠ๔z?ถ่LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLJ]ใ^ํ๓๚Šœ๙ฟU๚๐ฉŸญ_๛ ^6YำG๖๙ิ้mŒ~}กั:w็yใ่๚ก๑7ิ๙?'กN;ฮ฿ฏhE๊Bw๚yzv๘{B๙๖้ๆด\Z.%•ำDู;B๋3๘๔3S#หใ~๛tัร‡o…#่฿๕า๚cใฟ•H}้ใ๊ฝ1า๚ึ+ฆฮŸฦU”๔ศ๒๊—‡ญf๚Wx_yTQ ฒก}๚ำG๘‡E฿D?ัh๔miUๆyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyงšyฅiทcขบv\B์ศี๎>ศ๏CฆŽฯจ@ี—ั๖Pšถฦห ศV.๚VŠ2AcXŒj๕ฑฑQ๓†•škช๎j@bSJภ&๎๑]qฟฌ\ : ลีป๙‹H-ฏค-๔K(‚cฑัšู‰ตุๆ•ฏณSแ:ถฅ‹uCsƒllดภXคตอ๔–RiEฝB ๓f6Š โ&พัK6ี[์„,F AC–p[‹p]ธ”\ฑ ‡phภนwป‹Nจ[B$ -ศH๐S#l”ขใ๏ภƒิp0ม ฤศ๋แ ภ.๎“ŠJ9Yศ~E’ถkjPญฉbสฑผFฑa8(สˆ,F4ส'p ๐—ƒ?›กฟOูS๏๋ฃ=S~บ ไ'Ÿฤ๛“๘Ÿr๎Oโ}ษOน?‰๗'๑>ไ'Ÿฤฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่—ไ๔K๒z%๙=ž‰~ODฟ'ข_“ั/ษ่rŸไจจิถฬ๚%:‚œ|1qหWฤบTฮ—zกฑศ` ”tH๋pi_ฟ๊ื๋ €mƒXSฟๅ๑ OคPต0wฺBล9/&ต™ J`w‹ญGJ€…‹X’™ู6๋Oฺƒดท๎่†๚ดŠœฆ2ท฿@ถฃe bู.`•);มฆ้†”›!Yค๎โq0ช๓bจศ”eมxฤn!…hซWoŸœiีย&!D:9™Rdภฤ#]เˆูเtG@6~8A”˜ฅSด cP0;Ju A -$J7ln๚๗)อjธ= r—dภย<๔1(V1ฃ\D5Q #DFPดๅ,ฦ ‰pถGใ–9จw2XจUทป\Ocgsง…EีKฆ@U๋ถฏ/๋˜ล– —Aœ†ฃw๋†_ุ_ฮ‰ชJQ๊:eVw~iพ"bีภื“๎๘;๔pฏ#ยต+†›ถ}ˆ๎ฃ`sบฉ@]า€ง ็โซจ€ิ@ๆๅo‚d๖žcY E/ ภXฤ ย˜5ญZ.‚“บr?๖Ptซฏฒ'/Ÿ&แ‹ข)*F Ah]ี๎มคU#@i#่A ™‰.ž๏J ล\jฯm๘่0็ vN(--bv.๏ ๆ0฿ลณไฐษ˜B้๎ไ ผUw‚>ƒลๆ๑ฐษœฤฤnœ”*เk์‰ห็ใI‡8bธDKhŠh- ข9 ภธ4ŠคhF>ƒลๆ๑ฐษœฤฤnœ”*เk์‰ห็ใI‡8b่ŠJQ„ะZDu{€piHะH๚›ฦร&sบr?๖PtซฟมI›ฑC6ฎŠ}R๛9;lขฉ' Š ŸVA606ฃa|;AWM๎@๘มฤ้R“n8 i=X0ถhuK์ไํฒŠคœ0r*‚}[๑ุ\ภฺ…๐ํ]7นใฅJMธเ)ค๖u`ยุ!กี !ภกZมT๔ƒg”B™7ฯ†fnญฬ๒ ˆUJ‹ZIฤ0CKซสyw8„4}Œม˜i ˆŠŸZจ]ˆ‡ณcJVFHffเ ฯ จ…TจตคœC4บผง—sˆCGัธฬ๖šˆฉ๕ช…ุˆ{61กudd†fnญฬ๒ ˆUJ‹ZIฤ0CKซส ยีjr2่ํE4žฮฌ[4:ฅ๖rvูERN9A>ญ๘‚l.`mFย๘v‚ฎ›๑ƒ‰าฅ&pา{:ฐalะ๊—ูษeI8`ไU๚ทโฐธ9ต แฺ บorฦ'J”›qภSI์๊ม…ฐCCช_g'm”U$แƒ‘_๚ณูthinc-9.0.0/website/docs/images/type_checking2.jpg000066400000000000000000004637501461023342500221030ustar00rootroot00000000000000ุเJFIF„ย็dฤ  ฺ๎0๒ฝP‹e ส@ตฒถฺบ๖tฦDจษj‹=฿Ve…iYji{WK`6V•–ซ7฿ฑ1>m2E>z<ล˜ๆ#ๆฅ[<๕ฅeกT๖ฐ๎bvื@ฦ\๚ฃๅฆคฅหฃC œ๓ฌP•สํ„Sฏฏ&>•ทP‡S„[ Mึ•––ญ`x|๙tSฯํ฿lEiYmfrำTละVtฯ>่กูŒไ:๕/นู่่Oๆt#น*BฐH‘์Eพ“๙‰šฟ็ฦkา็โCผีtลD7ผฎฎNํ7kJh“ ฌGปš ่ฐa|1๖Vฃ๛ธเฝั~8ณjด๗nœล๔๑TWฅkwลลz‘HHร{ฟtTๅง๊XดM ฒ5ดมฏ"๚k*โ”ฝ็Kจ5!Œร…Ww^๑๖ไš[hุ;}W“ฬ…๋้h‘ๅŸ฿?ซว–n–d๕่๓Us๔๑k}?๙ฬ้fท์^6yXukv2)2K์สœด๚้ЉmF่๘cฒz7็ำซ†๕ฉS z!ฝเ€#D4tUบบ\ญB}าง๖„zn@่bูc—ๅบ,ไ–อ#ฟ฿โแ›7[๔Aอ‡\ีYoJ๊Ž๑GSๆ๚C"ื;ข๊่#ฎ:ฎตUๅ฿ }mmฟป—•ช’,aธN๎ชฦ9‡่#™{‹ฅ^้ƒ2ผ"Qg™›™็{ด˜ๅข~bztๅหrXฦ†ภ?ฝ มK3R๗๋คคšุ(ฯvšV)]B8่Šธบ๛ส^xZใgdณ๒•d…ฉmบb่{ ๅ๎ฮฐ}e lkEฅ๚ถ1ํuึdZ"ฉ!ด‡ง+‚.ังำๆ‹’8@่N8sาD๔Pถ๔x:›o่ฝูค6ฎtywฑ๖โ^^Tษ๐๏๗oญOC์Ÿwไw็๘{WIๆฺฎI๊สว?ธ๎ณ5งน๎แฎพ+บะZ็9ึŸๅ5Žฮะ>V๋ึyฮ#Ÿ๋m‹คl}ุc^ึwํต6ฐšcญKlอ>อSท๐\็๙v`k=ฒยฑ วฃw––š;4จ‹ธ๚‡ษ๕cณดัLฑจใี•๋n?[j กdฎ…อ~ฬ{ุZ๋ษู8ทฉ์(Œ๒?Dๅzฏdเ9O๓๚qO“’๑ฟ<คž†๔ึๅ<@ส@ถR‹e [)ฌ|rโภ RฃฎqหGJŽo{Lื฿O๖#ฃๅ$ (ฌŒD~ฅ^Šภฆ#๊{ณp1lค‹y™ๆž`yๆ ›๒ฅbw:ฌcpฎwkยJ๛sTaUกืKทิ๊ŒใFOš๋‹๎ัฃฺFtL๛VqVึํั“Nฑบๆ฿9ิ๊:ฒบใพ๏ญHc<๒๔€1พx:C ๆฺY%o^'>€-”€1o๊๙~ฏ—๊๙~ช8ท ฎฌ}cpสFั๋’๓<ŠwUI–฿ธ3zฎีN!s<uปM–สงF;vีก๋๛_ุ๓ƒ์BxFซ5ชK;ฃNš*Š๖่?เ฿–l+žˆ๚ฉ็?งถˆๆ ข@๊;๔|_ฅ4ภ™้Z๘ส@ถRN[ œถ0›ช็ฑo๔5Ž‚™a\ึ2=”ุbูHส@1lค‹e ถRลฒ [)bูH-”€1lค.๘>๐๕ณ‹e รพp†ภถR ;็๘l‹e รพz้ะฉ๋&ฮTlทQnห&า;ึ5ํช่š"KZsvกบG๐ุส@‡|็ŠŽฮ+ศgทƒฝb๙'u™ฮE๚๓]ัlfŒš๕้ฬร` [)๓ช6จ๎๏ฟeE[ญ7้ฉE$|{ทiณ:๏˜u>`dŠนฐ? €1lคwฮ๐ุส@‡yภbูH0๏„๙ุ ส@4~ภQึE๓€6ลฒ๏๓๛?ด๑,gิŽ•‰ึ[œ‰ b๕“s4วc๛๓KTฅ˜ส0‡Sฉฌ ?MŽtz๖€!ิลญm$u1@ฅc^Ÿห๕!ิล+ท๙ฅ5Mฬg„yฌ;ย*"PCMฃจ,fK„:˜ฏ“mซrV…—ˆกญฑ ขฬโฎณb0ฒภy๛ผ ˆˆPฎฬ้ถฮ+ŽlD‹ณu1Hน†Mjุ&๎Hs2ปฏซ/]HVธงปจเ$ป๚›ฐ]"ฑ แฐ-แ์]uฑuึลืžxฺN`ุ์Bถ8sฒ%่้GปๆŽูs#ะ5ฮ8™a‹;‹˜<ษŽ–P6ํฬGT๔s{ํZ\YฟสGฬ๎ๅNpยpD{ๆ๖๎ฎkFฌษwJL๔w๕tKฬแz๚[\ัืผj๔“>ํแKะู@ถษฯไ฿Žำ„บNฑๅV&U0๏MŸค๔ๅษั฿D4!`P๚xฟ่_ไZ EYeSY๗6}.ึ%ุSฆฤŽุืPC—Kฅ๒๊ฃฅfบeๆkฃ^~งฅZฎ#j•q๙HiWbฤ8๙ฏ“;ข;ˆŸˆ"”งูต5.jซชชhฟ!ฎ๘๛้ชต๎ž™ฝ้32h s๚า+/4Ž~ฬณŸฺซUโ R~bูH ง>wมโjซwBจ|้?ค.mdlLถป.4#฿-๋›lี“๒–ฆ5Ÿฌmโง๏{“{u๑๏ฤŽผjtKX๒W๎๙..+ฺmูRdP5ม8Wดrฯย>์<›๎’;fฤk`ช๛2ญ)ำ๗<1ฑ]ีช&๐ุส@ลฒ ฺm^ฺ์$ฯค์8ก;ณฅห4ฃ‰๓ช'NŠEsZ#K™hZ(F๏9‡อ๔๎]gUc›คj'›lรไฃกjw”ะ oYNˆฃะท96;ฉํช _‹ฮๅžมช็oHฝi7ช:]Cฉ9ไOชI่&’ฏ.฿_J' “ี๓k๔k{สTม;%‹*rธฏiด~O2‰/บiา!ฺD๏=ก๖IYฉuผแช;hฉ{9…๛ฺŽต7€๐ุส@ฦ๒@a฿8~uGlฆญ”oศ,š`ป3ษฎ PI|๔_{>"&–ศษธณ“แฏป…3Zพ'wณ 7๘ 7๘๘l‹e รพp†ภถR 7Zหv€ลฒaฑคๅ`ส@†ฦ˜Eฅ$ปุ‰6—O๛3azซo๙ูฮจYJ/h,:Doxs)ข6โŽS2)dF]ใ์ผฎฯดbูH‰[#v€Œ?RHฃ›ฦ พ—’bูH๓3ฬ<ภ๓ฬ7ๅNฺ๋; สถ/ใ่XอM%mซใฃ[-ค`๗?@7MwMdฺ„/‘›w๕_$"^iีP‹e [฿๚พ_ซๅ๚พ_ซ–๛กญK"a็๎ฎ‰,ใb}ถ5๓นะKฺfาs+ช๗คkฑํ %bNeง&%UtmJrbฟdO -”€1lค9่ฦ9คClบM…N[ลฒ‹ํNG‘&ภbูHำ๕~_ [)ถR1lคbูHลฒ‹e ษฤ ฺ้ภ {k ตdbOฎG๒ˆw๎฿C฿๐อฎpZทปฤ=ะk๐ล๘ุ๒‡Qy~Xzž[=g=O฿๐ฃ็ิ๒ย๖(S๙ฅq?ี•jZ๕}ฟวŸ+Yฒลฟgสทฬ‡ฉๅžพ?฿๐บฮ_L๛nตไt=ินฯงnˆX฿ฆz.าิร:๋่ึ๎Q๖/Š}ห๑w๎ฮ_ง็๕…ไf=ฮOิแ๛๎ฑใž๏าyฺพwงwรศ๖ผ(๖”t|q๕>6ฏฃŸGœ๊9Ÿ ๗ฅๅญ๛ำู๓ฑํzิ}7า~{ึsทto๒ฝผgAหฟSุ๙ŸำพS๕?˜}_๒ehYYฑsืใ1/ q๖ฝOGฬ‹๎lๅcy}สu<฿Cโ๗\ฝแ_–฿ๅฃญ๓๋๔ผ็Qภv<็ฏsีั๓คsž๗บ‡cวIีตF/๊—โฯฺุ>Mนw า๛๙้Rs๛L็ฏฦ{ซXแป๏™t|รปู้ำs^๚ผ—k๓.œz?Dโw๓'ั8—ับงG๒ฯกq?@ๅบฮซีศhข๔~สw?(ฎ๚O ๔/Ÿ}ง…ws‡๖y๗๊x๕ผ_Sโ;๏ษ?…•๋™๗ธ|>ศv฿__‹ึะแ#๐พ‡ฯnฑ๋xW8๎า>'ต=3่9็I๊ั๊|Oc€์นฮขๅ =๚7๊๐ ?0' ฦQร้พ5=ฝฟ%ๅ๛Q๗๘ปมๆ'{^q)ึทฆอ Sl^ฤ!ตบŸนฯ7้ฑšฅŠ๗eRฦšw่ฝF๎‰๊๖๙่ฌุงooฟอiลšปด๎ฮ–‹žฏงห๕UอuW/g#8+วWวY†šท๋ฏพีพ}8žอ็_d}ฟB๎ซ5๗๋C*z}๚W(ZชB`ฌ€+YญdZศz œฐณฆๅ_Eเtu€งUฦu(๔.\~ก่ก~฿o๛_ๆŸžฑค+YV…สw)งo้(ฑ*ฎ็ก ถฑ๋sุไ๋;๋:nxพ฿ฬฑo้<—aอ๔OWWศ๗ช\๒z™๗ผวs๓ฝ>ฃศ๓ƒำŒ5ฅi‡ึผ_S๔ฟแK๔ตm๒Œฃ(หฏๆk7สณฎทc/i๔น.ป˜ซซฃณ-ผงm๓>ง™๚G ูr^`ฝปF฿ะ็บ^{ฏ๙*๖™๙ฏา_ฝ‘ล็{Lq๑ฒ?ตฟB).R ึ@ฌ€าs`:Nlณมm ;€จฌ€+YญdZศk ึ@+YVฒZศตiฐ„ภพเZศ*๕@9ู ึ@WชฮศVฒ ฝWฏiๅา;Ÿลoอ[ต๚ฎCะกิT๓}<v@ตU๊ŸH๙ฯญใŸAๆj๔๓ๆtaส๖<–qล€ฮศVฒ ฝS฿๐:nd๗†อิํ๘‹๋๙ฏ•๊ำ็@็d+Y^จ; Zศ*๔ <€ ึ@WงฯฬVฒ8ดพ๓€ซี็d+Xฮ3Œใ6ถhฦหk๚M๓ฟอฟจฟ~ึโ'q(็€8 ๆ g เ3ƒ,ๆ9‰,dˆ3‚QJ#9‹9ฦbgœฦq”sฮ ฑ–bŒ  เ”Y”%ƒv@ถซิoQฝF๕ฬฯV•฿าŸ‚}{ป๙W ๙พบpูฦXฮc˜ส;5ฮŽa_DVฒ๑ุ€hp+Y1‡)฿{ƒฏไก๒้ ึ@กrสw)๔ซob&‹šง[Oอ>ี๒Žเ}#w)ฺ๒wชt<฿ญG ไ::žฏœฌ€+o”eF^…]๚แตฒญส๑h๙งS๓ำœๅwะ,S๔<พงชื—าpgŸํั๙๐Zศต|ำๆ/่o(๕5๙แาs`ตญ เ>{ั}|k ตJภ ึ@k ตZศญdVฒ4oฤ ฺภฐX,;ซˆpGฌxwŸณ“uhฟ›๐$ ๐ep ๐fภdb6โbนแ3ภ3ภ2ฤ2bห6Œzoนชห,quร™F–&Lsภ\๐—fญบใ<3`c{/ึ~eํ?.Qฟ”žzใจ[Fฟโป†sn๎ฟๅบz ถ ฐบ๖้ฉž์$ท5 ๔hฯ\oื2\6aทVX\ซHห)–น–ํYแI“^z7ฏ–๑gรy ๎ผ‘mห\ปu–,rบn้ฏfใ–;ue\ด ’g†zถaญ[1ห^mิRs๛๛3๙๙M๕ำำ;˜qYอฟw…s๏9wทTr;ะmุะบถ้ฯ[;jห0ูฃ<mืpฺณต3ัปV6jู5ฑeท š#~ญบถฬmjหM฿ลว๛kบy"2ฌตฦํ{&Q†ษข๎ีvแmฦุ๋ว%ำ– ๒™ใ–ญ˜g–7^ฬrีฏ-šภำ็\ฒ๚็ฒ8Gr_N^฿•๒ป๐ฟWแ๘,ฑfX(…™ Ye–eŒ[+<"ห*๘?ุOoึOณ๔ะX,ญš์&9หe–K2ภสYe‚’ใŽVXฐภ€\ฺภ žถํPfฐ2ูซf]cณ?Cจว ๎;oฏ,TฒสŽทฒ9—[r‰Y`ื‹ŽZe†อ{5l˜็.9่†:๒฿ฏ๕zฮC้๔/œCฐ?3Wc๔†9€ –Yfฬ#ู<หภ–ฑซ†ฬ$ฮู†อ;5๎ีณ …YŽXg†อZ๓ุึŽล๏O)|‘๛พœ๓ื Fsน9๗–๑ศ,Xอ`6k@ฐ,ฐ`€ ,X`ภ\@e€บ@m t€ฺู้Xb}:๒ว^Xๅ7hฯ ๘แท็hX ฅ๕น๋>ญXๅ› ฿6;๔e•|เm tถ๊คซnXๅืท^ฬ3รz3ƒrฟโ‰ภP€P€%( ” @m {wญฟง๔yฟƒœำ–pN_ฦ9ืZ๑ะRRP”JP”  @’€ @ @ค ด,าhX€บ@m ฐ?{๐ด€ฺ,ฒ’ฅ—ฝฝ)็oD๙ฏ๚ฟ”่๐€€@ฅ–Pญ๕O"๓Wฎ–บRส” „ ”Rdห ฑสYl   `๏J๘งู๔o\tx%J!2ลV ๐ฯŽr€@ภ,า,ฒ€6€€บ@m าm˜ำฐCฤป๕uฃ|นศ9ทไ๑ฎSฃ๖8ืq‘Ie\h%ˆ๔ไ,?7Q~วOนW\z๛ฬƒ๓qวๆSŸŸอ9ัlXXX•. N@ภoะN@ภrM๙\,๋ฤ:ไ(ไรฦอaœฤXฉe•น๐ทฑ?+๑8ž/“ฟงw์o yฃ˜้๛x8uํืfxe2ร)”าXฉe–iฟž~ย้^ง๔n}ี์˜๘฿‰Jๆ?oืืXFไห 2—๕็3วH`ภsa๘qˆ“ูฌXฐฃ|' @XHภ`ฐX, ฤ<  5 078@`p69!DP34CGI1€ ฺ1ูษ๎ไeใ6แฦ_๙ทๆ2ฑlพŠ@\๓^ e?MรK๚z8ถ \Cคd–ฐํฯs)๔t7 ’œห็๖๙d4ฟษfx๘์๚ืวŸGภู„|ˆkšึQŠ\Š%l™€ฦ•ทพหงbxงฮVa}}ƒeAฎกฺ๏ณ๓fY`๘ฺp:n@ขz: &HฤT.ธwNM@z็์O‡ืฯWSฬ\C‰1ฎ/;5\fฮ๕œ(๚neำัยอTชฬ1ห‡Fี๕ œไุ่ TGห†฿๎‡ฃ๗q !ฺํ ด™ฮƒยpOฒT๐ f‡ฉๅฝZ๛ฉLใlษLุs }1งฤ๑Gฮญแ9}‰Œ ษI\ˆ _”m‘b‘๓a๘ย‘j“สฝƒ!›=ผฦโ7โmQ้ฏ.ศ^#Ÿ๚T&0Q๋%ฑฒรE# ˜สnฐo ‹ิ~ปฆษ1$>rใซๆAฌะ Ÿk๖Œ”•GฌูาR[ฌ์อ™๛ผ-ˆหษ๊ŒิGKAžNึdmƒ๊Y "9…วzโฐbŠ๑qบไrวฑห.œํผ‘\{iuŽ&ษ^ู–~8ฐ#๖สิถร!ณหGHฒแ’’”ฺYSŒทlฏ๗สg8I”=ฉ›JๅŽ0<}อํ˜M๓รq-]`’ดFEฆoง^.ำฮ&A‡;ฌ )žง9ฤ1eฒ"Z~๛9ย5ๆ๋๔๐Q*5)ู1‘ห,ohซ),vํb=ซ“๚ัฤwย”)๓ูนใeป:ิˆพv‡ojมJ๐˜฿๑ฐJตฅnถล}ฮื6๘ด–ฐ$ฺคญ“—๔1= ^วใK ;Tฆ๓GฤถZล>ฐ+>ซ’…์ฦ06าXฝk&อœ‹•ƒŸว‡โ(ุ๎ŸQ ™[หีSฐSVๅ T์A‘†ค=Xmะถlัชeหถ/‰zย`—›ฆœ{๙๙~ษค/เzz™๎๖ฑ;š๊ "๋s,œƒIญ_หSVตฟ๐ ;_ ถ์rGปํjํc๔ณำวL}h็์ฅ=›‘้%ฤฑฮgาไ๚๕Jง5๗oซH‚_|#Cfา*ถัsอ”b วฤู+{6ดร.KalŽ,œ฿'Œ“ล๎vœ*SIŒ’ฦ €vตตกH6#ฐ ๛_฿ภ.ด๗}6๏บ"u๙ณw›ึ‰ต๊ห๖7๐“6 ฯ @ฌ ษึเภ| 5tz%m.2ฑ —฿ะู†ดŽป7นป•๑&ู_oŽ๔๘†ฦR‡๐™_L๋๛jDž0ชEพ$:๚ํj็F๏ะ๎Xค๛วfu๑‚!มํ‡๓z๘t๗…lณืŠ ฤฮ až้งลญ5อภŒขุAฃfะปƒ๘ใฅ^Žๆfฮ=ลฦ—_๙ฝิยอ‡ŸP1zlณมrรMษD…ดDฅสtูe~+#Toแสอช/ญ)|2xVuu5ดKƒ๘ภv(c&?.T'ำt &4ะr}ญ:ฤXย๋ึส9bฒำ‘ฏย^K.ท1จa^xฎปฌ/eF2แ`ทฝถ?W๏‰ž/\ช^bีณEFสีJ 8ob`ุแQ—–cŽ%ด"xDๆMๅZฟž†${)หตฌฤ3ภ‰อXYCภd|= อ้อ ‰6ฟฒฆZ_†LZžช:่๋*J ๕ฟhะอ9‰่ฝ‰%ดยึhš1 ฝDeg๛,ฮgบ๕โD#wEฌEบ• ยฒ\ #ศๆ;Œ\ัV"ขข ตaฎ_4ฤณ1คPั$ย{x4X๖ฮHุ๔OหฃR‘ ๑รฤฮฑ’LฆczอmFฺร๔ำึธj&9Žฉn๋฿>ญอฝiป๕ล„-ฎnทฐ[V$ฮโ P8่ษฉW ๖Ÿ6…ล[ฯUJŽpฉถ‘=• R่ƒ๚Iํ ภุ˜Rัาั‹NฎNdฃ๕œ๛^‹žs:ฌ้เ้VวHgพvไqk%n็ถ๘]แ่’Š‹˜wึ,ผxภิNGปŠฺGชฆ(ฌฌฯา๗ฒ qZดšุN}T[zญvnX5๏ทTจท ะo”‡ูฑๅคBญpQf 4F1ชญP๎มวดสฺห 4”๓/ ŒO๎ สž,5ฎYซาŒ–ฏW(6มž'ุเฆบuศ.RธP้“ม~˜>]4๕–fษ๊ป'q^ŽHด`7ำiUIๅๆp๙ฯF+ฉbฅปa…ฉฮๅr้†๔š3ูƒT&HXLsy™ฃRเD๋h^TๆppžiG ™เขov^Œกg ิ>t๘a„๎WMn:ูhยอฬ-TฅโM{ง$›)ฃS0"ฎVะtŽาพTุ‹๖บท#K^*ศu`บKIs๋kฟ6ทF$ุAbdฅ๒Z้ฒะ๛ hซฆฆ์‚‰SI๊พบž™ฑ–น#ษิŒKC๛ณยIGโไ*VD™บพyั๒\‰*#GJต*/:็6k3jš€,(A,@เ–ย๘*`ŽำF.5ฤU'๐๖ฯิี~$ฏฃ1N ฿†ย€?_๋ ]^KŒ\yไฆ๐†ฐ`ฐ5ลัฐ๘D๛9‹g ะHฉ็ žBšhรE้ฦฤ,ร–BH_†ฎ๊ัื:๙Z a†ภึ\]นnทG๗]๊ฉ0XLฏ‡5ญ์จ! U,แูbก[rcyิ?จณ๎`A๐อลต5k[“ต๑้ำ–B'/ กรk/”ุ1า่ทrธKg'ฤ;ัษญ˜ซ๏๎ั3ถ{:HเฐSLv]+มfxšฮ 3๘x@฿Vอ‡ZูนlษIœ.*ฦฦdŒz๘ K\'ฦyS๚v@Iˆ๒9ุญMฤˆ7Uน๚TR‚ญ#ืๅ'„๎ธ~qท @ฦ‰า('"ฮ&=ฌ|ูŒ}‚ฯ$ณ้น๋ษv*2goบjค<•งƒPTKx,ฯYฤร1Œe0ํีw+šU@—occ2F=}ปฏUI๒หˆPŽพฝUรKๅ่้9ฟำญa„;—ฒหตใมNฦด‰ใร7๐lž_oฺA2ฆ[) jล ทŒ`iKน\ฌ๚ึ๚}ฟใ9ๅ+ฅใs'Hz๕™ธกZˆB†nใŽ•z5v๐iVุ‰V็ๆไโใ&ฐrbๆ0ีหh๘ฌศ,Lฌ,hุปŠUู/rF*.b>Lฟิ๊Š Eฦ…qฏaŒz]Lง๏นz๔ ๅz+ึL\˜(@ำึ!pเ˜ธ~(แIตขเšCœฑ$r•U‹)B ](ฌ„ บ๖>Adเ๔ ^ _คุุ้-‹Xคy๋ฐ)Y;32uubธฟ%ึb๗ว:Jญืำ’eฆmccYวแ‡g๊ก[PaรW๎ๅk5ฌฉ‹ˆๅ†ด—ฎraE'/ึzGญซ]mv:ภชV"าื'†ใมBbrๅค"พขาT6พ ฝ“’“Lๅ฿ฝ••ฏZ Hq—%X. ๓๑eKd€fธฤ๐˜พ”Chป$uXต”ศœ™_™หๆไ}EคซŽ&' N80’)ุูksฑ์Sœภ๙ฌeดžพํ๓>`ำฉ…ุiT๏nG ทฒ,q)ร๙Œฟ์ึฑ…เ!>ฝฤฤํxzw‚Y%•มมŽฟหฉ7ฤCFทฎh#šจLฦฤ PbBcยร๕—๓tk๗`พฬฌ?&'๖ฎฬeaแฦ_๘ซๆ2ฐ๐c/U‡๓ุx1—*ร๙Œฟ์T i/R\0zxดGcRGSGฦk๕จ๋วšณ๐vJ\yM1‚มร!2กŒฆื่๙Nqoฯ‹^œวCmฑฆiqV–:Lฺโลq‡ •%๊#<‰น{ฤ๖๋ว๘ž'ๆฅร๙Œฟ้็S—้ืงNฝ:๔๊มMgElmิ LT|Tl$KƒV—nขธr๒{|8ZแยีฟHม ฆบโ–ส[<ปหฑ67๐!ฏZ;๙xงv5–N่+Vลปผฟ\ฎุK…*J[Zฬป6†F3&,|~`1‘|็L d๏\bร๕ฟ”ษzีp?๕"p1หฎา๊ษ•tFBƒ` ๆ”ŽLˆค1โฑี8U€œ™œ๋t.ๆ็:`ขฟ‰โ~a/๚\?˜หžๅ9~ฅจ3 ํŸ uaึส๋qฎร&ทว—|8๓๔Z ŒCv9”฿”ง‚ฯhX2ฆษค–ืชบ‰ูkิณ|Y’ปษืWฃˆg+b6c_ˆ[<‰@˜š์๖x†๔วh,#!Gโุ๘šำฐk#ฉtUฐถฑZ่i~R๓wo็dฏ5ฯ. แ‘ะ( `ฺํฎq้ษi1jุ„๑DU1ฎFหWฑำ2s๘ž'ๆฅร๙Œฟ้็S—ƒ๓ าแฦ_๔๓)หฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏Zฎ๕ช๏ZจŽฝ9gห๕้๚L?˜หžๅ9uแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พแ]พำงL๙~?I‡๓บh‚J›Iฎp=.\ทf฿;ทr6™ ‹—ฯ Ÿก๛a~ฎ้ ิ๏์ฯง/๙'ๆฅร๙ŒฟสํS!pd์ไq.ใNฤฒv*((ชุสป`กXD9แ ํ—‚ภcฏ1‘gCฐ!81’>Ÿ^\xYNsๆUน๑โ“v๚ๅ—6ƒรึZyw๗G>Žม†$xๆ9n,†๎แไ_”หf ถ—\ …i†yฒ œ:#pด5(›ขฎกkฅแzฐx6ฆŽเE้ใณ ฦ๘ัแ?ะƒ.จGšูื)cเŒkฆน~B;?๎•ว%๒์a/ฝuทŽ–ึCตรe.lIฮ๏ถj๐ `ญฆ้ฐ๘“<Pญpบftรล้#V๏Yฝ}ฏCW€`m7๊ี~๑Y3หžก&O&_กฦํ'Wๅณมsฟ๎†กb,๑‘าศฏV‘Œ๐\‘0า็p'ฬ[รŠW“๕ˆา Vฎ”$ฮย.Dไ[“ ’W๎กธe ,ฺุำๅlแV=ไ๓ฃel.ย้๖Tวn!hwคœœt,~lดผฤ!ƒ+r; €"อร- ฅลqj3ฺ ~Ÿaฐ๊^ฅก๑ๅฮ–{ฆ–gb เ๚:Yฅ๋(จi๔&าg: ภe[ไKเ‚1unฮ7c$พ“๒ž jnตอ๋ำ`eหธั้Ÿ/.ศ^#Ÿ๚V&.Q๊๙d็(•l8ีหohŒ๒Bed$—ร@ห๑€฿๛Rว‡0qบDร๑ฤฆ๎†ฉW•ด์[ujญนรฦ์b„—์ต^‰ฐ์"ฯVs™pŸŒ๒Gi‡ะC w<*ถ5๋ว_รb y—ฒ๘ฏGŠ!›ๅๆ๒ Lดฤ†m˜ ้๗ CRkeืoI9˜ณ=>แs,จ~WฮภยN}’ฒH๐ั‚ูes0uบ€p+่Z\6 ?$T[๑B฿–ใr"^2~.>nO7ฦฦศHึนฟฟธRKG[ต+Qฌย๓P๙ซคขBไWุŽMค๊i7ั*˜าWŸH?x†ผื‰nชง๏s1ฒบ้๗Q?0—.ฬe๊2#6๖Mสท‘ย_”‡Zฬ‡ศศ”ทยฆ"2$oุปjW†WX‰+xzz7ˆ ขฦ๖%ูg\ยรcู7dxŽ*ˆ=๐fd๏hึ—~GzBz้ŒŸ๋{pณ ทBYœ”ฆšญ็๓_vm˜Tฦํษๅh_Nบi›ื]F:cยฮNƒ๛…฿ฃ7B•tศšฯ]ž‘E,š{€๒Wœำ๗๙ ภX—สใฯa_gๆcZๅฏ…O™^ฅco)ทƒษฦู/X๋บ•๒ำƒrื๗์“฿e'คถ*kg๖'9N๒ผ๕}ด@ถ=rถ >tm†ฝ’ 7\ค๛"รืQ๎ฉึฉ€้‡ ขรๆOjโW1vK4…ฟษE Œ่เฝ‹:Lแk5Vษ|ธซZน9tF4j3SvนŒ`$ร๘‘~ะ฿๘์ บฆ๑rฃ^ิ&Œ3–พพ=6l‹cมํส-]vื[Šศ,_Oฒๅ ฒfษ•ถš๓vีjไฝหaม็5ำSqถK?๋&๊aภ~฿Rk?"้˜v9Nfฌj฿ื–cEรฏ„<์์&ฮ€;แ– 4ผฎะๆอg<ฮฒ}c†jk๑4|ตi๚ ปqj@’;mบ65\[;dถ>์่เบ>RผƒT/jะ๓m’ญสqœ&ลงALr wœc มฟฒ 5fเs„]ปำ =]ฑ่'มooEผ๎ [oblญ†Qโฆใ๖ojcซท\ "6›M8๚๊`ํง%F{ํํฒฌdเD ฯ`ิNแ5Žภ์โ๘9›‘rl.ผ…แฟฝtฏงย'ฃฮIฤฤฒงZ0oO‘ํ๙ช …ฟ{Z๓U‹Mp‘p@n“ย)žพEพห๋์x๖๖&ษฺุe!ฺcfฑgeyป(ข†Cy"ม‡]ขŠ65ฆโdรC<สน๐ํŠŒฮOอู—Iาฅ„ fูขieN ณfล2ช4i07(doซ’92สลnญXค_๒BEค๑aBไำaว{’๔ƒหg/u‰๓๑˜ๅ<๑kŸข™ผนPl6ภส1“›™o‘็Aฏw๒ึะญ:ถ+้ๆaใตะ(๋ฎื๓เมํ†yหพ1, Cฃฆ];)ฏ (—‹ฯ cr๎ฤuF๊&&ษ็@™H˜ฑ ำšœz|Cป,๐Fˆ˜ึูยฺ?ภโt รไ่:สK!IฬK•mญมzๆสฐA4ร/#?c6C;/์ฦdB†„IZ๚๐บqศ‹J•<ฅŸxรศ้—Nสkร %ใZฯ๙ะูOOI๚ัLฦฦ`๙พ๘ฦ†ฬ5คVญnํs 6สิฟ๎M8GŽี€9`*[?ภ˜บP~+้‚๎nœนไัZํo:"Q›บ฿–Fe#ฟ๔๓pึ•~YVu๑! ก]หึˆกqธน‰8ฉมศศ?I๚ำโ)lLu6&kปN‹ญPe~๓{„Hศ็ๅ๒฿Rฟ:Gซoษ๗ย๔"[g๑6OGiภฆ,b๛W\ วำjY๙ว^ำส๏๎ฦๆฤ^sYิ„ ฉ6มรWeฉ[Oฐ `ช…6ฺp1‰ัธ'ˆ๘ U0ไ๖Kฤส+Q6@ก'†c%›๋'$ไšใโ9๘0%K฿๐z,y:šN2t๎ผ-ํกF"`™?"a&—]ผ ๏ศฤ3m๑6?ภ12ลตข;nฒp—Tป>๒™C,cงฃ#9๏]˜8ฃ˜ึZŒu.วฬuB๗^บ…๐Y‘ส๋–™B“ฎMทฬ?%ฏ3๐0<ญ็ทาฏ๐มq[๘ญCธ+i†Š(.ุๅkŠ=,Š([7]ฬŸบ‰๙„ฟ้pc/๗$๚‚ณ",ฬ,ฦ ืฐ #์ฦำG\—อY[$RjํlVอ]'รej๘+Lฃ,ฒ~Lc’๑8Ž$Hƒทˆืนอ%Rฮ“๒œพvฅ a‚๑]ฮŽj ";&.uP˜PK ฯhฒ’VO32$mr$ญไ(Eecเใ๒EEGŽ•Œถ็ฏY‘ๅl0ึjดD ๐๕ฬฏ‡฿JถKฅj[Y + dคฆ!ˆ‚แj~ผร›ำ1๛ ปย…‹ล๗ฟฤถŽฟ š[35`suาsน[œ๐_บภJฝฝ1;YŽ"@#6pyG†)ซ\ภƒ ŒjซT{ฐ‘ํ8ๆˆฒใJ?gสำื* HอบบlกูK=~ฌ้N0ฬ วฬ,h?ถ7}๊จkˆC€(žส†WL!PŒAภ&ฤท_‰xYzF[Z๚nqv>ด=ZLi๎ภ(+ีผๆŠ_ฒRŸfH•pัฐ่(ฑq1กศM;n/ฮHV–ิIG4๕@คœKbY:˜พ้ฃ“‘Cห&G8D๎V็nศƒW-ขึ™›๘l„2ซXฟ93๋ผูa๓‰„„ิ๛Z๎ท†ลไ์แํŽ Xฒx*ร^i`s7โ{†3 aงŽ๕jฬฅแ q๑ฑศฅ[๔ุ…“TไFf‚ฆŽ>"Xc๋๋๚–ฑ„‘4ี8ผRงU[้ถ๙๘‚[Sฏfไ+วยญ'›ฟฺžืสฟdโด\+>ะaS„’8ๆwฝํrr‡aเลlช$u[ถbั#›8|ฤ•€า™ย ๑๛\:ZทnืOM!ฉŠVC`๒ฦฐR์Lฃฮ“ HpI‚๐‰&ฅ-าทณ* 4\8‰ฮƒฬfdธš๙{oŸˆ%ต:๖nBผ|)ฺาyฐ๋ฐฦ=;ฏ‡เู}|@xๆ@”กO๚๎ำลlำRŽF/๗g๒ฺ…งnฮชo๋้f6ดศE$5\L‰—4๏Vๅn๐ป^มฬธล X๖HษฬŽ kP!]!Œหำอ๏ฯน๚jŒ4<ฮฬlตฉˆัฑ่k๒"7๊จศVดUVu์จวVซUw™Y๖๛รี6ฺำก}’/Oซ;œร,‚aฉนlŒ*ฆ&่zบ‚ศs„kJ\ซdดžิfช.#dŽIM‚5RFX๕8ฆož๊d{L๋3m๕p๑u—"uงแไฮ๗‡๋ฆปฎZฌeXzaๅ63d$ซ`๑X’iE๑VAภPษ†Oฃ๋ญไf฿ƒ>ฆ w^$ฐ =น์B่Fๆศยชbn็ซˆjAaQรyิSน\%ณ๏#โ)7"ึก%๕ฎ๘บถ)Š็ว•ืณึŠ\W‚ศ๑3œ@gฅล7๕ลคkHห•jธ’1ƒจ๗๙ฑ๖uโโ‡็ช ๙eภ(G_ส‚๑•๒๔tผL#lุฯ%ะฅฯผC!ม7[๒ศฬคwเข~ž‚nาฏห*ฮพ#฿„!”t.ํำ3€ต`ืา๏ฎๅw๗ลีฑNlศ‰ึ†UNทํ"p- =aค๐ละ+wซg:Fบf’์/ราj,vyฎ5๑แฯ‹^ศ๒Av-2หŸเ0๘ๅจฌถผ๘ป9#–ณใ‹ไป#c“jษฎขวzB๖Uงเฯ๐ุ›]!ภePฮ์w.ZJ๑ธี๐๘ U0ไ้hp9lิ Gก๘™E|<GๆW7ฆ#aaกxแผOUC-q.Ž{*#ี%0zด.่fคฤ๔^ลnšฺah๑;’œฺฎช๖Lฦbดg•%ฃ~m าตฉ{"”\ค‡… 6ˆฑ)‚?็g$ีธe๚๊ล~อฆ5๐ ๘ลHรEฬ–s์žย“l&ญฯ*า{:ฉฑฏฃก™? ๏รสหq* ฑ€ํ๊ิ?ห‚ทีŒm‚ธ(:‘A:๚=…$ ๑พโ'ๆฅร๙Œฟ้็S—้1 E• A๕‘จฐ ุ(LัจAแq‘ฑBƒแAขWdฏŠ–.@๛M†ฃxC‹€ƒYณŽf8&.โ„๑มB1:’๕ลพท]ๅ@GŠdนWg3{’—6‰‡Tฌ‡็ฎ”A‘ —ฦ\†*Œ[ฏก ฒF"ก กฃ1ก'– Bฌ๎R„๘ยxCผƒ๐ข’5บ_@FหรAf'ี๐˜ใYPะpฃ‘ธะร฿Qi[.รณnษˆ•…œใZฤ2 ฤป‚่Dด\—็p”-รK'#๒๑s๐3pฐคฑ2cไ`ำJQฉn3ร๕8ฌX“็•%‹ƒ„ƒŠฑ ŸTA–ฟ–+๕‘กะ๑! ,ˆั1 ภ๐ห8ม๑Aฐ“2dp“D๑ทแIฦFฤใHฉ`AŒ|cK๋ตT8ถLาvKb+๊)#W!aฏDuฝSDฦKBวDฤDภGbรมHค“าางd์ูตjี‹“ใEx]#JFืKเซ๙ย04W…า4คmtพ สฟœ!๖21๑๓1๏โeŽ ‡aŽ‚(Œศ…$ฐžSใมqแฝ ‚ณEฐ,๚สq5เ'ษงเ ใoB’E$hx\hGฌPก}R]#ึ`ž:6:2%์mท@ฺสีSๆ7‘ื\8H`๔œœJจTำฒ9r๓‘J4†$ผ$๐เ๑Tuศ‚q5ศ'จa@p™ดHฃ uส๛˜ž4TL\~$D$ากZIŸzT‹2&ิo2Nิ•ทว‡:[ใ’‹Kๆษs˜หณfฮ5›X๘๙*•–i/ธ€ ั๙IIธ”C= x–ญZทfป6}&!aˆc๏ฤฯŠฌู7๓Š„อฃ๚EcฎWุƒฤ๑ค๋นhxฑ้Oจคe็cˆๆE$j `hf3ย ภ*V"ฒื'†ฐโฒฅ๓ข๎จU7 n‹rŒต /’Le฿ฝ••ฏZ Hq—&4ยแ^&ฝต~ศ^มฎf[J๕๐๚อทAื &ร™† ำฑ(ๅสoq–"๐a#d‚"†8–cหฑ๑์bXฑ‹‹>6:Wส ฃ๊)#Pcข‘bๆŠR ~S๓ถlูฦณkส•]ŽCศฒล ภr …ถ&`แ๐.ลภ+ึ‚’eล‹@'},๔3ฑ{0…dท.ฯ้*W๕‘ฉฑa’XŽฃไV”*›06…ธณbYทD๐ฃ’ก่w๖Sะฺคš€5ฤเo›๚^ณk"ีฦรฤƒqฏแUฤrV๕ฮwn,ึโ9ฅE ‚ฮqญa™ ‡‰…เ๒+\€๕ฤๆi ป_หD`ส๐แยืญๅฅ“™๙ณ3คaกๅใnรKB$“ใrVๆ`Hฤ… p์ว}E$hxX`GœPœR•]3C <*…•‚ฦI๎;LO<,ผ.$p8L{1–ถำ‹GXศฐ)U‚œ4sำdืๅอ5Zจ^ป๛ˆŸ˜K—ๆ2q-ฯผ ผํ๔สrb~a/๚\?˜หฤฯหฏ}๕ฒาืเ,ฯง/๙'ๆฅร๙ŒฟLบ๗ถZ๋,8lผอีห’!อuษฉ๚7g๚m๕๎vษ๒Š›XQ+ธึ0˜หขcdKู<‚๙ฬฐ๙ษl๏ผnๅฎึfฦ๘๚ษ•nจลS~ปW< ™?,ีรrv:0(ศหะ=๔ึ•ใบs’ ฆižฐb0๙mžิ+๐0ฅUํ}ฌ'/ฤ7๛จžใ% LคาฦกqdBBม๕DD?_Q†Dš†$จิO]3xโ‘`Iวแบฌสแ\๛l”๎T๘์์ำ‚a ด๊k9N"K—่๖ูQo\Œอlูๆ  Vฟ5ญ•2#_$Nฬตธฤˆ$^Y๖%ถฑผย5&ึvูlฦฤแ2๐๏ำbnํˆOำๆ8~ญœฑัก†&Oจžใ% LคาฦกqdBBม๔vั๚„Je{“{23%ฅฦ– ’มT€ณ๖LsiราO]‰fษlZ™Tก\0@9r:๛น๖'‰jJุ้ื๋ำ์8ีŽ่xๆs&TJ  $ฅLdหxผบJ|SG Xjb ฃ}ภmชํชz‚pm๕ ช^ฎ๓๑ ปKํlte8ณ๘}ึf^>&VvbโXฑ•7œs—๗lybลฌ ฮ&^>~&.v์(Ÿ˜K—ๆ2๕‘ƒ›{&ๅ[‡ศแ/สCญfCไdJ[ฮแS7์]ต/ำ#.tฉจหาV์qณ‹g–>5‹ฅฐฎHbv-Fb\ยรตs?ž^~๑๗cฑ๙ฺฝ{‡[–nใ ~7ฎG[ี ั๘<ข˜r|ท’ิ…ฤ๔o+ล‰ัง\(E๕ํ6›ฝ“yxใHๅ‹-กr…ฦอ*า)ึЉšต5าc ฑฉV๒8๗TฏฬธM๗ไ“ห๐QรZU๙eY๚|:Š)บŽt๑โYั!ัษษใา–บŽo‹ธถ3##e›wื VXฝ™{bTrg๔+ิhฒ์ๅŒรภ#YมฐลdjXโc‘8ดQhคh„f๚T8™ภ๛Wzsๅj็Cบธฯ$aˆ์ ้ฒึ|Œ‚UdปƒTม€ ฑ๕d5˜]$e.™LŠฃ๓D„=ช่ึเ๏ัIม‘จ ่ฑŸ\ž7นใdpวƒO•็ร•2้Pฐ”_ส็ศQยฐ๔๒c/J;+ 3ญฎ ๑ n›ล}ลฤQฃy_ุq?0—.ฬeO?๒œฟไŸ˜K—ๆ2งŸ๙F]y5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^wy5็xืใ^w_๗9w๚~“ๆ2ง ๙F_๒—้pc/๚r”e๚l.d†ฯ2ไaผb‹่ษ@ฤำ72ษฐุ…ื฿Pุ"่๑V%้‚ E+ภ๊‘qว๕O๋V‚]3[b˜ส‹Q—้ฐyฤKLศˆ๑๔บฬbc‚&XRศฑ้Y<โ# J๖n%q?œojz%h ZฏgEYปฦ›W๘(กr q™‡…๐9Y(~qถฅ„ฺ0Lห7ใˆ 2GyOf%ฃ”œx…ษthจq,X๑, B8 ่ื\พWˆiŒAwฆ>R‹ 65Zฝ‘๔uเgสจ™Qฑek้ฉ  q@ใํ๙K)ำ"JYธลXๅEฝ…ฆหWxCmฆFYตฅN'š–X9’R‘ƒ&ู๑^G„Œฒ’อ‘“hG–ตมVผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฌ\.Y๒œ9x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽฏ^:>ผt}x่๚๑ั๕ใฃ๋วGืŽซX๘๘ีุ&ฬe๕โยVญ'b–ฤ๙f€"%™pเ™.Ÿ ื…ทˆา ิ†ม•9œppcซ‹ำvธ(>ึ1ŒUฉ๛ๅ@สIูBub’s๘ๆ2ฐ๐c/Qำ}3๒๎czp›้ฮSฌwฆT฿Li>’“]#oZต\zWœซbึืำฤหัฑ4)ž"9 bhuุv3ีg‘kงฤ" l‘๑Q#…mN)]f†[๓Hศcm{$d#ล๙เ3”x ธH> ฎํˆฺ–7๗ฬeaแฦ^ธXณo—.v๋ฑgฅฮ๗Jๅbฯ+œn๒ซ–,๋วญฺด›3มwฑU ย๖ผ”q8YrUฬ^}„ฆ(-;<แ›ำdยgX A๑ฅC‰–5 บฯฺะ“ž‹FเVยJต’1์๖)*โ$z๘๖ฟต‘๑ค˜vš0”แาj n๎จYตชpsCฉQ่ข โญา 0).EdŒb๎-ึไผP`–@m“ฺโi่n4ู‰ฬๆ@y็ฮ4—0ู;†eอฦชfrx 2m2@vaZWฑ‰0โ(๛Aฒำ‘1‚#;€8z_ฎ˜1–O๕‡*S^…K๗ ๑[Idภž ๅพฟ‚ยjZศต/ !,0r“l0sำŠ„Bใ&่hฎฮm้qจžท-„NSอ‘g'ห ๖'gษ„—ฐ,„ู๘GYg๏ผ?˜หรร๙Œฟ้ไ?๘ฝ1?๗่,ศ>^ž‘k$Sฏb@ูหE€p,ŸูK๋แ ษฤ฿dIร๙Œฟ์;ํeg_ๅ๚bœ|œˆฌ‘*๖?~&wt‰)‡๐†ฬem[นZ๗5ฮ๕๑๋ว๘Gๆ2อธ1—mร๙Œฟ๓nฬe›pc/‡๓ๆ^๘็สsๅ๔ซฤc  !"1’ั#2A‘“”ำ @BQSaดถ$03RUVW`pqต%4bcd—ณิC–ทีPTrฒร&sƒมลว56Ef€ าแฺ ?รu&G—-๙๕™G~.z=?o็!~จŸo็!~จŸิJeฟH3+by5,<—ี๒„ฑ‹ฯพt$mร—-บKฟฃรP|˜™4+'๗ž๙๛ใ(๏w๏]6บœw—Lw‰๎แ๗cDK”UO,eHn>ไh๋ีm‰.ฎ.๑iถภUSอ฿ฒ‡ณ5ฉ:ั„ฮอqnRj>ฒ /|n‡H9๑็"oวๅ๗!หฒุ๊Gงซซ„Mถคฆ]’ำ ๛พk@ฒ๋Ž8จป ๘  ฏ๛™aXป$ฎcg*ั๚จญ3Xๅ„#>ฝDV‰$MฏxOMนz๗ถ๚ฝฦฉ.\:ฝู‚{งฯe}ถ฿eึ0ธท‘ฎ็ห]ใ๗S{ว]"ฤแ'ัพ&‘้ˆหญVc๔mป›"š$U๔ะIอะy ฏบจฝ6Aว8šŠb˜ }|601 g์ๅอฆฉส;29;qšhผœŠ l&Jโ˜7๗ธ‚ไ+ฺ4๖เฅ’_%W‘๚–๑ชบซนษ๋คsจ฿ลำ์s'ํkหkp–)ฝ`ื<›{ขฬ๎ถ๗ฎป>\?‚-นx๑์F 7 j ฬjU๙[ศ92ฅฟ ๘oฦ8‰ƒd˜T$.Kฟ‚ขm๗ก4้ฑ่ก2xW2™คัศฉุt^NคำรOุF…ฮ(6ฬ฿G].&ะฦhLqถžxƒ..)๚@Ž›ศปี)J~ฒ4EY‰N)ท!ำUR$TB๐>yˆ+ฅmง{ํ๒๒1ว“’tผ…ื—๚?G~๘Ÿ–W์.ํ>ก}ซฉ™%›8๕๕า l˜ฯีศXu3ม ฆ˜ศ‰แ^.š‰โXขโ~DฝJ^ๆทi{w€ิ๎๓ืH๘ ว‡๔oฟษ๗ตืำ้!ฬ‡yใ๐cฯ‘'E‰’ฺ๓Œ๕x2ฆ„ป‚mฒ๎–b%"ฎeณ๓ง ฦ:ศีO*…›bDeiฤy9*'TUM•kฒV*ฉg5Zํํlj๘ำ'8ฯxr=zณ!โ2iตlไ#ลหแ๗‘3cถฦ์ไUXJ็แ”จฅมลŽ๓“›"ศช ฺ‰™7s>h'eM_ 9“ผ>ิืSƒEถภพ;k๎zห๒ผG[™k+:~Di YM|Ÿ iL6œtใธ]่““kฟ๓R…qดฒ›kษ+gๅugษ“ฮSฟwxน๐ๅทE6๔x๚~๙›ถๆ๖yeช๙mกGˆมษ•.d6ึผุ}ีpyม{u!>>ใญฒร-›ฏ<้‹m4ำcอว]p๖ADU}\ฟ&j;ไรทX๕,)ิƒภฮ;ถำ"<่!xsm•๘ภค;*ตCฮœWWค์ip'2r+์">ˆm<bช*›**ฉ .ฑฌ\ผๅษ|ผ“ฯษVk:^G๎mty๗ฮ{๗ฃ†/-ำ๏p Lpา&ศฑ)ส๏๙ภ๋๛ฃŽ๋+ฬๆ!น่q7๘=ห๏Yปทญzึีู0ฃทNQ™v&‘&ไแ–๓™ู ‘oฝค“‘5\3†ž+ษ|ๅ7s’€๏Mฆ๚W้—ฤ‹eX๘ณ’็ู@Z๗%ฌ๖๒{๛i4ยธั๚7้ง;%๛์}r*[y/ป%ฏ’บธ—ื๋wy<พ'Ÿ]คw‡-“}ท}พ๕ตtlฬZŒแ๒FวmWั่ืa9>ฬณ6ขปsw6ตน6<อถN]8!*'Šขkรข้พฑt์>ไJnีจdุwฬVไfoY3“Mถ)ฬีึ]๓ุB}ดReึ„ภลHUHI7OJ/๏,=๚l˜’Ž iฮฃ๑XI+ใ%๖GŠ๘**๊h๘~ฏPำ>๕’กlป_/-๗ฎ็{ด‡๙ข;ฯ}ถ๓};๘}็ำ—ฦฦ๊oฆาฤห,o,ชiญ…‰ฎE6<™$า$กซB‚๘zuษ‰–cY“ปฯ|๎Zฌjวน๗พ uz}NN˜๒~)่๗kโฺฬฦกD”ล|ืf4’‘hฤ\cฮDDuKรๅMv Šฦภrฉ3_ษฮi•๘ธตฌ†สUห5oฯI mฦ2xX&9ชง๘i‹๗‡(;Pญ๒|Yส+N‘ส_y๏2ใ”฿ ท฿วัทŒะ?๐_กฎษ๒ฎี"็P๋ํYซจY‘,j*miยโ ป&๋aYqRฒB๔๋ณ)ธฆ+O*สภ,r,fต.ซOีสญzถฒเ“สฅศทE*>;งณvYFo<ชg"AŽ๕P7&\ˆM๗ูf๘/8ฮoลข๐๏2 ๒รˆฦ3Li‘:ž"๑ืถBŒ7ทœ.J6ฤถT"๐ำvญT๙NeO˜ŒC™ ‹f๒๔cบ๐๑๘Aูy๎b “”)๖RJ_%7’{Œศ:ชฯs•ืๅ฿นmษฝธmบ๒๐๛ษฑkซkฃ=2|๙ฏท8‘W_“&Cส‚ŠคDป"h3k(‚๑2Wะ1๘žI๓\เˆM˜ฬตMษ"๏ทโ๊า5อ ฬt•]cŸM๖๙+f$ ˜8ำ‚&Š$(Hฉ๎DrยD82ๅ1žH๔ืฃฐNตฅ5ไโข์+โพ…ืฯ•โ!u)bืฝ‘d–#,›6ฦOu๏๔ ๕Uฎ ) ฏ†้พ๛Ÿs6_WEๆE4<Š๚สขฎษภuิˆqไK ้๎๛mญ€ธ^n๛*ขoจฝว฿&=Kz็น๙bตป๋x7ิ้๕8sเ<ถ฿Šz=A^+˜๛฿g—?ge_๔ผ‡ื—๚7K~๘Ÿ–W]ˆๅฌ1kdอ›Ž=dำUวiถš‹% ีุ''Tว‘‚zXaแวˆสงŠlน}ๅย˜Vก(—P๚JืvูSb฿—ษทนŽDหsอลZ\zuŒjจถN๖š”ุKu–เม:๊rq7QD๔ฎฺ์_ฤ"๖ก˜ึใ5๓ce‘n฿VนƒYm%ง•$DุฬฃP•|7ุถฑ™™fSdEชY,ฆaF†ญ7"@ลM‘ววูi€/7ฤ‰Pธ๑Uฦo๋ญงใEณ 8ฬYใ“‚ศ_Z๛จฑฃฦŽ๋N ( ฑบŠ.qE"ไ|ก(1๎ษƒรภ„„‚ใ‹ูฅ,ZXณa32ฝุฬN๒‹OGT!Y/Š๘ฟเฏ่ึ#PQฉRฝห๎›ขฏปฑž๓Rฃฎณ”ะคVEฅq#ฏ7๖-‘9J†x–'ูุๆ”ํท 4yQ๋j็Nš฿œโ'y”žw๑?FคW†Qƒโ๔ู,aS#(ึG_ ซ8อ๙ฏQ#8œ(h‹ชlฃด,มช็-fฮ๎ี๐)`\oๅ๑ี5Fyžใ}๖šช }| ๊*๛Zœƒษ77vถfpัb4‚Bะ› ฎถ›|mซjห&ฅฒ/{ต•nVคY‘งต4gœง7PEg:โ:Dชhฺ*‰กรํ๛>ทฌนupมf-FB2Gy—,qรj:๙ภขครs็2&"นฏ็บ€ละคผ3ฒ์RiณkT๗nFJMKท†r™_4ภ]ฏงN‹ธ+ฃ่5ัXSbูฌpะ •๕.หŒFัx!‚n+้ิœ51r๗๑ซฺเ€ศ]ไฏ ษ/Ž4‘๚Pโฃ,,Vส;nฐ๕  $bฯใ}ฉc“rJŠเiŠฦ8lkก-ชว!้ 'ชฎถ\๚—ศ‹ŒะGมRc9Fo“1ม'@0'ถหO1$[”ง ฏค็ ifq้ึ๙ ›ŠfXK-:‹ท˜™fAG}sป2mพHIขบ๎ F_ฟศญโE– ศvธnE+฿aจฑฃ8ืPา;Žฅำ% ™ENIC$ลŸSกษ ศฬ+ี™MFyถ%ฅ -,p6:€U@ทํCดG ยดไU๔ฐ^™ไ๘๓žeTษืQิ3เุดแธ„› ูแ]กvy’\7Mi'ƒ,h$ผฺส!ŠMCƒฬม–u‘qงิlภ‰ขQ=8/G’หRt>+ฌผใN่TTTื๒๛Ÿตถžๆ)>7e \e1๗1R‰O † ท…–td9 ‚7‚ผHjแขmๆ{Ÿศ1ฟฦcj<ฉp>้ฎศ้ซ ƒn&27.|iี|Mไš ‚*p๏อช/™ถค 1‰b+ฆL#%mู0%D๒ฌฯะ๒:โ'โขํ๒jn€๖‹X๙6พSฝอผwruŽฒฝ z‹ฏ5มืn0#b=C?ซญญํ3 ค๗๊V๋๏`ฦ ส5a7p่๎ดmช อ9หฆฺถผฅโ๘ฮ/K~$๋ฌ† y็๗9ง^ฒl$ส‹1ัIo6๏uf,d.˜๒2EไฉQ ›.‹ฟ ํšฉ=๒–\ถ;/ฒ:Rพพv’*.ƒnขjคัnกษcะวห#ืตi•ๅ™e"Nยaธ๊อฐ์gwค๒‘บ- hHKฉ8ฦSSฺ!1อ๑จฝภุณ“'ษ๑™•–# ษ6Y|V0t๚‚๊8BŠ+‰k๚‰๋๙๔เ~๖ Nฆพฎ—UeDšสฐ๒ ~)".เiโ%ฑ'Šjย,ศyoh8๔Sš |™ทY๊Š๐`lrฐๆ‰ม๔ตE๊IŠX"ๆp@rาี๕ฺ๋Z>Ÿฦ}โ3DU^#ฤอึ-ak‹Mช‡"Kะ1"ศใฺ]นh๓2๊ํ'๔Oน€2,/šใKฤษฮฆษๆ 6โ€ซ€%ฬ@ี<แCู7ู~]ฝึd?I,๒สhแจ-อ,ไไ๓%Œโข"tใฝ็ž—P&7~|หV—‹วซ AนลUPพ=>:c^~ชบZสวžี]m—i™ 3%g[ขน_ELƒj)ฃ ฐ†ŒศyำqTYiพ]7ฤใ7 ฯ{?สlVถeพ-บMฃsquŠณ “Œตอึฺr1ฃเ(เˆใ”นอคxRฎ-ๅดฑสษMก5s\&๚แใ็"้ขoัw—›u…v‡†ไำ‰9Œ~ฑจื๗n›ณcF˜ฤา "#Šฎ  |M m๕sˆืžRrฐt_Ž๛Qส™ส๎คi)บ|:ž่ž‘๔๊๓p–ิลžษส@๖MตXoืๅy?…IคๆยLX[ฦ‘เƒึ็่๙=:ŸQ9%ฺ˜ly&ฎ-{i8งฮb}Xโ ่ชฦ I่MVรŸ’dถวQXํ˜<ํmklEYS'ศe’tั8ƒ-+‚œ‹™rP,ฃฒnำ ฮ*๙b๐B _’4‡oŒ “$าePGQ<[e™dหK)˜๏˜ํHPEyถ$8 €–่&M‚ชxจฃŸŽืeฉsค?“zา$Wาc`Šห ฎ๔|ฯBŽฏฑ๒พอEะf–ํดT2kูนฌfcUภQQๆm6/๛ํ1}งธw๓ๆำ6ƒE…วผค)ญ๘ุu‰๏‚/ƒำ่ำธX๕คVฌ=๏แTั•t“ุ”อEdIๆรหŽสdDQเุฏ3.([cธๆ7‡?C!๊ZฺW่ไ=์ฌฃฌXฮน \น ‰drW GtO—dิžฯ{)กจด› Žฆะb]Lพ‹QcL๒มฐไŠ ดo’lซช่p3|t(–oAeb1eiHŒ&ไ%#้ศe่ฎ„Ž ฏ P๑M_เป0วโคsaณ+ ๘๐ZIขmปPอ_๊จขฟ๑v๑ำ๑dXหฟbKฐแณ:ท]xขcข์b‹ทงLQAZfUk48ฑฌฅ`]๙NๆไSฏc>G!ฦ๓AFCฤ‘Rรส+3ื+Yญฑว 1˜e}1สช—๋%ณ š ภ่HfS*||แ/Šฅmr˜ๅิฬvดลLg]Gฎqฺุชะ์งอไแบr๘ปฆ๛๊Žฦฝบ้•#ŽOถล้ฬ’ใใ#สะ‚B:<#ช;ำ”T‰~'น์_๐yLbณ ญVโbสิ{;ถj•–šnuแ8สyฤชŠ๐C™๐hพ…ASิฮD4eบQt‡ฉ‘$ฒซ:ัขช#เeีQ฿คœถU๐ิ์-ŠG+\ศ#a๋^+6E/Oพอr`y3็ถ `†Aบข,uฏ,ศซ˜"{กgZศพฑa™ขr๏ใฮŽข .โซฉxf3Žœ‰ฉKA9€~Mซp\X๎6ไล}Kแš๊›ฌ!8‹เ่€ี^W‹ฬfพtpcx๎ณ˜mีพdำเM)‰๘์Iฏๅป_ิื๑—Q†A๛วฝฝงUู6GŒA<ƒ’‹โ;JŽะนทฦmL=บydZั@ฐยฆจจ๚็Kฒฒส"์b๋ดฬบ"ใN6ฬW๒*.้๎C‰0[U Qู J›*‚<‹ถ BHEKนCHฌ$R_๒o`ๆๅŒˆพNฃWV\ัโ–ึะ]nพ/GพWฤ7ข”†P\A]าซฉ1ฅ^LดพŠ๛ั!ณ•f‰ฦމ…6Mืๅิ๚๙“๑‡bIรซ‹^ #ตR%ŸUธ่ˆ~{c๑ต3 ฏบชศนyฎA,Q`•`=Žขช$Yˆ๔ฃs›?"7ม[USUn&ป@ร[“-ป1˜ˆ3ใืฮnพา<ฆก็Ry‡cฝ]h•x๙ผ‹๙฿๓=ฏ่ร˜ฆ๑๘7ด•ฉi—ๆY#K&%H๔[yึcฦ& ค˜ขnt#yฤmษk"g:e„ฤ๓Œj7rB%ำ‰<ธฬณ  รป6M™๒6—}#ีาBื๔uŠ„7ฏเ™ฒอsร—มถดฆ~oหแช๋o ๖ะ L#-๔Fมถธ'Lฑ๐DDู_Z฿DิO)Jeุี”•]B`l๎็ชคHฮ>"\tถ฿ƒdƒ็*&ฌ๛9๗นไO}ไ๛ษ!ๅ/{])๗Ž=ซ‹๐ฝ/+uบ'[ฬี22p…m๑'์R$}ตL๎•Vx8‹/ชฒใo๘6เ๓ุถบ์๛ฎงฌ•‘K์ๅบˆฒญcTBmeKุr ›lŠธญ๙WŸHช."ฃิQvŒqญ้YjO7("eu๛tŸูไxา3‚m<€โ. งท"พฤ%๖ดuิ๎a’แ6ฺc0!9cถ™mฺBฤซงผกฐ“ษ๓”HQถKญปภ้กบฺฎอ ๋๙๏‘ฏMีDสJ$iW—ึฑcJ๎หฎ[ฎˆฅˆ;จ๑เซr^t™pอMlyฮGวฅdUYนลสฑW•i2H3n)vฌฦq‰q‰ฅIมฒh›๑SD๛ษยey…;7งเNมHาฏcšx ‘A-ฝ)ธฏ‚ชj–ำeฝRสศD#ฐNฒษ(Ÿehฏ(ช๗yโ8๏.ไ฿โฉม5ำ"‘mn๊ซ2Kึ‘ห[็a7์QฆูŠๆำhผR=ทR]]v}WSึJศฅ๖rDYVฑช!6ฒฅ‹Š์9อถE\Vซฯ$UPฌถ๏Si๏aC#(M[Wu\…ึ"4iึอง„ ”ƒ—"‘/ๅ?“๎H”เึzŽ๐ฏูจฺg ภ๐ชุeวฮฏึ=ณืŽส‡aจฮG›า6 ;ฟr๐AG lt4vY5lI๊๒J8ษ%น V่ำ6 4ใยsผ0เฦhวeๅ๐tํ_dƒ4ตre(oXLภฌaฐ„ข๘‘˜S๏T7>Sโ‹3ษ๐<ฮq2ไœf -GฉŽ/ด—“ฅ7žผ!x้Kmมx7s–ๆ฿็!~จš_ลฟWUฬๅ7๖)K‹ีH๋$C˜ญ+า'ฮ่ldหถํ 8d„(ชcgูQDrต์—‡ธำ้aุศ‚ :FKธ่6ใสšกquค5ืPkrZ˜ถ‘ฺ{๘xส๐|<7๖๐ๆหˆmง†โปnš•฿ซลฝฬR}gาฝ๎rr6*Vี—๎_ฟ+d]๎=8 ‹อ๔มโ๐/น๙t๘ํำฌX๔Eฉ ุEธ„ส๏เ‹ ˆซM—ไีร๗๓คKว์f5ฎั‘ฅ‚/ZโDฆAฆU]เภทอLˆทQE$Ž๔ท1jS$›„#pซฅ‘Y-เd~7Gฝ ฅP/B.ณžะตZV›ตฤ›ฟฟvqู$>๋#F่ฌriรไ-™:qTๆCโˆwธ๛'“ผYCSŸณฏ๒‹ไu†šW9 ๔ษ 4^ !k$jV!GWQาๅ+ํ›F—bใภฑŽ/—yฅ๓_O่]]ทy_jืสKhิฤ`$ซ*,ฒKๆฎ่*ž>Ÿw)f๊๎Ÿ9 vP[ฎนˆQฃลง๗๋ํ6\]p`5_ำรวY[6๙v+๙•กYwูjบ#&’ศฆWƒ†#ๆธป๏แบjQใีูœฉถ˜๕ฦdฝTYWŽVฒY๐u‰&ๆEๆษฒ$-:๕ฦ5ู]D‹ผ…–$วƒต%ฌหทLxD•ทฬ6๗๊-ทoฮึBะ็“ฤคFว๛ขธใ#”W๗ไcบง๎fœweไใlšห˜ ิขฅ2Q๙.๑\[)Voปเล๎’๙n>>+ขV‡9์๓๊Š/6ฬgR nŸ* l*/ษแคV;๛›ป0ฅ๐NถCŒeUัg#›~7r‡%K?ปW6ธ•๚ˆ9VELทc บ:J๘ฑ ต*2‹ฬSส ˜›ฝถC฿ดŒำด๋x–ฐงdrํ2Y™=e]<ˆฮรjm‘ƒ ว%ูNฐหBปสiวำฌข<|Pk้่ ฺศm-โฤ๎2!wxฬ‹ฌบ ]>>oงmต“ณYๅถูDŒzฬ๋ฎd ‹3๓G-"ว‰ว›ๆยฃ›:ุํ่]—รR๚ธฺฎษ =‰l,ฺ๊K‘[W4ฐm฿‚hs‰/ม๘|šต”™ตf-'kSi2ึาษ˜ฎฦ€•ี“h‚Bp.ฉ8€๋ีPูu๗O๐บ …‰๖ฑ…Xvvถf›e-12ž4S%๐NOLฃJพ‡ ไ12๏ู๙–%~ปmฏ่ี๐ปํKศg3)๊๙q%_ปuTnสd มๆ$ธ๎ๆฃ$-<๕ึ/ูตM4‹์‘–%GฏฺŠm๋ฆˆ’ถใฒ„โC็วvšS3ง#…zฑไKe˜ท1[ชq'ถฆฤv#œ”ฮŽง?uGY”A€Wร_>\หkœ•ตฺ๋Wึ8๔•ืowP”Xพ^อไVืโนŽ=!๖,ชŽพๆ\้ K>,ธqๆ๕XZuว}f]ซ๖‰&ๆฒjŠ[Œšแ่K9ฮ์–R"Xล9พJ=”9%หˆ4ปฎฒ{ฐคื•^:ณa\ฺH›‹3W*ใ>ผภ^c™8ƒษKรฒถiฉ๒๋ƒ“Žฬrฒ๎Xู0น๙จbี|g\oเžlถtE|v๔๎š’“i๏k \ีLdeึูลฐdฃRฃF%ฤล 7ูQXฅฤGฃdt2Ge4lสณฦZ์ไzฅGd๛ซศำŠ้/ลๆบ๑๗?cŒฦำ|็vlrฒJŸƒ๋8๒หŽ‘L‹โˆสHSQS๑ใzWNซ+mMwZ"จซK:ลจจ๊๘ง[๘jะ0l–ฏ2‘iตผyiW๙ตŠนl1&;f* ฑEฦ๗ูDšSM๖bgผ(^ฌ‡n๛ฤjสcตฐ่`4O"๕YŠ๔ลl‘ ฑ้๕H…5=ฬgหW y>ฺli’"ำูฮ“ ^r(8h3cO บCลQreฬQ฿cฌ+๋ซผ˜RaอI5ั^G๋bผะ๒y—Cc4_ ี6ูu—3Xูๅฃc3ตw“•๘~Gb7YชŠ๘'ž;"๘z6๗0ซHุผiRfdาm"ศ„่‡pฎiธฬด„‡+cuดS๐?ว้บ์ฺ–ฝยโถื๓Zฉฎผํ‰ฯ=ๅh\?ลัุKํg"นsดjmอั—/†ฎฟ`"ศOGŸUUŠ-qG 5 \ฬ1พ•^ึ้ีvs ในแYฬข:ชˆƒีG€|Xฝ๛ึUQn์gB˜ฤ&๋kฆOz ]ู™ —zw๗;„กอฑ๘ฉฯuT๘8เ๎$ ฤำ๎'ฒง๗*{ตฐ-#fh๘Gฑ‡k๐ๅ•/ RD… ‰ถ฿e_หฌzŽฒWoผืิภ‡#ฆพดvฤถ]“t฿Ys๓ืฑ9Uํใ๋Wxn”หz–็ื3฿šŠQ~ง›=ี“}‰QwMeฬมฮ,r{*่TEWx๓ฬศ2n”›)ฦNฒบฺ"“ศƒฟœฃใฆ&{ยŸšษ–์0ถซf5Y2‚{N4ส)"ดฬ–f#bŠNSฆ$BIซAฮr[Lส=ฆีๅ๗hฟๆื๊โ0™ €ขšส'th"uA6฿)บร๑qJœร0ข)AgังไุNลแใวไซ"bOํท 5ฺ>kฺŒศvŒป”ู[d๓2ฺชˆsแธฎฯ’,5<ฉ.ก `›ภhขŸ-“VิณkA˜ณูm๖›yฺว ชp I?ƒรญฎใ้ ำeี๚b3,ฒŠจฐฃหซบ˜ใฯา]qซŒ๚‡Oผ3'๙yป๘์2snฬงSZ3)š๊[ 'w &นฮ‡ไ๙ฒเ พ.2nพถŠแ‚rืm™V ‘5Y*ยง“"C๓Xดล" รHแ?uu‚xg<๑บ„ž*ๅXณนบษา7‘y{‹Tฦdใ9fจuฯผฌจภ๓ฎ.่ ศ5žฝ‰๖L็‹๖UEY”ุ„ด๔ฃ–6U ดไžl‰<ปรžp41šใซ–œ๎T๊ึkcc๗X๔*š้ฐŠš F๏๑cถ bˆ-nฉ้Vง…Aฬฆqฒฏฑx]$ญMc]oiๅใน ลฒDR็ๆrT]ฃN‰ืสๆฤfส+ะgw7๒ชCˆ์˜R\dœo‹' wุั 5U&้ณธฏฅ[SP฿‘*x8๗š๛ยHœeร_7ไึ?+k#Ž์่5Sฅ72Pื๗“fวhvถˆŸ…~_w)gvํนnีƒตทS๛p ฐ–Hต1ŸAเฎท๑๖฿ u•ณIY–F“Jrฒ๎bXฐ–rศลบ่ฯ๛Eณข+็~T] ][bY์่๓ฑ๛๊jห๓๕แŒlAูTi๑ฮ"ใฦ[วpั;ส์r‰71œnื]–ฐไ;&ช41-ถฑฅ2J๊/Ž๑๛ฆK3ข•ล้๔{ตไŠถถาู8๐}\;&vืตU•=h2ไภด–’^ธทฆนญฺญa็6v3N8'ร†๏ฒ.Lีฎ# \}ผ`€TีูกE›ทฯฅะuzm๛์;–้ฌญ™X5=\k[ไฌปmธวnอ„๔a’[uฺ๑U<๏ะป]ต•ทJG๔jญryEbฌจะี-X`—šm็ *x๋ทฌ๋พฏถใ‰•Nลj˜€ ง#ธU2ŠFำสLŒHย&w4qOq•aWo“IeŒRช๙‰ฃydลC๖WO๗ฃ~kม gW”y|›ชํฌฝ†๓ยวคUŽ?ไปาqgอŒิศั๛๐ลXพsf%หฏทŠ๏ฌฑ˜ูหปศqจฒํว“m‘H“\฿~f1EN ฎ๊ษฟถฟ*ื๓ƒฬ–tิ‡เcVทำˆIOGช„s]f8ฏ‡2@โ<•ๅUDuŒุcqW*ึDysšณbT[~๐‘f[-3ฤัc8†ั‡‚‰s๙ุฟเ๒5c!rห }ŒyฬjEmŒ[๙๎0wxh[a9Q D๖Nš–๚…$ฌโY.rUข†ฒNฅ้ฒTOO๎G†_ษท†ฎภ2ผ>้EFิ‘D…๘!k๓๐ภe๊แf=ฎYชญฅึZIฉž์ZFRusskูxBK#ำsค็1pz|๖-ฃหL5š#ฯyฃŽปb์JฺvhPค1๙]2๑>r"๋-fฯ0ซอ+ฺŸLw‘ฮ;”’Ÿ‹h+.\VใฏHำŠ๑uw]ำYssŠฯqส้”#WxำŒฬ ฦZKvVlˆกz='7QyPถ๓U|5;+วฐL๚$‹Œ)วgู@ฺL๎๊๐๗นU ใฅ—Z‘ๆDt\$F๖-_vฃœๅฆ%]๓V—–ดT–X๔ฆํก1=๙ฬ #&๙ฬ‚ฒ;"8เ๒‘๊i!k๚:ล?ยา"ขๆHจฉบ*)า๎Ššรฑ_=Q๖:ศZว ฺJr {ฮ@ตœษežนฒ!Rรไ;Žไˆšสูฎฤrฯ}>๗ฎ ฒํ๐ฑ๒†aสฑ#8๛|ุ?…hveู|4๋น M]ๅNrษรbcNO b ฺy’šƒ%ฐuz)+ฎhmข —ษใ’ท๏ท˜๛ิ๗ก็yS฿ฝฟ"w}บ}>๏ึ๓๛ฯS‡Kวใ๙š…"&Um"ใ6ขa๘๊์Šฺ™ฌWัมAuZ๋ๆ**ัGร]ธv™•๖ื‘Wdp``-ๅ๖า$Hส$œ˜xๅ$ฤ๊QซฝŽใาPวh .\VใฏHัQxบป.๚ํk-์ทล–ย>/QK=‰ึOXฒ#…g~™ฤ›^๙ฮoUแR>\[pˆฎGxgฒ™ฦrฉหk)ุcnใ}โ,ู ฃฯว+`‘ ‡z|>มx'-74๊ฉฑถๅZ|)62"W{รฐju’ร„&้ตข)/๔ภ‰TTV^๛ํ]ฝ”ฏJ‡s•wเWฤšjJˆŽ= x4ŠE๑rึ๑๙Qใ=X+ฎ์N\hq‚;ฮซ•QŸDT%M๙ช*๋+g๗ลqA&›ซYw;พฑสไวษqŸแวฌ฿ƒœWวรๅำ2m(ฑkY-]ณ lž,g"qไ…ถีลMWSt–ู๏j๙ำ!ถi„†Iฝt๔ฅโE]1‰ฬ 6ีฒ๘ฮ:MxชถNyจฌGฦซ๏ิฬdA%ซถ"Ir๏ฃbฬภmภpJA'Lม8ฆร๒k๚W๖ฏ๗1K›S•ไ?*^E”ำ ึ๙uิF;ญyดE/€™๑p=<rE•๐mkfN]}”F'A”฿.\$E’$›ข.ฤ:ภp๖ฉฌ_bM…_ฝฺ— O‘นลzlgZPtšUUiM‡โํจQ+kก2กภ˜pขGm8ถฤhฑะAฐ๐ADMvq„Sฌฒ—งๆOฉs๏.$ๆ=EN[บญiU)ดfUeŒ8๓kได$„-?H“f(จŠˆCท†ป,์ใใ?๔บวh๑ศ’๏2"ะิภงŒžืxyŠ๖>"#ษS}‘ไ๗{(์ี็ž3uื]มqwuว ‘ธแ”]ิ•|UWX&ูE+ ^’žqFt„Žฒุ๋mฮข*AหeTOษฌ^ƒ&Lฃ7ySฯบ“จˆแฤ)`Jั.ษน6จบวi1ธ&h๋‘(๊แUฐ๓ศ<:ฯท ๖๐ๆ[ฏ้ืg๘NAj่4ำถwxฅญƒฒ=6[9“ุqลE/๔kณ>ฯช์ ผ`ุืa˜ไ)ะไดผ›‘\hยใf+โ$Ššร1<žL6‰ˆ’2vข้๘ฌ‘๕ ˜๎ู2แฉyส"จ›๘๋ ล2yฺ&"?ใตOEdห™ต&\P_TM๕KW}R๚‚ป[o5Œ&[2,H9คKmำไึ‹VาX TJฦ`XฃkธyF0ทล๕O‘^B]aโฬHYŒใgS2ิษี”ี:ณลฮFeอ฿uU฿ลuู'f_๘ ฅีe}5T &แึUB__ฒ5t‚4(‚ ‚) Šxชฎฐ>ฒๆSr~ส;UYท,นƒีeคฌ$H๖฿yoพฑฌ‡%๓&.=M]KDžš5bตถฤˆ ๒$฿dDิงiญ"หf๓สกดŽXb๙4!$‡bศ๎*m3%”1ๆู/ทV –ไP!๙๛f]ฝœLพ›บ๗^๓“Wd๑%ธdคซo๎งณ|”5€แNb‘ฅฌ๘๘ห˜ตใั็™,ึiIŽ์.ชธkิ๙yลใโบฦ1ู$e…M|-kทUิL%eฃซ์7ณฎงŒSc/9uŠcูLh๊แEn๚žฏt'Qว!”ภ5h‹d›T]cT8ฤG‡ASฆ;ฯ ๐๋พ3มL๗/ำฌSสcE3v#Wต0ฌ๛›Ž"#ŽC)@Dั"!+jŠฉเพ์๛qฌWแ€wฃu1฿ 3zNฃ Wฌ(๊ซ|๔ๅ๑ผu]ฺฒk})•ึq#ฯ-ญ๙tคร”$ูŽ่‹ฑ ๋ณผ2‚ฯแeUŽUBœย:œ\ฒYi ก$๐QmE?Fฐ์[,๒ox๒wพl~ฆ๛ธwฮ๏นyQงz]^“}Nrเ;๏ล5ุ็e๐๗คิ8ตีีัcมฏฏƒจ ยˆา18ฌ ƒM4 `("(ˆ‰ถฐj_9๏™,jX HYยIน`Žrq<>[š|e_vฎบ๊ฆp#SjํกFฑฎ˜า8ส…0Mท’!lbพ(‹ชส๚j˜ ๔`ีิย]] ฎJ}(ฐกˆ6ุ๎ชปขnบล๑ฺฬ‚๏,ืาึยธถัี๒œfล็ไB๘S/฿X.'“LŽn่+,fดหfฎ 2Kdโ7บช๔๙q_•5QYGS "ึSภ‹Y_ นš1 ƒaบชช๑NฐlO'Eธณo(klฅฒศธ1ฦLฆศ๚\‰Kคซรu฿ma˜ฃy5t`…_‘;Pฐaต k[‰Y๏ 61ศ˜ตPŠํฌ~—%ฌW๏'฿Uยถ…ึQ’4๐0CDUโh›งศบยฑŒ]้Aำ•"’–|ฉ-rCFคKŽแ†่Š€Dฉฟษฌ สlXŠXŸ‘โิwsY„ฆ๛pฺ•fรฆ- ธแฃh\Pˆ—mีuุ๏e๐๗คั2OSู5PR\&cฃŒ+ษ๗€H„‰Uวeำ•ฒฒ†แ๋;้uNฝ"วŒาšพ<—dฬk›siณ8ž)ฒ๛ธถ9•CŠz‹$คฌผOMZ๏ 1fำขลTyŠoฒชi†cDŒหqใFŽะ3%วฟัฦวช›ซฐP๘งa ้พ_๋:$ฟงT๕Tะบฮข’พ%UdN๓ ฅศ๎ะ €43p๘ŠnDDพ*บ์๓ศ์ŒDฦ๛ ทœ@€R์#ธโข"""r๔j–ฆŽŽ(พ1ฉฉ๋aึUGOœ™Bลt AqรpะCฮ""_]vMูใ“ˆ๚ค๑b4j&๊ฏ%uฦ:=2-y(๏พชk'ัษ‹$SLUS๐x๔๛›ีฯŠฒMq๐้จqไืc•รK“X>ŠJ˜ศว—'ฦihไJŽ'ิ$=XหD`…็ ’ชoใฎฯ๐๋l‰“iะปฐวjฅูซ‘ั3Žหyฅ7ค้)ช๐ู8ํฌOญษํ›yซLŽ \;๋&ค:พ…ผv†Cยfำfhใ‹นช๘ŠjuU~?[—ึZ๙r˜‚?“rฆ;,:/<,ศ–ข.&S—Šํธ•ีpขื@ˆาlิXP˜ัcถŸล๏w ฤ๒ว+ลเ€y.9Ozp‚B‰H…hหชฺ€s@}“Bkฑฮสแ๎%Iชi๘๚GbQLซ…*™"Fn4Tฌxž›bˆ€6D]šแ๖ฬŸV=”nฉ™ฑnPไฃ\ู๐”uƒึgWR-–=ฌ G‘–กี๗7Iชฬ‡็uPใ—งั๒๋๎xฤ~พ?๚๎ฑˆX†b๔›G^็V,x์ฬ&เ:%xธา ฏร/งไ๔kฤr—ใ7าŽGำ^<ร\”บlนfหช#บช์‹๒๋ล้qe”ถ”58Mu-’ฯŠ0g,๚ธmu˜e /0DQ]ŽvWq/๚Mbธ)cร"\lnŽฒ‰O€tล๙,ึ4ะ™ ๙จDŠปxkณผ*NLn๗ƒผงzฬๅn„“S)+ษฒl๒๙้mb˜ัๅ‘Eภ”YdQุล ะb้Z๏ „ษ›D‚็ˆกU5ู—gื–๓ˆmญฦŽYูL6ฺ9Sฆฦ7\QE"]‘= ฎห{9ชดฏ}นP,ซpŒf ๘RZ^MH‰2,aqณ๑EMbXสf฿HฒดกซLš๎‰ฆWฝ.๕ว ˆฮ_‰ๆ|_ bxออํŒ;IumCWcmN์i=๒3•v37ฃ“o": ั๓“ววL3*$ฆ]&4†๘๒#พ ฬ>หˆข`bช$$›*x.ฑZ Z4๗าLึhชกึ ทม8ถไž๊#ฯŠ* r๘ฉเ›{ด4นh๎๕ุwWี†_เญ๕šjp‰๑UH›์ปk ฦ'ฺว[j|บ:้D# d๊:ฺ๏าDDk‰ฒqภ๑lษลxๆนŽิ“ๆ๙Qd8Jืœๆ=E๓ฟOน„โถ–d\>†ฒLงษŠ,—mU“ัิ฿mGaจ21Šำ@vใˆtล€`SŠ‚ &xkณ\cฟ๔๚ฤ๑ฌ~S์๗wไาQUี>๓ัฮƒฏAhƒ’!qUtEึE‹ิอ˜Mˆd‚c“๎ๆe} _Fโ‘—19pฃDeqดn3ฯm“‚$ฎ>Giถ#ฐุ2ร €ดห,ด<iฆรdDAM‘>๕–ŠC-บำ/“`ฏ4ำ๊$๛mบพ"&  h‹ใฤw๔'โXหน|p้วสœกช<‘†๛ฑB้ณxMw‘N‰›[#ฟT} ฉ๎`|<คvA_ลวชุต๏/๏ื–’i s‘uEๆ[ฎ๊บร๑ผa-+ๆwˆธฝ] ุJHN3d5VำHแง. คŠฉฟ†ป9AašGด‰K™า2๓o 4ฌว ั็ lB\ภ]•ฦuO6ธz#๖M#ลf+๏ƒfMณฆNBž2DN_yู†6ไž)Xษฤ่”“sชRค™ฑ๐ฎ๒๓บŽn[บmตa[้+*าVธ๐้๔v๐]ŸaดWN‘’ฺิใu0g‚บ*t%GhMด4Uๆช!oใพฐ์Zฒ}๓%๖m~=S]ิs๘์[IŒศœ€]ืqyI5ุ็e๐๗คึˆb’&ด L‘ใTิOKeฒ๊6ฬ—jูhŒDผPIUuูf2dษuษ$HภฑWŸ๛ฦฎ<๓ฯ9HŒ‰Tˆ‰wU๑]vyƒcvขำฌ %AO`,<›<ศอฎŽœO๑‡–ห๒๋ฤฒ[(B!}ๆ?Wg-ถy ถศ‰ดU%Q฿วmaxฐะฃF6Xๅ<แฆ,dฉIL—w้์œ:1h๘š*.สˆป*mซิพฒฌห<™ BUำีtay<ฎFš

*Ž๕็Yc”“ๆ=มถบาฆV5"Cฝ6Dy*์(ˆŸ"~%†%†ศสชJšH‹^5ู‹uPัgAŽ—x0J้๏้]หว๗Œj)’ˆี๐ซkuXณ•["โk`}ฺ*ภN๐US lS‘ฆ„ใ0~7]Z๒” HŒJxYŽ็ฅ5ศfแ6'.ธQMPx๎ปi ผŽLa™()"+ญผQ&ย‘มTyฐ๛n2J+ฒจ๎žธ ฤ์n้ฑ!ปฎbมš๛็wc๏qฆƒlƒ<"‘“‡โจ)ฌืฬ็ศ— ่ว ว‚ิ€ษคึฅ zสDf ฃธŸฃาšŒีk]จฺŽ=†Epึ๋Eว4ป้ ป๐o4 #฿ฬ•รไ. ๆ“3œ๘๋ž‘#!ส]~MYไเcฑ/D›ฎmํ‘6tƒr"ๆพX†‡พ๑ฅ]rหm‰P ษ๒uรDxบั$pๆข{8*)ฐญ ๖I…ซอษห mฌูaWŒA๑Ž๒@=!žLฏ๎fื—ย*}๎?w›๖‘=˜็]ŒVC–)฿EV’&ฃfN๓ูTZ†คป(—Oำฌ~Ž…์A)Dฉ tคX?1‰lฬI๏ฝโฺฦDN;x๏ฟฟ1šฦไ5 –เBztน“ไน ทๆ 6[ฦ ฆqฆ้ฎอแc˜Ž{P@จ•~6งw2Žึไjน†๐ษz> hBฃออ•xฤญ3ผา,๔œƒaށบ‘W-”- H,’บ`ฒƒ็ฃไžฌชช›*ฐกิ้-"”h•งล฿]tนฉI$_;m‘<=:ฬ.q์ใEดƒFรฌฝE˜ฑาKิvuาภม]4Hๆ›!๔๓ ถnฎำeU ๓ใU‘ภl k uw.“‚mศcuUF%ๆ%Vไ/ี๚‡๙ศ_ช&ฃ“\DศOŸ%Tฯ“oŸŽHˆ้ตี็ใษดUU้ํ่๐ฟงŽFŠL‰;ฯeE{mธ7ทŽ_r:ฝฬ:„]NƒหŽษเปฏ†ท๓‘วม|||SQ[Jะjฏjํโ’(ภ ฆMjต'พ"๎/Fต_แaํ๖M6แf=จ8ึG`ญสc4eษฺ(ฎ›žw'Eว&บพ•WKลฟwตชlg“<•G*นง฿…ัฌe‰(*๕$‹ฮงย/|ž„ํฦ‚TfลvtPฉdNL6฿’ภ—“e0QwO๏๗r{jEŠYBŸ.‚rฤ˜gฮฬ&œ5q ฐLก6ำไู+dจc็ kด<bฯd™N5^1ืสwะž0$ไ8ั+ญ๔แ|3,๔„œ5u8’&ญไ–k‘Yเฐo฿wผXWVW\Y/hไ!rq˜q„ั/ˆsy kตnั“ตบ|0๓น–‹}n~L ฯ|kโ 566ฺ|ๆฎ๎yไอ‡vG6]•ฮŸ]—ำ่ื‘Rๆvฦ‹ชดvบ.;ํ.าDV#รšฌ6ำ#ศๆa”‰็]U๘นvณ„ฬ‘)้ll"Y;‰ฒช๚Os๘`}๏ลf(pMี“-ŒrหผF–}žhYผdูe\ืh *Sรฒ. f>% ัฃR้mมรึMuw‚d•ณ^โ_x]ฝ้9–ยž๋ pd%ดไwb“อ6=@UUไˆ?t$ฌ#ณีฆl vw๊ถ‚T‹Fู๋:N๒ำˆ…ิ3†ใ‚^`8#ฒ'iY็c๙|W™fู•›Qคฎ<๔๐TDY QๅฦAWYdyG.บ๋%™=iŒb์7(ู1a;+&บa%)‹/:iษฑu8ฉ!๎;ฆปJอํ,'dํึ_ฆUf้vNรzะJ[ฑ`_‹ #ศm๖$ฏŠlk๒_–Vฺjา๏&e๗M&0ใ1€Haภjธ๋ฬจนม…๐pต๗Dไ๖ฝฃิูWœ ถฎฬg%Ž๙t&ผP– ฏT#fA:ึโจคœ–;Qห(ฦฉ๎คDW‹2l0zdFศHZ{˜"ฏไ฿Xผฎฦ$ๅ ห3ว(ศlไPAฟGi$ศGญ†ัใj3œHฃs=›๊ Lฒหึ0Iีu๎ึๅ4ฏ;็‰yๅ‹'๋ถจหฮอฦS*ฺpU6๖Mตšf’k๎๊ใหs'“>1d๑IสyำzqeฃH(ฑะSp๘คZส๒ผจoeร–ู๋Tึ&=กฒl‹q†ุKžๅฟส‰ฎN1€vZฎำ4๐ก4ำ+zŽ>ภฏ‡-ํ]๓;Ž๙ฉถฎคTgY.j„Zคเใ0_„x๛Vnผ๑rt’ร‰ฒ(‹๖่D‡ฉ-ุ9‘6๕KaมๆLแ๗[*๙โฃUด†ฺ|ขฺ8ŸยnฟyW\ทฉjาๅaว[AญŠ@ภ๊=Tgจf}4.;ชฎ๋๙ZŸfใ๏k+๎+ษ่า œ8๓ข๐ค ธy"@ค ชx"ฆ‘มด'๖DOพวฎm$ศจ‹p2k„ Rฅ?ZTH\‘XU_“ล5QeR’ขEx,\Œแอส0๓ฮ4ƒ5Oช฿Œงฟ1ใ&ฉlh;@ลฒK์ขฎƒ"„๕ ้n%“W)ปah˜๏1e+ฬˆ"F-nHคŸsŸhlgึ˜งผ[วชํก’เy eเ๑@ฌาš‰9%lหŸX„vWbปฯO}ฮ<สB\ฉปm[ฆjY์+,น[นบปสC#ฅคณวฃๅื,Sc•ี ไafะOฌl6จ ฑj‚ฉkษq~6ถ๕*ฮAEaK8๋n16ช^5ณm) ๒>$‰ท$ }ฬฒ๛RŒลฤนธๆaC@ัๆ70E!Z |ั&อGชุ อr!6—มฒ,cฒ…ฐณใŠืึWfBx๒%‹CV[qทT]sฆNช’๗fDA\๛™๛W <ลปภธ๒Qpฬ๖ ืMฉฺŽ;Qฮ๔Žก๕Kม6ูw;ฯ{;Gˆ0๛2HืQซfJฆf5pC์*โธ๚):#Q| า•-ฒ-ึล“* ๚em+อผS,ฃT ;ีQtXhน6H"แง›บTปO˜ห+!˜ฤŠใฆ•"#.3_:MAˆ,cuคแล“gM0›.ัฑ‚ผ eธํ:๕ฤ'–ค)ๅt"Cm็•ณฬLล“ux /eู7f}˜v}1๋+,บ;๐ๆZคูQๅXต น3ึ7†Q™ัksqำูP5 หึqlU๊ธVOœH3ฅ3”ธ0dฬlMYถVบ งหŸe์C.์๚NBYฎDฤืซแฮฮW๗ทm‹*FŽหฒMพ&G't้&๛ va_ฺ–3\59•,‚rUณธ์! <:๊VAzช๒oษัm (‹ภ”‡๎Cษป=ฬ]ธŽ๕ŽHxฝzˆQัทT)Ž1,5SWค๔ษ8๙ขชบ›ๅ+jŠš}".6ฎญจRฆ๒4E^ฉ๊ˆพ:ฤfฦ์ญ‹Œข(พๆ,ไJธ0Xํฬ\ญZNนษ เฎนิ$ ผฬF;ตชGข%knฒฌ™‚่Dqๅ9๐@้>\X/4ะž)๗3๖ต%œŽฝ๘#Œ&;•4ไNต|H=Eท๒9!ํym‡ใm๒xแ7—สห๋2\a๚,™KmZˆ็5บ5aฏ‰#ํ"ฒˆผ}+ฏนngi.VฺNwห(่Bึ%“Sœ๏ ๎ญš.‚š“ฏ$uฑ.™ฐŠ:์ฃ์พฦสาBใตU0†ข๊‰$ˆ,๕6อbq75Œึริ๛Ž\ฬฆณ6cT9-†Q๊ษีZ่,=D(จ„๛›%฿ฦ3eธฎiู~“C“]Œ`ื.ษK“t”cr,ั šh™mษ ]eเŠ(ช˜–MQIหสš๖า†า=ฐษฮš—k,ๅ4,ฟิiะ้r9<_qhิfฒ„ฬ๙ูf!ำฦซ๖ฏฌšุH 8<‘‘)ฎž๛&58์[z‰0%dธีtFg<ฐฃˆHrณA—c๕QฦไGm๗ZT่๔หฏฯ›QไํDซบดŸ่ซ ถ’A๗๚ce]จU ‘ูrZE๔’์IŒุ๖‰—ใ‘สสf+งๅฯฑศฒ4vU}ZฤbQ’BnNๆmฐH}saB>ๆ~ึฃ3Wณq…วrง\—าซ—]ิK#Š๋žู~.฿.ู้ถGูl๘ทฒชZว๒€œๅฤbi4–เŸEร}ฦGf•94^zฎ่ aƒไ๐์็4ฑ]า5<ทšz<9๓OŠ'[‘ถหธรwoตยํช๚น6lภ †ฝฒ3_f-L8"f๓ฏ๘ HปชงษใฌZฦพ฿2๒ถ/Q‹dตณซคCคด…mL`ุƒo›ซ†J(ชา?พ—ฬm;0นฒ“?อวญๅc‘'ต$@™"โ3+ฎ๛ „y›นณrZl<<ๅิศ๒๋โ—ญz|๖lทฺ๙–๖Nฌ)[‚NŸ%O4๙vิุ๓;@ษ)ศฎ‚-djvkฺบ%ฐฉช๎Q ุnG/ฒ9๒l‰๎v–๖ก uJXIทวึๅ#WสYŽฦ๒kMฉฐ|@]๓œุ“อ๙W๎pํ3$๗๕.ฎ์ด™UG’๛คษ’๘uผ+ญหฝ๑฿ˆmว—ย๘๒–5"ธซ™ิ๏4{ีฅ•„ ]`hนฦ๓>m๎+ธก-*ษฮ7ะคข_ŽืW9+&ฒy,Mฟ)วก|tS’สhพE๗q <๒โณษำง๏ick฿m˜ฏ‘๛ŒiŽNœ“ใผึื~)น'แฺeBเQผ‰•O๒ฏ‘rพส~Fgกิ็าGsŽผ~.ป+ศ{-~ฎdXะแd+fฎ4๛$๋’ฃyNพฝxถจ‚ผDำวาšถงฎ\ถ›;็็ใต๗ฎม™su4ฌฌ ฝขจณช0อpG๑yh”ีHธ๒%D๘ลล7_ะž๋ ธ[mษฦ€ืoษน&šmค_OL7:๛Ÿ3œบžm ๔q3Šv๒ าฝ๑ใฒ%F šCG]’l ฯiQHtนรด‹ฆ-๒๗-ฝzฏ(ฅjฝซ8ะ๊G"4„Qe#๕Tี๑฿}ผทYฬึาQ@‘ee5๒A"ฦo™ช—โถ โDจ"Šช‰จ/W=>o6ฦŽ*ฮ=ยT–dฝ*ู?-ุยซ้HศIเจซUไ/ี๚‡๙ศ_ช'ภผฆ‰K…Vาย›S(fญคณฌทฐฑtโ“@ญlC0yšxขภo)ขRแUดฐฆิสซi,๋-์,]8คะ+[ฬfž(ฟฃ๗šถm่n่สŠ๎โ`bผุ—๑๓š}“Dq—AP„‘5’ey%EZ#U'—NญฑŸWAšธณ DŠซฝพๆ ž`’6"๎Y฿ณSู๎Lน8Pี9\™+ฤL!@ฟIฑ2a[hูT`..น็oฒง‚'‚"|Ÿ{:u\lทผฦdูV#e_๖ฑฺทๆW”qด}ฑuMฅ6ศP‘7O 9a*ฎพeŒ›KrŠๅลฝ•ฌต’๋' ดหDb8แมกูฆ›Mื๏lฏญskฬz>9 ฎมสโวฑธฬีฤงrU,ว๛ŒE12vAง๎‡๖Dไœ~๗.gญœล„ฬVŠา].D๔g‘ๆG!TŠraฅ6ƒ๑วgM!Fฎซฌ‰}|&B%พB#ุห‚ํอLF‹หฏ bNขฃ;ศe6Rๆาuิ€—เ๕ฎะ฿ฦuอดสขqiTถ๑9+ั\3ุHมตึY‘^9˜ฯsอ]ญ„—`WำB|ล๛ x5d)ƒhƒเำ@กๆนฌฦณทบlฎ…,fนษ นRŒัƒ +‚BŽศ ฤผ|ีํง*ย+๑๙9 ดnยาD๐ซญโV…th1ค3ม?u!"ข์œvว_tE๖cA[!๗lqฉap‘ํZr‘eล“5ภ๓\0sฮ๘บณห[ห#ใ~Uq์ซ[ ๏44ŒึC†pษ๎pWผ๎ฅบขงกU|ณ”๘ช๏๓ืตYŽิถ`าอณ’ น๑#ว๓q|UlHถE]ถEึwOomลำnฐ’ml๙ว๐ฅ%ณLSฮ^’‡่๑ีํf=Nม g>าSqYWO~œvy๘ธแlผm‹ไEืhT๓ฎdนั‰K6UM}…ˆZb8พแ~(4คE๒"๋&…ทlณตf7-ี˜Pฒ–,ŒF]มotๅMตฺŒมฃyXฮK*า[lึซ’[ญมฮ‚#% 6ฤOล๐ถoX ฃ‡jวP#<0eนY'x$@uงน"|U๙5ฺ…ฬmยhŽ+v“๋รภฟฯcนSdmNกพv}T™8ิำœOc๓ฆซ%VLฺ๎กt:ป#ฝ4RD>6ปzทย2‡œ•"Sghอ4nฒฤ—qษmDŽ)ธ๔˜ผ:ŠฅษO•ญpฉี1ูศฆZzส ป2–&dy‚Š[ผ‰น‰‚žๅน—h”5๙H’!’ห}จRKo€ฒฑŠัฦŒIบsIฦGอต สศ *.OHขC๒e๎๒K๐_ฮBQ?a๚ศ{ˆŠŠ›*/Š*/ฅ5tๅf ฺ6UeC^ษqfwF\„Šข$ฐf(oฑข4งใทญยซจฒบ)ณQ`ม`cEŽฺ~@DMMศแXUภU!ŠYฃลตฎ‹-ษฌฑ1%GxฤpUฦŒWŠํ้AT๔qO๎Ow9^ฯ๏Yw)Ÿ&้๓๏M_Aa๚˜E_=ืsรืmใL›ศJิภ๑6ฑฆn๚"| |๚d^~ชบYสว^ำg/ ฌชfSt๏’Œฏ9[3 ˜แชrI'$ิฉัสชP86p-ัฤzม‹wqโrGžิ๋ธŠ KŽศฐหล่%c‘๋‹ืpฉํค ๔•‹ ฌฆ•#Dd)ถศlhDป"|ŸูG๛‡’๓ฟTOมุ~ฒํ–4-Wม‹6™–:ไhs#šลŠิ3Žฉผ€”ก๐E๋4…IOQW ว™mmZ๕-‹oL~๊ฝŠๆL]7qด฿žํ ๏รn&ฎ€‰8จ"ฎ&สj#เ›๚|=,ik2ƒFฌƒeฃทŒ9kwส:ฯ"L Eqง$ๅทMี5Ÿv{[ูfG_ตŒ~ํ‡[ทŽิ3แน#Qสpzฒ‘๗‚bช ~*v‡ู˜vsW‘ฤŸyG %Lฑ•M"ุfไ1กLฐ zฏ4ฎ‹{ษ ‰ScJdฑฐ๎ิp“uถs[pซlขฑ%eEbyฒฤ มKปบ.„ำช(ๆุœŒ;–ณYล๐๖_Bธ}ธหU‹ ๅqรไ-ถา™ฎ๋(ณฯฆ9"ฉซduชฉ,”˜๓Xูุอ>ญ;ุภM'E@‘TKoึy…CศฉไF—ŠRใU๓šฦ›|ฺV-$d3kผ›๎‡o ฺถา๓โ„‡แeMq˜มf[ถ8๘ธ/ถ6/y%"‹ฑโ—™ ปถๆ์ๆ$พwฦ^า0zŠิlฅ1“มp์šm™2eม‚BuVmฏwY‚:ู‡Q6R๐Dํ ชŽำ์!YFฐฮฐ่อ๗f‰‡Ÿƒ™XะGธซ1ž&Zaฤ^Dœถ5ํณ jI๕า)^ษlBY9S&2ย}นj‘:mก8mธ{๘๕w๓—(ทjVH–3/2š3:™ฃodำLีขค,ƒQุ`›3^ซhH{#Š)ฺๆๆศฝฆm‚v5]฿ฬhฅีL“าผbCจื™ญ(ษs"`ฒ‹eฦเœxํบ,ีรi๒#&ัd>N<{ช[ŠŠvŠWเ9,๔|‡!ŽไษีŒŽ่หฮUI…%ณ“ฒVึ_Dˆซย ฒKQ‘Rd๔w๑ๅษฮeS,-.kํยqb\ึ+ฤa๕Rแ๑ฒ๗๙%๘/็!~จŸƒฐd?ด๗๙%๘/็!~จŸƒฐd4๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\t๋~ธ้ึqำญ๚ใง[๕วNท๋Žoื:฿ฎ:uฟ\tจฉ๛ƒลtพ_ม9 ๕D‡๋! U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉ U4๊ฆ€=Tะชš๕S@ชhีMzฉคู?px'r_‚r๊‰๛ี๊Hฬู้rE7“ญXฬฒ ‡฿`b–ศ๓~๒ฏ่]ฝรšh ว]pmฐNFfeเˆ‰โชบํ ถ๏EV%6M>1.6 '4฿ะ@โข๚wศ‰2ไฦจฒๆวฝฝงัzอ๘นลBํ๗ฟ์?YํรI~ ๙ศ_ช'๏=›ๅขฦฃ๓6๖ุเธ๙q]่ฬ™_];ไ๋"Hจ.บใ"~”^*„ฎ“ต๖xๅŒˆ๊ใFรแผZภv<˜๎์mบัก6๓Fˆ@bBIบ.ฑ<ƒด|๋ข2%Pc [Wถl$–ฦdi๒ๆญบจ€ ศิ|qห<ฏdไนŒdmจป";`.:Pไ4D`$Ž+n2ญ r%ฬ๓)ั_ลgV๛๗„ฤŸ ฐๆ:Ž=0žไ(บไ/Wม@ผS_sœพา%ฅด็=๖ตŠAถŸNป๓๐$ภz6๊๘~t@n๒b"%AีR%_“]•geู‰๋h/ว~ถ ศ์shกOŒ ษh… ฦv lผGๆYbฎWWYAvž!ห“bอบ“†หˆ‡Wจ ษ๒ว$ื`ขb๘U”–ุ‰”ส๊๑x^Eqฃj,่qY2 Nb1y"*ŠฎฺณŠxชpฟjฅศ๎C๏้=รsnyๅหn?.kฒ,็7ฤฉ_&ฌฒุม& ไRMฆกสF…Sฮ”๋%วe!๐ำฏ,F1คร– ๚ป๒[๏UณฺlˆQภไ%ๆ’‰ Šจ’{9ส\}˜ฯฮ ฦ“9BTๆซ๎์๗ม—Wงรฉำ.;๏ล}ว—Cธฒฉ๒Zฺ๙go'p๘~๛ข~ฅแ๙W๛—๓ ^ฉ+$ฬƒ#ฒจ*Jปะa้๘๐ Rโ‹พษพ›้w่Qe๔นs้๗–๎Ÿ=“}ท}“๗ฆnฺs ฒUqๅˆ1แ‰ษ’rต„ฌ>๗13›ฉq๙ฒ<จฅtฉ=.‡y๑ๅอv฿Šํ:+zๆฮŽyFขญv1Mฉšp%,wxฉ6หŠจฆ้๒&ขๅอ]Yฑ>Dsถจƒ l#Ÿ#จ๛$^ —1|u๗9ๅ๖ุ†30๗๚Vึu˜่ฮซmต5$•#์6๋ˆะ้$R๐฿uU B™$yฯ๙!g๙Qa๗+W๋8๗๎Œ~ง.‡=๚#ถ๛xํบ๋7m3ู5Uaๅจ1แIyฅtV2G}CฐฏŠชwป:-e]tgfOฐœ๛qกรŠภu‘&Cส‚(›ชช๊&ymทIฟ-ืะVcจ‹ฒ:หvSใหPโŒ‹๚5pอีาqกุ:รัไฐปH…6$‘Yx7NMธ(ป*n$$บฤ‰{6ŸknV๙,’็ษ™ ”=Tฏ๎lw~}>ฎg6฿Ž๋๑พ๖b,๗Išบ˜L๗ซWู_๎0QTEEuำ!lwRไBŠ๖E\ูพ‘jห+aB‹m-ยูˆqfึส–ุบ๏˜>ญ๓-€yˆฏนูFEฺผ›;กหญว]œำ๕L5ฌd,๛โEๆ&เ)ฟห๒kณ)ฝŸฺbด๒ฌฌร rสkRแ1U"ฎUkีฐ—žU.Eบ(๑Q๑0Žาm™(b๔NJnมๆe;ม้bPโM>,งœ_ฟš์f฿ณปฉัl%I[ผŠC–ใหฦ:ิ’๊aนณํ€๐Up| 7O๗๏^Gฉฒด๎Nx๒|3—ะ๋q.<๘qๅลv๔์บลื๒VM+๎ uๅฮฟvช‰g฿;าD‡ว~๕รงำ_‹ฟ/“_s._WC๊E4<ŽสขฎอภuิˆqไK ้๎๛mญ€บ^n๛*ขoจฝว฿&;Kz็น๙bตป๋x7ิ้๕8sเ<ถ฿Šz=ฺุ–๓qไค่ืNuๆbศ๒ฎG‘ฮซŒyษฤd‘ฆ฿*&ป ฦ+๐,ฉh,คdฑ๓ZwdEลฎน~Xfฌ็๗…$Œ็UVzŸŠกหรQš™'ฤ2\’ศึโ‘Aุ7ฮล['k%Kuบึ,”Q’h‰P[$ใถ๊:์f฿ณปฉัl%I[ผŠC–ใหฦ:ิ’๊aนณํ€๐Up| 7O๛ึn{8ฒ‘UMไx1ๆIŠ์fœYส๛์๐ๅ5ฒŠหแแใ๎ไ‘+ ึศเT4ฝ๒๚ื†ีี n้ง/5]T…~9Ž™ฝeŒzT(“า๒h&ฎฯhcปŒg฿ไ›6\ทT๗1uห<ซ“Fว;‚]yก*ๅู๗ฮ๔ฑ&rบ๐้๔ำใoหรeมk๓’๋ศ“วl๏aTฑ ฆฮจ็I–SŠ.tZDน)q๐๐์ทยeๅต6ื`์ ‰ซน![ ขสdY k๒๘G๋œi@อ uฤU~๓šวฏ‰&kฺ่!8ฌลe_wฆ*ฉบ์+ฒoจ= แ๊ฟCQ๒FeQ@bฦjVฤ‚าว‘#ป0qคพค\ฝ(จž๛˜ณ •ณrชลๆCeO|”Geธ๒&ใ่ n6ับ &ซล|Q7ำืห5ถฝฉึ๎Q†๚n#ห‡><ธฆ“๏FIUใ4ถwึ# ฑzYBฉ†sฅ$fŒ๘๑4E_•4“Tึ2'ฦ`-ฃ5r9],กH๊0ร '0^>ฃถ‹IARส=:ยZŸะ‰mถฺi ว2TฺlHฬ•EUvิ|๎2xZ๒๔œ~ ีฉ๑YฬYฎM้ขyถ]5:=•Mด8๖ถGcL…-คz<†\OHช.›๋w2ๆ๔น๔๚ฝี‚งฯe~;oฒvฑ5ลJŽํiF ^%็{/'5ื๓)w_ฮ,‡๕ค๗x๔Rใ(WyฆใำF๋y๒OษทงR ธ6+Œ#ŒŸ{šY ILa"๙หลื7oษ ~.๚คipŽใ๕5–b~L1ณฒฒฒ„๕˜|c``ฑฟTๆผQQy%f!‹7‰ฺŽ9AY=m+;ฯึ„[)\oฉป่ฆ4qษ}u–™ขŸ7ษัฌ๙ูŽรใฒCS๒"~?NพNT9žศ๗i‹ห•สอU|ี๎eทsหษฉุ๔ฬf?N$Aฦ{˜Vย&ฅœA‹ X!฿ui@Wว}ผ}฿ไJ๐ห]5gA…ๅ7Uฎ8ุผs๊จ฿ d ภQ_๔jvU:ข๒๊=ŽIq yw‡Yฑ์vก"KŒ*ฺ8D์™`fเ€˜#Fซ#yvc%ŒธQป“60mšxซไฝ}š}4–D4TE7TCลq|GนJหrF’v”‡cฦy‘ฆ $•Ž๑FeธJขฺryมRL<+์1ฉอวฌอ 7NLูŠฑฃNฏTp%ฦdY!Ulัท›T7q|fŸ9/๓|š?|๏ฃI๎๔›z<ฐY๓Q[Ž+ˆู:N/C#%Ÿ งbูv8ฺฑ ฿he9ถ]d[h งšjGI๎‹.ถญjคŠ6x„jฮฤ๒yฉai['มลhlฎฺบ่ฝๆฅI}ˆHj์ญQ‚^o! แ๐;3ศ๎abv8hม.า๖าดŸ[KrD~p”์ัธฒ :ˆ{๘ว‡oK“c๔SวN,ฅZZ^ูึ >[—ใข๎์u๑้Šข*๘+ธFQ€dถึMf+ ฑVœz๒*โOv4Y(ไใ ๙พู๔ีืวXํ6Ek’ฯ‡๋›‰ OtOH๚uy‡FธKjbฯdๅ  ๛&ฺฌ7๋rผŸยคาsaŒ’วwถฏ#฿‹1AKฃŸ%qื:๐Ac#฿๑ผาท๘$จ๙ฮGMD9?ๆว๏ฃิุ Hv3ัจผจ*;]Eู๏์ดญ'BซษฒYVYRไw็฿X81j›€YŒ6 †Yภ."@’œะ{@ภ&ทฬโว๎mุFvCะWแ‚จ5"3์›/ฃj€ป‚ˆงฏ็หŸเu‹W๚ˆicฌ์๔Ÿ‹”็9,^ฮฮ4Žใ)ˆฑžbH ‘y†A#8ฎtษีpdำ42‰•ฮZb™v6ัF…tpJว tƒ‹Œ3$›wขส‹Dู) 'นs†ม์๏ลฃฮบoฉwงj็†kฺz9กดQQ^/๛๑ { ็คห3{–(ช`สฑf๑๖k๊ฑฺ๋L6`ฬ4adH\EqUฝภ›>T๐ฎ๛hํkj ภ‘ฤซa[1แYL&ใƒคณค6ฤVQัmUTิ”เvXh˜4๛hตที80cFs['j4ฦกร๑ุ t๚แฯฬ=นjƒSsQ&ึา^Pภซ’ขZฦ‰3“\"Iเษ๒4!OH๎‹๒]แะฯสิๅ—9–บไป;้CzฌW?าฯ‹้O๛ฌจWตJว้ใ[O ‰”†ๅ†J‘ปEyถลSบ˜๐iฑnบ“s์z๓1II ‘‰ๅศ8‹(๏w๘>๋bช*xjยœ๛FrVYUอzjฑ‰ฟ"ุฬL^4W‚๎Ÿ"้(s9าkๅJs จ‡ีบ—;•#€อ™2ม2…,๏/(๑iพfKฤWTXๆ?•ษว`R;F๚ฤถ๏"}า.[๊"ฯ$๘W7๙wิ"อEฬD“™_มNภ'ฆชฌ‡Z=)็MวคGV(›ซ›ƒฝ๛เ/นิฑ…ˆ%-ธถGOo|Hป2Žฦ’€"ใ"B^"Š<N+q|ฦ๊โมhV6ไึ‘ไn3s!?yด๙}3 ล fcZg^ฌ‹d๓5ฏศ9ฒlคข๔œbบ#ฯŽ฿^o“T๘ฤ๋Xrฅ]v‘พิ†)$ฦsa€Uฦ๐B.$Y*โ’Š }3%ฐล๓*kจษ( 7^ไg๎g9SZlœx๐[-ฅŠ3)‡crAQ0?Bฟ—๑ฏ๑lƒS!Bฐตส“0็WFฒlก๙"Dฮ ิ”Tๆุ๙ษฉ1ฃๅj๐นQไศ†ฬธศ๕ึC[]=Jพb๎ิ—PSไ]•=Fํn\ว๛ำ‘!ดแoy.สชจ-‹"Bศ8็M4เŠํฒvq vก์ฒฟณฒฉG'ฬฦ…ฅฐiๆ8ไ๊‘ฦNฃ-๙PLม~GPาฒrษ•Q}V.อW]ื๑)-0๑ข)6ใn5!ฏ•ฤ๓‘}วกGห’ะqง์“z๖oJฅSณ“‰?ม\๓รี๖!3ดว ๚ึฺrฝ^ศfl"5พ๒2uIง‘/0‰ิNS“t้Š2ุอbๅe7ณ๏o”PFzž ชœถ๐ิบ้F ้ฟG&dz›ฒzภฒqgภัะzจ/L‰} แ: | ซyไ…ฌ‹6D‰ฃ๗‰ํ39ไRk”™0๋TGe )ŸJ4™๒Fšotiยpxูa๙ฦ›ฮ*ีษqจ^O—ษ[ฑ$`]GUณŒ]V‘x8Ž  Hนส๓น8๔ $\๛…$&›ถ่คพ=>›๐[๑V‹ผ%ฑ๗น\ฑ s้ ป ำZชฌaืSฤ[)ดŽ"ช๊ˆซฌใ ฌร๏q›ฉฒ0ชบfขGลW`L•ิใ8๓o \h{๚—KbS๊ซํ้้์ซงไyMdห3น}ปœhค‘ ต็ฟgh่_œK้]N์๏ ฤ]—b8ๆ-eฉ3/Yญxข:หSๆB’ฅ๐ญ›*๛ลtKamฟDผsถl6$สw#>/%_L€๘ใ–๎1!&™9L<ว.ข‚ด^‘!M_b;LqhภŸญmกว+ี์ๆ`w๖ย#[๏-ณ'Tšqx๑๑ูR็ฒ *ž5-bอK Ž๘ฺ๕$*D๐}ช|e๑รดก‡Sูไ+;จ–oX7c5˜ูKc ฐ‹ึศ•ถSช๋iษSวoZPศวณš™++กฝ`W1]vmt‘)ํ=Aฺ#‰๐oŸŠ‡งjชื$ฎ!“:ฒ R}\JW•WHyo๚wีt ŽiVM‹’กวb ‹ิ’ขซถ๊ซถฅVภฅฬฌ๛…ิgชขJRŠ}p5Oูงแ๚?&ฅร‡m?;ฌก์่์Z*้8ƒ ,IED.คV——งมSๅิ๚๘ืูcดƒr๔ชธณXu'bฅk#ฃ๔โ๏&้วะžL&ฃ‡ฎ{ธOw‰o‘1S%ถ…-2Er2yฮกHjพรเถูQฒwQ{‰^ยsฟ@B#6ต๒œญตІˆคุศiฮ‘*nAล~] ZY้รnงจŸs`MQๅ9Hqถg n ?)*&ฌ{=มฑ&X†3‹ZDntหึซ(ŽดVRกศU๘P6zไ์d'Dผฦ๑ี[4™พf.W]Hd๋ภKฦ+o)B๑4๛dษ8Jัxจจ๋๙ฉs๚ฝืธฤ—เ[e9t ไNษ ถณyRiลN ม>6 สjๆช๋ง—1Reณ^็JH*ฏ%9œ&๚(k`k๙>๓๖ฎ~ SฝŸ[Fjuล๐+ต๔,;์…‘`‘Cpˆ้๗ŒN f้xKฤs3:’ฐceธฬ^ไํ;แ!ฆ$ผhฤH\’7]ฃ}“‡นถผšqHHuPฬ>L;ฌฆ๚KKaถzัไsŸ\ูอ฿เ๒ Š7ั3t5s‡g˜†u)b•…kPญฅฑฤโIปแขw†เ๓&6ป!ช]โะBพษ2ษiษ}้H ตh’‡อฆ๛๘oท‚๊๋ ฏฎ๒ศ,vK๖' Š;‘ˆขศ๓xoหล๕ถํq:บ Fช”ุป N ๎pส9ั@๗š๛f็$^B( เˆšgรyว+ๆใาูจ™%ƒเatภhVZ6ลฦQณlทเIศ‘q๊)ำฏงH…u•_ษhฃbŒ4ย;S•ฮmศ\ูอ฿เ๒ Š7ะ3t5s‡g˜†u)b•…kPญฅฑฤโIปแขw†เ๓&6ป!ชk๒ๆ฿ท๑=ฯไd๚ฌf๊๖-lื้๊$M ๆl์šŽG ณBEื8‚ธIฒoบ๊๋ณzบžฒVE3ณ–๊"สตQ ต•,\Waศ.mฒ*โทๅ^|y"ช8œ5Šห{™=์(de ซj๊—:ฎB๋4๋fำยJAห‚‘mฬ—วอพะl์๎3 ฑภt ว1ชฦcPQW๗Yขฏ|ป!ู1๘ ›HบŸPใv‰ฌ‡•;QR|H6IQnิศ๑sฃ‘ค8ยฑ๖AฤTแศคZ๐[=GxO์ิm{ฉ›Šม9น†o’ฐฒใยqดhdว‰ฦž\ห ๛ำqๅTD›#"ว.คๅฐ[™ˆf๘ิu†ฬง^๊ท<ศอ4ภ(ผ์wcฃ4mฝถฺ11˜ํ๕Vฟขฯdโk๚,ํ๖J^ฟ‹—ฺk๚H…๛1gช๛EŸ[COjŽัYp๋%Eี/99Š๙฿.š่ำ^Sื]Uทฦ"Œ hƒaœ`๐Pq‡ไ]๕์ŸHแืcUoX:ร>Ky…’TTC๙ถศ๘"’*๘oฉใผง,žวpษšzย๎%{็A™Saศ%UqณhvddpัK‹mจฎชใิๆXผัชษ*ฃม ษฐฎภฐ‡9MHโเtŒŒ›6อI8ชษ์๛ณXU๒lยซ’ฤ+‹;Fk hB{ฐง‰๕๘์ำห":8ป6d‹จU๕ูฮ+%jฅน ณfฒk“ “ิ๖kโpšR0poฤw!ู €_b2-lWkmฐลน๕ฃ6Eš Fyร—?4Kdื•๏gถgpœGวณ[๎*ุ๓w็็ซ Cฐ‡+ึ9^^ุ=&Iฃ ƒปAnKOทลy ย#ฎ8๎๋ศE]™แk&Jw5ข1ช_.?›"@j4eu็ˆ‡“K [@ไc#tฯ\ƒ!›๙>๎๕Ž1.ฒ/tnศi”Pt›ฤ…๕qฝว˜ถŽ*’.ใ_จJิ(r{Dฯ;อKฉI$๋%จจjy_นีษ2} ูƒ@ฺชŠ๓ไ ‹d็hถt๙†&เ4ใx“2จ/k๛ฌ!GพŽ์hAิ2—๓Kg_ัUฯ๘~]๗ฟอฏ๐ื5k๖V™(ูภ(ุ๓WRญ˜ช„๓ŠœWจๆ฿จฐี$˜lฮUTฮ“’ฺ) #{๓wš“๊ฟen5ะฦฟม™าใ4๐T˜ฮQ›ไฬwฐIะ$ ํฒำฬIๅ)ฦh+ฆ้9ธด‹ณ8๔๋|‚Mฤ๓,mฅภmลŠฬ6ำ lศ(๏ฒwfMทร !v'Žใoิ-Œัr7Yœ-อ๚NีคjGD‘Tน=ีU  5#ษ%ˆReT0‚นQษ“\๐๔ˆฌ:l;ภX€b๗Š€์WธŒ.วq. ศmฟ|๏ยX=<‚;G<€vyŠ๘(๊ณธBฯผJ๘ู v%-]Kx– ๗5„_ษช่6™]ๅค<~ ฮŽฆณฏvt๋)-0ญ“ˆ(ษ M#น๎ Bนgdขยฑฯ|6 0gWซf$Aณˆu๖ฐด†เŠผfอ$ศ฿แลท U฿9oEI:ส ฎlบ’rผ™็๑Šฉ~Fั{ไrŠ<šE1ฬC…\๖qqUv๒แฤZl’EF}‡l๑“j2๙เขฅป †AdCuOู๘šSฤฟj"๋๙…‡ฯGื๔}”…9ฏไ‹/ฺ)šดก`ี WูืLzภne:ิห*pf9ฐฃดฦำแ รัฝฅ สžำ/fฺRฤฌzมหLIศeZจํ6$ศ^“ฎ'$_ผ{p’_‚r๊‰๛อ–W=k%้Vี˜๕”Hต๒”}Iฝผwe%Utฮ;†Žๆ๙uKLโป๔(=๑ะaฦn(ศไ‰“’UT”ทUาPd์6~๘1ฉŒย›(œQœZyท:iเ&".qุy๑DDz๋$ส\[n๗%–ฤน’@+RVQฺh@P7O›œUE ‰7ƒ:dXp‰IiOทฅ „Žฺ‹kไไ‰็๎โ๎ฟ"k&ํŸฅดm;๗4 ู๒ฦcMษišฐU D4ET๙Sำ๎ุdPS•:\ —Yฎๅ‚0 ฿)C—ศS P8๚W}6Ÿ—Eง9ฮุ๛ฬƒiŒq‡ค?$ฦ€ žี฿“,:*›์ู‚ ขVซ8ไf 7TaŒI4gTฯvญ~ฅีษ–๗hP€…ATTUSW9พsช็Sึยสฏ๛ลv;k]_ว๋แดำqไjข/Mพทจธฐv{์d๒เูtQ่เFHัฃŠGเฤ•w]ีwีฦkŠภฒ{ฉ:‚’ึT(ข๓Fข…ŒWœๅ็ ธใ‚>AM“UOซaะ’้8แH™>sฯด/ุXJ?4MEE5dEClปcb๋R_n3oษm5qwqภ4ำ๙5–E“ƒSีV1e +Pb+ฬ@ฐiะ(ฮ0’byด๓Z_O๗๊๑œ‚•ผดรœฤyั€gFฤžy๘;š=ฤ]mwใทง_ฯ‡6พ[Kะป/ผr/•5=์Rk–๕ฯึZL…a*ƒuK)ž}XM8\dฒ๓2"บกภลKล ˆ•nD์ U#บQ*ธฃQ[ฦ‘ล VI๎/0๑9ี้ว}ก#hฯ8qc ๅV ุใ๗ึ,สvบtHถณgืkฺŒศvฌป”ู[d๓2ฺชxsแธฎฯ’,5<ฉ.ก b›ภhขŸ-“VิณkA˜ณูm๖›yฺว ชp I?ƒรญฎใ้ ำeี๚b3,ฒŠจฐฃหซบ˜ใ๏า]qซŒ๚‡Oผ3'๙yป๘ํ~œ จ–Žd ัถฦ,—กูศ๎.ฐ2พ ฦ= ืšŠŠ›ๅlQb๒r9แYwkXg*‡`้›ใ4๋›2ูžอz6๔๘k$k#b—ณLา=›Wภ๎ฏLฤๆนmฃฐฅษ—ฬE๔x๊๕b_พ Žึดฅิ\H‹yเๅจ—‡[uึœง#๒GEx—%จRaใ™-ิ๖ซVBqG$ไoไŽลDฤœŒสณีู|ข~]eฬไ65yk–ฃ5WyX‡ไ‡โ๕•หXฌ๙ไ#ฐ’ฏ่Ys7ท๕8ฤk ๖๊๏a”xp{ตtง•๛(ฌด\^} ุMUynˆจŠฉs—แีทwุŽGIkmY |Kw์ นc&ฑท ม~;ใณœTyท[2BีŸiนfUŠV;} ,:โรgฉE\ฉ3ุ…Up9ฉp ลA/s$jo‘aษ&šˆซํrk็ซ1ฬfว`ฃ"Ž๒lใยพoฅ7ฬ˜šฝqq\T฿ผแMพหไนRฯ|ใ2>าข๕ถN^rฆหดKyxE4๖่๒ืiq‹ ่Xjฬ+ใา๏ ร๛์Ž€"ช*†๙ฯj๙๋ถำ+Zcชฝษ'ุm*HดR$DถŒห"l"ฉtH๚คป bJบIฉMEEWSR6](lAsHƒˆเถ"„&Hพ (พศ“ด—“Uว]Uไท‰๊glbูถcYšดf"จ็๑๐๙u$ฒ Wย— ‰*4YŒฌชบlก‘ต”1ฆ6ข1มทqL`l—ัซ‡œฯ›์“4ฤ=้Dฌต—cืMŽถDใ,+#"'}๕wƒmกขฏ1ใฉiš‹#ฬ-ญf“Oผ1+เDbLน ฬa7 € —%๙WY[.เดใnCไหฑi‡ำŸ[ม`œd”ฟ๓aธฐพฎฏศj๋•W2SPm #3ฦห(๊ซ ญ–โ*ž>๗ื๓ชง!uผf฿๙‚วบม)ฏฉป้|y5ฝ๓หU-<_#\ยdc฿ม{ส&วkฅ[9‡แnศl„ผž"าฉ๐semึซฃึถฟ๓‰กd–v=&ž๛ Œf{๔ฏXจ๒œ9rl™ไ )ฆก| ›L๘ธกพ๋ฌฯ%ห0*\หw#อฏํ์ฒjจถ49TK[˜Uถๆา ฝฺŒI}ธศi๐ฃถ๊ช‰˜วง‡˜ื-พ6๙UอJไi—ปำi[ๅใ!•ูิ๓ฝ ถVอ <ฒโŽN>๓•—sRลˆ–7ศ1 ุฯ|FK ณจ+็xznv4le”ท.Le—„Bž๖‚SUึN‹ข$fใฑ๓ล“ Š›๊แ๋<ชv7;mGฒิJผšคฌป˜ใรM7 F 9ิ๘WoงศKtŒ๋Zจ97pศŸ™ข๚IXถำAโแใศฺx— ‡rู5ฺ?i4น4*8ฐฒ,YŒ'๊ฌH‰KTะ!วq• ‡”tG86 แฺฟ,ชฦ๒)7็1W ษ›aช™$ษจฃn2CพฐF้B฿qqรญลkฃะ;6เใษz;!G˜ศŸkฐล3&Zษ6$[xxฆฒ๖2+*่>R›ชปุ ฤ.๐z๊ๅฌV|๓ุIWวัถ ป"ฒภฬฃEุc๑๋Žu๖vMa˜ฒ„ป!C๐๔่z™Gkู$๛b’เ์โำลž๒ฃฉฯฮ๓5ษo/ศ@Œ—†Ž\\~5Tธ๖–‘ Mฒj™4๕@ี…ƒภ๋ษซำdี\-ƒ‘$วrHธคm.ขG—(ทๅฦnnŽr€ ‚8Š้:ƒลUxŠชฆฝ๑ล์ท*ฉ‹Ye}I™}\ุ$V<ห2aก8ฺตฮ4ทRu•uB.H™_jขุdืQ๋ฃณOq‘\ตLณQjยPOŒ*ฉหˆEไDƒโคHุ!r5@(ฆK้_สพ้ {ผ?ด)v์ลTโฒ๊ฆ2(O‹ฟ‰5ฦs฿ไG›_ฦี-–Cทบ6•4๎#RvClฒ์Y$ŠŒซ.>ฏ’6€ฆขHพ๗๙›“‚?ฏ้6ห๖ZฃPž•OY$รhW€L‰c]uบพra’|ฝ3šฝs%(yํฝคธ•vัเTถ๖5nฤV็ฐะฉ&ฃขฉ๑eี$M“ฯใฐgซyKฺโ‘q7p้T๖ะญ๊mŠิkณ๏lƒ ‡™uEา6N’Ÿ$]N,fญ็&^J~Ti๒–lข๘’‡xฐu฿ 9ฤAoรฉ็mใฌญ—;?NQฅไ^Lป™}pi๕<FIK๛กๆXT๑฿โ๎บธ-iํ๊+Ÿf=…oyผญiป!ซ@ดiƒล้ทบ็้}ณฮะpLใ™kๆซขถญฅ‹ฎฦvชถฒ3ศ„€Hำ์ ี% ‰a็Q!]] -ณน™พโY•ฏปสตๅ›‚เห2=\.ˆฎฟš—?ซ{•Uถญ3w”ธหvPbฮmง?|T BH‹ท†้ชZฉ6ฌธm\/*HjันTwD^*ปn‰ฌน“ฯ„jkื๒]โ:“"฿ยฑ}žQ{ฏšศ๏ืไE฿รYs!ŸฺW&=ไปีufJฟ›`ร=๘b๗_9“฿ฏทŽสป๘heDภ๓zvุk $LแฤCˆภ‘nร๑ฺqึล…—Pััซ4ห์ผตa"าสต‰i_Zี’FŽ&RžXiทไI1EฤGว’จฆc๖wูŽKžส๒ฌu๙0ฌ]ผภถQhQzo+cบ|7'ฤAgนwhะ+.Iฌว!บศฆๅt๕2งฃ2่โทfฌ„p•)ธณqฆW‹>pŽษฉํZRA)5v อ5)‡96.ˆH4Mั~0ฆฒDฤฎdไ๐๚U๓*oeHบ!ยšฅdWัฒm฿0…ลE฿ไิ)ูฟftv -UL๗ท‰g#ก๚r;ฑDAq9 —cฆh*&ŽซhฝผeXPฤ'Qใ*IOzศ[๊ฦฆ˜‹|~E๐}แว_9H‘5C‘ๆืีp,dGa€=R5fqj.m]y9ฃ(ื˜ธk{สฃ›ชฌX.ฯฅqซ|ว™ilvี[Z๘ฝัcš)xF—ื ฤหคIฐต4*ณzหฺ<‚&—p๖3&ถสT5uv่ผ๚ฤŽf‰ลIฃีDถฝ ษฦDึ{—vฒไšฬrฌŠnWOS*z3.Ž+vjศG R›‹=ืaUxณ็์šฬcAลฒๅ!วmาถ๎SVjฎM˜Qœt<Wแ[elึโ9gพŸ{ืYw ,|ก˜Gณ‡ฦ,Hฮ>฿6แZถูv_ dํFม-"มฟZ๋‡}'บฌฤฺ 1สRs$T๓™Mพ]ต•ณOผ‘ฝ๑y2๏ฅื'~Eแ;ท{J๘-๚|ฟวVฃ;YU4*ญญœึDimลตž0mlีa2nI๓ฺP๓7]ว}vแฺnW^E]‘ม€ต˜[H‘'(’raใt๑–Zuืุ’ฝจJ็EDี>QE,Z,šธ3›ูต=7ัๆ*gใlร‰4œQ้์nดเ"!๒๐๑M];Œ ŽwkeUe2ฎฺE]งCซfยIต์<ๆ:#&ใจJ/6 …ใดYma๒ข\ม…*Cjยผ๕IuM: ๘๋ :ฺ*๔ีC—คwห™ธษ๊{@ฏ~ยจ*๏"œvชเุ@žk&|V™.›ฎyฎ.๛๎›งŽฒๆlณฬbu(ีวq‡h่cฦด—.+qืคhจผ]]}Yeธพ!œ;i‘ใ9F=ci^ำŽุ7dยK‘ZแฦYD้บหf]๖ก›etฅ๏šท#++ซLrฒv=,,cภฐ‘=€wค|T‰ั๏โ-ซผู?&๛}Uฏ่ทณู8š‹;A’—ฏโๅทถš’!~ฬY๋ฦuOqว ช7pู้#32kuU_Uีœ|o‚ไ*ั’0f?1>ฝQZ‰TหฆƒแฤP[โ‰๙Y[?ไ๛ษ฿“.๚]๒wไ^รปwฟ๔ฏ‚฿กทห๑|udน;Sโถํiฤc์&โ—‘o%ึณมฆ]' #+MŠทฑŠ"บษ’‹%ย!ZWXใ๏ภฐ;)†ี“๒ขy-ถQy^’ps’9ฤS’ำ=2๎๑? ชx_+Kฦ ูุ6ฌG•ฦ•0bฦ 4OGฺ$,ฝปูMGลae๖ฬ๙3บฒไGฉhเ2แฯœMšq๊rMผSัฌq๙vดrkJL†ผณ$†ค:H’P8‘Šlโขฎ้‰rpuญกi้ฬ2ใคHป•>ภZdถT>็=งฺhถST=ฝตำน8ืgUvVถP๊ํฃีี๕๑ห6ซเK›`ร!d"บmฐ*ค‚หŠh>4ฑฯ๐vu\‡ๅๆioh„Hr๒m"ณ_•คn๖ึc‘Iข>1#E4ๆaล9'ปบ sTTึฏ5›M;eY sญตไ(วำmษ@Jƒบช์šฉฌฉศMเญผ@› :1Dy*|Šบห˜ฝพฉํ %…„๊๏!xp่ฌ๋คผฏูEeขโ๓อ†ภjพ;ขmบ๋.f฿(ชร*ŸTwฑN;uP#AžK&|V™.›ฆ#ๆธป๏บnž:–xfq*}ถ9‘NfSี๒โKฟv๊จ”ศƒฬI!qธƒอFHZy๋ฌ_ณZšiู#,J_ตผืMท%iวd1 ฝล:‡ฯŽํ๙๚ํ7*์ซฒ๚จ/ยถwjษ8เุ„ฉ๖ย$]œoFWžlฎ 8คโeู ืf5ฯร๏™ฮM:ึ๚+ึu’$ญU6ฎณสDxร""wpฯe_4ไ็f`7’"ดภป!ฑฎYา'"UUD}ฮ#า_ยฒศŸ“\ๅ6G0šjmหฒขšฟ] ๆ—๘|พ:จบธลs จํืMฆฎš้ัKf2บ@ถ,+k™mีูฑRyะ'XxแOบ +“”;iบใ‘'ผณ3„ฝgœ—U 1าู>[kิO3e฿T.ุ็๙ 63VๅK€#5˜ูใ…i5ฆว0ำJรไ๓ .{2 ค›jZguXœœIฌ:-=ด{kFb;ฝ+{ฃ&ษ„‘เ}RtAฝืชกลW_ฯฤŸ‰ฏๅ%วฟัฦวช›ซฐP๘งa ้พ_๋:$ฟงTีX4.ทsจคฏ‰UYผศ)r;ด 7L>"›‘/Šฎป<มฒ;#ฑพฤจ.' ”ป๎8จˆˆˆœฝล๑ุ˜‘ว—๑xิตฌcฅ{ฆ่ฅHำi[xpžฦคJHชซฎว;+‡ธ—&ฐ\6–Ÿ `ฃ_UTใ•ีทqƒŒqํเร`’ †ฺ‹ยIฤˆ} บ์<~ทฌ!า†-Jอl9าQLศุdAง\AqภDRDุ•SU5”U„‚]<ีต๑Dอ\4ƒaน*’๑U_Nป์ฏโ_๔šภpผZล๘ง๛ sฃฃš๔' CvUc 4FfญฉqR]ทึ'Žๅ1ใ๕+w๔๐-{ก:ˆŽœ3˜Ml›“j‹แฌWลโH!rK450ชฦSบ’ึ บIบขŠชž๎„ๅmฦnv9+Ew9ธm8Nต%ู0ใˆุ“†B["‘.+ฎษป3ƒ: †fB›ลฃK‡.3ˆ๔iQdณ ท4BEDT]๕,๘8๒แMaฉQ%Gtxบฤ˜ฯก' "ข๋ณ\šๅณ๊ฑe[ŒSฤ—ฯใยu–‘X_็นูฮูฝลฒผฤ1๛i๎ Š๕&OŽใ‹ฒ""n^SีำาEiฦ"ำีืฤฏชŒหฦN:ห๑""" •UU}:์ญv๖บห…‰‹ำ265– ๔gึสlYโQ฿Qyธ|a]b8ลf/`2ย~7_AU†hOoฃ8%ำวhcธš๊kอ< tืc•รK“Xถ9‹ืK|ฅKŽาVRB“$ฺDˆตญ6j ฆBซล= ฌSล#Mt_™ขซขb[ํ‡L’ี[M ’‚"ฎฤฑšŒ†้_[›ฺสธ6ห&BK’ถvqZ฿๊:ˆ้๕Lนœพ>>ํ-NCO)YYU7•ะํซdฌw†C เใGมมCเHŠž)ฌ~“ชGœ’•˜T j๐๖g๛smทฬถNEวuวX–=”ณ ษศc{Q อb๘8QNP6ฅถลมS—X6'ˆ}H˜์Œf•๊(ฮ*๒W#ิธสฐฟŽโฐ,.5^ใI๋ฃตbžoนี39ƒํqmฑ้ด‚;ฆjkฑฮสแ๎%IชšวhVีญ#"Bึ=+–ด‡ฃะFัแว†kณL5E๒ว[บมลฉJทs’“a…ŒWPxYxEึAฤQlั5W]KSตj ]L(ีีะฺSWธฐกˆ6ุ๒U]€Sลuูv:วสKำไโ”ŽH“$ฯจrf3๐ฮ)x๓w’4 0ุ2ห,€ถำ-6<iฆรdDDDM‘=z%ฎไSโ<‚ Žค[[*ฆwึ †โณe1dฬฦ๑ŠJ9R"๕๎์Šฦ#o‰p%tE๔ฆป%›„a5กฝ"_h:ะlh๊“[เ”ิ4ูqe „eภQQ7-3๊h* SW1แ๐pซbŒHโJž•โ)ษ~U๑ึbX ๖=k^ลoWต u5ฑN›่ญบ.tEEุ‘u„bุผ™ยญฬ•EG][*C\๚ู1[Vะ‘ๅละšจซฝฉ•วผึ\ภ‹g_#sผ)ขm–สˆฉศ}:ภqnลั0+ z ุ3บnศLeดpAw๑$ั๗—”๘ฯh๕Bี^Aพ†3™ใจ< าีด๋Dนtหq๖&อ†หJ3นa[ๅ”ึชป’yrบ‚๊`D^k่ #mQษ_pm?#‰Uู c“–ถt่ัฦ<‰I~qŒำชHงฬนฦ/ชฟzํๆ—Uำจ๐าฐ จ ืŒŸ…’ใDh&๐ศiญˆ๚œXqผ5ูถ wrfŽ=gi‹Rอ›(ะx M๛*O์žŽช–฿&ฃฑ$V[,f›bV-^=_ิ๊ฦhdCcŒX่‚Aธ6(‰ฒx"kณผBื(‡QNห––๘ๅT0zฺh_~KDDL๑ูต=ิ6๓vี%FCO ™97•ฐญซ_(๎ฃ์ะgƒˆ˜*‚ข*x๋ฑฮสแ๎%Iฌv‹ซW”ตธ๕L X )แvJรญmถ๚„‚(Gวuู7๔kณŒ*๖ุศI;‰ล`%‰pqUรb:มฑqw\๋=ކ7N”ฝลฎ_GขnlˆŠf K๒ฎซk้๊`4ŒAฌช‡พพปฃ1!DmฑWอDืfธ ๕ค…E•ึŽฺO}Q8ขฝ2tspผฤตOW_E)Bb– |H•,ย4T8Vฐศดจซปh|}์›ณมžŽ#ศ๒b4{ ่}D|่๔ะ๙x๓A฿๔"-ˆ ข‚&ศ()แถ฿&ป)์๖M‹Žฎษ{ขq^xห‘>๛dว5_d*_งM5; ƒ,0หbำ,ดุ๐mฆ› DSมdืg๘tŒฉน,rฑฺฃถYช+SNi5ฬŸ “ƒฤชcฒlฉฌKคบผqืnญ๊(j๋m.~Bห}หI๐ฺdบช้+ฆ[šฉ/ŽฅTฦม1kป ีนS%3g:$วกงwซŽห&}$6„n‡wดุ4ห@-4ำb€mถ่ชŸฎว;+‡ธ—&ฐ์Zf)ข‘1‰XLŒz7w.q๛ฝ+ญ,`เJช[M—ัฎว;+‡ธ—&ฑ๊<~—›ฮy"ŽฆMg9?้' 6[น๘๋วฮ๙uู๖Ct้-ญN7Qx+ข ๗BTv„CE^hฺข;๋ ล+fไ [้1๊ˆrฎใ9ฟR=ผˆ์‰ษw”‘uูฎำฌๅ|RŽ-Zฺ๔/•fOHEพบ'>ƒหo Qิcต ›5”•ั*เถใ‹ปฎŒXBศืฤหmี|Uuูf2dษuษ$HภqWŸ๛ฦฎ<๓ฯ9HŒ‰Tˆ‰wU๑]vw‚ใVขำฌ %AO`,<›<ศอฎŽˆ'๘รหe๙uŒะe5u˜—๕-ุaๅ v็ รe:ร๑ผX%q๏kEOตู|>'{~0 ปทษิ%R๋ [ไ C%9)šๆผ—“Bบผ9 งMŒbMv9ู_=ฤฟ้5AKิƒฎพ”pi๋ม็ื“ฯ *เmด#_.;ฏหฎอ0K{งWŸณฑลi%ฬ”๑ฺอyๆU_/ศN๒T๙4ำQใฐุ2ร ถ-2ห-ši ูEEdMvw…5“Ž๖ทกŒำšM๊u{๐หFy ผUไ^jพ’ึ)3•:Œป“5EV@ใ/&ฮดๅศ4’TK๑…\ู~]Sีีพขฏึืฤณ€๒‚๒vะ6หe๑Mว]เธีจด๋gA‰PSุ &ฯ23kฃถโ 0๒ู~]a˜ฮPฑว„go)k์dF]ิcI’ใiบฏ€kว1fคจฌกกฆVRิ`)nC'U>EqW]Ÿa= วn"Yd8ฅ ิ๔Šษต&Y0ใ1R%ๅฒnปzuุ็e๐๗คึ=KyDHสyฺฒ…bwtฺ:Œ)@Mขทfจ;โํฎอpCวŸๅV่ไb”rชาื Qผจฐคฐ`ฒzDM๕ี9๐U[xjำฦ/โุAs%†้า5ว†๋.ม‹i ป๔‘AAMำะนog7Iˆาะ8ย\D˜u๓)ํ#Cb;]’!“dFdnข๐๔nจˆบzš]ถisf8“UrdLZผzสูหฦaIeฎ/+a ้๒โ iษPึ›}‡6^eเyงƒ:ู๎„$Šจจฉฒฆฑls‡)๕*&7IYGLžš5bฑฆ„ฯŠ ๓$฿dD๗; ์นื]2qว์7pื‘™™DUWลUuู๖ŒY”w"–=ŠPาฯ(ฎ›ฑŠek นำ%R[*ข~Mb˜๎S:ธQ›ฟงk ิDqศe0 Z"ู7&ีXอ/ว็aะTมฉŽ๓ศ<:๏ท ๖๐ๆ{—้ึŒe.@Bv๚–พอุขฅฬaู`D Jžx"๑/•X6gCUหษ”–อ,สŠ๎eศป…l†I–w_้‚hถ@N"เˆ‰เˆš์›ณ9ฒไ:ฉx&-&C๎๎N<๛ัT‰WๅU]UVฺT>ะฐUŒณk^d6เหฐd‰4B›&ยฃถป1มjญXqaฉj\7Sะไ'บ[ฒฟฅฎ:ฦq์ชพ<‘›GM]y ‰€ั0ูf . 8`†‰พฤIพสบ์sฒฟ๘{‰าkกฦ+ไว+ฑ๊Š๚X-ะ”p๋[mตp„HิwTM]แuw’ิ‹HีDY†ภVๆU–“nฐ‘ v๊"ฏ=๗ึ/โ‘ฅบฒŸ‹ŽาVัฤ‘3คŒŒ™1ฺ๊lL๘ˆ2E]‘]ก๖3&ŠษุOสfKศ/“•๓te,ิrMœlU/ฃN0๔สjŠšSฑ”ส3ฒjฺ๊‚๛‘ษัPRQR]ฝ(šฯป"gษฟฌ…_*ปV์โ๖O8ิ(’ฅ1T{Hฤแ—บก/งRซๆฺใฐeล™*ฉษ.ืบoฺฟ8V3’ฺeลN.Š/&‡ว๏๗^ชk*”zโ\ˆQพพูซY)ึŒหๅศ•€ ธxขฎ๋ฎ™7Žำว‹%๖วˆอดwyW/๑({e๔r๗Ÿ๗๙%๘/็!~จŸผ6hqถ %NR€WeOสžฟฐd?ด๗๙%๘/็!~จŸผ~r/๋a๛๕Cทฑ›๋IฅnสGi@\G_ฎ๋๑0-ศ6ุ…~Tื๛ึC๛Ap’_‚r๊‰๛ว็"ถผเy.tVฒeGr>8หฯ;^‘š้Hห/l'หaัฌj๊ศ๖ัi๊ฑ่าแุYฟ"1JzC_ม#lฐ‚(้ฎ&ˆชHš‹+ขฐ91'/zšสยถrก–@ZWเŠ4>*hŸง]‹vƒณท^ ัC“่ Ž‚ฐ‘๖U๐Mงlฅๆ!oชnะซmฮฝkเใฌพsž= yส4แ‡EEAเ&ั@ทูQS]še,mชฏs ‚ิง/kZj MH– ŸฤŒ{ฒ›+‰๒mพ`๎Aณfธ+๒&žfTฐDbO|ai•้๎็Šพ"พ?พฑ L์f‚mค8ึ*โB‘)๘$tHc%AุM~MAฏญณฟ[ไ“ ฉ$ค|•’Lฅg ’อว<ๆใ‰#_9Woผไ๚:T—Y9bร›คwๆY็gถ๋'ๆ‘&ฮ6ฉซ$ทศํห%K ‡ฝ๒~[:ฒ'๎Jฦ™`xฐหaๆ6›ํบ๎JชพๆN/’V2Cภ?ฬ˜๓^B*๙๗lDU้D๕ฤaวO]๘๘๏ศท3^ำฏฬฎŒH‘๎lช๒*a;ญ!ฒ ำmช‡ ๖WuUืb๘n9สbภ…&SถŒ‰bสศV ฺบจผKล5ุฎ=Žเ๖ฆNZdPค™? ืน&,†@ญ๘๎t‡ล’๐/B}๏iXŽ+„ำbง6u5ลL ึฏูV ™ถ2#น.šwƒŒฃ@ุฌ‘NHพ้[ดพทƒุSE–••]:ึ1๚ูอG่S1ตูู—2/ทู๛ฅ2ฬ9ช าหjธ(ฝZb;SA๔ณa๐๐{‡ ๑wๅใฒLšๅU-Mฅไgใ3‘X9i †ยึtHo๓lž๋8}v-“‘'งฐ|Fโ‚ุrบษ‰šjPG’p 7iลฦฬ|แOFฑฺNห{R95˜ryฒ๊ฃ‡‘ฃ9O{4;4$IŽ>&*ๆถŸฟฺž7Aฮ๒Œ]ฉlใุ9ัvšnTล5„7ไศค„๓fเข+บ"๎„…๗ะ*,์— ชงjืz๎Ž๐yวTFญ˜‹Jฉฑz7๐ำLฑ/!ฦ(/%1ŸwfEตSSiŽช‘pqPyฎ•๗k.r|ึ๖*IวฑZˆฏ‚ฮ$6‘j`M6่+|ZGž฿m™TT]aด˜‘cxํ•ณฑ#3pลฬK7ชึถศ,ž$E’}D่s@๘งน`•Y,Zw+gฌH3า9สศแภ}{ฅ“o2{ด้žฺํพ้โˆบฐKL†๊›ึSา$(=แศ๗าแ2]านถ™ ›lฬm=ฏŽ๋๗ฝ—ีf•ุ‹ฝฯ&ศไtเสuนยฝ{tvฺy[>่‡(tE\FวฤG 'ดA$9ePษพฐgว‰- ฯr+R”œeศฮ›bใ$๋œ„‘ภ2H็jX…Of”lFฑฎวŽฆvAวS\์(2’ฎ8œๆฏšพ”๘ฉd–๙ฑไฉa` Wฃ้_•ฮฌ‰๛’ฑฆX,ฒุyฆ๛nปชช๋ดฌGยiฑS›:šโฆ๋W์ซL—M;มฦQ lVHง$_๔ญฺ_[มฮ์)ขหJสŠฎklๆฃ๔)˜Žฺ์์‡K™—Ž์ˆ‰๎^ฅ žXต“ค-]=ฏZ‘ไJ่๔ฎcศ๓ภWŠ†ํฃ๊H•U_%๗8ˆsy๘€๋งฤ7UUูmd58พn๋ี๋Yswฉuั™n{nXƒฬ=pชนฬ^*ŸาขRไ๐'Eฑ›jอ?Fƒ)“รg]W€Onช ฑ&eฒ.<}nBช‹๎๖—uู~g‹L~dสศอฯmฉ‘ฑ•ฮผgจD…ฏแ‡d๑๙6^ุญ๛WKQซJมตกn—ศK dwยcง2_Sผ๕Zๅ๑x๔“ำฟ‡๏xฎ4๗f๔ -/$&๎Vzิ1jPฅฯ A!##ฦห/ศŽ*ึSฤWeืŠ/Š*|ฟ{๗Ld๕u4๕™~i[†วล˜๎๐แVA~๊6<อชุ๎‚‚ฺ0๗oำ]Zหผพฒ›ฟฺN!9Rปฆea7T…<ฦZmด๐๔ k๎ศป>ฃ˜‰ŠภลYณ‹^Q`ทKอ;(๊]gž_‚M”ถ๑}d6-ด^ะํ๊˜ŸdbใํืฑŽีJj(จ"yจใฮš~’]^ฅ"ไนlšหญ๊้์๛ไ&า7ฮ๑฿้~s\Kวำซิ๗€8’Yฅ’้๗๏๖†รญๅN๏฿?…^\{ว“mผ5š[แ9p;6†t }„ฐCU{เp;สˆ=N<š_996†=ขaŽc9ํ87ัF-c™ดิ๖™xŽ“ˆกฟ˜๋n‚yข*ฟฝ:,D…้rŸ?ˆฬxอซฯบ{|‚(ชบฒMƒฦ”์cˆbย[$GTยูฤE"D_-”๗ˆ Ž~๗e:็“)จ9>;,ล๔ฉIn …KŠˆBŠพ$[!์ฤ้บ/ฤ›™q_ˆ๔y ฃฬ:„*ŠŸิ?๗๙%๘/็!~จš.‰Š ๒ๆ็3ๅษIทอ๎Hi\qฮ>wWcDiSmถOGงั๎HlI’ูyuฅถโษทงำ๒๛ƒbุpQ>~j๒ๅฬ8งงูฅRุโ&๋้]ฅทโบt้*‹œ ’""๙จพ)๒~จM4งeN#eิ๓ทเH;๙ฅว๏ำˆแ‡-ี7โœ‹—฿ไั๔อัูวoŒ‹ฒํ๒/กt่ธF๊š rเ ลร’'๚%qณ4๔‚๑BO๎ำภ}^Eพ\|โไ‰ใใ๎DŽVeGนคะ–ใ,I <ฉศEIw$๑๐฿ะšCXฌg๎Zp^1Vฎs,›ชžเ™OฦQืj–ตูถิC3วzเใŽT$sgํลฃŒืšGบ+f?"Žฒ*œฆ!หmSoHฎsีvฦ“Y่8็ฦE2p๗O;Iท๙’ษ|"ฤชT]ฐd=ฮ——#G‰[Dฏ3ku=บถ&ซn! ๗dtคฃdŠ'ำโพ บ๛ฆฒˆฝนฺVฬบm๕ฝž‘จํB“ก๖ปฉผ^<Bต,6_เ๘ ๘ผํล•T๛ 2โภž6l-๊dื5.พล๙1๘Jx™Gมy๒eๅิU]-–e „W“^XผS ‰ถ%|;G๕%&๚hi* ๏๛ฎ8 "6๑ธถv7=ฃf(–๙<‹+ UีB~=cxศQZๆG(ร๘G”ผโknั๓ZœJ 3าkฑ๛nฮๆมสืล”ฑณด )Mˆb‹;8แs5ถ๖ษงdธณคฬข[œ"‡)Š๘ืต๒"ดโš4ฎภ|‚SMชธ"I๑|{Yด์ฒฌ}…-ิX;/_`ue,อถWz)๓uข4GฆศE5ฺ]i}ŽfะJ—-ๆ;5์v้+šรLผ๋Ml๊;ป˜ฒm›o+€‹ฌถฯ รk 3;*‘H๙56าBใ๚du‰ต4H็; ซbแฦ'ฒ๖ญp๏gnย’UŠๅhVฒํ%๘&ใท"ฤE]๚3€บษ/6แŽฒมปT๕rล››ฒปZZ†ท†m)๙ยRูฯใฎั๛Gก“rWJšXqชb๙7'›Rี—Y2Nbย8{—ว"]dEˆ=ฺ„ฤศฒฆ]q™4ุ์7ฃมqึ>ฐtฅฎธษ œPูยื“v‘Se^vp&ฺน1œš;ๅะš๙B๎l6ผUP™๐[Šข’rYnใถฏลญzสEl—Z“[)Rum|กูมKวWPบ|“๑;Jห']ฮฤฃ&wGhไYx๊KๅŒ8(๛วqyฦ–R5‰"†:>e๛yi๎ฯสKธ…“y‡^ฦด๛ขZ?6D ๐†=Š{zo๗ูw~ฮM-1ุน๋‰ๅXููฝk#ฎFXูว‰f“อูu๑ื๓๏๐CฉAฝXฯ•%๖f1bศ™!๘๑„;Ey ์ธJ!ฐ๙ฉล=ฑŸไลก"Z๎๗#ธ๒%Žฝหบr้๏ฯฮ๘พŸNณœƒชฑฅžล”บ‰.„j"ึฆ(:ไฌล๑(ทzD ็ๆขIšd—Xhณaรธชศg๎9eรt๖ษ`‘AถqŽปRใH4-ม|Jฬ—ํI๖ฟฒ”๚สOžL๋e๙s:ิšœigตUเไ…>๗ไซ$&Bส6‹ฤอ๎‚ศ๎๓š๛ˆcyKgjํ„\Šภ]๊\ˆ‰3f(b(๋/u€ผ8˜!Iผงฃศ2SปybตนๅžษฟMO‚ฎ฿&ฟฅ›๐ˆz๑Zv v+-ˆTdJม[6ป“"A๑mัO1ใqฏ]bษ…ๅsษ,ฑฤ' kGขม.Nฉยฐ ฝโฟฏๅC1c่yล ฅดบ’\ใีA9ฯ ๏ถโ ใถปAอ˜h2™Txๅ/iบ 7s†ลŸ(ฬฬbK@ห)-ถฺุRqำ2-ื%›—Vblฯฐฤฎmž7ฌbบs ฌฃชnp‘cO๔‰ลIฃ _tอƒคษmOƒ‘TาIล๋^i cษฌp&x ชtMธ+ˆ=GIย"4™vQ[m{†ฺฬ–์แ•Yjศ๏@q๏เ†Sวู้๕qD”ฒยๆว%ํฮt—bศฃฌ,.dk ะ˜#Dะดืžพg‚๏ฎั๛G~cUxŽ\”Oฺร*"}๊ๆ,ึดฃฃปฒ)pA็ฟ ๕y”bq/ดล•ึฆXฃัTรdtโCเ๛1อHTœๆญšˆฆพ้Œฦถdk “q‡\ุp*„JไŠศตw0๋ะอโD๋๒%8๒&ฤD’ฆถUอCSชต‘3ึ5ฌุp๏อ@˜เซ 6๚ˆู'.)พฟ๗l๛0kตc&ขรด‹“gมqg-5Dvป|y ์Mค‡eวGLI‚(|S-v••ฺษ›S@ฦsGnQdโืฎ;”@R—S@ˆ๛์ใOธ๓ฤAอฒ๐qU?“nฟjg}โฬ‡†ไ๒ข /Y1้u„๙’&ฺI/v‰";ฎlœษˆธ{‘ภ—ำฒฮชz๊‚–ํฒZ]Eซƒฺษ[dcถณ์Zy€จkเ(Ÿ&พ้›#I’๘ž "ฉค“‹ึผาว“XเL๐T่›qWzŽ“„Eถi3:์ขถฺ๗ ต™-ูย1*ฒ(ี‘€ใ฿ม ฆ'ฒ ำ๊โ‰น)6E~w1บฒื๓?%{_า}ฏ์ฅ>ปg.วฐ่ท นƒ๖%Rduฏ3๐uญZ>๋*/"Š๔ูU6ฯš‘ดโถ ฎูฎฒด๏า1ค“5hิ–กบรภ3+Fš ๐: ๑1l‘vP๙sตŸ•ฎีsY]คc๘ํ^DเŒถซ๑ธ•๑bฒฏTc1!ˆษ‚šc—zqICแ™“ˆ๗zฟ้Oฆน—แฮdสK+†sQจ๛ ำฮ์›s"ร_ศ––zaฉ/ใX๋qŸ%$X }*ๆ!๑เo“b[xํ่ื!“ึvฃu.อ๘q#ZปผTXpเAއž€ 1œeฑd…ฑ@/9.ฯ'Ÿูsy#๎›าญจ-RK0ั็Nฃ#†โ‹ฮชšƒ€%๑w_ๆฅฯ๊๗_พƒุ5i2-ธฒวX๔์ฎœ”l‡๚ฬ๑๒•'ดFณˆ๘๓ู8ๅnย‚๏ฝเUF๗yUV—=CsCMKq-ฑŒขบtฆ&ๅ7G&’tž`ผ€อ่๊๚~‚EO“]ฆf‘ถ(‰าึฮh*™ตๆๅl‘fƒ๎อ5wfฤ@ฺ้ฒ;6จDjถถVQ)_Js฿˜๓ึ*rZทใ(ถJน\aว#.๛ทหa^"(6o;w€Mผ&สSฏืGy)๏œm๙Dช‘›6โIiwูRB—ฃS,‹g#ย๋“% ‡xmฃ›๔ัุตmFmฯ7ฤฅmพฟขะ?dๅ๋๘นํํงน*^หR๊]๔Tฤ-\ธฌ๒ศQ:’Fะ†g|#|๘๔๘๊]๗ฟฉ๒:ฤ๏ผƒ|š•|’v๋s้ฆ๛๗นxํท‡นษบฌ›ฎศeฤdPY๒ธลฆ˜ณ^A๐NTีๅ๙^_•|t๛ัKj„Gpฺqdxง6ีY†Kฯดlr4|†YKid2ฃ๔ๆ1Yฐqdh‰*ˆHJบดฑ~ ๎๐]‘!NL7'ฃคึ‰พ(lM‘ ๒ RŒl0๋ SMษo„"d(ใž=6]kžํt๔พๅ*{๕tQyีap…๗8ฒซวv#คfP‘n3eุคf’;Kj|iAฬ[o ๎‚›๏ถฌฒ 8ถvlฺผ๖E2ูMพจฤN›.AQพ-"์ ซพ?'ธ๛Ql์โF•M!๏Bโขkv•ํพ{/6บš"จ‘"*ฆพใซ<ฏ1วX*Zศ˜ธษฏฝj1ซQ$HฎhพM7ฃศp]–แพป3Žๅญฤ™k; ์า‰ษvVจ, SnฮxT[6:ŽฃวN`ำ6๘†o•—cVฬฯซLiš‡๚ัBฦถ`กฮ=ษดqค%C~bฐฮƒ(ยJ๘—๙=qOHฮ๑ข›w2ฺF—diลU^oฆ๘ซŠฎ’vkcฺf>ๆCK9)๐ษ)f%c๎Eฐ๖ฃI๏1Oƒx‡‰2จ$ผ„—Ž#aƒลณ‡&=ดY0ๆ<๔จั๋#tž >LEฏa)$ศ ฦ{ทเ†#ุหฝด๖aฺ,น–เ5ต Xcาeฮ;gVB4ฒ}ๆSจส6๛J ีC๛œh;-์โบฌปตๅ+uyr฿#‹ะ—T๋ฃภเn6 "r๏$[4x|ฮะกป˜f1VฝjŽ7LธชิX@์‚mุ}%mๆ™wค๋{บ=5D^ฦ&`šCG‡0ŸFณnD†L„ŠE\็ุ…๛ฅฎ*™mไU5'ีeh[rๆ๏”อ[.บ „™ฬอ^waฉ6ก ข–ไจ›ฎพๅ^ีฒ๑ง.…ห˜pr#K[\‚Uึํ7–S{y้๒…ว—†๛%{7y_f–’g๛yถKสฉวœ`ช#ๆรัhปงTusเ๗…Fk!๘Lฯ–bK7แ๕Qi}q5Œu!Tาภ—ig-Xห๋ไผ‘`Auฮ ธ\EvR_]Tูั\Aƒrjฎ Jฌฒ†Nไำ_leAš ๋j@Bb„)ธช/กuC;(ฑฅงŸe ฌG–ฦ๎LH๊๓5’;OŸQๅNม“]ืภWัฏน›ตชP์ฺยžqำž;•Xฟ’ฒ6๏ีฐœ”์ฃะ:[ซGถผ}์/์ข1C๒vษยลท๎ก_@‘sะ<ฉ_๘N%ฐšniพ฿/c‡hุไŽE๎3“แq&L‰-๙qZญAqศ‘ไ€$†ใ0}hน๎!"ฆ>๖i›ท6?‰ฬBPl'ณ&D‰ัAy•eธ‘โฒ8โ+ฆM‚(r๛žฒพูgๅwฆb™%~,9L>สTย™ T๖œŒ1ทYWฯš;โCฒ๋ฑซ†qี`%[~๕#œ์s•[V[ุึF(เตiฃJEF€ ฦหงฒญ{–๗Tู%NH51ิ;ๅ„XQคภ–ฬ5D7Dd๕Qฝ๙ˆr5_นด๊81"c8|ฦฦ.@ล\`Cjฉ๋ษ@(6 'ชกIDDด๙uุDุ{•Z^_1_-บนๆ”ไฤeฆ7NP—แš$โŸsพGุ„ †l2|ฎฮฑjฐ›f|imHขิQzE๎ˆลไใคโ!ˆ๏ฎฦržื<ปๅฏ){ฺ[t๗ฟไฮ้๛๏’ช์ฟาปรฝ>}?เKn~<~ๆNิํืด๏๗ปไ,บT๙s {ฟ•ผˆ๗_ฅ๚_่อ๒ๅหอŠแYึ7&mิฮฯค ‡2u๖IะฐนŒEyูMXฏ ุLลIHPพ็ถ‚{5T‹’ฺK‡xNYอ…‘ย3ญรฑฅ€2d>้Šผ่๓$Œภ9ฬˆธ*ิูัAljฎ Jฌฒ†nd“leAš ๋j@Bh„)บ*/กue]วไืศศLฉaK”Um$k‹”็EL้N๗ห๑Lม}ึั่“cฝK%บ ฑไ6ฌผฺจ๘๙ยชž์›"ํWณœ‚ะmq๛|dlVyE„™P!หFžu”i™qŸh š2 บ…yˆaW}Qลป5ทmโผnถ >ิIํ จฌลŽืOฤYY.ธO(mฟ/น๋+ํ–~Wq*f)’Wโร”ว๓์ฅL)ฅOiศภ3u•|๙ฃฑัพ$;)ปธgํVUท๏R9ฮว0(ูUตmม…ฝdbŽ V‘Š4คThะœlบ{*ฯ=คdึใUBฯฉ๋ฒ ‰h๛1ฌ•,*—ฤlิ˜$ ‹็ ๘ข๙บ๛œปN‹ซ‰ฐ'gV9]]tlƒ$‘jๅŒศrช8qฦO็-x๏ศw๐์=ํ๖ ,ฦฃ]Iญ…*้ฉ5ง ฏซ–ใ"้xT4๐Jฬฌdw˜ปzvAส)™‚ิุ๊5$ำ‘ง‘ษ๎ช๊ŸT| m“mืตํฤg‘ไุ}Kง8๏๙ฺ4ู=ๆพ›)ฑ›Xฦ๘6H฿?d$฿๎nถ์๒›žZืqช๚Lป$ h[+•อK ้รƒัR]ีี| ูทv์ท:‹}+,‘>ฯ gบถศ(fพuxค8ฑEๆฤ๘‰8ภงž?•7์ )<Ž๊–ณ‘—S3msŽXิ,vRE…clม‰พ ๓2ศคHแŽฐ›nะ๓qneฎ%Œ๕฿ฐ‘e“^๗‰ัใ9Yjš@nGmฃFT‘PWt๛™ปZišŠ๕‚ธฏฝจ|bV=ิKŸ#ขŒŽฎู~/—tม2ษงdŒ]ใ-Sไฬอ[ส1vบ๛ฃa“]sEDFผzdˆ{๚>ๅ  ุRNฐ ขš€,โ3>Yุ$gฎ™ฌœ/ ›†ญ8)‹j-"ญ๋ณ,[ณ‹[Y']UAบห1๔5rด/เ!6๓<อฑๆ็"O8šiWฮj\ฏu๎SJณท‘ณโT "ษfึU,'[ฉFN.< ๙ถข้q*Š—4ฑฌ7o+Ž!ืบƒ1ึข>{ˆŠรว_q•DเFฃฒmถช]นฬbhฤb=iส๛ูฐœึIดา’๐โจ)ปŠŠ จต*2uบฒ‹ฝิ ห*VAข‡e&ฅAฎŠ“„๛Cณb„-‰ขyญo–2ฺ์vึf=[า9 .ัˆ„q[๙ฯpฐ>.*#iโZฃ›Zๅ}ฅ{8ไ๛pฑyv ผรฅkษ&ŒBว‘ฟp…UT<ง gๆIq} ฑฅyใธQWS๋ๅาtช๊bCฅ…฿ฝš๊M ๏ฬ2HqPQมU๑W/“ฤ๒ฌฆVO’ย+–๑š kฮํKH cดไซi—9ั[๊l…ภถ฿o ?ถ‹ŠG…3#๗อ—n™:ิฃ2.Fs๛ฏ„ญF‘Ž—โ๐ใแฌ7ซฐf‹&™ŠFฒล๏c9xAŒฟ[*ฏ๋0่…๘˜ท’’พŠ;๒ีึ7l&D๙ึ_ีฮงฐ*หล ฤqำโ——ไึ%“bฅewŽป\™ ฅฯi†์็!%›MuD9‡% ๖ไ›๚SO G{Uร2< eฏฅI๒PะฬymP๙9 LN‰^Ž„พ*ˆญ vฌW –DIท'2u๏๖ขfŸขg›/อถ‹{@“—ฏโๅทถž็๔ฉ{๛-K๎ษb1Ÿ™6dงAˆัbFm^‘&Cฮl คDซฒ"oจฯวกศe†…:๐yJžฑc5&j›*lอ}wฃร™:๎ฺ๛•ณํf•ฅSƒถ‰าˆw #ล-‡ๅ]ผ5Kl์:šhZหnบaฦฌpYD&์โษ'สŽ*jฆฮu‹ัึพ|จฃยž‰!UVงE฿โ่บๅŸAaคูqj ƒ`ะx+eSรฤ๙.z๐กO1ูQ9+lๅ๒งT‰TD๙5Œฟ•รjึ vตี๏[ฒ':มbฮ†ศด๏Xc›DB๓„“ภKX์bฎgZฌ‰`หฬธ๓…Zต1˜i% fโ fใฮ> ๓๓S๒! ๘Eผ9mฟบ wYrlQ=ˆ$คs๙Ÿๅะ๒นฮํฅX›ค›qjKœผSจ๙>็้ ๙5ใ*uzœ!œ๘.„ิ‹ะ„๓@*ฟ‘tฝ+|Y–ฑหx.n2"h๗hf๋G็"8ศŠงฦCล]Vทyc‹ธ:ฦ(AbW~e9xบœ•ภqก‰อMัuุ#5ำส\_)Kศ้ัšุฌ ˆฒู'Ž฿!ต2ไ‰๑Z2XEžXO<Šถ€$›˜j? sŒHฏ์ฺlมŠz?ป]’fื๘eBˆw0{งtY มw‚๏>]O‡ฃ๔๋ธทด•ฆCธฌA”ถฑฑlLwEธ๎9ส2’‹›ฐž…]’fำ& ฤซน`ก๗๋&งขฌต‚|๘๔๘;๏พช&bv9)5Vข๗yญ›]fง\ฒัๆš>&l4๊/๐฿มWฒฬ’ึฃพEจ<นฒมวฮCJใัpL[S๘ฬธผ…Š๎บŒ^๘r'’ล๚ภQ7šbN93Šฯ/†puHS~;Š|mำ]’fะG:โ*ๅซนS{กXช$ค‚>[๐ ถ๔`ท˜W“–wKก–>R๏}nชฦ๏Qcำ|y|t฿o•zถ๙K.c•[คJ;!๎ำ ฆƒฮTm“/B|edื„จ5่sGt$ ๓+ ํกฅ็LQ"P?ไ—เฟœ…๚ข~๐แฉฦุ@T‰xส]‘?"xร๕๛๏ฦO6ีๅ5ในฅt๘๎SŒัm†แD8ๆwะTทN?‚ำ?E’Vห…™›ๅh็"(ขo‘‚3ฒ,RUโ*}mฺbO˜้ ึๅตฃ”‰ศฯคอZr*๎ปmใฉ3ๆฤวฉ๋ibฬด|eYสY!ณ"ยH#‚ฆ€;–๋ฒ~:ฺ#ํ&อู๖O# ฆฐvลสบtŠหD,)ธจ้lำ^wšป wšำ[ะี-<qKz๊ดห)ูJแจR๊*ผcธธ)วรmd™ฮ@นีŒคฬฏcคO%,…gษั๚|๛มuwๅหˆz6๑๛้r 1‘Qฺั?: ด3aณmเ;&>&่ ŠMฉง$Mั}9’ C“:kำ์Š9ูYMฐ’ฏป*qลmฆิx2<[M›O“ฟ.+fš๚ิvนuฺhqp'ฮv=E]R19P”ษKqถb6/4หฮDี˜*้๎gญฐๆOeeeaY_–ื3Lฺฺำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸi /ฃOดะังฺh ่ำํ4๔i๖š๚4๛M}}ฆ€พ>ำ@_FŸiคŸr๐oŠื๒~_ม9 ๕D‡๋! บ๕?ไ/ี๐๖ฌ‡นgeQ%์‡„ณช'ษญžyูDH’™ศ\m™ ์พ…ึ{ฯ“+/ฦ่ฤrœชVM[“ฤปฒ๙‘bEทRuน`ูซญบห‰ว‡ˆฎฐ‹๊n6ฯ&~ถm-T —'3˜ฎnUำ์๗™.ฌvQvBFŠป$;‹W2{่จฑ˜ฑผŠfDฏ9Uฑd˜6หฑM—๛ับ๊6ู5N<ฑ[\')nฏห‘+leึZDถงI=ั๙u–ิ๎บษ“ ์—bจ„;ชF“ๅ๙$ผŠlvภV3g.š2์ๆIผcรŠ/Iyxง€ฆไจšDู9’กmโ‚J‰บ~“๛ตฺwjทR'ๅ„ํฌ\๚ุ+แVO6พ1u‰นค ฒเ˜์จ‹โ>Qฺdน}๏Žฒ7XŽถSฑืfฐŠโ€ X#mธฆค ด†Nวรน“ฺNี”˜ธ}$ฉ ึ๊Tt{ง}๎>^Lsฏๅฎๅ็๗ž.ŸŸำXuฦ_3(Šีlฺศ0฿6c๐96f, jศ๙ฤjFฎœฉู†ajฦ*v1๓ึŽM%sธญ…A—•*šขุHeฐ๋ฤDlไHแ+bแ;[w[ฺ†< แุFqิร๑K'!๙ร™*พย‘I‡: ‡bL‰%šื ฉคฐขm˜ฏˆช*/ฃRUๆІฆ๒ฒูโ5\ ณ`Jฏ"iวUHไ0ฅ์7UTtP”‰MWS/r+Y.UK_ ๛ฌ"ท“ฺ•mw{>NบBำBn €ฅu฿๖{w‘Fฐ—‹-œ๚;ชหแซgฝO‚อ• ๏SgwŽ3จžjก†๎บีU,d}๔Žาฟ*Cฏ<1aย†ยmอ้›l2*จŠd›ช'Žป)หฑ~y-;=:}๘๒œฝฐh–'R๓ห K@}แbIS4SA~<Œ^;\วl™ฐ,ЁปๆN;cโ(ุนำ.^•๑Mc๗Gง๎…ช์๖ P๎]ฎt2j|•iแ^ผ์คDsw )๏ษ=>r"ฆ }ฺ?์œj็าำVP7fาษฏ‡*า๕ๆ€ๆ>สušŒา*จ**๘์ลล2ฝ๗Aเ•6ตฌ9]mY>น‘l๊,ใŠชn>Qโฤษ=vrื.+4%:1ูtW7บhฺsE_^ฯ๒l&mษว_sŽุร~Bฦใ]“Rธไrู'ยลwฆ๊"ก nI‹ไ™}•”zช๚|fr$ฉ"D2,&ห6ฃBŠ~Tง€ราช‰ฎฯ๏qื ลห1ˆ†ŠD["สIด๗#ุืIA&ีุาC˜sl๖!$๔n*Š‹โŸุ๛ฏS๐_ฮBQ?a๚ศ{•–๏Iศ0ค*ศ๒ไห8mๅ\š่„WP[i อม€ข–้ถ๚ฦGหPะ’•ญๅจ\…D–฿I“ั]‰|ๆ๖_R๖ปeU•3’ใึšZfฎE3•^ิIิึ๕˜ฌ†บ2yŸuึี ข๊'รs:ธ๘em“_aฐ๒๋YYัVdฌฝ}Œ[hฯ‹๋`œ›–qBN๛ญฉฉ)ขโชGn–šk e]คeอ ฟd่5"–ฆƒ*yืB๊<๚ถ*›‘qีKce mฉ{FมฆB˜๕๑ใฎeRNถรฌ๛ODdw0N22/^JŽ<ุ:๓/Fyมๆ(์y.x๙ภb„‹เจ‹ฌ:ำห๏[dฯNฏปฒสฺ๋Q ชg“qษ-FA&ฃ ใlhจ็Š—%ฆ})1้นรRŽบฝฯ%ัรwzhI8แาŒูYBโŠ[๘๘j‚๋% { ฑม๎ใใฐตธฅ3ธnณU +ฬš2GrO5UdEฦ/้ X๖M+ลช-ซ฿‡‘_บฤIึr,\กDW›ไ๔€Oแ 7๓S}ตูžfฮke‚ึabฏัผึ)‰5-Tญไฬ‰S ภดมu`ัiไVIดQๅฆlผŽ?sยแk‘$i]หส^๘EŽ”vแz_ำ็ฯถ:์ถ๋ฌฒ$Pว&Sึๅผ~ฯฎ[eฮใ฿ใ๗ดช\๋HŽ( ๚}/Fซ'ณFฯdธ•$;j[ี็*์ลrฝปW…ื›m@น์จDž:ชฒŒฟhงอชfDLปg|‚บ๖WšyQQงEU]D•|,;2ึ‹.$–km่๒c>‚``ฉฑ"*/ง….สฦvลƒgฆM™)๊ื˜ัbวB75]„UU}%vฅูี-E–.ไฐ(๋%เจi›ผ:ไ‰$kลc<ฃมฮบq-๑qษ๛=ํBwhถ4่๏Vฮฎg0น)p"Cฒ๗“ฆคˆD{"‡‰ .™ใX฿gึทE๕ๆeC/y้ฮR;M]AMruค:๙ณFndช‰จม>๖ฒหษซjyj์f๖=ำ•FdŠ;พ& ก๙ฝN์ž)€g8Xด๖c.๖ว4วžว™ฏ”—จฤzš๎๛ใ-๓3R'b๒h[๗pSXFsQvŽEฆ9k†ใrฒFm7๏zสขัaฏ๎gTšWธ‚Š‘ข.ฐ๋๚๛wพ๋๘™t๚ฏ&L์g3dŸ*฿› จpR๏ร๐ อŽฐว%ฦ;CE’R]a”32ฉ1,กัตIcAs uู^lร=•ฎ'วช.ฐฌ‡+.ฺqY6๕rฅJศ(๐ิrdo-\Kซoz๗z.>จ[FSA'ำยฎฮวซŽ๕—gฌjวœฏ:dŽโ๙<ุ๔Xฑ†d]'Q๏M๙ษฑฆล[ahnิ๛7ฐอt9]b™—ๆฮyธยJ,ฒฆ๋‹ๆˆ๘’ขjถม๚šฬgดๆ,ฌุ…%ฺ๚๗็ฑZY›1ฑVฺ7ธHL‘OŠ๑฿eึ=Zวํšล`เncoท˜๖ฏOkš Iikีo@Ž@Cฆฟย๘าvฟg‹g๐qkJK>ฬ,3ถ_ฎฑจฅ Iดน-,๛@เหฑ\y•AไMฉ ๎‰ุฎmiE”fๅ}yŠYไV9h ล‘ำŒษ4๛ว0gํ‡Vi=เ7ๅฯŸ4ำฝจ=ู c-tํb5‹ฑsฒธหนmฺ9aก๕{ว&ลอ วd๗๎8rไดC์ุ<*|œ~K*ฮไ‹)๏[wยˆDBํพฑ~าk1 ”5]฿ด‰-•…ค๐ห๙ใู+า‰ศw้ภt›>ฏ๔P]i,โเ=‰ZfWุuผจฏฅN@Y‘‰แั!Kuทฮšป&้ช๔Eูvฺงท;ซ‰ฃ›ีแV9-f๒1G#cง.ใ~,FR๒“ณ฿ไ? ฉyบว/ข2r™ ษจฐ`ฑ๕—†อ‹หb๋i:ฎถ฿_"TWU™ฅbอ๛ค2๋<Œ1ฺ๗ฃๆ’ป4ฐษvยห jP#Ž:๐๔J;ััT›ไMฎ:ฦ{^ Z>/›ย›’๖™'0!๛7šˆ (y็ 6Iฒ4f $“็ภM฿]’๖‘2ูฬ‡6ฑฦฆลฆหfๅฉ๙4วโตo!Vนลwš๒˜+ค๛dเ—ญ—.F)eหสdืG~mm ืุฝ„ดbdึZeก~JDhˆ‘|5‹๖๓m&ne’ไญ‡fwฝ 9ไ5Yาต…๑ว&3ๆ•รjZสลx๕9šx๊…์]ˆUศIŽศธ;๗้Žcว=๊๗ฎ~น6nฉ จงลQD_์Gืฉ๘/็!~จŸƒ๏ป-ฟ'› w($T™&Sปพฑี-ฑ๙}๖ธTEไi็‡สŸู?๛ฏS๐_ฮBQ?1^{‰"ฎส*›ข๊4กoูจ‘•<๏aฅOˆฟ"ฆ ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUfขEPlโtลcดขขกT๐|WmA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูจ0ชวณPaUf ร๚ซอA‡๕V=šƒ๊ฌ{5ีX๖j ?ชฑ์ิUcูฆg–บM|ธ๚9pD฿mไ/ี๗ุต๓ฌjงj,;>ฟt|ฌnXฏy #fช-ธfœKไ๑๐฿LF‹7!กฎถ•Q"ฒ๔ฦำmŽฑqE_Dซ๛อmmฦII_"า%Mฃrbฤ%็ลl`ธำeaV ฮqv๓ผ#มซศ้์คึdupI้าkฆFI$n#/GT๑2_„Qอี%vY‡”ถว'แbๅต™’”*aทA;ูถฑ๘Š๙๊…๗น“ลจ๏KAไšM๚ไ๙o9๙Wปw฿๔ฏ„ผm๘ฟร๏ญ’–๔2:85k๋,ถ‰1]๏ wkf_kฮโžw ำไ]I๏—7๘&'sm/ฃ7zฒณขbdู(ƒAอร"เุง Qร๛ไ/ี๚‡๙ศ_ช&ฃ“\DศOŸ%Tฯ“oŸŽHˆ้ตี็ใษดUU้ํ่๐ฟงŽFŠL‰;ฯeE{mธ7ทŽ_r:ฝฬ:„]NƒหŽษเปฏ†ท๓‘วม|||SY~_s#1ฝผ”;‹ŽšzถยฝุฑฃฌA k0„๙กlˆŸง~ึฌ๒8๓,ฆฟฦฏ—dl =+kบ๓Oƒ๚จญ~็M๘ฆโ‹นkด‹ ณ&M5]E\ื"yrสฒo’ไฎ6ห jใ€๓ฤใญ‹|Zomิ๕ฺ๛ฒผฮ;L6อœท%•ฬyธํ0๋ดˆ่:รh]&ภ —‘ ภI2Œข]„ห๚๙ C.\g(b•คัˆโFŽ๓ซรฯึyž3)ุX๖Lดฬุลayฃnz@ฎ]Qเฃห~?.งLb$‡ฑN๑™Oตyฃภ}fAPKt๐]ำัฉำ ›™ ธPไฝŒRตี•Mำ๛๕’ไธโSซ’r[1]”RใD‰เ=ะx๎?ง}vc‡ั3wM&ๆอ’ฐฒฝฒ%„๘วฉŠI&?F2xธ๚๕|๒้งA-๒‹K™U™t5[๗๘ฅŒ้ถ ู๐yาDข7*๎‚žFป@ห&e๔ža๗U๛๋Qจ+้Xง‹ฦ Hเเ$ eW’’~Fฃ็๘Iruย7eY:sสค๔ีจตzพ4ง]ิ&Aตtหฤ‘/งiๅฆ œSถ^[ภฯPฎ[)ศ“š€ ง๚LrTxข‹ธ3%ฒ๘i‘ ŠฬJ+sd็ๅป่ฅ M=#คn*lป*|u๛†N).HNไญ+ ;ูZฅิ๕นFื&˜}w้uQYึWqeึrฺศ๋2Kไฟ5šูpทอุญฒหแ%‰HLธQ๙ดใ|๙* ฎปpwฒNฯขห˜S\ŒSส:ฌ๏ธถRnถIวปธอ๑%sงฬ—k–๙Ž/{icG&๐mXQ[faฬ=จฬEŽเIbAb&”t ม$๓vœํNEœ[Hฌ ˆฆฮญฉฏŽ/ูqํๆ>แ:ร(๒yอ‰‚ก๑!ํง-ฏํ^+๕’m.ญfธtธŽ‚ู$Q† /`q[ ผmำqLˆeณ>ษฌnยth‹<ษ ฃ*SUวบ แ๒1kช|Qx๒-ทึF^ธF!Sœf2^r ษำ)ฑ†]ถกฆV gคmจ Jy:|‚2ป*ัซ๗ ซo"ฦKืv_อ๋›e>หt2u๏.; อ€‹b"จๆMไ‘ฑ9 …Uฤ’หxฝ:ฤ›$ขyB3ยrdศh‡&bIlำtEภuyg&m?ฤZศRRนxีGHMAsฝพ„คRYหงหภ[E๘พ9ฮAk2ฮถ$๚๛ ึษูฑaOทaๅห… n(ต…„!เคˆ[งkูh๒$bVŒฺ3sLv›Vๅ3w&ล—eO–ปŠF&ฤxงฏŠz5ๆpj!deIcตฌxฉศ#…ข4ศฬbCHfค0 จฐŽ8|œuย-๗ส,2๚ xฒ,q+—ษ๛=cฺตs‘p~พnตฯ€8ึํกž๙Sb็’eY๒ ี‰P#๖„๐Gฆฌ™7ชิ6O’RFฟƒ3Eหnrฯ{B ฦ๋๎d๓6ยใฝฤญ๋Mข2’ุŸ…^e ๊4JŠ)หร๚๗๙ศ_ช'๕๓ฟTM4ะsฤH_8“ำ๎4า<พ ๏LzŠž้๗hŠแ6*เ๐š๘๛4โ‡ˆ+‰จฏ๚ผฝ็`คี5€[8ŽฅEfs&A&dฌiM ๎‹๐›๓=eœFƒ\“Xณศณำ฿๏ วqagWC|I\๐5]‘|>]v\}ฌเ9ใณgษ‰ ด-'ำOŸ+ส“ ปƒI…i๕w“=7=น‰ข๑์ ›ณ์พลๅ{ฺv๋ฒ5ธB็]KงŽฆ๛p&›kˆ'#Y<(๖๋ฉWe 6s|›bฉ™'จญ!ซhซ็ บ๛๛Ekขฦ&dDผb ‹ก๛‡›Z•iฑUt‘dmฒ|—T3ฒSรˆ“๋ซ#ฝ6c'Ur—Uฮœ8ยn“ฉ:ฆผ6E/ืc9%]uัjื[\ไค=^=Yว[hmํำm็แˆผ<~ฬ๒nัฑ'#K‡Žท<žฉั€ม้iลDqIE9๘ข๘ฎพ็๎ำ2Eฟb:GU{“ฯM@ชไsๅฯ}๗MตŠ฿Lบฐตลํdcตี“ํ-ซ๚ฐœzTy"ตีฮGำp•กู}(žSฺน'c4kD|ณนK6q˜ฬ=\ต‚~ธ˜จ\9!"ขฆ๚จดขดfร!7ซn+ๅึOhบyึIุs@1T!U๑Osง–ฑL“#Qmzๅณ๔4v–์ึ6๕;9bํ{N (BำŠ*โฆ่Uื๚฿‹งโฑ‘ewถ,ํ&ต›R~พฎ#b๔v"พ‹็๒ใlจ›‰้ิถfๅซOฬŽDh์Eๅ‡˜Ggณ˜๛6ำŠญงฅ|W์ๆ๓$ญญ ใษ“_m[]ฃ›w9•ฒิŒ์Fe8ผ˜Œฆช=็ƒgเซฎศrพฮ0Œ"ล๗ฏ,2hS™้ต2\Wo\z\๘๑Z7บQ›f$6อIHษx*๔๐nิป5ฦแA‹u‰ึC‘n ห‰v…Ÿ~ซ`๘9l99ธฺดโณา{อโ…๗9]แX๎ z ๛ูc‰Yœd ๛‘์ฮมฬZ™ŽจDa!„vIQยไ้*๕Nขฮฉา>Pฦrฉะต‚ใฯ98c๔ๅทณF=T ีตDRMพ็ฎซดsZ๘๖7ทuw๗[6]๕/นN‡ถZ”‚iฮDแผำqv-crฏณW.1)w4ุMmญเ75ถLญVถ3ไ‚ŒำŠจ.]”ฝ:วebฐ๖q†ใWnภฏฏzณ"ถœฐYทฟƒ&2ศ๒ซ•ษQะ“ฉี๊2ƒษฤใˆd˜fg\xefE_ใถธ๐N˜ฦoWตอCvlตฮ<‘๓ิ[฿ค็6ืภD‹ฑ[ฬฎ1)…ๆXสูZVN%ฆุฝฉ ื—ืม”i‚BAน ใ“ไๆIe–ณ†0+ๅ—cSRฏ่Iธเ๑ŒษF.lา6F ่ทิB }ฬญCgฏ…ฑ•วrง`๕ู)มๅพ/้๐์ฃ)์ตำฅ๒VR ษทƒ>๗‰q|ฅ ๐NJฺ์›ฟ&ป ห๛Jร-๏V๋ษ๐ุ’ฆฮ“I\ษK๎lHสK-1ฮ;ชt KXฬŒ"FK๚cฐC FŒB๏3ฃศyค#qƒฌำf๑นำAๅ…=ฺ u๙6eๅฬfถS‘rkํแK dw‡c—‰ฤเŠ`JขHกฑv{wู‚ยašุ๗๑eฦ‘'ษญษZจQœฑj9ItฆIvK๎2วMกš—> ืฟฮBQ?จœ…๚ข~ำห[‘u:ูว๛7ไฺj6NRสšR›šl[u“t”]e‚ุ^š"ขฆพXAซฐพ*%bu’>Pู๒VEๅฒE?8#ร้T๙52%„์nญ`I›H’YNHๆยHA=ถ4O9>๚๒šฦทดk+ษตี๐jN€นC—อีโู _;๔_9 ๕Dกจ๐’QีดE^Iาa.{งๅ๔m๘;๘มณlทชษคฮฎnozึพ\+J่๒œlใ“f„ฺฐขเธปจŠ๋ด†‹;๋คทkสl๕์ไ™Vะ  ั„OŸรฝr๘E&ฏชbDฌ™ฆฤฑ[5NwจE…๔ษ‘ข95ศบ,“(ำ[#‰ษฯฤ?9 ๕Dญ6ั๏ท๐ƒหmฟ&ฃฦ๚/๎™`w`obO๛ไ/ี๛mไ/ี๛mไ/ี๛mไ/ี๛mไ/ี๛mไ/ี๛m@pโtษEPOŒTเซู้|oฒฟฤ;1!2@ "03p#`4AB5QCP$%6aD€ ฺ๘cฟๆัิmO๐@/๐tG รฯฮV๘89Nฯq}#็‡้ฦอ’65ฺ.๔ –Sขl…ฟรX็wลdพSำ้,i{ฐย๘-;โw~ุ฿,]ำรฅึ๘cŒส์Z่ื๋2ย่M๐6’Wท ๚I#nf*vHะTั๊~‘:0 ปลฤ]=Žุฝ> aSAฉก฿‰อŒJ~ูฑแŠh๕?Šใ?S•ั'7#ฬูCูสjƒh6>F(]1ณ| สX ฒ๘Jว๔{qyox6D5E ๆพ>dศycๆงิภ๑๐ถ':3 ๏Ž %๔ษขv.Pมด8 _ศx)ญtๆ–œ\‡T(ฺ๏Je#ัร๗ˆ/๎่bd—สx4ผ๗‹mๅhบฟ•ฎๅ๒๔]Ÿ•‘ท๖๎์“๛4๊ือษูSย‚—„แธฮ">_ดลU๐วเ;3IูพHววึอฤvCŒญš.RnคไiynฬqrดQš.ะTRืPq]”ํeฆโ๘ัฦร\Yอrœ์ิT”Š“Œแ๙Nn?ไ(ป!GV8ธิ_๗(๓}“๐๔๛ IัB`/ฐลBYไ†7EบกˆCบhu๋yŠZ๐d‘ฑำฮ‰Uจ๛Ÿ8งษฝิ฿}จ†สn๊งg \ŒP@้แkZ%‹LD1วม#†1้ŒQI’๕Up| –œ€ยKUdyyงŽฬ&^๓ไฅcY$ฦŸjฌ๛ๅA \ำ,ข('LB+๓bงœZE๗Thณvbษ&ฦ7ถ–'ks‹Y%โฮYๅ ธ‚๖ด>*h@l•ทม๛ี1GZYM™๖?๚3๒๗ลฏ/“G‡nOำ˜รM<‘ฒQN๛Cมด ิยุˆ,„S:ฬuCฅญl1x}ฏ0ร$&HYbเRศYm]”ฎEKOมO?‚้X๑€มูุ๊Ou_-?"(=7วIเ๊yŽ0qาท_dศ๕N่›้๏k&บ).่dc.$u3^3ง๏๘ฃศ๊†69qmL,อ –*h_๓TBฦดKS}ื(โฑn™ัE$FX[๊N๊จ?อxJŽ้ฅb†=ฏมcIžฅ$ZฅมภQ—kFุfลฬัแŒบ-๛"(bˆI,บ-xฃจ‘ฮdjท๏(aV้ฉ๕b๓มDฬฅ‘หำไคŒปXž-Rbจฯบ‡๏)~ใ”~3)&†=Bhฃฑข9iๆaา:•] w>ษญค•ฺฺ๖–8ดทก๎Š:s s๓m„šฅ๓#rUŽ*ึ๏์G สqี๏ฉฌๆx>VาVU๒”ำv‹ณ4SqqA'gปQ%ุฎ'<ฌจํOห;’ชไวdaC‚d+w๊๖ช]—คกๅyj๚สžฮTr๎ฎpไ๊xnN~fjปAย๒už ขฆ์ฮ\Gj#งฏๆ{5ส~Jฦจฟ๎P#ไ๕ZS?ฅ‘Hำ=;L`)$ 3Q†ฒž7Gร้x[โสlrLImDR>6Aฑu3›๚oพี4…’ศั)ตไย*ใvPcแ\L ‹ฤ๚F0ฬC๊๗;˜’{ุiฤฏsCฺะ‘œ ซŒ6ฯmœศ›แชใlไ~บxฅดิปŒs[hๆnt๙ษ>ฤม จผOฅ„9ฮfษ=ธ<ตSฒC˜้ษหูษฆ2ฉe2๕ทGwล‹๊‹Œว/ƒtฺ|:ํ฿๛๐ล4ะ?d™แ—ลCฤK]ๆW๑๏ sZ2iคไhโ๚…๖ฮ็zG๑aิOัขs[!.ฌ๗ไฒ=๑นข•ํOsq…ฺสฒไ!„Iตxโถฉc‡=สชAตฏc๐Ÿ็d๘‹)ู.ษM๓ถฑบKK3XูŽ7ฒX4<้crงท„vQฉม‘D#{ŽศฮŸ9nโCใง๙4=ุ’ุŒm ฃ†Nsd๘Yถผ5R4ฑฑฉำLภ›เ‹Tnkฉตตฆ3€ำย;(„Tเศฉฆk\แ&ฆ7ๆt:KฮๆC Oุ^[<่6!…Jมฌัๆ .lง•ฌkb† ว4BPใ`‡O>๎…ใ๙8-_;Iย๓t๔๐*˜ู CแcI=e$5ีฬฅจใ)8^;‡ฉโW5ลั๑’1”dœฌ;๎Uษ๋ภ๐ผ\Œงๅ*;Kว๐ีO ๑Xu?ภวS€dมฐ:/bษƒ`t_Gข&ไ_ใ฿ผ๏๔ท๑qิOโกิOโกิOโกิOโกิOทqฐบยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹\‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘a"ยE„‹ ,$XHฐ‘yวฺงฟำ๙รํGSํ฿้‚~แ๖ฃฉ๖๏๔๗B[ž๘{Q€v loxป{m‡—Km„38ฉ๛จ4ธูฎŠFyธ4ธูฎ†F‹–ฑฯ๔อ ณp ดุ่—ชตถขข6ฐŒDR—๚f(?p๛Qิ๛w๚{'์ํ$฿ฬว;ใŽ๒ๆถ็#โslุพ่U?uG๒S—Šg9ไตั 2"8ธ!ฮa๙jๆ†ูฏภ๗ธlvQส๛‘I=Sณ็ิฝอpkf7งi?‰ฯ>ิu>ž๑+D&>่ecCป฿+]บ7ยะ ค’จฅ ;lqฺ†Pห‡6XฃwศKพMั= K“™7*kไ.RlFJw,ป 3E ษ&kโ ‰ฯ>ิu>Ÿศ'๎j:ŸnJธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎยธW แ\+…pฎย>ณํGSํ฿้V มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐV มX+`ฌ‚ฐG๎j:Ÿฅo๏๐b{๘#ๅs๐ ?O>ิu?G}(B๔๏ญjค์L•p|”|Eeg%๚Sุ˜ๆส7ำOIฃt}†{C[_ห๑•\ESจช ธ}จ๊SZAฟv'+๗œฏๆ฿น่๚W••๊ืฟ:พU–์k'ฉ!ฦ~!ผ็m*iูู๚vะŠN6๑7ทนVORK—%|9ผไ๗ตOัศซ l‹ฎƒฌฒ=7?Yม์๐vใ—‚—Ch9z๎:ฟ๕*{cษอ –[šชๆjUQOฮ^(ƒ%ๅ9*พVsW[๙รํGSํ฿้‚~แ๖ฃฉ๚้๕฿้‚~แ๖ฃฉ๚้๕฿้‚~แ๖ฃฉ๚้๔@บล[ฮหo์ญๅe ณ Ÿธ}จ๊SZAฟv'+๗œฏๆ;าœ.‡Dแpš,๓ ขอmปž™ีy]ซS?O>ิu?A>ˆ6Yž์pq CvA?p๛Qิt๚๏๔A?p๛Qิ๛w๚ Ÿธ}จ๊}ธa“ไeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeZeNฒธh:Ÿof๛๎๖ฃฉ๖๐}ัฦ†บซๆ‚AY”Rฒ”ฤณx)wบKM„{ขฌฆ2VH๎๊บZY-MDอดysƒiตO ฤิBJ—ฑถW้6• t;ไ85โ9$cฃyฮ๔ฆŸ์Zlหœผ์Iฐบหo็epV^vส๗Oฝ—๗ %—๖y]‰ฒษeๅt\ฎ “O‘Av-w’&ไ,ฟใฏแพ๛ฝจ๊}ผtwqฏluYบJ๊ฉYญ์˜หO‰•C|Œ}Kไl฿U<5rพ•็หษVrฒ Šxdฃ80š‘ิจ:84๋\"ธึ-ํ๐™'ฬ]1จŽI๊๏a–œŠยW#›๏J#หศ€^ขœ.์บ8ฏ;/IF๎ พ_*wD}Ay฿4Gอu)ฝSฎ›๊@ูy฿ฬ๒ฏ;!๊M$b1VทQไ?อ๗ํGSํโ6กŒ๗D_๑<฿}ิu>นฮac™โช•-MCงถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญBI.Vวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lzุ๕ฑ๋cึวญ[ถ=lz๊n} ๊~จ๓(†E$ั2nBมO€๐าžƒS<&฿Š™’\_ ‘อS u(:ๆู|ึ๎.ฑทsnเnฏๅeะy0šฒ.Cา˜ฒ6yน_ฮศ๕๎ไมQ๋ไฉใtาUxพK1๐0†ั\ฦแUš๚wc|l้ขv๊H›#๎๏ำ๒บ๏๙jTIถT‚็Tฆ-MLะ๖ษN^๙&exฅดqฮึพ;dpŽŸjŠc!v:Ÿเcฉ๚"มบ„SzขT฿๘BมtlSzฏ๒N๋ศ‚แๅŠ8ฆQPีK e'7c‘วนŽŒา`ๆkฆŒ•Jๆ๊tj'1—c้ไl|<ไ๊Rฦฯtส‹Nๆพ&5•cลๆ.526i@ lM€ยค`‰ร5ีYโy"G+Z๘#kžc†ŸSŽง๘๊}ฟ#ิิ52g1…ƒ้ย๑ๆW็!x๘e˜IX?žง๘๗๖๕ะอ.:ฟOช๕*jJ†T e :ŸใD]bญ๘Du?›GS๙ดu?›GS๙ดu?›GS๙ดu?•ฤG !1A "Qa‘2qฑม๐0Rpกั#BPยแ๑@CS`br‚ ขฒ’“cฐณฺ ?tKQำ3o’^ั๙G๙ด•ฝiH๖฿n_Iอคb๙๑อyr๓kถ_@๖ใ,ฃป๚7ฦyG}-๚UฉD้พ_,ืฅฯกงฟI๔ถ}-,wำžLช๖ฟŠ9tผฒ3ฎศง๛KG>Ž&ฟ=็.ƒ9K-ป้lบ ‹ช้WC}|1>|N\_ ๅ฿๖.‘ฤ๓z็.h๗พtCyNmๅ่nท้v]hg›วฌ˜p์zฎk–ปชs2ŒO\ฝ๚ซOwh†#๒™นjF’rํ์]†4ฏ7W9žXา๔šOWพ๛PŸลฦ๓rืพii์B~krŒ๚อ๚ _ซŸ‰,/'มบKW'ัฝ{ฺฤ๒|X+NN๏พณKK฿b2xqตP฿7Š','ฤฉ6rjQอฅึ๋>{าฒOอMuปU™หาฏั^ซ<ไ<ข?œ๔ก›M'ฏŽX้์ฃ๚ฟฺ|w7‰ฯ—Eš่>ทC๚6s-ถz,ีณoli\ธvtน.^—oE42ำ\=†ฬOึ=อหmŸ;๔lๆl„ใวcั=OXํ—#f^n:šQทC๊|QšXญพถส๛#๛ึฃ๖w{๐๛ล<ื—=้~=ฟ5ฯY_s5๐็=.K•๛Wฤyฐ๑5แ๎;ฟคฌBดว}x๓/ิl๘vพW.=฿฿รปย๏ดุทlz<ห-ู~ฃkGaฑท๑่๒93B฿Cฐํeทุlm๛อใฑi๖œธฝฐธY!<*Nโ๗”_&๙Y0ๅ7Nโ๗mญ‹ฮK”ขทO*‹๐kมูิฤ๒‡,ฐ็ึQมหปึaayฮตฏฉ(ํwป์01้fธ์’ๅw๗ะyTg์Ye๘š๙,ฦ—๙g ต)" q“”!-žiIx.๋<›ษ`ำPJ หGK[i$ๅฑ…xท)eธ๚-๏[3 6& a\tฌ:{บ฿ฐ^nZมํฃ”tตื‰ฬJyๆd’Wญฝ>G๕ด๘v‡oเkF๒7\=!$+C๔ธjจิ๙ิ $!p{๔=กณCป‚ะZš![ ~Qคˆฺ9Š฿iฺj|๏รZโฌ[ขqิZฑjhA3ด‡ฮงธๆ;พ?Sโ…๙ต,ูญS]ฑ๕Zษ}๔พ*ˆ๕%<ูนSv>ฎ’~ปฟ #ž8•ONฤตห k๗%๎๗หiVซเศeM๖ฏƒ้1าB๖๔>u;Mธjn-(ZYซE%ว็qŠลช=Bาอถ ”W3cqPณ!eดฑiF่๙฿ƒ฿3fวh‚Q\๘-ลBา…ฅ‘ฬุต>u4ถ9‰zอ๘ฟ์/•ใํŸโcโbGz”ๅ%เู‹,&ฌšฟ]nbK]ฒm๛ฯ(ฤรdg(ฏฯ*ล”eบx“i๚ี˜ำยO|“”}ฬฦž{ไœฃ~ ›ร’็O๎1ง)วfไํzป=†>'zgฯ,ี+ณส๑ฟ๖ฯ๑$็'ปn๖ณส1%ษอึ›sๅหฐล–+\็'/์z‡cกฝx6:$x=:,uมะ๔4ขOว†]pv:่=8I’~<š^ ฎ|$Gcะzt]~<$วD|ht=I?ุBOฤ“๑ƒเ๏ŒskbษGณ3แ<ฟโ|1e๖)3s9~&$ฆปไ฿ฟ้œƒฑ๒ไjI๘ฑะ๏‹ฎ‰?|่v:’~$Ÿˆ่o^t$๘62OฤvI๘ฑะว วDŸ >ƒำถ5Lํย?>?ฬ๗@่žง#QW S='ัฤŽ“GyถนoงฦUํ1%‰็ณzUห-U%ัK6๚บIv g”ผLo'Œœ”rๅRQอ•๎๔_AŒฐ0q+.ซ4ณm\•๒t”คœบีอษrฎฯฒNFั้ซก+‘ฒิŠหtmน”็๘ะUggA[bี Qr0ำ],ค4X“!•Š๖๗ TB฿hชHW๒ˆฃ\ค49ๅุ-D…\vG.ŒžKผทฅ๖ึึ}Yืฃ' vงO]หไบRKZyป 7bร*ฝ]=;๊ci’:ำ่ฃุู“Uนฑ=tbe%˜ฤDำ662Yคฯ‰ู,ฌลตม๕‡F"ะyจฤสK1‹Cฬื1ะ๕ไฒฒz๖Ÿ;ณ๔Œ]8b-I˜‹RYธฝ‡ึ์่๙v’ธสฒห.บoฌโ~Rมร๓ ฏJปQ_ึ*๔{ษgŒdา’ฺI=๙๏พ e ]ฮUJข฿7๊ทๆ~RมŸ๒ŒlะYsG.q฿n่๒ธyR’vใ]_ หง๙G jYžฒ฿R}๘‰๋W่๓?)`มร.[„ฎณ=โ๋oณพฬyฒ"Š(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ขŠ(ฏ๔ ๆsย่Fศัทมp\ูฬ_kฎ’ฒ5วs^ฬ1๐ฤ7";Lำํit9pNฤ๏็ผี1jอ˜…ฐดแNBืeฐ๓๙ฟKXชฟ๑5ู๖ิ๘X~ูๅx_สท…ปtšz>จ”qmง™ีe฿ๅYๅ๘8ธ๑ ๑Ro$8ฅ—/<ืUโyf,๖รู_ฑ3า\ึอvฏถซ๊็อฒIkํฏi?7uคึ๚(']๙Ÿฐรฦ๓ฑฯ๒k.‰ฅหณmkCo=๗ึŸ๒ก>ถLžฌ‰ik๖Šk๊๓พ๛{ณฦ๓ฉ'™>WตJ=คp๊ผใO?ทZoฝฏ]’ใผืฎk฿7ฌ†ต&แg_Yปต(ยpUิMsป๊CQฺRO7ถš๘อ'เ—b]Ÿ ิQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE฿mฝ๏ีส๔–ฆaลu[อีWซ‘5†ฅถ๎9ฒ๊฿*ํ๖๒&งฎjŸzgVซๅZz฿ (5ีำ*ๆ—ด’Œp้๋฿๘‹อว๔ฉหqฉยRTืฏc>qทQืย๖พใ;๛&$|๏ีืย๖ฒjบ็๐1bณz;๕ฏgํ7Z}แรท่ื฿ฑn๏w๊็ZKS%งrK‡†œ55˜œ^hคฅ•eตูสษรW่มGลธ%ฃ„น^_า๕๖๒แ5––ู~ชๆ>ดฒ๚฿X’ŒณfWขzUY%&ฑ3Iญ–หy‹ŠN[๕ทบฏ”o็ณWฐฤยP๊9ืฒณX๚rO๎\‡ด!}ฦฉษ๔7้v6ใศพผ ๛๎๗~ฌ+๛—ฺwป๕cงฏภฤ—LœŸต๖ ’cccccccccccccccccccccccccccccccccccccccccccccซ]E฿ภึ/aฟ9.^ฮŽฟง๖ฟ฿๐=,ฏฯภ๔Uฅ๊งัื๘‹TC3#Lู๊๐Wฎ‡ฮ„t็มxก!Pญแjพีป”m-}cฟlธบ$ญฑๅ“'wเ=;I่=;วqcตฏธ•vกฺ้b-If%•๗Ž่umซw8w๛า๚^}._j๕ฅ๏์%ฏถฝฦห’พฯWcz_ฤ9 A!0p3"1@`#45BPฐ%67Cq ฺ๊/ำ๙ํ›kฑg หฌ Z ช๛จฅฐ=ํDฅBาGอ7 ’`G•ํ๖ฺ›ฮFโย"D๖}ž๎ฯฦอ—ส1„]ฉทฉ๖ฅิ๗6ulู๋๘]4ู๙''eุ๗‡)งeฟูSf!พ„ิฤพฮฒ`1๒ฌ|„gฌ‰G˜Vีk๒สๅI.‹zบ๕iTตสeไๆญf๋๘…4FหŸ"Rฤ็`ึŠบF่ ๘ต1Œๆษ|1-xค UlfJภ‚ูไฎม8ั๙vdรืื4C‘‡F‰&cแฉyfๆโ๎/Z๔v่_}}MWNวงฑ้ํ]}เลฑ๘ํ็›ษsxBZ8\สk dจหg)ผqA—อ1w๎พ›=Iิ>šzuฏZk้ขhต]=? xvAž,๚œdทmU˜{Yภ…โฦœํฯ ณp#^6โ0บŠชh๙.]Yฌชl* €ฑาš˜็R\)@WฒF๛ ะพ3X่lŠhงๆY+pe,‚HลS8๐Q˜‚ผ฿๏qZ ส”sฝ๒ิหฬ’—ฬp>’ภG[ถ%“Xy•าyๅ*fโฏ~Žฺ&=} ๎vีบ.;u]}โLเrŠ<,r-B&a!",XฤZวท&วTjZฟผถ’!@†Tsฎ่ฝพฺฎD๊Nฎ๚.;tฎ;u์ีuNŽ _ศ1ฃ‘ ][”ํ’๒†"˜ษ}v‚เ Ž`?พฤ™“&ฝ 3Nr^"AStฃ1BปDB”ซผVI6๎าๅ97\3œIฐC9ล่&ใv๘ ๏v๛๙ƒ๏๑qฮฬรœ็ปy๎•%ํq Rฎา@๔ฦ2&ย:8ํ๗c–ฝฟฃฃ๎~ฤูณฌ\0!ํ่แ้ขkๅ7Œ๛:๑Bk.ˆั‹,ผ!>˜Œ๒{*TฌCIฒˆศGAโEึชฯ)G€ภูšใ#ธNhบ;้฿Eัp?~ฉ์/เ“ซ}๛ผ<^}-{˜ปฬญS#ช-{ๅˆูQQ๏t5oŒO‰ขซ<[Sภetcxva8.o{ถฝฟ$ฑ\Yย‡1ƒfิaฉฌa0ฦA’0กวˆHธ™Qœˆ.บA‡ศษ$ฑ9„ใ€q1ณื ำD\/Fอ4ูงฆN฿+๖ำoGm ŽุMEีt\.๎๙_ถ‰ัOLzi‰บmำำq้ฆmc‹Kf ๆ[DEr์Fไฌฮ๖q@E<ญผ™หศ2m•bรศฃฃ)šฦšLบสฒ*ขถฤS.IbZป2ึK“bใ LฟvLโณะQ iช%3_ต‚Qฝคแ+i6!ไฦ$C(K๒่7์Rxžา๓qI‹–ฝพCBZ>ฅ2…qg>๖ฌyfE}~\ !นฎ_๛อŠ„˜ณcโ$‚1 y{'๐ฃ”ฝ๛W0vำ0์&ษ/Cฯท`ถ ์3U[jฅาๆZ@ฌ@f๛Kจ™)๓•,$ƒWˆWภ๘ๅาโยแ2๊[ธ€–h็ๆKyv๓%L,ฒ!หษmnวHYDโ›๔ลXฒZ”๏™่้…rB0†๐๎ล“Yr๒์ฐy _ุ&ฉ96Bข!ํ_S:f^๒ˆ*1wP:y g๑@คใE<6Q%๛ั๏—!^ซฑ›,Yir๙IkC๙ข0K ! |Jปw CŸๆ@Oฎ7vฌนr'ษtนuสš'"ปูWา&_๋fฟ6ฎ—Ž{+ีG0.ฌแศŽ[!œซhU’™r”ฉ๋& +อ+กฌธ (‘๎ฃ<ไฑxะcRNๆ!ษขฺธ0DW๏ฎใฮ>ว3ƒู+%,0ฅำž'!+&˜-.—y๋ิlM|r๑†Hษi ะ”GA|พ0ซแษฎ์‹ต6โฒ–!!ตำ%y๘|)hHึ,ฐEaๅบTqคบฅ+1สฬw0(อdd†p…์ถsฑElyˆ๊ฦ8uภcZUjปๆุศ‹ผ‹ร ฦ ีSๆ ทT+ซW+ํ^ฤ}จื+F๖ํมฏk‘>\สvํฟ‡(r็fz๒T:š}lช<ป]5aญฒษ-,๒6d1ๅ‚“‹8ศูui•ฤ'dป7ปร1ณคกiฏIDrผYบuM่๒‰•็ ๏9>kซ๓ƒ™ษ@<฿น€๑ขโ'๕a๛DๅุๆnGT้ํฟTฦ'สYZ--Y }ๅ  0ฑ!ุ@ฬYxdผ‡ฒณ‡Œกcฎ๘2ฅPSฬ‘*ุy"ฦตkๆQXๅPัๅน็iชaญ•šaRfBˆฉ’ท2ฟ˜&:g…–นLyyˆฆ‹ˆŸีƒขชทa’๔๖๙š'๕hคฟ5ืน#g๙ีF๗-‰“๋9%‰฿ฤL  !1A"Qaq2BRp‘กฑม #`b’ัแ๐03Crฒ๑PS‚ƒ ฐ$c€“ขฃาำโฺ ?4 อ•AFฆซ ๙8๖ยซู(ฅูน_แžœ6Qbต^๖ข<}ะมM{ปœRูำห๓ฮ-NqJS Iฮ8Ÿงล—5;ฝI>‡˜—ฒH ิใOŠลอฎ๙Amฑ˜€~ตACำKuhรHขญูด!ฉ{(—wใgแMฤ›๙ถคต๘๛n27‰->b•J]7p]ด:ฤฝš”ูxค๘Rภง— d“ส7Š3อTวaิ๘ยw/~โ!;™ฝฃฤšฐว‰9gธƒ๏0* ธ™1-2ฦ–kยwฎZูB]I๒๒bว/HธKปว“๏๚#วx†hฯตฏx%››Fkธ๕{`ฑK๛bมG๏…;BœŽฟOTPดไRXŽ๑ฉฆblZœ>l^ฯฏQR•rIrO2c:žE}๙Bส2RIw‹ฦ6้Ÿ๙DีอPณญEEป฿ร5hยิกฬ“ )่aEGœLRG"DLQ๋YOBD,งก" PฒHีแjซ‹—๔ฤีฃฬ-Du…u/๔Du„zx—่<๔๐KOูžƒ&T,k๙๗ย‰ฉ๓๎๙9ฤส”€]™ฟ@ชฌธ—Iณ฿ฟอFSง‡ฉaY๏๑ฦIa”|ฐข ฒ:~ำ๚P„p>ฤ’ฦ>ท๐ขฺ ผ๔ว’=งอDนEชJ‰บŠดXิ๐‰R@Žส๕๓๚Rp”ว"฿xŒBG0x}nP\Ÿบิ๔๎ŒB owpTM_†žณ๒๑ Iwคถ‡๗ต้„K5ญฌถรฬฒURožV‡O‘…-อRม๔แKำž^<ธนXC3ฒ•๓ศHcศ4YHXน™AฬDOF Z๕ามฦถฮ็(šŒVVฺ#Cฯ?K›ุฦ2RH˜ฒ-^โ๒ฯฦk[X๘Xa#ๆ๖…=ํXฯง‡€๗ฤิํ<ž”Y\๙D๔ฉcOษ๗@vnq5(Qำ๒c?;—ัใ๕t)ธT๗๕4gR=ํ๊‰3'H G๊ิิช†๏จuŒ๔ศšZต’&9d๋ฅ!ฯ๏ \๚ฝ๐•ิ9ส<ฟฯฎ5f๔|W?;้—8 2Tด’Ceจดณ๑xฅI ชถ5“ssSxฺ$E3dŸ`p8ณo่ๅ2ค๙รมœธXDฉ*JI.ดจช๗ัcูd4ฤ”ีปึ๙ฯฎ?ฬ@K๙ZมืŸX Fถ๕†p€•ฉฮ Ÿ๐ฦ–ญ™ษTšO๖ฒ๓ั‰—† ฟซ๐ธ‰ษRJJ”ฒJnอซ“งCO™f"ย้ซะ}#แ ?e๎อ่ส๑18Uกฏ'gฎœc-)BŸjZ…]e†๗ึใคb‰ฉ.่ศ\†ฬ๙่&šV[Gq™*งญH๗<`ฑ‰ฯน]O–ตH1)RKฉ+ํT›}ัๅง3ฯB%ฏh5‚rเสLIร…ํ…lๆิV้ะžฺ๙ถq&A™•tฉ‹๐ๅ ฎb๎O็ีย&K ‰&—ฝ™Iึ„&ภ@ฬTฎ?ไฃQIฉมcubtยJาšบ‚ช,sึ$ชqGiˆ>—7<„ญกฅ)๑ช๒y3าั,ส˜ี1bใ‘ถฐ ษซฉ’3ํช็€|‰ฉSฎ๛Bม”ก‘ถƒ1sชบ”ป}ฏ@ฯ(’L๙๓`ฆภjUู๏„™SeกN“อ%ˆ"ฤD•์BR หp้zฉ}Z พ.๗"J/eธตTฝT๓n่”fฎซ,_Sa๘ฦjูพำฒ(#1sผFvัฃฒฐ๏๓บ’งR,?x>Q/xdIR›ฅDยg)3 I2Š๘\ƒญหX”ด„,ฉHฌํV%๊ีŸˆ‰S… ๏อR๕ะ%e๛๒„(จธ›,๊k,P3q›kเ”ku8QX๑หnปeสธƒ3!dœกb(2ีHr/P-จะดKRค์ะe+ด^žฅ†ฑ‡^ีRย;;™5EY ]ณะ๔ZŠดzธ๑ึ$ฯTมบมS6gGฉ่ ด$ัฑB_K(ูแ$U2iฬfโ๐„%ม้็oO=ผก#ัฯ )J๊rœ์’u}DS)e œํ๚<ผ๎ศ•,aะ€้M๗‚—ุภฆRHฺ ์Aจ๎fZ๗Œ ฤใ1)JPzกPิeacฯยŒ.7|Pีค3๊lวRH)เbLฐ” ๏€k4‡ฝใ $‡\บฉ5p|๓„‚FาํีHVโsใD™sv–฿ฬtŒ"gฬ(PJl”&แิwKซAk^$ฆX\ฃน˜ 8# -2&Oš•u•Tซ““U’iฒmค e๎จ$:;ท/พwพณŠJรสู;hSฟ๗‚'!2า™‰ญJ Iธk’ืฬ^&'e๑ตชทำดU๊ษนยำ1#y$(vFข฿๑น]้ฅHbฬ๎ IKป๑ณFŸ'ถ฿๗๋ใ๕;s‰jR—ฺ™0&ซdฅR8—s–_่ฤ.!1aAQqกฑ๐๑ ‘0@pมั`แP€ ฺ?!๐ฦคฺ๙ทข้๙ทข้D CฐคBณฉฐWซ'’nา„ฉWtฅŽแ ๆถ›{lึ๚•’+ฅภฦ|,"ตฆepฒฦe>ฅกpœvำœ"๚๓D ํฃ๖)wX‡ญhใฎ๏B“้i‹ฯ๋lD4ฤ?(ŽผShฟLาIไ‹‚Tฝ•ŠjฏZ%Ÿ๘1 ๎๒ฃ[zกv=ฟปoDL‘ƒuไ™!์นjiuœz—๊้อžชษŸ๕Œุซ๕J#!ญฒkใา‰ โF†‹ฉ`:8บ}&Hiผษ๒ยะly๔ญQILDด5&M|z œซ‹cล“'ษ๊หซ˜…ฤŽ/ีZปช์S›9foœzXืฌ15้ฦtC[Q:qCrˆ›‰„คk„š๘!ฅคf/?ญŽPj8ฃ "๏l$Hอญฝจู•‰Pงo@IษSmแุ-%ฆเฮfฟภCQAศำ\ลHิ|3ๅ—ฆฒC 6สiจuไ!EVฤDะž'_Mยึ’™…ณNคีwa~๑ฉ5,L<ข4 ะK1AMMต VฦะH๑‚a3-คฉรPลj็hN อM ”ทฃะP‘˜ฬ$š(WPDQUดI”ึฝW๙l/Aธ"ฺmu$^h•นw“$6๕ท๔’ฅ;•; ้•†ำฒ_ื’VwTc„Žh”ำMuๆฦกร9/าุhZึuQทœ•oฤO๓เfEvใ-9กตN๓AI= ํXU•2ฆ๛nVโZ“๖ืฑg‰ูgาณu ฅ.wํX5ะ aล๚/#GปFOŠZ็.9ะmQธิWKL๕ๆวžD–‹\ รzycฒ๗G1ึ;ˆt{gMส'™>wz่T๙T›Dแ<#N๎สญ%โ —qิD-*U}ฝ'Dเ Xn๛๛ Šƒ‘ณK_๙/ โiฑ–‹pำxำึข/gž#NWdอ๏^B™pีญผUN’ณ6๘Dcปดs_ฑกIฦู>:–ยQะ}dNkษD*ฆ๘พtร5<Sฬ๐๔tํฝ’ูฝO‡ฯ@ญ็ฺฑพJœะึK cFใt'วV‘IdK๖K…X^R๋-0•;ุยŒ6;า%ทฤดาS;ž๑pIt<ฆืuL๊๊} ขŸๅ฿ิุ›V&Sฏ่^โm!๊wKพD ษซ:ปl|บ,ํ›สณ‡dต'U‹E•z๖CV”฿ภำjEZ๗RZ+๐*ฉŽ•k๓๚*า๓ฬWvZdwH#ึDœ)ฎuŒ๕nคิ„E5ฎงM๛~r๊\i%GuNOJ'z~ฤTud{1‰ภขฒTวJต๙Jๅ]p:K๗ฒ็Tvโ-+ัH้ิฉดฺ?Žขจh•~foZ๕พ‹กาขฐp•d#ะosZc—์‰zฤn…ฏๅฌ=T49uŠข†ืmb๋โ‡ฌnจiTชฑา ฉ&์Gฤท$„JmXยปR(rNsN„ณjRbดD่ขttฉc/เm'./Oƒ{ฤปZwoq7ฆ่ใ‰๊1อฬาœ53MU‰Cฆ›*ฏะน#HYกะ$าค;อl7ฬ4ำY-TŒCQถณešจ’˜^nอttDuจ†๔์^๏9Sฟเv™ถRืด@c…ล%J€2๑ศ‹!ตofRFฅ:ัY!ซด—} ภ–ิณJrฏ*ŠY8ใผ็่ม๒ซภอ “›AฟฎŸ/K+qސ]5:โN}3vใBM—4“ม6–7์tๆ๔mQิพฃฐ\ๅพIไ/็ฐฺข‡‡G1ก ฿ธจ]ฝ4e,zhชn๋งรƒeโZ‰PŠค๓#lท$(‘YCฅ  ’—ทR!g๛ศi#TpM—&ใ๖็a_y9ิZะˆษ/Fบ ’b[IืIร๖Jษฅmน ผJ๊zใฟ‘ปIBgชญG4ฺ€คšไšเXTึ…pj`HM]่Fะีโ{โT‰]ฌ.ฃจ]ฝ *ดัฮ'^M%QฃฅŸ $6จsมต 8 :Ÿ7๔MญšŠบฬฅH‰nฤi4-"}gsQXฺกมV]KLฺขUm้)N.N7KRชeฆ๗‚U',ป๊h<;lข†่T™pB™•zฦฝC฿๏๘†ๅหฮ~‚-HRUฮ๏:…๛พฏ=Dhอu5+pตiซกUL^๖ัDะด]:He|ฑ๛T๊J T4ด[OF\๏‰‘์ฒ\~ˆลfšน ฃR‰อFW’t๖B”๋8~†@ฆฎ1Žๅ $ตพะƒY9•d๘ศู!7–žใnŒทผ๔ ซk`”ธC–ฅฺ่ด้Tญ/'rfด ๑@F+4ีศ๔4’ใRศ ขูงYร๔R™ฐมๆjำVBuำj{‡AีH-+=*2๐o๔œ#ก<ˆkvโ่ ๆุGพฅ ถ฿้ {ัjPๅปั้รง๎ค์ษณ wฺ”ต*$กHิ/]โณ”ฅKฎF๋ˆดฒ/c’uj[”œ,* ‹Yiz่u ณ] ม1ำXcยฬข๗ดฉ|Gำ™D ฝฅKโ.ฺS™ชษืRพ฿3๐ ‚Jฃd;IDล6;ญ†iชฦ7ฒำž๖.BbJ๐›ถ”ึฌฮ่็๒\‰L+ฉฃKธึSeศส]ภหผe]xŒd†L‰e—:[›G—F\lsยiถDร[‰-๏‡VSD"‡๐1ฌฒ๒"‡๐3RKIq๐9‘ถ(]พ&/†aดyw๔‰tอD"ษS๗ตฌปภnYId7ถลญ„{Ÿกญaฆ“O‘Œ[“cBA<†ฒรภŠฤษดฝ้'œฝ์Uรh—mฝ๎ไ*ร‹รyw๔Kโm’ถท$kXiคำเXฒฺ…y eวถใKsh๒๏่ฃ-งฟRx‹ˆโกวz3$?ไ% กฆšถไ๒๏่]ฤไJ‹Yฏฐš|ไXa‚y๋ งภ๒N้:16œก”บ๖ปฑ6ๅญอฒ าึšซ}uื~ป!qdQืถ-ณ ฐเฆžฤ–mœฮณพw์เพŒr’”๗ร:zีNพยi๑ฑบWยFฤ่or-ู76I"R…๒2ศl8.—"f\9'ๆ–็*๎เpyw๔c,ถn“‹ู8ฅ–ฤๆš[ุๆYภเขฟ‰ถ$‡ฆๆCfค9nP@ฺWQผสบ๑-dšl‚‹ะฉล์œRหcI&4ญWN—J+๘›bUฬŠ ™mˆไฆ!"›ีืˆ—a4๘&ีฌฑ*๛,ฺะ๒๏้.ds8ฒธL)Wc[IดŸฤๅตป๑WEำEำ๑WEำEำ่S๛Lฝ่rcV?ฟQeSŒ&ณฟ;eพRšถ ัฟฒGี๎Ÿก m ข}๐งู—‰ ขv^7T้ฌ๙bjฑ๕ฏ`๙฿i|Ž๎ดํu๔ทดNผ)(โึPIŠๅVmC๕๔ผำhBm5iJขnTbฒ"คห ฬK่Yqหm–Nฑะๅt4W๕&„ŠtQaN-ัtัt-อ›ฎห/dธฌ#;ง‚gพฟอฉฦจมตšRM}†(คงย–๙'uJe๛r.ln†„ีณพM0gŠ๐A๚๙ิ“EWฟ˜ฟk7;Œฃ™}vฬ้e:Wถ$ญตJx฿MBtE‚จNฤ๘“ซํ๔^ว-Rqพยak~BีตE3V!‘kz_˜~+sิขซw๊†(Wฟฟq†TMฒ0[ฎ1๐6ี๚'ฟ‘ท9Š”๑พš„่Š)!ญ๎ฟฮdบi๑nf}4Qโฑ]?ข*bํh่Tดา่zš!ธทู ‰rŽผŸQ}E‹‡ฟงๆ:[K€$ฆ&=P)ซ•4J‡Tฺ{ำ*c๊LIฉ ็DžœHฑฆ๎ำˆฒxฑš[‰]$n.๖“ญŸๅบ.Ÿเ๚.„%mฆvB™ุาwุ†IผใT2l[฿]ฉ’Dเ"gE5ำAต$ฒkk_q&eIJฎ‹qaซฃ]๐Nš4๖฿๛ค“˜P๘"ยƒฃ›9ะVซESq๛B$ฬ/บq฿น ถTDฅน๏6์ฃ_vJˆ†๘ฏOห™Jšอฺ๓Mวผ˜Tพ๙Gj‘๎$…Sาx๘โHjEi—M&-‹]uP(คฏWกวB•$V‹ ๅ[†ฅใMว)DˆฎTใฟr(›Ž]๑อi8~ฤ์mDฉชeUฆถh!&ปหDนษoiน…K่”vฉฮเhPต๎}ณP๐u๊ศ38vเRpฌท๕๒Qแ~ฮ:ฌi$2$Lฎ—evฒ.q;์LQAถท๙ซ!%ไงโ๔vภ๙‘=ค'ูชH8ฯ‰mYฺๅ้xย‡4ปUลb@’รHEe[ฒพํทuซiŒยฉVฉ{?cฃŒF๑j\r…(lœ$๕ทซDgขHณยE’ฅY!6Š*ะ’Z ฏ;ฆ85/y)p†ˆ]?หt]?ม๔]?๐”ๆu๖_ฯฑ~S™ืู>Šmฅ'jo๕5*,/T~†ห๔]?ม๔]?t]?ม๔]?t]?ม๔]?t]?ม๔]?t]?ม๔]>Žิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉzธฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ“ต'jNิฉ;RvคํIฺ‘Eใค[ํz.Ÿos๒Cำํz.Ÿos๒Cำํz.Ÿosbช„ีดี.๐€Aj$%่ฆฉ@์›={Bฆ•^๕eb,KP"(K,f[ณ*ผV=ˆ็ MUMJท๏%Qท๙ิ-ผมอฎ๑GCำํz.Ÿosjœ K]๑ ฦิc5๔2 Sฃ*„sจฟ์>ญx<ึค๕สๆF ๋r™มZ–!‰ฟกึเ–&sqฯงaA—รkฃQะ๔๛^‹งฺโง/ใdฝ›๎=s{€บฏ%ีช hH“ิํใ!„้ะ๏7๖–‘ฺ {žQu;ฏทจญ3ธZษ’ํˆ๕ดกX*ทรp€!งํฎt=>ืข้๖๗? ๔=>ืข้๖๗ ๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฬๆs9œฮg3™ฦ˜๑ำํz.Ÿopภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €ภ`0 €่z}ฏEำ้J= ;tก'eJ5WZ}W? ๔=>ืข้๔m–เHTJฅะ…MัiศตัตR#€-f%อ ขOVCแ]ๅ[ฌฤ:#=งแR/(P่กฤฤ†ฆnภ.์Q}œ9t1๎—+|Yณwข ีF์๊QืIM4๊ถวุวข>้จ๛่ Tz ‚>œmTzู‡M‘้ฆศ[#d}Tงdz ‚>œmd-”ูSก้๖ฝBT{็cU69ๅนGFHR‘kัศป่๑„2n jJ๎j0œ-ืึ๋^{ฮPๆ#น™้NQriISŠ๋{&ศ ญ^…-7ต fš…ไ%ํำeŠj=‘ฉBกGฒŒโ8ูMŽ…ณ‰รj‚„e5šŒ„P ึ ŒB"ฅ=(3BSAv๔=”สlกOF›ฤ$Sf›(3MšlW๖Qe pjSk(?N„์ฃุํณM”5 gŠ๛]ฤCูฆส 2P‘‰ 6i๊{ฮ'†EุฎjPbพลqำ๊t=>ืข้๔R” ฺ†6” HCvื/P…‹VKฏ:่tษ(Nหั‰ัQ]wIJyTคฆซชs 4ัD—–ๆ˜yž๏ซVลำŠ9˜i%๕ปฆด Y๊C:nL๕l‹ยIRtั$พ-ถmฝบlcHM ฦขฐ„-bุฦ" ฦิ1ุลr*;šlf›Vแ๎ถ@ลq*š•ีbธf…ฌWะลณQกŠฤz˜„+‘Qะฐไf›ถ!ฃAPBุ๖Tิ†;าฌ@„@๖hkฑcฐˆ4*+ํw 1กœ" š1X[4ู‡ฑ-—E‘ก †„qู] 2*1_bธ๏๕zŸkัt๛{ŸWO๕Mš}qU๗KํQM”๛:Gำe= ้t=>ืข้๔(ง๋ƒะ๔๛^‹งะ๏๗๚ัฉs๒Cำํz.ŸCฟ฿่๏N`lณQU*TH}g้~HE=4ชBžฅ่ญˆ~˜5ถƒ(=ซm#ะพฌzฦ#M็Cำํz.„จ๖+ฮฦชlsส?P๕ ‘‘!1h!๋ uP:sณFยVส2ฅอ‹c.1ŽาXะาIฤJคŽ๛gbุ์hh_cวcสlVูa๏ุฤษืaQ฿า๖ฑ\wุฤq#4ฺอ>ฎฆฅ˜ฦ=Ž๛;tุถฑํะะ[ะ~‡ก้๖ฝOก฿๏๔Yfย\ฮษนrฤ1“้˜วh/ฑn)ตl[+eักกd!ิ[X‡่ธ๗lะDzU ำัq์ะC๊-‹eูคุอ6-ˆ{l{Q#ธฦ!์wุvลตz๖1}ต„่z}ฏEำ่UOืน๋n~ึi๋Ÿ‰๛ฒvO๚‡งฺ๔]>็ไ‡งฺ๔]>ฎซ฿๒fๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬfๆ3sนŒฦnc71›˜อฬ_s‡ฺ๔]>฿ฎ่ ๖ุ}ฏEำํ๚๎bJRงB&จๅFEไก‡t”กส5ฉ=ฑญ2˜GคฟHPไบijJญIPฅอ…&ฑ&A0‚uัฺ„Jอฒฐ‰_A#€†)ีIœงU—BpMn(สž7ฝธ‹Š7Bm้ ๔ฒ‘ีฬEYdาiญฯy(ก๑Mช6ทฐแ˜๔3‰-ภ๗ขm๛szHท0^S9I:)73ํXุ‹KCpTปdž•.บถโœ=ดดnŸช5Cศฌ"&QBE&•ภv dF[‚ššŽZŠ"Hฦmช dyใ† i5&ช†‰7ฟc™ม!๗เ—จ’1Š•1"Zt&าJ#a๖ฝOท๋บ=‰H*ฌษ)ฅz_ไvญ!|bŸrขRkFฺb9M:ค๏ก3ฃญ&ส5ะโฤไbภhI,+ิHYีดฆณVo’–žศยดmๅญuฅ‡DŒบ‘n&ญ๊ฦaDณu‚zฉ พ&บ›)ะ…$›่CA{—D๎U“T[ๅLcบi6 8ถ‡Pฎ™ผŒz6aRaิS์-›JิชMส{šึl?Dยšชj]S[%ธkW`ES˜%ฆ$:‰ข;ซ’iึฎ.์ซ[Mงธˆ•$๒ถŒVา7กFฌ=ฐ@อ0๗I \ซ๗โJษโ-Dฦฑq/‡ฉYZฯืภ๊.Xา-=W‰๊Œ KIลn@j(าTi.าE[๐m‡ฺ๔]>ี™ฃ๎:า.Oa๖ฝOทล^œ?r;ท๖*้Z7jษๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™ๅ™มFฌ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬ๒ฬmืํz.ŸUh >‹ :จคะ๋4›เl›BY฿+Š| UczaV“J+฿ำข_yxp๕G P๛กlษ|่บƒ่บๆอืe—ฒ\FศŽFด•Tจ•Z†U/=ู0=Ai…Š6ƒ:ฉxกRqC{CนSื฿ำ่vฤฅV#พฌ ahณŒ5Sl’Zos_แ า†9hIงF๛ง๚๊iฅย—Uฤ๛.[ึ4”ลฟQัE3ฏOศฎฺ%ถฎO๐๏๏Bธฐ(›e‘–Eปฤr๗O๐}BถศS;!L์i;์T^โœ‰จ&%yc%&1pสn"็๊G{%Tm๋ A*Y.งi‘ฅ`ใU8m‚๖oทฃบาว/๚ส1ฐvำ๔F๋ญๆwญI =!ษ๐e^๊‰๋๚,ข$†ึ7/h €C(†žช1.เ๊~œู๒(Srฎฏล•$Ž-Tำ›JPกกพู>๒TƒJœ_ั้]ืŸ/๗O๐}Oนำ"wžฟQeJSัก‚๕3N=#๏EำPฯต}๐ฅญI๎)Pว“WขRTิสฒ“๘Gข้kxhโ|Š.e่บ~m่บ~m่บ~m่บ~m่บ~m่บ~m่ฟ๘ฏฤ/!1AQ aq0p‘กฑ@Pม๐ัแ` ๑ฐฺ?!ด ศh๎ไ์>ถ r‹ฺฝzศŽ#Bfˆข9D“ฬใีR๘)y7วKอaM๐”๚ๅขk…BUๅ'ษใzใโy า๚žesฬkฟgภKชCSฤิž ‹ี!ฉแ฿Fง†ˆฤ‡๐WY‹โjxง>$ืhŠมึ๓&†hน*งU งอ๋Žo'Zึp฿สฬuถZm‹‘*iMkณฆv็q?"๓[2๖–ํอพํš$ณ-๛๊ฉ_์([}aืุMๆ™ัgัyQdึšTฎ๐qfด’m๑ข‚o#cทsMX—p๖ๆ๛V็ณV2โ๗\†่’U[]วnxง๗<ัคl-tlkคล๊ถ=Hjๅ +กkD˜VK˜5ฏ๔$ฤT›ฏ=trd{$ัุี„จ๚ส4+ภซ฿ƒh„p†ตะ“กkฃSฏ๔รซ๖EฆŸ7}๘$แแ๊ศyˆCb>น=lGtฐ๛>G“N์๑๕žฃm}7ณg๙–‘gpืiSJ๐˜๗KรaX•*Z๐–ฦณะƒะŒhใ` `Xdty๔!!”= 1ฐบ5:ญ›0ไุHAฆqƒŽ…‚65ิc้1๛ๆW๘ั๎้‰ฏf"ธฅ่U'bwQฺ™ฆ ทบG๔ฮวQlผš‚k๎˜‘๚>–!V&์•mอWี-E3œ‘_Fหๆ>โพณgšภf'•ฐI๔Lcว†›S๕TjC{ส}•กฝๅ>ล\ณO๊…}Jfซั{•ธใ;eO๋ศใถญ๚ถ ฎxnึ5ฯvœV+?/…zW๑๋่๘ต ๚WเNxk้Xง=หญ}/JWใ‚"์O๒!!9iํ๔ใฃ}<็๚ทำฯา4o฿ธ‘Žว๖฿เข3์/ย}บWแฯ‚พ• ฿~ ๚Wใฏฅ#jโผuU๚6ฑ๐ค]Rฑฮ:ดHผ<๖ตฦ๑q๋็‘!œa"]( Olธ’๏•๙ ;ถ&dmำ๒_{dูv…x จ5ัrำ„ป|คYPnนฤฬถสๅ45๎ รVdNถำฯUข\ย๘62ด!ทa^…กgฦ|Sfxใ8U๔- 83ฯEKŠ7Nzh=๘y&w,^๓Wฯฤ‚fสq็^G๕พ&Dฤู^'๙z-ใศ`ง/ ŽฎWส-ผt๋jด๖ศ˜žข=eข4ๆYฮ1ีh์\‘lนฃ›อŒQ ฬgะ‚ˆBฦ๚btฤ†™ฑžŒlz่เโ(„ษๆ)ษ6ฬH3ž๐‡•|-ฏCaจณŸKFKW*ค์ŸQAะ’i—๏~<บส(ฯ–™jo“ศ…U›ฺ:G\{1แ-1ถ๖.ใฆBใส<๕rMZ6nอt_.n'่n'"************************************************************************************************************************************************************************************************๙วฮ?n#ะF‘๐aPฺ์3FๆศืJoGcฅฅ์_•~ž/6\‹=รเ๕เO5›ำ*ไM-‰‘฿ส“๎%เoN‰  ฬ2คlHด?"ฬR๎:tฌ7H{)๒ฃผ|ํใ็oฏกPฉiยลำฮ]zuX]o -ทู ช™]+อsัค๚๖้l’ๅๆ?ฎADำV•jJิ*๊ดiฎŒ!รXcํธำฌ ‡’่F1๙รpฦาЉ6ค!h9i8ทG์_ูmท๐ณnน0๔ U๎ŒO†%UVDน}<ฉณ+S0๘ไyŒค๚ˆด'ป๔า๛&jฆดื |มใ๕ญ L_ฐฮct7ฉ๒W๎ฅไ"ๆนซ๖a< Ÿk๙–mฏฐตถ=ซั4ล/ด}y๐๎zฐlxแ’†}็นฐ๙๐•ฯ:๖!ํ*Z'j\vยฬม{ไึ??ปPวี๎= lผ๋๓ฏ~ฟ0xrฐม(ฐน'ณ๓8๗ดรNX$”…H†์ป8Cน6๏96ฺฆุ…ฺฐำe&Hฺm&“ ๋+ใ[”อ3f๙Iโฆฏtโคแฝ]Nแw)?KyฎํzำdK–rห๗<๚ˆฯต3ฬ๋นทWด“ฬZๆท‘k]จา๛!ถƒIvKทฬ>v๑๓ทฺี๘ิ;*(งSX|>฿0ธšaศn’ณRฒ)‘9"ขคFฺทรI$๓,บiีไP]๙ฉ\ทKD3฿Sก<ซ'*กCซั ฒY…[ฒt๖ษ‹ฝ?˜<~ฮŠึฑyCZำsW\lึ ๛ƒžs์ข๒ยำีบdK่—n-u-a'ทฬ><~ฬค‡คอญ#ฮm7[ิOxฬภ›mร๎ย•ฤอ๛o8€๙์ืฯ XI$’(‘$”B๓^q)3‘ณqท hก;,†œทนbcT _๑.>v๑๓ท4TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT-~ูงฬฏ4ุ่ ฅ\HีLฎจ˜VYฅNฆž&‰ิ;†ชฅaฯ˜ซ+•ณถœ6“=-ยgu[๒b๏mตHรUm ป ฝ’TcำcŠฬ-๐q™‘สIS%‚๘VL-ธฅD)ส “c5p3w บ#ลjM463{YHaงฎสUโสMF™1ๆ๚r5๎‰ว?"vLˆbต lLต!N๕ฤO"Xาห!ํW{*โaืะ$ซ์Wญ~ูงFpV๕ฬ*แdB๏ฃ>€๖ฆsผขNDyห.Ž๓ึฦะ^มื•-P[ฏ ep’w…/fh 0ว E)yฮSO<ฏG’อง ;ฉp5ห|ั7ท)ขชEโฆp†qŠ5z+–NF…ˆฬาMไX๒์8ำ˜ด&ฝคศยไPOgพ แ†–ฬ‰ึชz2•˜าš bHnถ]ดฅ็–<เบู5ุเึ๘YyำISO)ฎ฿+ึฟl“j>๏ๆ ืํŠQซภบ)ใ…~ฦค4๐D(Y\๗'กคั7Wั|ฬOไฯ6ถ'Œf}ื†b๘–ว๓ErภVษ:ต-I–ฤฯ@ษึฉ{็o3\IฑCREซDดdŒาศl ฃLMิVเQJมืผnเปŸ ํ›ผๅ‘ฆl=ก*(Gธร12rP๔kw#K2ฟ๒4‰ตhฦŒ„ฮ๕ƒ9z‹่ขY๎–๘p4|“fˆ๕2.เฐกqำ๘?’kU;ม‹๕^1YฃbL‹eŒxfะช<#jศNฅMBw๐V*ี–รN๏•M,ฝ“yมแซt–UM—ษo7Žช๓สŒc…™ฑฬ ฦฒฏ ฌ@วqชผ0ฟ@ฒ’F;D’dmvhธUg้ๅ•ไ€ณt’ๅc4c‡— ์ลmg”งxd๓ H‰- ด ฦจผL“4ล›:uTk4„ิ1n5ดxyร้ษ7?ั๘฿”%|„,2!lนศจ๒ฬH<cิ)๓[๘?žŸ๙E๘‹๑7š้i]‘~„dTŽ[rMกฑ๘๑9ฝO}`B^ั(1(6v˜?oฤ.!ม๐1 AQ0aPpqก@€‘ฑ` แัฺ?ัœUŽgู}๋ืƒฤษศ๘ ฃm˜ ชแผ …‘ gีไW7.๖แuฒ6ะ3…mA็ฝง˜=>^2ีๆ1๘ˆ ืต?R้(tฏ๔ึวึุPa๔™0W ฑู1e0‹yD€OA|ฆLีGg:ฟŸ๙Y์ฤ›๛œ‡8O:”,ป๐ Šmsš`$ณ คตD~%~์ ช_ฐk>-ฦYฒCํฏแŽrไˆฐ ชแขeB„Jx้‰๎F;"Yฺ+ใnOถ็dต‚tฃษ๋)็ศ 'ภ  e‚Q" ค ธSeh๊คr$^มS 4พ]jJำ[3JขD…๒zณมะ†จ๙‚†z*EŠฝ27‚๖T๓ญทๆ)`Š –B=UPไzXz๘fx)P*€‹oง#y=๒'dBษP „ CๆeŒฝ›ณเz\‘๙XSดGeร ๆmu^๚฿ไ#ด R ๎ะฏ๒นei๙ุช Lฤ๊จyp๐6 เฦ์ฟ์DHำ–ั7Šc5อ๔sๆใ QF„ซšZNQqมๅด"X+ึOิฤŸƒV‡ยแL[`สp=‘tyoฎTD„“S#*‘ุฐ0cร‘D™{W๘ตF"Qn …Rว๘ฅgปU๛k๒วูฟSt8Uฮง€}VŸ๑่bาCฉนา •%F ไู(-€ซทŽ)์*pฯศnŒj'jMจึ—mูš$๓P=ฌ=w]ฒฟ๓4!5ฐ'นปุ_ุ4ฐ)^ข๎zป๑ฐDิ+]ƒ8๚ฺัGวมปXŒ'ศ๘h xอ‰”ล๒์M-๒ัiL-x่6†ฺจ-uฃุ){5AGv&ูะฆEI’F๓9% ธน๔}ยศfธŽชญqxGฐฯœW(ซ๊ŠCโ™uฯLล^o^ใๅ–ฆRR ‚Žœ. ถPSArง;พ็๏ๅ€ cธ˜C<โขAƒ$C๑Bๅ }บ p9 ๑ฮ>›7b‘cฉกpCูMw)ึB้[ƒV|Pั en–;`z|นH$8ขr=ฟ=ฺนZ(*!}<RZ "ชAน‚|…Z%Fa0ๆ&ฆ’Nr!ท€ส–ะต?h…b{ฐเ๙ฑq๒†ฌโBตใ|ฅ8Z]fห&“$HI๗l ฎUsฎุๅvB5F (HŽxํƒC0฿ieuๆ+๎ผ„ิกอศ–ค๛sA yp!หjฮUS„Cqึ&ฑœ6๎HJๆสB!djyF kYxศแw6บu’T:งKY(cึfsฮp“^Zษต†๗RšYืแPพ`”/&m๐ต,๖ฉ•—มม1ฅ๘š๋Aฎ ˆั๗4ฃ:m`,/nzXก•Ÿฦ7พD‰Œwื่โฮึ h4ค*eh๓ำภฆฬำSAG วฺSnI$$งp/ฅ‘๕>—=ฤŠa< OXt๎‘ะEu‘qeGี๒ฤf C๚ฉbd'nฎตม1ผ่DŒ”|๎๖-w๕…VF†กสฎBัฐฎ‡[w+ปU์gœ“๛ฬ๔zไบๅn๑#3Y ึ3ฎ5*๖ขOwมqตฬa ฆซ-(้ผ}ซฅฦ๓Y•ว 9๔t’1โYทฺeบ้๛j{†ส„ภ%{˜l 2@„ฯ|ซ)ƒ:oรiี†)›PžžพSฏ‘ห,4ฟ๒X่eขEI๎ƒ H่LZ ใๆSUฆ๕nดLak‰‘฿ป Ÿ‡ฤ‚ดตEi4 3๛ตากGb๚‡ูrŒ๐ รใะ)ํภีีŸPภUทx{„Qxค†z\ญ๚ฃ|-2ฒ‰Dึศ—ขœO—๋ตห<ฬ™J{่๊่๓Y!FNFอ) Šˆ[4?ฐŒL)ฌ+ลณQ€Mศ c’’จ‘๕…XDOจ Eb”v๐ธY)rOp“๘ณsb6 i์ ฯะฉะ0"เ™CE*"าi˜กฤภแŠฐkgPFNรปณซ:BS1ฮqง'ฑJrต P9=w„Eม@ช2โz Ÿ3c<ซว ™ลx –e’คฑl'ฉ"Bยิค“ุ@=-ATูๆ ๐๗ฯร2‚7้DKธh๐™@ ม๑p ญภZvแป„๕sชXมnFท๔ถ&„ž[ฺท˜Q-‚่คญ0LคhREp๗D\ฮ'‰cฝ›ฌJJ}‚z๓’ํพจฑฎิฌ$๖N›ั$QะฃƒRƒโาLCวพฐ์งฒศ ‚BYๆb`อ‚E๘W่p6OซY๐— จƒ)eูฐ %œูช๏3ุ$eRŠ 0Šฅ‹ ฝ|“Ÿ๒ ๘mพAˆภP๚4„ oปฮ›พิ–AM-ะƒoํฬอQŠิT$EBž๛>ไa7.‹๑์ ,ZtD๛!ำฆEศrŒ3œ"ฝt-‡ส%!u B๛U๓+U ฏณeณ{€ฉ†_!"3=u‡'฿ฟ้ิ@$™Irา€Houป1้ ืๆUด œ,ิชN;€ญIซฆzฐ๊ซษภ ะsรด4‰ค|Pา~LธJ/ุแ]bj฿ฃ8ฑUฒˆ‚ PDŸ"0ะk้ro๎ AL เถŒจ9ญŒึd…#์Sj‚โบI`ดDT๛หญkฆ.๖ผDvาKวฟิ[ไFญ๛จษกศฦ ๎5ol–z‚`‹ํ๔[ฟร ฮ2nRืผb,่พ`Šี๙c๖1ฏQ…ธ™DฦพEู]ซ‘:kด…ช*{{นเขฎๆ€T? ลlfณ$)`py๐ ,ำถKํMาฬฃ@ธ-5ำ —{@ROFะ9Bป)ด8˜๔iจว5w(œQฤ๐กgaf‘ๅ˜ั5ฮC๓‹า˜Z$&0คD\ึ9aใ…ง3ƒDh%p?๛™„Tz †ฮ๎/h้ณณr6{T iถ ฃjBฆ๚ แK๓2อ}ฯ6๙Pฏใ€Mง" mุeญyเะฐS”ฮษ๏P `๚ฯvf?ฬoูถ>ล‘;P๑Iฃqผ‰์m‚๐ต‚aG3ตeUU\}ฑZ(ะTัD.@ˆ1O „uƒgํกจจma่ศ[ลฌ€3ุไ๘9Q!ฤslƒึY`…Mn+ฯใ๛ฃdธย ิ›K?jํ๑ผa [Š€;ธก๒d2vฐwถ#š@gvเ2Uภ Aฅj'AR&ฏไŽ*๊o Kฤ{ศ5 ฿ƒbร,ฅnฉxฺฏbดฌEJmfณ๐ๆ›3งJน ฮใ{]Xm$ ฌ(W*ฺจ”#ฆMฺัฃ{ MRj >ž? ZUPe2™}ฐW7 ไำ8-03ŠaFsึชWyั$ h@ 5ไญOจ1D " }ต>ƒ*แ@]™ปฺ`rฉ9‘ƒ•ƒrึธั0ฅRN2 •ฺโง.ต$@“R&ท ๕fฑPฒะษา.2ฬX6asD‰V$P pฦธe)ˆส cฐ“ำRVซpŠืŒ‰ฮไ"ฒ่ง…ฐค-Kๅ|;ฤS.๔ฦฌPภ`ฟ›ผาโ$EU]๏฿`,€Q.‡ฤฑ T`'bž๚;Vะภชส;zI-D“ฎDl2-4‘ƒ•‡pF`์)t’ตHvƒƒก บ:‚นvง?นๅณDฏvมส“dฬƒ4 ฟxyb5EKฐ(กป,Š{ฅjนซะ\n™ฑjก*ฐ ~๓’~*H|E๔คw1!h_|90๚ใ=Œฃ 'ซ˜0–๎\23 Bภbvฒฅiฐ"‰,r-๚"ษŒ#‰=ƒ๛.ƒSม‡}หŒ•็˜ˆ!€๕gฉo\.A/๛ฟt ’ัึ…0ฯž`ณ:ั~๏หdj‚น2 Šภัu>ศร๚"=‚โ†hต๕ไิ˜jฑว0Xšq8KNUภจ้Zm๑ฌชจ“่w‹bถิ(UpฦG €)BŒส˜Cศ,ค^๑ม\ๅAIHFƒXbอuAcH—„8Gฝไd๐ง1Q,Š1ฬ{“˜LhษvMXš๖v๖อ ‹O9เnฉ& E3ช9V1๑฿ใƒฑU4H ‚S๏ˆ™2d*Ai8ุql฿$J“๏Še@VkOิ)A+ํhdฤคDึ้›žฟ๖KะxhWŸัจq<‚7พ‡ิ๔[0cตjฝa๚๛0Aคฐฉhม—ด่”ม5ัwu/zก•Pใฦ6ลy‰๊๐เ๛D3”(2มใ๏$ว5่1$6573Ÿาช‚ ฑ ร๊a‡Jฆ~†ŸM‹๗;4‚หึP‚ @t1nิ๘w๕ฉL„ำz€tณe’|ใO{๙NงY๐มzหฃž4!งcw!มav 8ด๔4ฯถ๐a?“$ษŽHญ3mF๛G_ฟ‰๊sh๕G๋๘kรไ6S ]kOฏ\๗…3๙pฅ&ฟ:€ z&‰&ส‚Lหp+’‚ฺ๛kVขRž?|*Oึฉ‰้‘žl@’ุ๗ไ.r"ถ)ฅfำี๘H/>ๅฮft๏xซuฦuฆ๎p‚0>!›ษˆ2žํ๓(รูข›„ฬส‚†ล)ว0ˆ3์Œู/1w‚'ฤnณ}ฬy^zษ?$ชซsฆ#wฐ<–;€_อ^ป 8eา๕Xตฝิ$:œO`1Žr๙Ž๖-ธด„„ูaฆˆaQ‹ฌŠ–๖S‘Df8pฒ๋ภ&O€{ฤทฒmฆฬX'_ฯ1็า๔๋OEยB‘+™ฯ]A*อ3฿f,…%ข5ไ9N&1bะ[ศว ้,:e*า๖ญaฃ€_อ^ป 8eา๕XตฝิŽ=_ชชp mภp }:d*…z—TCช?u=0wq‰=c\ธ๔qษU•9ๆX-D?๖ƒP๐จBฐ&kA~Ÿ^(คd๔ ’;น!ธ|ธnsIhm๑P% 5๕ Zฅ๙ozโ้ฯtCYR g|  ๒ฐdƒAท:จพโ‚-Iˆถ๑๔Œ ๆLู@ะ% Tb)L“'KฎกหRŽเT!ษขJ&ฝ๘†1 มคŸ …6 ZƒZ=xู>ค iห0‘"Wตฟ0Hžฎฟ?ด"ูVF๖๒๊(DHะgฝ•)**Tดๅๅ} ˆX8ขŽ็dckˆ ฒq"พbะˆŒaป5V#ฝๅพš๏๓ ,,-ทฎอˆŸส๐RŠก! z>๔a\Š™j[8zo0„zะƒ(rฟใCVู€9ึนฎ_Lฅศdw(E๐6q‡tr๚K”žาฦ^ƒ@PBfํdy๖MมษŸ่ซซแ้ˆสงม1ž(ห;Hหๆ๘†๚Yณฝท}lถ๖k6AฆCC,‚ำ๚ธืYr[ ๏๙LŸๅsSคQพ ฃะ๘์k[ฤgGส ฉ\ุG1ŠฮLช0ิ ชษธ"y3๓ฝu|=1^ว'™๘ขX<`mDad  `Qำจ"qoXง&ฤaฎ%ฐKทพ๋„ž+žfดฎS’•๎็๘๐VเGฺู๛zžี#•รฐ](’Rมิ3ำสฎB1‚@w*lfG’ž7ฦฎ,2H‡o ถVแ<‚^ด“s๐ป2C“งY4๋”ฆŒ„oodfน:zๅAช0Vฒ๒่า๖ศC=-ส M5๙[๚‡lญัŽom,F–ฯฟ6ŠLB!นะ๒,ˆRจมV`IH‘ูกณ๗ม*๖โ€fีt8‹8็รซf:dพ฿‰ถ2ุฤ1“ัพ\„2L˜ _ณ๒๛mO๚ฟgๅ๖Ÿะe˜b2แ!ฑ,เa—เฉžT‘ฆsR/‹มY@๔kณชบB•M ^Mdœจ฿.๕:*ˆ๔ๅ’Cบฒื0ฬฬฆเ\6 ?๔d&L™2dษ“&OpSฆ‚% ŸศvL™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dห๕2dษ“&L™2dศฬcJS„4w๊ษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&L™2dษ“&Lพแนมฬ!wฟ'ฑฤ๖8žฯXIP›‹’ศp }J,œ‚:ขํŸb<Œ*)aฆยป้ย…๕๔ได’*BE ˆ…Q‘Žˆ E งแFจU0Ÿคะต น|GIภ1(€ฉ`R+เคล๔ *ซีซ:ฮVฮ™ าม๛๑จฤ q`3่,ฉฒ‚ดีษ•ต ƒฆ*ขำ๙ิPฐซ>€lX!n,sVษszƒษƒŽ๏แมยฒKปRm%Jœ!๎ O’‡} ๖baˆP้kOdLแ€ "i9อeิ’ฦ็Kร ๑ ,Ww•†ีวœฺKฬฑ0&ร"—xฒ'sjxฆuoือŽ“ชงบ ˆˆมp‰้DŸeG˜&+ะuv1f$Fa'”Wเ้‰ะทP๛Alam.ฝ1xLาK5๔ŸgQึ‘!‚† มมhืzฝั้ษด&9p22ดัิ‹eภ‰ๆ„นnื*ดPƒุ8[ kœOfศํZป” ƒมย๓ำโP5olเข๒cฃ1@ภ,๓<u|–7‚ม1 ฟฤ 4SIุbถQ”สœ˜žgฦุ1Jœ๕‡!ŒVผ{%Aึยy ึค๊–…%&v/'ฬฬว๛S0าญกีค%E†2G๔ฅ"<m‘ํ๏ล๗{mผซZา›†:์ล‹%] ˜?TซA$5ะ7fmแตกgฅ gมร]’Eหผ!ฤ๖8žOœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓Oœ๊|็S็:Ÿ9ิ๙ฮงฮu>sฉ๓๊$‚มฏรIํึxฮณฦuž3ฌ๑gŒ๋’c•๔mCๅะ`I์ห”O๓tlq1งฐ}_ฒ–Yw?3ล(Rพ‹ถ{‡… Pฌ++๘<7ฺ8)ƒ{”b$„emcPJ„d+`v)G๛  ซ@`‘ๅ@v iIย{สต}O(ี iUlbศmซำ‹a…Nq“5!ฝ‰&Y้๊[ุีkฏ`๛aFๅ”€œฮmฉค˜9w/คX สยauฐAฆ; €ไ๐ไฌหุห‚จ’ํ—;%k้GcpญFW0Mฆdะู tฏ๚‰–ฃSmUŸ_ปXˆžxฃิD:ส>+ดฐ๕๚Nb!2!5„Y๚คเiใ๐i ถrDำ›"CmˆฟA1Rรรน๕ ๚e%อ+G~Aฤ‚ ย‚ฆตV๘p<‚๙๛&ร๖&*Xxbื>ก~aชp$ัฤฏ?šƒ ฦดญณ?-š„hฏํโ ๒ฯีo˜ไฏ“พ?pŒl•๊…น„S๐ษย•mู๐—ำ)—ˆ 4ŠD0ฮE˜=Mc๘*01ะฏ,b @ ะฐก๕z…ศ 0Aิe็Bศ ถษtไmŽูไ…%ฦๅaภธฬœศ mฑไw@7DfUผ]+ˆ(@ญผ+แฝ~:่~lิ>>1 |…ฐฟ$งŽืฑดš_\nๅkน\ฒดเb˜ฑt๙ศ…=ž๐ยE•บมฉy d7.๙1”OŒกš‚Ÿ{ลฒ้Arช„$˜Y)Tžว…ƒ ?๓‡g3ฅหtโ|0ํ่ ฯะ Cซ์โHํ0ํชึD N) 0ศบ๕ช*d$ญแ’‹เJฆHฒท@85/็งRฃ3~Jฃเ3G6 ,ชไNArIฬ60ำ,›ผกวึสbm๖ฑFค‚,ซตw…Œ๘ถ4x"ู`งฟ่ใm_X สENŽ๖CSƒ9ศฏ wตƒฺฑWœr Iฃิงyโ ”; ล™Ÿผ–ถฤnพ4 ฺBิsธz๔– ‰–i!ศMอmI‰-oขเQ_๊ˆeฒ๗ิW…Um”๎Ÿj€ปรuWr้wˆ7ฐ;๏Q๊aขlo๛‹า6ห ž 6IทณMแฮ —gs Zป๖ลV†‡ึ/ŸฬOEDCฐฺฃ๗—%*๕Bงฆ๑[ …iUฏํŽ`nhŽ วHๆ;ฒHฑซ๏ฝ๒}™B า 6‹ฝฐ"~๘90ฮฝBฤ๘-๙?:qxฑc ’b๊ุnฝ‚mณฮผY„Rฃ<มeิ๔Xอ ึ_Gz9uฐ.ะ‚CXู๚š๒DP€ !|p˜`‹ะPžžด๘”l0ศ„ฌfŠF”ัI<ธIฦ`-hฐDไF๒Tdฐa{ฬฅ น“มอ1B๕‡ู82ลด)ดฮ73ห!cผ์ชรทw&‘มPRB2ŒkHดชฅI^ี=O“š )๗ย.ศo gmษฅGY%Cกtบ๔5R6=eHAฝสป…็จN‡ะ“มZ‹h อ ็พๅผ‚๙ƒ%BจฒvhไธCAเXkฉๅ„0๏8|(:์SxาูOKฏฒ›ัฺOฅฒp]-BOู๐`ZI—ฆ9K79Sฃ‹ฎ๛&จ6tธXผืY .ำQฯ๋˜ซU(ข8ั>ฦCw\บุLV’u)่ล[/ปณiตR๘๗Œ54Kฟo# ุถG๔พdZไanุ„Z(จL—ฬ”6j(ฺน7†”ูCรก๐5ยฎ>IโใTƒ‚dำ†Biƒฐ1ฒ‹BเEา๎`xฝๅ#D`s_—=8j"„|qิ6 5ฤ๔ W›ศEฒ+ขUH1"๘ณา*Vอ€}๕,ฆ&-ตํฐฤ…ะ W tJ}•zภHปn€yc1 ^ื1hX;&๗อœ๎ึูOแC่๐ฏsํฆŒŽ์ั"G‘ว&>ง|uแ@ไศ฿YตƒvCdฌC;(rKๅNค๓๓0ุลJ+อไ"ูั*ภบL9U'g๗ˆลUำ$$ ท^œUค…a•š๕๐จ Žฉ๏ X†(5*ฒฎเ฿ํ!ใ*=1๐–^ Q – ไoท!#!่k5ะ๓bDwiข^5=Zp…ษPcฦะธˆh๏€ท7;๓gH็ภ Cพ•ŽqLd๘Z๔ธ\…cz‘ฬ›’•ฅ„|A๎Ullr, hศ๋ตย่วNFท“ด†, Œ 1%รโ ำgผละ )‚JgถK@ Y'๏v>๑๏SŠbฃื*ว™ุ%EFtฉ“•Zฆป Rคฑl‡k๏ก9$วdะ0หqVฑนWเS๎ฎ๔Œ๖6ฺI_‰kMโ•,NMi1ฆ>>-i&ถ<ิ@เ)F eรโ ำ|=เ4O๐ฟ๋† *01tC๘ๆK{ ำkๅ)?• ึกt6$]ห‡X…iyใ‘ี๚ะ๎4)อ๗ค B˜_+‹ีุ|sj$^›๛ม%b๔ถ’7ํ ปร/๚โqg! 3|…7Ÿ 0l9=™ˆ ]‰ป!๑lbะๅ฿พ\,D‹Cๆฯ#ส2ฦ4wš ๓36 ะ้๏FMฒaฎฝS(ฝE  %\แธl)?)b๋ฬ(๓Jh‹<ŒะO้อHฬน—๔มงY ฮชฮI?v3ฆqยฑKึ’ทS<โถq€€ูC๖Bๅ ]€`Qฝmงิเ็ฏทถ;๓aS#Yn †4USจ˜•?ุ&ฝ O^ด9๏จ๓ฏŒJQM’@‹@Rg ฑธ1Vฅg:`มบ๓/t…10 žš ๘‹kวE–Y^z“ัค@X#พ‰ ˆ ๘AฤิVydv~ว`๒^dš๋๛*Q„Q4v0๎1ธย$ฏฏIq š๖S Bค b#9)(2๏ีAfี`๒ Y’ฑcKทฝOกะค5‘ SเซiกM๛ํ–d:๘ข€†rPญ์ตqzTไูnvxk€|xบๆd`…Dฌๆ(gึI™ŠYบฝถ3IH†)จz‚?นšฐ>ึ!b!ฮ(M฿ษ๒--^๎0ปI`ไ_ 5ษ5Eฺ7€ศ€๐Y)Š™ฟฉ‰ฤีร†LแซGงฆลV–฿„lJกฯPo”!Rฃว#๙์,L<ๆ&สแ:R0nํณฅl้b5ด!†‘ผ„ั X2]๔oS‚ZSๆD๙@”F-ว%ฦ7ฎ(เ€ิแฌ8ฒD‚Œ&L๘8s1๒/ฌ ๓Yโ„ชA์ZBสžJ^๚ก๓=-†#‘™[ู-ƒญ`…ไZW[๑ฺช•r†j›Fข่ํ€<‚^:ิฐiC&fR=รZˆE/ก3ืlJฟ›žmๆั๒(ูH=ป๐‚"‘ˆ๛+”ึาข๚D*ฝL_U‚1Vษ๓ู๘iชงaR –ึFV"iฦrฒ&๒Š!mำšฬ้ทญ=-†#‘™[ู-ƒญ`…ไZ๙ฬ[ฟเ๋-ำว่ํAโBUทt๏–ธ้เฌ3๘!–ตˆSก„Ž\ฌ฿ป&๘cPณจ]>่9D)ฬ v?เ 3‡Frฝกtภื’ืK™ั\ภี˜‘ฦˆ•}}% (ร๒ิ๎… K›ตižX RD?4ธ 5 ฬ–&3๊ขtว(โ0\Rํƒฃ<“ฌPืษชFh็d—ญ,HญzศcE๑i†Naฺ8j๕Sˆ‡,ดฎ๘„ลXŽฒE จHแุขyฮ งั้]‘B7ิ49สดย๓X๊คaำZํไ๊}ฉzฦTลฑฃะ'g nA†ณXi๏*๘5”œ gO7๑=`ิVฅช ข\ ็eYEh0ำฌPืษชFlฝึžqx:ƒu‹ะ_ฆ6j>ซe(็4Ya=๔ฯ๊ฮฟจฝ๑D‰+Žพู”รS-ะ˜"G˜jงฮ๖ภมhˆถbN{ .ญธ็oฐc้กภศถ.“…mHก,้๖0˜ฝj;ภุ'KvๅžเะIญ†ขuE…U๊์m๑2สๅUVไh95›ฐH{้ŸิQ{ใณ‡M,vZE$ “Fฏห/ะฆOsS)ae๛aL6Eว€eLมg๓ไu]แ"Z”ื…ๆยผ-๎0ณUฎŽ6V๔กi0x|……?Dซ;ัาo๋f € ุ”พย0€ฟ๒ƒ&\๖ูQ้ญํXFๅˆ7เูR๕O8 "ค๘)฿๋ลืฝˆ*ฒธๅศWCŒ AC e}&J3n”ฏฎพ€‘v„ืbKMเ–"ƒˆหeื9ฺ“Cำ˜J8( ฃธhนˆ`vตQฒ<ณ$ลคU†จ ‘า•ฐ€ศmQ];“ กถษA y/*.–}ญ ศ&,(ะไ Žอ_๘`‡ DฯG<€I“๒๘8, †kDh0ิX`‹`*UI;ฐŒ“Ž๒rb‡๕g„ql“6PF…bีฑž@@ก „p ี'H@S?ต5$ แOKแxึฐ[rn%,+แz๗ๅ&๛฿๋ސrฬGV&œงMI๎Zhื‚า ™s๚ชcL—J )๗ษ!ูQh QUรเw4Jf p์NƒบOC;@ฮc-L4 7z‘-8„ฉ–ะ๕ZŠK„๒ }สTฅ+Š๒๏$ะP‚๑89ถdr\$;*ศE { พ๔Mv‡ย๑4กZŠtnำ‚ฅ~จ y…(ฺ9ใ๚Ihฉ €ท‰Z‹ญท'M๙8่}"TๆฐnชnZ;0๘G R€Šห์ิ7ษสซ๏&3ัF=+Nธ`ฆ*p*โ๗y”แ-ัƒ'Av&_๎++>ˆษ่5ฃ ๖r8ฮ2Cภแ~%}‡อ ัๅ+โJ'ˆŽ งh๗ๅ๓ผ@<$๘XดนAUUธ่œุwlฉขˆ&ิ`3;‰์ ่ม@๖์ˆ6ฑŒ+%ู7’,2~ยN™ ุ]ปรฅTฎˆk‘M,แ๒ซ+ตฯตIก Lร†Œ/v(:9กWฟฮ1Rิไ˜N/|-]q@ฬฦJ๕๓ธ@ขฌr2zฤ1 – 9$ฑ=iลN๐/&Bช0ยรlช@ฤ;.Q๏ญ`ษ‘xึ2•ฝธd0=ฺD=ค&˜P>ŸมŽ&z#ฌAฝŠz}์q8ไมiบใ blŸๆพว Š{ื๕๑K)e—s๓‘ำv{1ธ8œ$ฆก[ri %™‚งฑŸ ^7ƒ)Dหีธืfอƒญ่๗า"Q๎˜ส ฤ๗ƒไš‰`ฬXฟวTI`H?Pร!‹hYS@Oํ“Eษฬ3ม($ฌ ‚ dศsฮถnŸ5Om“)wCK’G์๒๙ำ^ิฅ0๗u Lb7ฐŠ„ฉณเ$>ใปฐDนห41;ฌa;B๐๋›>'I‘žะ˜ั+ ”ีRR(7ม้>ฉ€ด}„‹ญ3ย|kX:ะใ Aก๗ตDภQซๅG ‚ป m ๋1„ภx^ุz+็ะgู–š{ลtŸ-ถ-7็šBŒTCืy๊Ÿ<ภดฃช˜ˆท†0ƒBI?ฎบn!๗„j%ศŽYก‰c็ๆ…๙ๆ๖๔0ะี๔ฐ2bkา~,ฐpฃ!ท Dำ๒[R='ๆซ#๏ p9ผF”A=G๊kนสฯZCD € J"{Žห9ฝ*3™"ZRอ5jต Fง๏ŽH“ญ&ํํ์ ำj๖%๖ฑ"IQš?ฐ=ด",ฬ๙Ow[”nDLฒT2rŒ…‹V๛jลW๔ๆ™{z บ4z3M๙ะฒ้ำG๊#mะข้าฎˆ0™{~ ;ดz๑“‰ผ9ม ’์๏๎{มซP7bุชะะ๚ล๓๙‰่จˆvT~๒เคฃe^จA๔3ljU/ท‰NยณK้้oอt).็ัw%วปฒ \)PAุb6GXิ9ฟgป ึD<ปB'ˆห้qบ)ถV]ื๎พญแrM0@r[Ÿth๊ํิฦ๎+.ซDˆณืพฎW๎QบSึฮP˜Rยพ‘๚7ฏ๏Bh›ธ‹X#ขา"?;i๚ฅNฬฬ6cา2 ญa9™QE …ณฌณฬฦHLF๑‚ฅi๒'Cizซฐ๐ใh๕hคไอwคฅ†*4ยiแWูuืX>ห"ล@ŒŽฆ&e†ภb ๊ ,TE9ฃ7ขyuB!ูAค ฬž”aอeriV 0Œ #?‚0๚2ถaž฿9€iญฌ$;ชV=ใhะ๏8‹Gp ะX4L้ลx๔ํ ๑ฒ๐KF‰‘‚ฃZม˜๖ฯจท๗˜Uญถต+G&'ƒ\ฦฑไ๕ZจทHŠA็—RY?7่ž‰z™kญXTyŸ้ขLา'ึŸ๏ V๎{ำ๘ย4)’ฑ ะBS}c:oโ0xP~_งR7x<žH) xฤฐขF>๏b8ฮเภ] นe์"ฯ‰Tง๊“f๓๋๓ažฬสvฅอเ๊Pau?BxผถrDX”^๊ๅฦœฝOGG–ํ‰ว€Z‡#f)x๔เฐณ žJ0ฌmsัGd„ƒผ’ด^y ค)ใVย‰๛ฝˆเC;๑๕Zภ;]ž฿eฉ7&๑ กเ`’EฬWั อ’W@ม„๑Fฃัจึๅ‘€๛๔ล!kํ Œ-ว‡ฉ Dจ”ใY-๛ฏP~™bค RbูษAC๐ว‚ขราอ๎”ฮh์B#ฑำv%k๕”œN;T^Jฐ€…U%"OaŸพIฃt‘ F6@JŸ๛yษ๗ษi-kc#„!ำปฏผฆxถ<ท_˜ขธญPgฒ{๏‰๒ฅ/J ฒe Jšฺ>Nัb81‡ฬW฿eชญHยF_Œ5}๎\Jdk„‡YHซ็Ž๙AŒผ๓ƒ๕^R๓ำ) '(ร‚ฎSRdwณ‡‰ะ1"ซ•ฟgžiGTรAฝ๑gEU`ฒž iี€=ฤFส=€L่๘๘่_x๚๊๓gษ8Œ sฝทุถŽ~ ฿/จS‰T0ฏBยผรhย" žสSู๘(4ฌŒบeธn ฬ๐]๙!ฉฃวึอ*mM™บ‚ฮ๕‘A2๒Q)<`ัN@7lบั€8ืŽiB€๎็ท™3q•Qˆ๎œžฦŠฦ#ญ"บ๛รŒ‚ด,6บq, •์c;Lจฐ•oข,ƒ€m* ํใะภy้ส?,ยeฤ‡r,@Z' "Zม˜ืภุ™!อS!Q%‚UฮDCา“škR0[yMm๒”ํfณ๑LcAbฤะแ›k้ปfฬl#ธRdิ(๖y›,kฐ5bโท{ฆpฒDLฤฅaึAt๛๛^‘ZvP#<"|ั–pU tŽZ™ดZฏฃmeไ๊ื๓ื)”Tฑขpย%ฌ| ‰’ี=แ๒nย(PR#kA”ƒIภkc™บ‚ฮ๕‘A2๒Q)<`ัNR$"84ณp9M–ฏD77เูqBส4มieฆทโqp{g|t˜สฤย๐‰ฅd,W‡2`Q๚ํ˜ด฿9 ๘๙ฉrNSŒe๊แ…fญบ๏™f†๗ใอoธ.๛VzFด ป2jkุ9 ๕พ(ก0e6๑‡su-5ปํ,~L‡uฑีขFkน Ž๊e oถ`ฟ๛™oื๖ฆ-›J‚ัh๒rG๊y“รวฤ:œฎถ7Œžบ2š„ฦCk:๙แัZQSˆŠ;X1 'nƒu฿บโeฉqา_ั‰E >{‡]ๆ[ oศ$ €(o8อJoผUม ฒถ2ูHฺ˜›};pg4ผ}˜`>!Y โhฌ‘JIฐ"ŠUยCก „>็ซ-A–% ณงภฯซฤฎ฿์%ล9ฦิ~jฃงะ*สๆTi๗I๏aกฉฅ7`ื#–‰bJฬU“‰ภฑaรสZ ๆแบ(Tฮญม›Dขะ˜ะถ9Žฏฎ4'๊๚lะYญ‚P๛€I๎“๓%+‡โ"”๛๎k8Qv"3้[ำ”MjๆP[e็IFKกํ†7˜น8aqZU …มมPบ…™uQf-ุ?๙ฤ฿Dbbชต __้vQC_Bpด†xุ o๚QQ6)!หdหgษ่ณ"๚fฉ|ฉ๋Uะ!€˜กv”๙–Q๘#4Ÿ้cผฆฒl’GฺขEEs๕ ฟ1คeB% BตH-๕(ฉ|†@ศซ#H28I‚๊U=2X์J{yค้)%Po๕สงฃ ไฌgQ๚๙†มฟ.5่ PฑGฺt1[ฺ.อqซ`จ†U’n๔ไำ#็ภŽ…Y้ยฟ:k เ…๘…๕i`ำ๊็ฐฺ ีฬจx&E์ตคUบ ๛UWภQgQ™P,œA) ]กํt,q=Ž'ฏ๒:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำง๑ฎ:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN:t้ำงN jAŸL‡๗?คฦ๔Iw“ุd ๊ ษZธtMNฏ. M”๏TฅlIoค๙3ˆUจ L ‘๊;(&8ด‹ฅSค “q๋ Žภพ…ไMภ`ี€ะ๖ปนฐษ$ะ_{n0K? ถ†ุฮo฿<3#ฬ>KhXV •ห2f†ดฆU๔‰-ข7ปกve#ิav…ำ˜aฦฌwช•ขูไ๙mษ%๋…ภP˜njผโย:Xฦตฌ'f0-8pZbัฦณ6*”๑ ”:รDป๚&c๚fˆ.๓›„กฐตF&Oฦ‚a%kŠn XqYAx‹ (gข‹ๅFณ[.iตนคลd‡ณhJ๒ฐ๊:ชๆคŠญธ•x๋'‚จะโ๔ช ”ๅ:฿ถu…rท>€ Xแฒแ้n1V๎9๕ึ+Eัภ๗๎ษp3ฦ ่&‰”t‹ถชxด๚`5–6Pอ1:d>g€วตซvV”H<˜Fhโމสฑqzr( 0Eฑ€dณX๎:tHC๙#้:“ูศ๏ๅL ฒZ๔1-&กฺkiไc™dq*ผYฐ$–ด ๛ทyโุ7YMLY๋žcรถA‡ญb็tXR2O2!ืhใล๐ว๗ฑข;็‰ฐ็IfXEซaโฺ 6>ฃ#“ํ‚2ฃืGณŒศฅ ฉลKMฒฎ'พlิ*ถศdัฐ@$๒moฑค๔Nธrะ|Z–4@Q G่๐e_{Lq$)๚Qมแj/_uั#นJดย”‡'ดู๘ศkA๎$F Oฺz\ึิฌรึ๐„šิ๊ำECัรฑร*˜Bˆ|–ถ—ธ P1e}jไ0Iลขฑ„ฎณธ) (สฌ€ม฿๎ก&๔y็'ฅ,€ฐ7ZFkOxs@o “43 รHlฎŽMiตq3mฆฬIฦƒF9๗`Ÿฐ ”<Š[aŠŽue ฝ)gก ญฤP œ0hII’x›ฝ1QมC0™Šล‚uถUๆป๊fmซc๘{ฺุaS๏ไ‡ง๐สLf[#~-๕๊๚ฃ%vv!b”†ฅ?”Ÿร)?ซyŒัˆ&ฝ๘lฃ๊ ฟไ?Ÿ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓๚^|๙๓็ฯŸ>|”†‘B0ฟแ|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็ฯŸ>|๙๓็qพ๏_U&†Šุฦช>;บ ใ4ฅฐjื๔Tย_Uยฟu –่dpฝะ†_เภ๎'้>Jฝส?ฃAฉ๒ภ›VA[?eญขดค ๚„แศ&LrEh›j7ฺ:OP{›G๏ช?_ร^$iฐ ™๋Z}xฒ็ผ)Ÿห…)5๙ะ„P ำ๙1X หึ๙๛Eอ ็ ว6เ€ฤฦร ฉฮ๏๙#0ฑ ดO3J’Kฺ.ิฆ&ฦg์Dx1๕ลG9jˆ๋uี`’แŠ9ฆfๆ $ญษชห^PyZม}ฉ$†b‚ะฏิ๎ pฬ๎๐ถjซHช๛>ุ๓Q๙ kช์‹ใW]อž„งร่/‡(นํ็ฃ…pNAET>‚i"0aืCœƒ‡oฉIพ–0sฦZัQ&Xธg[ัs”žาิ?ู ’ฬอdํF๐‚Vะฯซ>6โ< Qอs.Aมhz’mมe”ู๏XโกžbpG‰ว>œOƒJฌ\K๛ ~กAๅ…plแxแฯK…nŠ\นŠฎ.?QฆlซfฐบYkT• ‰€ชsม-ง๏ฅ?[๑งลv้UฦfmKUvKฌีึ–5 W@Zพkf d-zมg$ ๘๒๋O(HถMqŠEhYx.์9>›<€(…ฑฃ‚fฝYUvKฌีึ–๚ฌ\ศŠ^)ืดT1…ู8ชจy>Š’่€_&๚pP€ชคG!N-„ฒ่W‰๔#}ลุœนІE)พaหำ…kˆ%wk๔‡Ut]ึs/ณ ะŸH๙žba2z*(/+u๛@•ฺiญ]*บ๔5า์-…ง&j .ษušบ็๋ ๛ื;ศพฯEน€)iฤ_KŒฒt๋‘‡R๏oPศจ็ฅ้\}?๓ย—A--สฟผV๐มkปา๗๓h๋ Gmn|#uT็~ ˜ฃKภo๙†pn9๖ Bษข˜เjนB7ฺ าฟF[m๕ ูฅBมmqัCม" D6ิZl"€ Dddม†๑PrSใ16ทโุF๔M[ภl@ˆ‰eะม-Zทืœ6(ฬาฬ:šฦ.“XฮUฎ5F‹0Zภ๖ๅmเ-ฆืKLทIW? ๛'ป้})ฤw3@น*๒]๕นฝcภšดผƒ๖;๋เ(]ล B๒ปเ้Uอซวชฐ๋tฏT•Q™ƒr้ด๒็™ไ‰ใต ฯ VซฉY9Nฑlไุ\(”บ$ฃวP2Žn8๓!}k-cwJhตIe@ญ:œ.rษดฑพ#„ซ0ืŒษฒˆQg-ๆะพRจ€]น—f\ึe—เFฆtLำข‡N0Tฦ†Pจ^ ~็Iƒ2แพŽธZไœแ๒ซษมBส^ ณZJGUาฌฤื™มวำh†?-Mชแceล#]5Žˆญ\ะuป[qฑ@/nNi:ฆFฃ…แฎ™ฎ๏ขVยฃ^Eq1Wcจ่8oฃ,นc t;Œ2๒VuƒชฑTK%ถฆซ‚ข,ัท!ญi(‰ยฉ\]ัึKส%:๑*๓ญภั-(ี•ฎสแด$[nBๅˆvจPTะดภธ5t—l‹ล๑,Fน๑ชlrIoh$44ฆUZํฅฮ/‡>น?ฅน %&l]ˆœ8ฏ0ลeุŠต|‚าณ›}“u@VกฺTทญ†,ิหซuฐR%+! U‚๔3:ญฺ”TตกE ,}4~C๛‚ว/ิv<1ีK€ด/บG็u”ฃ:Lhา๒d9็‚'=46ถปˆฅjzj๔่ิฬkโถ๚ะซ™t\ำยˆD[z–ๅˆศณ%x=c้มUผขะ ฺ฿,ฑkYKtข‰yเˆไM๑ฃ็ค๓\๒า'ฌwVญ™iล€m€ถซx2ฃn†uD ๒tŸ–ภด8์%ญล้ร๑Fีศjื=v~7 kZโ๑ฝณ0—eRC"s1ฬเV \^?lร oงร†L˜ซซฦ‘wกึีซ.Y&QCัฌV^0i ำชดx5UทCXาฅ@ทํMถฌคฎั‚eซŒVˆณภ.ฒ–"*ุ ญุ$E–บq-xสแพMบฮถ{‘dืdเ`:Q“G<โ๐“ฦ5ซU-ใ|#™€\ มมซ‹วํ˜N”๋n{˜ึฏ}Sโนโ0‚6`ัปฐœz ส0ฎญw" KGƒฯ‹‚ฺฃ›TpดผDRN+5eŠขZ)ิเ ;ชึำZเลๆ่ ดpฉw6 ฝภฐKššล฿“๗3<อฝฬxฎกฤtmวqย้ญ`XใdkPuขdYัˆd™๕ฃ^ชIcํ*”h‹ฬp`-kTชiขรคr…/ๅ1ํzHyTšEทณ/~ฆ37tP๕๐จฏb+)ฝํ‡ณ<ำ<ๆ]ถท๚R`ไ๚ฦ‹H iฯ/–0๑ฅ3โ](Pœx0<”?\AEXYฉVใu(2-fํfp“4hŠวฐ ข่==ฬ๔๗๒ง•ไŸ„Oแ`&ะV Xู0jˆ’`_ุฎEqฤฉผ•ƒ)Œโะ๚หkก‰ij๓CœiคTด) X 8—G•AV[f„x๓k™– ัฅ5Miาc‰ยล`โƒ‘าเทJฃ’4˜ฦmEt+ZฉrY]ื๒฿ดำๆŸ‘}พยœoฑุYG 2,สŠ.๔๒Dj๑eบจด์ฅธๆฎ˜YqA๊šจšส๑ Aiฉeœiฦšมน๚ูkขัuDึRˆR€65MYx^(k่ถ))uGD˜Gสุฆฯ๔>ˆˆ้no†t๕ยเญr5vำš„ฉSiซํAuN„a?ฉu๛˜้O_T- 9งN}"#OVTฏ!Nฉ’“๒ห‚ๅกxG„ฝุVฺ8ผSรค7โห4Yapลีหฝ ‘nE@vฃšsM๓5jhใP/‡ต1„บ-P5แ’T‘ruษง1W:ช#€ี5งNRซU‚ิลSEฎ•x„Cคบm|ช<*YำBIผb”:M,|ร]๛0ถนค”mB]+_ 8'49L&ฎšŠะQดูyฉ0ำ‹0๐”‰™)t๎)R…Y8้ฃฝ๚“@ญไUj92ิ ‡Š^GK‚@‘4อไื† @ใf/ฅนตŠŒต‚\ยตzภ!VZก…sล‘]‘‘Lขe”๐R[+็บเ๑œW๙‘ลาไ้ ษ‘—|-ณS6ฑผUApดS ถะTำบ9hZปืigPดโ๏สx›งŒ็‰ภ^–ซ1๊Bิ…SK*e?ฏฃ*JŠdJUตฃ nี,oƒ'๋tQ"นแNสฤ0DTเRธศปฆ@ึ T—‰ะIฉbฅlเ4^, ‘&`ซFศ“$กใD];iI0[@ฦท ŽS<ใž๚๕CZYกลโะ•ฃL™€ิ…น7Utprธไู้สxฝ4_ูšb6ฃŸขต๊ฌ^E3๖ึ3ฝp*ง$ภ}ณ?…๊ิ ‚Zฆ”ร’อ+5‰jKขšี[ฑ๑แ.6•etน้+v‘m  o6p๋R‡่4Z"โq{8*˜ๅAฮ0ฒฝka Xึjตี'็^Wญpซฝณ Œ#QบVฅฉ4€iK€™ฌ^8ย;0ศRsั ้m4๊†iื“(ชTeZu0อa Aาย/เ04C i›ิชsjB๓/ฮ9"mฎ8ซ”FKiโ\!มดร%ฎมh้žk…ใ(ัiaB‚ะถœ1"โ3`ีตๆ†oV’‚ี บKฺภฺ๎fฒ™โ๎ห@ฌฦ๚า-Edๆ9ถ…)ถต#KRiา—3Xผq‚ฒฦm†ป›Nฃ%u–‹ฬึQTจสด๊fE`Wj0+ๅ.‚ส์L ็คย7ฦ่ื4โ:มPc(jƒCqy็*ว ดภ[‹\ล%/ก….ฌฎ`โฟiI๘E-ธคแ๚2xjœ#h ๆท๙]qฉ”ve6พA|๊+‰4ฉ0ซ๑žfŠC˜"๏Šโู็œlฤQฒพฑUถbซw‚šอ๗vd๕๕>๎  ‚ Dh๐ฐ@ๅ”นัญ@-กธ€D™.ฦYœฏขhฌขห—1 CiIŒ zq@ˆต!ํภD –๛ : †t˜F7Q[Jึฺฏ Qา“จR˜1จ=ฅงภq€@Іศฒ…Xปkฐ5ขfญ,ฝส0hBีซe‡ŽO&0ดo<)้bมNpๅ•ึ \ ฐVc)tธ2๒#DŽถึœๆ็B๔6:ุ_Zื๏)Y๚™\Yฦ3ร ƒDQ:&Iต:D๛—Ÿผณัื˜ญ.’ฺ๊๋่™๊(U[Uสซ•]XQ๓ฃTญ1uŽฝO3HคN‰’—'ัeUภซะเi,๎ Z…—Vต2wAS๕7ว ^–๐€ ผPัจ&4ยค฿("Tฏวib-0Jฒล๒ซ๏7ใ,ตit—V๋ฯัU…kuค๔L…™ŠชฝW,๛ฌUห]6า 6@a|v\ๆšL‚ั๖—Œก95M๑Xบ งLkฅ”ป3ํ”ต›OV€"Aช\^PI AC๚UฅwYwv ๒เณAJฏ#PbนZ้dัึŠฉWศใ5จ+ArหตฆŸฅpฑaภ.ชnบ˜๚๘kEM@๔ะZ ใZœFฌeB6k{Šำ'๋™Zqส8ญิพ•ZGยผ้ 7ŒFšq…ษa.‡ ‹uสWP.ฉ Tp•Lึ2Pผดณ—˜DฆˆP…าีYnฏqGz†ฐqญkฅสต`Rาฦฒ[Pฝ(ฏ0,m^ ๅช๔$pnซ4โ“/6 ‡ตrCํ๚ึณT–_žฌฏ๎…ีT6†Rต2สช(xฺWๅ็ ๑–ฆ‡01ภ2‚ฑz.OQ€ย๎›ๅกฅธC'พ.Gdzˆ5+rc&ะฝ3 =ิ l)ฦxม6๘าใธฏL้ฆc2uV\—64‰iuTโ=ขrนZ9"…Vบไฤา;ะด5ƒkXฝ.Uซ––5’ฺ…่qN2L/‰ุEžpดาnŒZf9{Kภ;Ylบฺ5I”:ู/ศ8Nื!ขด:Šภ0ญฆฃ•a.จซแrฟ8Q`ะชhศP๋ฤฤล๔d฿ฯy„ ล\ฦk+ ™,ผทชi „] ›ja”ผง+Q0๊}Wก;/ฑชV๕XSพฺ˜I‚ธKขภ%ี$)CW‡๏จ5ฆดืJK2ก\ž™tๅ‚๕Z„ฐึบ'2ฤs›—ฃธH่ฅีo.9G˜•Fญ ผผoސTMฦ€บ™ฃ ิqAD|่]็˜–ง3„7Jซ3๖_Chไ5S ข๕ีพI” (hฟ`=Pพ3‡ซ8ๆฒ๖1ย-์ธ˜uคว <ฆจ †หฉฉž9=ท็\/ูญoฯน๚_ฒl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎Mrl{“c›ไุ๗&วน6=ษฑ๎MrีŸีฟ?๚็้~ษฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6‰ฐ์M‡bl;aุ›ฤุv&รฑ6ˆLVโธร๔`ฟgชgฏถัธฌ…—๔—์Vท็,UนฦCŸฬ[ชsbีNa Tkง+sก๛๕ีD ชตŠภะ]ํฆ ขส๚Zˆ#(Bูl'‰™‘ @Hy(6ฐ`!†Zฮ *ฒ$/ญE๓AL*‚ฑ ลnhMB๔ j^"42'กbแ–ขS^•t๙€uk๘@)ฦทOจฟ ,^Qกpir๑ฦ>€ถ4.€ุ‡71Ap”ืิ‰ฏัx‰‡ักH.‘F}@ujQ˜ฦ…฿ะ-^xmDa–ขธ‚^Vi ฟจ่า"k๊ผฤUŸUโ`^?P[Q)งื\ขš‚`}q‰MBลฤ ๐๘!ฐ?žพ€แ-w้่Hะว\r๔•^\ยฎZฮ-›อcถTฦ%iิ๑~Q5>ขแพ&ซO;าีyก@%0ฤ๑ฯถeฌชีา“B€€Q[[†– 6bกKL  รyลจๆฌeˆ"ž ITษˆ๏ฬต •KTi.ฤ= pˆส4” €p”ฑIX_’  ˜04!Qกsดb“&e&ฟJแ ฟU˜b0ถxJภBiยVˆ–G’ ึ“ึŒˆL8™Jวฆ’sดว@•z‰Mzy† G’„”ede"เn’ƒ่cD j`ิณHƒ @v† G“ิ@NqF[šเฌๆคˆ”ืค/†)†ฏDQQฯฅฉซeฦPbs'2Pะpอ@\ลmค๚LcBธส zh}uฉ2fQ’kŽฐธA,๔XjzZใ_H[Q Lก๔ะฬŽ€Uฃ†%‚ฆธ lษˆ๋ Iฌ โ"k5วX\ —ฤ“น2f g,q,ฺ%ะˆš'Yก5 ี"ุ๘ ~๐–=g_Aฉ““ถ ฅ<๛ม ๕๙๕Iๆ lฌมฬำŠ6o!ฃ๔&จˆท)KrกEURภ}ญ๓W(ฦRc‹& ฿AW)'ํUbํ ฎซ\ิ@ป รฒก‘5าbR9šๆ’ kšg5ฬ”)–ธž8Ž*Su สDธฤาฆฑFฒื๑=Cww8ศK…L2–หา‰ฌื>น`5q…ฃpN-Tฦ‘บ—,K^}u"fD<ื)W ฅฮ๔๓ฆZ๑nฅน1„š‘FฟIฌื3ฒs5 ฒ™a)ฦjฬษ‰n0ี้ก่ธ–ฐอHฌYn3HH ิ ภ”8ˆคEฒi \p๚ๅHan ยหq–q)บ”ใC3tœHUฤภฃlQ–แ3้:ฐิ๔ตลn้)ฦH‹‰[ุะ๔๑ลaCอ˜'HWI’!Mcฌ5๚hฟSYฏั†ุ‰–%95ฬนMQืˆ[ฺ"hƒ‰”ื้:อ ฉ๊ิJk๛ึ๋Ÿฅ๛=m็-—zหYiง ฆ’๏YlทX%‰lา[ฏฅฆ’eผๅฒูฌทœตึZiu๕ดา[ฯา฿KOKeฒr๏YkฌทืIฌดา[-–๓๔ทาF’ืYLฎ9ฬSซฌาZ๋๔)าyœa’฿M%ฎฟUฎพ–๋9–๐šKyหฝeพ‚1ฎ฿KeณHซฌบา[ฏฅพ–๓๔ทŸฅบKbก๚Uu—ZKu–หyหu–๓šหYlถk-็-f‘WXฉธชn*ฬบำำIo9ฌทาูnž–ฐSHซฌดา[ฮ\ถฦ.ัl่ปืาrืYiคตึZi-๔ทŸฅฌบา[ฮ]๋-—zม#f-ท๊ถ-ท๋~๐ ESูฅ๛?ีญ๙ภj๕?Oๆตa‰๚_ณZ฿ŸฏS๔MŠsŽ1๛มS–jรฒ+spkGX@ำNง๒…ต5๔j h๕Cฤ A4bSาsB>†Žฅ›ฑฃดค)๕ j8kิดณะ[Lม๚hd๕-Š‚š!อ8๕#ฌaW˜™ข”ฌQะฏไญ}BiS@ษ8„u”eมO๒8ว๒•3oฯ‚๙๋่ื~ž„ uว/A้Uๅฬใ$:ฎq ทDผTึ‘Uฉb4ปaPbษ“n๙z6ฤฆพ_!j<๘รjT๓}็้~ฯAmL งŒขฝ"ฆQ…SKณฌ(‚:ฮกช†๓ p' 5๔Vฦัmนฎ:อNš3 fธxยแฉฌš-–5xšž‹ ƒ-`‡,j:Ї ฦ+Y=4aถแhิ๚ fนlฐC‹š‘ฌื0ดก5ร*จ)๔…ต0ำˆj@ถฆbชฑa‹d$ภจjzฺเ%โฝ>šฅแฺ.Œๆ˜ŽKšฦ‘ช:มฦeร.˜ั/7ซfฌZj า ™‹ภ†ณWลฟ?๘ ^ง้.จ็6ฯฬชผ:อข๙ฤึP›วJpำฉ่4Aศฦ–‰L ฒb %‚ฎฃAฎbัฌn ทqVFซ2ป๚‡Ncฌล1Œฦนˆสภ+ธƒ ฃ‹้ฌšฆจe€\@ัธึWT!MFš^‘˜Œทxิบ2ีจาUฤ*€-fฉFOะึWR†าิiฅ้ญภ9ธ+ฎใ2B‡, ฐ ปBIซ9Kฤ5zsผJ^e/ซฬO@zึํ—นJ361 ™LV5=mF่ี9วBdEถ: ฉษ9 ำ1p˜็ ฦž2ณQคซš17โq* ลทb฿ŸPใ๖?้~ฯ๎C๋ฟ๔ึสจˆท๕˜n-ท ‚"pกQo/จึfน~›*EฟA[ล%โฟๆm๙ื?K๖ซ[๓ฎpำlส่]Zฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ฯ'ใ<ŸŒ๒~3ษ๘ลภFYVK‹ฮ๕?ด+ฯฯศU๒iVธAA,ึSไ;จ,ก#A€JžญฐญArฐวxะ)"ำเz,Jี‹SเฮจŒง+FcV๊<๋๛• ้']„ฐุึ&j* ตPP, qขI4โ\]ัL‰ฒ*๘Kw8PคนฃธฃถFธกาดภC=+™ีฏpNycnฤ˜าๆbo$ 6` `Kฤถ+-ีBะ`NL‚จx–aใ๊•ชE๚8G™ฃ์๏)Vœีฐd=ฺฎ‘ญฮ;F$Zภ4ใฮดva”pK„เjฌ_Mฃ ๅญPปวh7ใ:šุยQณW๒9ื`Z@ฃ\t๛ห]QB๎ดป็rถฃGr๘w3|ฃ$[H๎๑ไMmpใมQSัžcั?QZฃส ุ<ˆV6l ^ s„Nืฏฺ"ขไซชี’Yƒภu‰eชหFฮงšฅY+šโใ”C๐Ÿฺ-ู8)Zš…นฎ0ฮqษM็็d*—๒ุ™hฉ nงtŽ‘… Xˆo$šj@mkdฺ…\FซaCฦฮVฐฉP VจMสโ๓ ืXฝฒ0*ะฉAŒ`(œ‘GQI]ไพๆ˜n•:ะแT ป@t› ‘tZธŽN”(ฅ,0‡ –ขŒ‰"u)Xเeึ#ฑบTโ+Lกจขอo„wตe‹ธ์”ŒฉถEร› ŒU™†าภึB"@ภLั hฃลQ๋„B ฤLˆำ๊–ซ๕0L"vศ๕าd†SCV๓ใN"…ช•ยจ็ฟิอtDจ*บ•Yะ็๖–`.ฝ G”Yฐrชแลำ} ัD^j‘๖แ ™cƒPฮZำฺ าŒัŠไ๎~aพGX‚ <8Dืกฌ2่^wศๅ( ฅ‚Hgคถ,E_r๑ ญš{ปแyช•œC ฌWuจข ซvo;t๛ิ&๕\๖*mฅŠpศ‡[€.Li–ผฆ–Ž&_dฟฒถธ็งโาี ขr๋ห๏ร2เ.ึญ š€hZEQ๐hy1L8]ึืM็็\#Vp -5 cŠ๋_ฺ8๛šžy๙ื0’ฃŠภา b9ั๔‚našRล ๕ž5๏๑Š'ฟจฮQZ€฿8IYจIJฦกŠWฌ74zบ”ต^ธž คธ…‡ๅ ๓เp๚B„ูmFโ๒œtใ †—4XZฅ&sHื9–,/NํฃฬGtยlชTโDตJLๆ‘ชึ ” ดS‹ๆตว‹%ั}—nห@MKH…”‹hb‹ข๋สa™' /fฦ ๆ€ @ไ~๒็2ๆVdึ ง”OบมBลฬ1ษล†เ8 ฅกmU๐3ฐ๐AŽe (œนWmEsA€„1เt:—๖ภ๊Žt&˜)ดฎYยกซน‰ฮหEi?๏?? ๘P ทง /gั{ฮ5ŸLฐๆz ล๛>`ถ=‚ ฺi็•่Esš๑—๎ฎ _ฤAฃช 5+งฬJดฌๆ ญ”bช๔๕1p!i„„)uzœฯDำ ƒE2ฎW ฦีิUy.๘ฆ}BU ึŠโ†ฏRF|ฬภt ีช”pืS^"ช`€งCฃeู˜ฮพJu บ•“กG8?3y < ต/[แ2ัจฤฉตžDZ…j 8Zัiยk9l ้z.O ๕Š€tEษฆu)œ4.G”ฬฎLยผWwฌ1›–๋2้ ^็Nss=ZCฎฆคฟฅ7ลฅาน,G‚@`ž˜ถ„รipกAkuช*าํ\dP๐เuึ#ถส†ฎฌาั@ท].ฟ๎? ํ™AY(RQšัxqE%’ ผ๑ahขมิภp๚†(…jš8Vu็{๙๐cงฅ+์W๕ํะg†๕โZฤคv๑ ๅƒ๑ฟ>v•˜กจ++p4–ˆั… ไืyๅาWZฎ g๘็ถŸŸฺ~๛i๙ํง็ถŸŸฺDร‡oฤ+!1aqA QP0@p`‘ก๐ม ฑฺ?๊nW๙ึี๖)•ำจญwe*ฝ[ฮ ฃูี œX ก"ฃ-Ÿwฅท‘:ฃถGฃ)bื( 7$กY+ชฌ๐ฎถ~ž`ฌฦ๊มu๎ฎ#hVokณz ๚๒ฺ›_ถˆ›Dๆ7Rล|ATDFขm๑ธ‘lฏ’Šฟ>ทสŸ’ƒไิฏ˜ท่บฒต็ีUฬmUS๊หฏ‹(Z _|xqgHU6]AฐM4๐&฿>โS^V‹‚ฝDำภYEฉJ๎BO€ะˆฉ๑‘๓|ำำเ˜แฏˆห_๑-ผzšPํ„ก%QHภ6ฯ’‡ซ ฉล+‚ฬชR†Œl อยห‘<พšผ’ษ{q‰qaธซxฌI}ั‰๎›๋!Tป:ฝทฏXปซY๎เีๆi์ ุ่{ ิศช‘jQUซ&Žห๙mขXU‚ตฑ€ซ%ฦ๎฿ๆภสg|ฒเาฑkEๅ|Rfฑ`ใ๛ˆ›’ลำ‹*“)ด ยแBข1– RฬจD๔–ทcุb8 o?ฺiฉหz1deซั็]ฤ€ Bก’ฏนRad"ํ[žํWƒกนŸํทค>Z bม๑ฃยg7็Tยฯฆ+ E๖€‰๖Z @‚!นน๑nPิญฎ|ค fฏ'ขI ๚OTPา)ธะลภํ"ญฆฏ *\ฬ๚d๓’จๅKlL1œยา‡p…dข–๔…^aถvฮ!T์ก‡6ิŽ๕่\5บ\Kwrฅ'9Qะ•Ryฃี-ช …ˆอ4B•HYdl85ำw@ได4ฌาO๛Iซฏ‚๊!”ˆ0‘.~2P„ฑfz<;€ R !ฉ๏็ำชUกภfะ…กžตเ{ภฐƒ๑ „ๅึอขลOo#ถ- ฺR๛x๔— %)ฉฑเ;;็ฟ/P9ฌฃ ’Œา์๘้„WZน๗ ]บ?ฺLH 1&eจ3E๗Œ‚nผKUล—€ช”’์m/ S‚หผุ๓ฎ$ุิŒ.ฉรจUW”โยไ5๗8ตธโ@\ย๒“€$ัM’Bจ่เ Xฆt]aยๅลn ูzฬ{้๔zง่้ฦ\K#-๗๒ดศ…TqƒิฎG8ณIXา‰–ญ(ว,')”๔ ูzŒฉ1C€ฒ2E]็Q5ฆน•Šฌ2~ฬfญ$Jาถ9 ๖๗-๚๋.˜@ป(- [รกฟxˆิ~ๅ` Eqd—ไF@&ฑy5Dˆ๛๐มP ‘*ŒK๗klFH‹ฏศตJ”j\Š/แข[.จ‹s$n5˜#lVยข#L( 4มฝ$&$ฐญข‹†ขCD–* kศดŒ€Ag้ผyDj(i€3Qธ,ƒ.จ—~ง3| kโญ~ีZv [vžฦใg{IัOฤ -ก U…– rˆ’ยวั!XzSดดหSแhXh ป ฐ)‰#a๖#ฏa@Kศ 0N#!๎g๊ *ก`ป&ะรแ๒-"ล3ก๑xจFlMศ‹‰‰ b ฐW๎"ณHj{ห~เ:DHMWลฅฒˆ[น’ญกV2Bd”หƒ๊!ฒ๘งPง Jl b(ลVัุ ฐ*โุฮาห อTTฃ6ฉeฬุ๐6฿œBa†ม-Ž”ฐiM2„ำผ@"ย~Yฅจ]• สฯSTW+QŠฅqUื˜Ea ((ฅๅ๑+8%บM> K Z๙ p€h BT๊L0X6‹-ฆฏ,i[-ฤดXP๚l„…І่SG โUCีส€-rใ0=๒ˆฤ}‰Qอ‚ญZลฑอ‚B-{`}."ฝไ}žอ็jv๏sPD€ถFl’€ซชฏึ=ฺฮชด*ะtG๎‚*๐}€ะช€Žจจ.่Z…ซF/วRป–๊ j*๎ j[๗แNุ)ฉษโฺฏ:ื‹u4อมMKu5w4ฮHs.cศฆผ*๎ kแnผZiœ’ำQWpSRนฝหM2ื,ไ๑ษw-02ฺจV_€ฆง$ทqMฐ&+ํ‰AM2ื,ไŠป–ชนmTฑฆrKjฅบ๐ซฟ&Žฌ bเา qŒ“้ำีxนณnึ.ํ๖ทท<๘๖หิฮษื%5AชฌVผppฅ].้AKตฉmW‹jฎ*๎fตw9"ฎุ)จซธ–T5เSS“ว'‹\,ติUิUดำ9 ฆฅฟpกถ\ฟ‡'‹\,ถrE]ฮHซถ i–š–ีE]ฒำS“ว$oิฅsโะฏ๗ B๏ี"ฃศภ฿์€)๚*_ฬJkศkPๆYจ‹_กฃ๔๖„ฑ=!j๓)”R๖{๕๑xDR ฅส`} S)๑&ƒ๊ํ9?CIี๐6oIFืV/… ฃ๊ํs๕ฯแช๑X๑^ลlz–4z๓่ušiX๖-อูsเฆAฤSญ:๓ตžnQS<•ริห† ฒGAฤขŸฟ4๛Pมฝส]‹qด_sศำqLฤ[†ฃL @2{”‚ฑพส‹E๐I 33)v-ฤ+Wิ-ˆ”ิ;Š–w‚จฦํ๑ี}๔ึ๔…ั_ gj€…กฅ#๖5ณ๕๒T๕@-a^จh8Jฐfร๎ะE`อU ท>]์ ส;๓์ดฉ๓@ภฺ)”ฝ$€+(ฑื”\ŠT ฟฉ“/[(ส$k!ฉCpฅูศ"ภFฬL›Yบเหw(นj}ˆๅธ™MภถœDุกธึCR—Cp ภ7RY„จำ ตฆ๋ƒ-!Gก–,`ES๊•ฑ47Znฏุ‡ยกดํ"ท๊ืX็ะญๆBดฒd็ีbภ "JE8]วฯื“i้ณ‘Vแย๙>จ๕‡ฺึ7H˜4 -๖์ดึŸˆT‡Lฺ—ถดn)!Q €hน“VoJฺผx๛„_ฑ_ขK_ธKแ”AยY๘รศ&ŸŒ7‚i๘ร~†Œะ{•4jฐ๘b"โส)žพUฬH ั-<(งqฆaบ•MEx- ๎XO๚โƒOฦ๒-ป#–เ4|,\IBฆŸhDไ!ป!ดmXa ?๖& ๗ >ษฌLEl`1—๗Pi๘ร~B/ ๘ >žn^4฿ฬ0ไ_ ฐlhฤ๐”[าRฉbแ‰“hQuฆebข,sAPi๘รศ&ŸŒ7‚i๘รrูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฒูlถ[-–หeฐำ๗์ดBม–ฒ9ท„ฌ๐C@ชดWวฯ“Tผ‹ Œpƒ5ฬRาฐ;wm^ณ๋ไo๙ำ๗หL)ด ช Aจ๓จRฅXH2สฦ™™FAh4*r†@rฦ็3™Šศ*;ูI์ห-N์r๛ศDe`vaœฤ‰L€qoบฌm›•มภOกˆงF–+ ‚ เีีภ&sฅั„t+~ ๋tE๔[^”ทw a~ฺ 4™DK7นฟ฿_ํ๏๕o๖†Ÿถฟเj6—Rฃ|"๖โˆ่ึๆภไยๆ{–Nl฿ญ้Š•ยLfไXฺะ˜–๛NกYฅnฬ๕>J/ฉ๎้+}ษ8ๆ3์{จอiUึด๔-อาฺR’ŒฎgWt›Vษd‡/Sจ1พ฿ฬ3PŸ๖Nos˜ืฌ„<“xร๙ฃๅ๏๗~~O่>}™๐๗๚๋ฑ4๐ฑ”l่lWwBŸde•#EB(“@รฑYYRLเ0I‰q\ณCuสšj ซ˜+GM 2ฐ(จรแ'จ ดŽww๋^่! ’“Qดฌซ{Œักt‹ศค@" รมj[Nห…๛XKb[A[อุš(„j+…-8ึ,Gฺฒ‚ˆPฎฝak๖ชชชŸฏŸฉ๋๗งๅŸะ?K฿ศ๛OฦA4aฟไOลๅขสBฤq[*ตFM? `”Pอ๒จธL7iSธˆ่ (YQ{กีDX‘L๏*ฃ-Œ€€ๆ5ฎ<=ฃx1uQ@หชข5.ภ—ธ[สšกฃ฿๋ฃŒB~ฺ^<_ฏ‚>/ƒ>""†+@R  ZฐŠdทธันY|ูgฆ ^AETŸl.N5กŸ$o๗Ÿ๗gฬ๒๙๗๛ฃไ๊i‡ธ0ฮa•†žๆุ๊‹๊kSpฬฌT๗SD ฬpิร_ะfŸ† thinc-9.0.0/website/docs/images/wrapper_tensorflow.svg000066400000000000000000000324201461023342500231500ustar00rootroot00000000000000 thinc-9.0.0/website/docs/index.md000066400000000000000000000105061461023342500166520ustar00rootroot00000000000000--- title: Introduction next: /docs/concept --- Thinc is a **lightweight deep learning library** that offers an elegant, type-checked, functional-programming API for **composing models**, with support for layers defined in other frameworks such as **PyTorch**, **TensorFlow** or **MXNet**. You can use Thinc as an interface layer, a standalone toolkit or a flexible way to develop new models. Previous versions of Thinc have been running quietly in production in thousands of companies, via both [spaCy](https://spacy.io) and [Prodigy](https://prodi.gy). We wrote the new version to let users **compose, configure and deploy custom models** built with their favorite framework. The end result is a library quite different in its design, that's easy to understand, plays well with others, and is a lot of fun to use. ---

[![](images/type_checking.jpg)](/docs/usage-type-checking)
##### Type-check your model definitions with custom types and [`mypy`](https://mypy.readthedocs.io/en/stable/) plugin ```python ### {small="true"} from thinc.api import PyTorchWrapper, TensorFlowWrapper pt_model = PyTorchWrapper(create_pytorch_model()) tf_model = TensorFlowWrapper(create_tensorflow_model()) # You can even stitch together strange hybrids # (not efficient, but possible) frankenmodel = chain(add(pt_model, tf_model), Linear(128), logistic()) ``` ##### Wrap PyTorch, TensorFlow & MXNet models for use in your network ```python ### {small="true"} def CaptionRater( text_encoder: Model[List[str], Floats2d], image_encoder: Model[List[Path], Floats2d] ) -> Model[Tuple[List[str], List[Path]], Floats2d]: return chain( concatenate( chain(get_item(0), text_encoder), chain(get_item(1), image_encoder) ), residual(Relu(nO=300, dropout=0.2, normalize=True)), Softmax(2) ) ``` ##### Concise functional-programming approach to model definition using composition rather than inheritance ```python ### {small="true"} apply_on = lambda layer, i: chain(getitem(i), layer) with Model.define_operators({"^": apply_on, ">>": chain, "|": concatenate}): model = ( (text_encoder ^ 0 | image_encoder ^ 1) >> residual(Relu(nO=300, dropout=0.2, normalize=True) >> Softmax(2) ) ``` ##### Optional custom infix notation via operator overloading ```ini ### {small="true"} [optimizer] @optimizers = "Adam.v1" [optimizer.learn_rate] @schedules = "slanted_triangular.v1" max_rate = 0.1 num_steps = 5000 ``` ##### Integrated config system to describe trees of objects and hyperparameters ```python ### {small="true"} from thinc.api import NumpyOps, set_current_ops def CustomOps(NumpyOps): def some_custom_op_my_layers_needs(...): ... set_current_ops(CustomOps()) ``` ##### Choice of extensible backends ```python ### {small="true"} encode_sentence = chain( list2ragged(), # concatenate sequences with_array( # ignore outer sequence structure (temporarily) concatenate(Embed(128, column=0), Embed(128, column=1)), Mish(128, dropout=0.2, normalize=True) ), ParametricAttention(128), reduce_mean() ) ``` ##### First-class support for variable-length sequences multiple built-in sequence representations and your layers can use any object ```python ### {small="true"} for i in range(10): for X, Y in train_batches: Yh, backprop = model.begin_update(X) loss, dYh = get_loss(Yh, Y) backprop(dYh) model.finish_update(optimizer) ``` ##### Low abstraction training loop --- - intro - transformers_tagger - parallel_training_ray thinc-9.0.0/website/docs/install.md000066400000000000000000000076401461023342500172160ustar00rootroot00000000000000--- title: Installation & Setup next: /docs/usage-config --- Thinc is compatible with **64-bit CPython 3.6+** and runs on **Unix/Linux**, **macOS/OS X** and **Windows**. The latest releases are available from [pip](https://pypi.python.org/pypi/thinc) and [conda](https://anaconda.org/conda-forge/thinc). ```bash ### pip $ pip install thinc ``` ```bash ### conda $ conda install -c conda-forge thinc ``` If you have installed PyTorch and you are using Python 3.7+, uninstall the package `dataclasses` with `pip uninstall dataclasses`, since it may have been installed by PyTorch and is incompatible with Python 3.7+. If you know your CUDA version, using the more explicit specifier allows `cupy` to be installed from a wheel, saving some compilation time. Once you have a GPU-enabled installation, the best way to activate it is to call [`prefer_gpu`](/docs/api-util#prefer_gpu) (will use GPU if available) or [`require_gpu`](/docs/api-util#require_gpu) (will raise an error if no GPU is available). ```python from thinc.api import prefer_gpu is_gpu = prefer_gpu() ``` ### Using build constraints when compiling from source If you install Thinc from source or with `pip` for platforms where there are not binary wheels on PyPI, you may need to use build constraints if any package in your environment requires an older version of `numpy`. If `numpy` gets downgraded from the most recent release at any point after you've compiled `thinc`, you might see an error that looks like this: ```none numpy.ndarray size changed, may indicate binary incompatibility. ``` To fix this, create a new virtual environment and install `thinc` and all of its dependencies using build constraints. [Build constraints](https://pip.pypa.io/en/stable/user_guide/#constraints-files) specify an older version of `numpy` that is only used while compiling `thinc`, and then your runtime environment can use any newer version of `numpy` and still be compatible. In addition, use `--no-cache-dir` to ignore any previously cached wheels so that all relevant packages are recompiled from scratch: ```shell PIP_CONSTRAINT=https://raw.githubusercontent.com/explosion/thinc/master/build-constraints.txt \ pip install thinc --no-cache-dir ``` Our build constraints currently specify the oldest supported `numpy` available on PyPI for `x86_64` and `aarch64`. Depending on your platform and environment, you may want to customize the specific versions of `numpy`. For other platforms, you can have a look at SciPy's [`oldest-supported-numpy`](https://github.com/scipy/oldest-supported-numpy/blob/main/setup.cfg) package to see what the oldest recommended versions of `numpy` are. (_Warning_: don't use `pip install -c constraints.txt` instead of `PIP_CONSTRAINT`, since this isn't applied to the isolated build environments.) --- ## Set up static type checking {#type-checking} Thinc makes extensive use of [type hints](https://docs.python.org/3/library/typing.html) and includes various [custom types](/docs/api-types) for input and output types, like arrays of different shapes. This lets you type check your code and model definitions, and will show you errors if your inputs and outputs don't match, greatly reducing time spent debugging. To use type checking, you can install [`mypy`](https://mypy.readthedocs.io/en/stable/) alongside Thinc. If you're using an editor like Visual Studio Code, you can also [enable `mypy` linting](https://code.visualstudio.com/docs/python/linting) to get real-time feedback as you write code. For more details, check out the docs on [using type checking](/docs/usage-type-checking). ```bash ### pip {small="true"} $ pip install mypy ``` ```ini ### mypy.ini {small="true"} [mypy] plugins = thinc.mypy ``` ![Screenshot of mypy linting in Visual Studio Code](images/type_checking2.jpg) thinc-9.0.0/website/docs/usage-config.md000066400000000000000000000577741461023342500201340ustar00rootroot00000000000000--- title: Configuration System next: /docs/usage-models --- Configuration is a huge problem for machine-learning code because you may want to expose almost any detail of any function as a hyperparameter. The setting you want to expose might be arbitrarily far down in your call stack, so the setting might need to pass all the way through the CLI or REST API, through any number of intermediate functions, affecting the interface of everything along the way. And then once those settings are added, they become hard to remove later. Default values also become hard to change without breaking backwards compatibility. To solve this problem, Thinc leverages [confection](https://github.com/explosion/confection) - a config system that lets you easily describe **arbitrary trees of objects**. The objects can be created via **function calls you register** using a simple decorator syntax. You can even version the functions you create, allowing you to make improvements without breaking backwards compatibility. The most similar config system we're aware of is [Gin](https://github.com/google/gin-config), which uses a similar syntax, and also allows you to link the configuration system to functions in your code using a decorator. Thinc's config system is simpler and emphasizes a different workflow via a subset of Gin's functionality. ```ini ### Config {small="true"} [training] patience = 10 dropout = 0.2 use_vectors = false [training.logging] level = "INFO" [nlp] # This uses the value of training.use_vectors use_vectors = ${training.use_vectors} lang = "en" ``` ```json ### Parsed {small="true"} { "training": { "patience": 10, "dropout": 0.2, "use_vectors": false, "logging": { "level": "INFO" } }, "nlp": { "use_vectors": false, "lang": "en" } } ``` The config is divided into sections, with the section name in square brackets โ€“ for example, `[training]`. Within the sections, config values can be assigned to keys using `=`. Values can also be referenced from other sections using the dot notation and placeholders indicated by the dollar sign and curly braces. For example, `${training.use_vectors}` will receive the value of `use_vectors` in the `training` block. This is useful for settings that are shared across components. The config format has three main differences from Python's built-in [`configparser`](https://docs.python.org/3/library/configparser.html): 1. **JSON-formatted values.** Thinc passes all values through `json.loads` to interpret them. You can use atomic values like strings, floats, integers or booleans, or you can use complex objects such as lists or maps. 2. **Structured sections.** Thinc uses a dot notation to build nested sections. If you have a section named `[section.subsection]`, Thinc will parse that into a nested structure, placing `subsection` within `section`. 3. **References to registry functions.** If a key starts with `@`, Thinc will interpret its value as the name of a function registry, load the function registered for that name and pass in the rest of the block as arguments. If type hints are available on the function, the argument values (and return value of the function) will be validated against them. This lets you express complex configurations, like a training pipeline where `batch_size` is populated by a function that yields floats (see [schedules](/docs/api-schedules)). Also see the section on [registry integration](#registry) for more details. There's **no pre-defined scheme** you have to follow and how you set up the top-level sections is up to you. At the end of it, you'll receive a dictionary with the values that you can use in your script โ€“ whether it's complete initialized functions, or just basic settings. For examples that show Thinc's config system in action, check out the following tutorials: - intro - basic_cnn_tagger --- ## Registry integration {#registry} Thinc's [registry system](/docs/api-config#registry) lets you **map string keys to functions**. For instance, let's say you want to define a new optimizer. You would define a function that constructs it and add it to the right register, like so: ```python ### Registering a function from typing import Union, Iterable import thinc @thinc.registry.optimizers.register("my_cool_optimizer.v1") def make_my_optimizer(learn_rate: Union[float, Iterable[float]], gamma: float): return MyCoolOptimizer(learn_rate, gamma) # Later you can retrieve your function by name: create_optimizer = thinc.registry.optimizers.get("my_cool_optimizer.v1") ``` The registry lets you refer to your function by string name, which is often more convenient than passing around the function itself. This is especially useful for configuration files: you can **provide the name of your function** and the **arguments** in the config file, and you'll have everything you need to rebuild the object. Since this is a common workflow, the registry system provides a shortcut for it, the [`registry.resolve`](/docs/api-config#registry-resolve) function. If a section contains a key beginning with `@`, it will be interpreted as the name of a function registry โ€“ e.g. `@optimizers` refers to a function registered in the `optimizers` registry. The value will be interpreted as the name to look up and the rest of the block will be passed into the function as arguments. Here's a simple example: ```ini ### config.cfg {small="true"} [optimizer] @optimizers = "my_cool_optimizer.v1" learn_rate = 0.001 gamma = 1e-8 ``` ```python ### Usage {small="true"} from thinc.api import Config, registry config = Config().from_disk("./config.cfg") resolved = registry.resolve(config) optimizer = resolved["optimizer"] ``` Under the hood, Thinc will look up the `"my_cool_optimizer.v1"` function in the `"optimizers"` registry and then call it with the arguments `learn_rate` and `gamma`. If the function has **type annotations**, it will also validate the input. For instance, if `learn_rate` is annotated as a `float` and the config defines a string, Thinc will raise an error. ```python ### Under the hood optimizer_func = thinc.registry.get("optimizers", "my_cool_optimizer.v1") optimizer = optimizer_func(learn_rate=0.001, gamma=1e-8) ``` **Note on type annotations:** If type annotations only define basic types like `str`, `int` or `bool`, the validation will accept all values that can be cast to this type. For instance, `0` is considered valid for `bool`, since `bool(0)` is valid, and the value passed to your function will be `False`. If you need stricter validation, you can use [`pydantic`'s strict types](https://pydantic-docs.helpmanual.io/usage/types/#strict-types) For details and examples, see the [section on advanced type annotations](#advanced-types) using [`pydantic`](https://github.com/samuelcolvin/pydantic). ### Recursive blocks {#registry-recursive} The function registry integration becomes even more powerful when used to build **recursive structures**. Let's say you want to use a learning rate schedule and pass in a schedule as the `learn_rate` argument. Here's an example of a function that yields an infinite series of decaying values, following the schedule `base_rate * 1 / (1 + decay * t)`. It's also available in Thinc as [`schedules.decaying`](/docs/api-schedules#decaying). The decorator registers the function `"my_cool_decaying_schedule.v1"` in the registry `schedules`: ```python import thinc from thinc.schedules import Schedule @thinc.registry.schedules("my_cool_decaying_schedule.v1") def decaying(base_rate: float, decay: float, *, t: int = 0) -> Schedule[float]: return Schedule( "decaying", _decaying_schedule, attrs={"base_rate": base_rate, "decay": decay, "t": t} ) def _decaying_schedule(schedule: Schedule, step: int, **kwargs) -> float: base_rate = schedule.attrs["base_rate"] decay = schedule.attrs["decay"] t = schedule.attrs["t"] return base_rate * (1.0 / (1.0 + decay * (step + t))) ``` In your config, you can now define the `learn_rate` as a subsection of `optimizer`, and specify its registry function and arguments: ```ini ### config.cfg [optimizer] @optimizers = "my_cool_optimizer.v1" gamma = 1e-8 [optimizer.learn_rate] @schedules = "my_cool_decaying_schedule.v1" base_rate = 0.001 decay = 1e-4 ``` When Thinc resolves the config, it will first look up `"my_cool_decaying_schedule.v1"` and call it with its arguments. Both arguments will be validated against the type annotations (float). The return value will then be passed to the optimizer function as the `learn_rate` argument. If type annotations are available for the return value and it's a type that can be evaluated, the return value of the function will be validated as well. ```python ### Under the hood learn_rate_func = thinc.registry.get("schedules", "my_cool_decaying_schedule.v1") learn_rate = learn_rate_func(base_rate=0.001, decay=1e-4) optimizer_func = thinc.registry.get("optimizers", "my_cool_optimizer.v1") optimizer = optimizer_func(learn_rate=learn_rate, gamma=1e-8) ``` After resolving the config and filling in the values, `registry.resolve` will return a tuple of the resolved config and the filled config with default values added. The resolved config will be a dict with one key, `"optimizer"`, mapped to an instance of the custom optimizer function initialized with the arguments defined in the config. ```python ### Usage {small="true"} from thinc.api import Config, registry config = Config().from_disk("./config.cfg") resolved = registry.resolve(config) ``` ```python ### Result {small="true"} { "optimizer": } ``` ### Defining variable positional arguments {#registries-args} If you're setting function arguments in a config block, Thinc will expect the function to have an argument of that same name. For instance, `base_rate = 0.001` means that the function will be called with `base_rate=0.001`. This works fine, since Python allows function arguments to be supplied as positional arguments _or_ as keyword arguments. If possible, named arguments are recommended, since it makes your code and config more explicit. However, in some situations, your registered function may accept variable positional arguments. In your config, you can then use `*` to define a list of values: ```python ### {small="true"} import thinc from thinc.schedules import Schedule @thinc.registry.schedules("my_cool_schedule.v1") def step_values(*steps: float, final: float = 1.0) -> Schedule[float]: step_list = list(steps) return Schedule( "step_values", _step_values_schedule, attrs={"steps": list(steps), "final": final} ) def _step_values_schedule(schedule: Schedule, step: int, **kwargs) -> float: steps = schedule.attrs["steps"] final = schedule.attrs["final"] return steps[step] if step < len(steps) else final ``` ```ini ### config.cfg {small="true"} [schedule] @schedules = "my_cool_schedule.v1" * = [0.05, 0.1, 0.25, 0.75, 0.9] final = 1.0 ``` **About type hints for variable arguments**: Type hints for variable arguments should always describe the [type of the individual arguments](https://www.python.org/dev/peps/pep-0484/#arbitrary-argument-lists-and-default-argument-values). If your arguments are floats, you'd annotate them as `*args: float` (even though `args` is technically a tuple of floats). This is also how Thinc will validate the config: if variable arguments are annotated as `float`, each item in `*` will be validated against `float`. You can also use the `*` placeholder in nested configs to populate positional arguments from function registries. This is useful for combinators like [`chain`](/docs/api-layers#combinators) that take a variable number of layers as arguments. The following config will create two [`Relu`](/docs/api-layers#relu) layers, pass them to [`chain`](/docs/api-layers#combinators) and return a combined model: ```ini ### Config {small="true"} [model] @layers = "chain.v1" [model.*.relu1] @layers = "Relu.v1" nO = 512 dropout = 0.2 [model.*.relu2] @layers = "Relu.v0" nO = 256 dropout = 0.1 ``` ```python ### Equivalent to {small="true"} from thinc.api import chain, Relu model = chain( Relu(nO=512, dropout=0.2), Relu(nO=256, dropout=0.1) ) ``` ### Using interpolation {#config-interpolation} For hyperparameters and other settings that need to be used in different places across your config, you can define a separate block once and then reference the values using the [extended interpolation](https://docs.python.org/3/library/configparser.html#configparser.ExtendedInterpolation). For example, `${hyper_params.dropout}` will insert the value of `dropout` from the section `hyper_params`. ```ini ### config.cfg {small="true"} [hyper_params] hidden_width = 512 dropout = 0.2 [model] @layers = "Relu.v1" nO = ${hyper_params.hidden_width} dropout = ${hyper_params.dropout} ``` ```json ### Parsed {small="true"} { "hyper_params": { "hidden_width": 512, "dropout": 0.2 }, "model": { "@layers": "Relu.v1", "nO": 512, "dropout": 0.2 } } ``` Interpolation happens **when the config is parsed**, i.e. when you create a [`Config`](/docs/api-config#config) object from a file, string, etc. and **before registered functions are resolved**. This means that you can only use it for hard-coded values like numbers and strings, not to define placeholders for resolved values. For instance, the `[model]` section in this example will be resolved to an instance of `Relu` โ€“ but you wouldn't be able to use `${model}` as the argument to another function defined in the config. To achieve this, you can either define another nested block or [variable positional arguments](#registries-args). ### Using custom registries {#registries-custom} Thinc's `registry` includes [several pre-defined registries](/docs/api-config#registry) that are also used for its built-in functions. You can also use the [`registry.create`](/docs/api-config#registry-create) method to add your own registries that you can then reference in config files. The following will create a registry `visualizers` and let you use the `@thinc.registry.visualizers` decorator, as well as the `@visualizers` key in config files. ```python ### Example import thinc thinc.registry.create("visualizers") @thinc.registry.visualizers("my_cool_visualizer.v1") def my_cool_visualizer(file_format: str = "jpg"): return MyCoolVisualizer(file_format) ``` ```ini ### config.cfg {small="true"} [visualizer] @visualizers = "my_cool_visualizer.v1" file_format = "svg" ``` ```python ### Result {small="true"} { "visualizer": } ``` --- ## Advanced type annotations with Pydantic {#advanced-types} If you're new to type hints and Python types, check out this great introduction from the [FastAPI docs](https://fastapi.tiangolo.com/python-types/). [`pydantic`](https://github.com/samuelcolvin/pydantic) is a modern Python library for **data parsing and validation** using type hints. It's used by Thinc to validate configuration files, and you can also use it in your model and component definition to enforce stricter and more fine-grained validation. If type annotations only define basic types like `str`, `int` or `bool`, the validation will accept all values that can be cast to this type. For instance, `0` is considered valid for `bool`, since `bool(0)` is valid. If you need stricter validation, you can use [strict types](https://pydantic-docs.helpmanual.io/usage/types/#strict-types) instead. This example defines an optimizer that only accepts a float, a positive integer and a constrained string matching the given regular expression: ```python ### Example {highlight="2,6-8"} import thinc from pydantic import StrictFloat, PositiveInt, constr @thinc.registry.optimizers("my_cool_optimizer.v1") def my_cool_optimizer( learn_rate: StrictFloat, steps: PositiveInt = 10, log_level: constr(regex="(DEBUG|INFO|WARNING|ERROR)") = "ERROR" ): return MyCoolOptimizer(learn_rate, steps, log_level) ``` If your config defines a value that's not compatible with the type annotations โ€“ for instance, a negative integer for `steps` โ€“ Thinc will raise an error: ```ini ### config.cfg {small="true"} [optimizer] @optimizers = "my_cool_optimizer.v1" learn_rate = 0.001 steps = -1 log_level = "DEBUG" ``` ``` ### Errors {small="true" wrap="true"} Config validation error steps ensure this value is greater than 0 {'@optimizers': 'my_cool_optimizer.v1', 'learn_rate': 0.001, 'steps': -1, 'log_level': 'DEBUG'} ``` For an overview of the available custom types, see the [`pydantic` documentation](https://pydantic-docs.helpmanual.io/usage/types/). Argument annotations can also define [`pydantic` models](https://pydantic-docs.helpmanual.io/usage/models/). This is useful if your function takes dictionaries as arguments. The data is then passed to the model and is parsed and validated. `pydantic` models are classes that inherit from the `pydantic.BaseModel` class and define fields with type hints and optional defaults as attributes: ```python ### Example {highlight="3-6,12"} from pydantic import BaseModel, StrictStr, constr, StrictBool class LoggingConfig(BaseModel): name: StrictStr level: constr(regex="(DEBUG|INFO|WARNING|ERROR)") = "INFO" use_colors: StrictBool = True @thinc.registry.optimizers("my_cool_optimizer.v1") def my_cool_optimizer( learn_rate: StrictFloat, steps: PositiveInt = 10, logging_config: LoggingConfig ): return MyCoolOptimizer(learn_rate, steps, logging_config) ``` In the config file, `logging_config` can now become its own section, `[optimizer.logging_config]`. Its values will be validated against the `LoggingConfig` schema: ```ini ### config.cfg [optimizer] @optimizers = "my_cool_optimizer.v1" learn_rate = 0.001 steps = 100 [optimizer.logging_config] name = "my_logger" level = "DEBUG" use_colors = false ``` For even more flexible validation of values and relationships between them, you can define [validators](https://pydantic-docs.helpmanual.io/usage/validators/) that apply to one or more attributes and return the parsed attribute. In this example, the validator checks that the value of `name` doesn't contain spaces and returns its lowercase form: ```python ### Example {highlight="8-12"} from pydantic import BaseModel, StrictStr, constr, StrictBool, validator class LoggingConfig(BaseModel): name: StrictStr level: constr(regex="(DEBUG|INFO|WARNING|ERROR)") = "INFO" use_colors: StrictBool = True @validator("name") def validate_name(cls, v): if " " in v: raise ValueError("name can't contain spaces") return v.lower() ``` ### Using a base schema {#advanced-types-base-schema} If a config file specifies registered functions, their argument values will be validated against the type annotations of the function. For all other values, you can pass a `schema` to [`registry.resolve`](/docs/api-config#registry-resolve), a [`pydantic` model](https://pydantic-docs.helpmanual.io/usage/models/) used to parse and validate the data. Models can also be nested to describe nested objects. ```python ### Schema from pydantic import BaseModel, StrictInt, StrictFloat, StrictBool, StrictStr from typing import List class TrainingSchema(BaseModel): patience: StrictInt dropout: StrictFloat use_vectors: StrictBool = False class NlpSchema(BaseModel): lang: StrictStr pipeline: List[StrictStr] class ConfigBaseSchema(BaseModel): training: TrainingSchema nlp: NlpSchema class Config: extra = "forbid" ``` Setting `extra = "forbid"` in the [`Config`](https://pydantic-docs.helpmanual.io/usage/model_config/) means that validation will fail if the object contains additional properties โ€“ for instance, another top-level section that's not `training`. The default value, `"ignore"`, means that additional properties will be ignored and filtered out. Setting `extra = "allow"` means any extra values will be passed through without validation. ```ini ### config.cfg {small="true"} [training] patience = 10 dropout = 0.2 use_vectors = false [nlp] lang = "en" pipeline = ["tagger", "parser"] ``` ```python ### Usage {small="true" highlight="6"} from thinc.api import registry, Config config = Config().from_disk("./config.cfg") resolved = registry.resolve( config, schema=ConfigBaseSchema ) ``` ### Filling a config with defaults {#advanced-types-fill-defaults} The main motivation for Thinc's configuration system was to eliminate hidden defaults and ensure that config settings are passed around consistently. This also means that config files should always define **all available settings**. The [`registry.fill`](/docs/api-config#registry-fill) method also resolves the config, but it leaves references to registered functions intact and doesn't replace them with their return values. If type annotations and/or a base schema are available, they will be used to parse the config and fill in any missing values and defaults to create an up-to-date "master config". Let's say you've updated your schema and scripts to use two additional optional settings. These settings should also be reflected in your config files so they accurately represent the available settings (and don't assume any hidden defaults). ```python ### {highlight="7-8"} from pydantic import BaseModel, StrictInt, StrictFloat, StrictBool class TrainingSchema(BaseModel): patience: StrictInt dropout: StrictFloat use_vectors: StrictBool = False use_tok2vec: StrictBool = False max_epochs: StrictInt = 100 ``` Calling [`registry.fill`](/docs/api-config#registry-fill) with your existing config will produce an updated version of it including the new settings and their defaults: ```ini ### Before {small="true"} [training] patience = 10 dropout = 0.2 use_vectors = false ``` ```ini ### After {small="true" highlight="5-6"} [training] patience = 10 dropout = 0.2 use_vectors = false use_tok2vec = false max_epochs = 100 ``` The same also works for config blocks that reference registry functions. If your **function arguments change**, you can run `registry.fill` to get your config up to date with the new defaults. For instance, let's say the optimizer now allows a new setting, `gamma`, that defaults to `1e-8`: ```python ### Example {highlight="8"} import thinc from pydantic import StrictFloat, PositiveInt, constr @thinc.registry.optimizers("my_cool_optimizer.v2") def my_cool_optimizer_v2( learn_rate: StrictFloat, steps: PositiveInt = 10, gamma: StrictFloat = 1e-8, log_level: constr(regex="(DEBUG|INFO|WARNING|ERROR)") = "ERROR" ): return MyCoolOptimizer(learn_rate, steps, gamma, log_level) ``` The config file should now also reflect this new setting and the default value that's being passed in โ€“ otherwise, you'll lose that piece of information. Running `registry.fill` solves this and returns a new `Config` with the complete set of available settings: ```ini ### Before {small="true"} [optimizer] @optimizers = "my_cool_optimizer.v2" learn_rate = 0.001 steps = 100 log_level = "INFO" ``` ```ini ### After {small="true" highlight="5"} [optimizer] @optimizers = "my_cool_optimizer.v2" learn_rate = 0.001 steps = 100 gamma = 1e-8 log_level = "INFO" ``` Note that if you're only filling and not resolving a config, Thinc will **not** load or call any registered functions, and it won't be able to validate the return values of registered functions against any types defined in the base schema. If you need to check that all functions exist and their return values match, use [`registry.resolve`](/docs/api-config#registry-resolve) instead. thinc-9.0.0/website/docs/usage-frameworks.md000066400000000000000000000327631461023342500210360ustar00rootroot00000000000000--- title: PyTorch, TensorFlow & MXNet teaser: Interoperability with machine learning frameworks next: /docs/usage-sequences --- Wrapping models from other frameworks is a core use case for Thinc: we want to make it easy for people to write [spaCy](https://spacy.io) components using their preferred machine learning solution. We expect a lot of code-bases will have similar requirements. As well as **wrapping whole models**, Thinc lets you call into an external framework for just **part of your model**: you can have a model where you use PyTorch just for the transformer layers, using "native" Thinc layers to do fiddly input and output transformations and add on task-specific "heads", as efficiency is less of a consideration for those parts of the network. ## How it works {#how-it-works} Thinc uses a special class, [`Shim`](/docs/api-model#shim), to hold references to external objects. This allows each wrapper space to define a custom type, with whatever attributes and methods are helpful, to assist in managing the communication between Thinc and the external library. The [`Model`](/docs/api-model#model) class holds `shim` instances in a separate list, and communicates with the shims about updates, serialization, changes of device, etc. ![](images/wrapper_pytorch.svg) ![](images/wrapper_tensorflow.svg) The wrapper will receive each batch of inputs, convert them into a suitable form for the underlying model instance, and pass them over to the shim, which will **manage the actual communication** with the model. The output is then passed back into the wrapper, and converted for use in the rest of the network. The equivalent procedure happens during backpropagation. Array conversion is handled via the [DLPack](https://github.com/dmlc/dlpack) standard wherever possible, so that data can be passed between the frameworks **without copying the data back** to the host device unnecessarily. | Framework | Wrapper layer | Shim | DLPack | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------ | | **PyTorch** | [`PyTorchWrapper`](/docs/api-layers#pytorchwrapper) ([code](https://github.com/explosion/thinc/blob/master/thinc/layers/pytorchwrapper.py)) | [`PyTorchShim`](/docs/api-model#shims) ([code](https://github.com/explosion/thinc/blob/master/thinc/shims/pytorch.py)) | | | **TorchScript** | [`TorchScriptWrapper`](/docs/api-layers#torchscriptwrapper) ([code](https://github.com/explosion/thinc/blob/master/thinc/layers/torchscriptwrapper.py)) | [`TorchScriptShim`](/docs/api-model#shims) ([code](https://github.com/explosion/thinc/blob/master/thinc/shims/torchscript.py)) | | | **TensorFlow** | [`TensorFlowWrapper`](/docs/api-layers#tensorflowwrapper) ([code](https://github.com/explosion/thinc/blob/master/thinc/layers/tensorflowwrapper.py)) | [`TensorFlowShim`](/docs/api-model#shims) ([code](https://github.com/explosion/thinc/blob/master/thinc/shims/tensorflow.py)) | | | **MXNet** | [`MXNetWrapper`](/docs/api-layers#mxnetwrapper) ([code](https://github.com/explosion/thinc/blob/master/thinc/layers/mxnetwrapper.py)) | [`MXNetShim`](/docs/api-model#shims) ([code](https://github.com/explosion/thinc/blob/master/thinc/shims/mxnet.py)) | | To see wrapped models in action, check out the following examples: - intro - transformers_tagger --- ## Integrating models {#integrating-models} The [`PyTorchWrapper`](/docs/api-layers#pytorchwrapper) and [`TensorFlowWrapper`](/docs/api-layers#tensorflowwrapper) layers allow you to easily use your predefined models in Thinc, as part or all of your network. For simple models that accept one array as input and return one array as output, all you need to do is create the PyTorch/TensorFlow layer and pass it into the wrapper. The wrapper model will behave like any other Thinc layer. ```python ### PyTorch Example {highlight="5"} from thinc.api import PyTorchWrapper, chain, Linear import torch.nn model = chain( PyTorchWrapper(torch.nn.Linear(16, 8)), # ๐Ÿšจ PyTorch goes (nI, nO)! Linear(4, 8) ) X = model.ops.alloc2f(1, 16) # make a dummy batch model.initialize(X=X) Y, backprop = model(X, is_train=True) dX = backprop(Y) ``` In Thinc v8.2+, TensorFlow support is not enabled by default. To enable TensorFlow: ```python from thinc.api import enable_tensorflow enable_tensorflow() ``` ```python ### TensorFlow Example {highlight="6"} from thinc.api import TensorFlowWrapper, chain, Linear from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense model = chain( TensorFlowWrapper(Sequential([Dense(8, input_shape=(16,))])), Linear(4, 8) ) X = model.ops.alloc2f(1, 16) # make a dummy batch model.initialize(X=X) Y, backprop = model(X, is_train=True) dX = backprop(Y) ``` **In theory**, you can also chain together layers and models written in PyTorch _and_ TensorFlow. However, this is likely a bad idea for actual production use, especially since TensorFlow tends to hog the GPU. It could come in handy during development, though, for instance if you need to port your models from one framework to another. ```python ### Frankenmodel {highlight="7-8"} from thinc.api import PyTorchWrapper, TensorFlowWrapper, chain, Linear from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense import torch.nn model = chain( # ๐Ÿšจ probably don't do this in production PyTorchWrapper(torch.nn.Linear(16, 8)), TensorFlowWrapper(Sequential([Dense(4, input_shape=(8,))])), Linear(2, 4) ) model.initialize(X=model.ops.alloc2f(1, 16)) ``` For more complex cases, you can control the way data is passed into the wrapper using the `convert_inputs` and `convert_outputs` callbacks. Both callbacks have input signatures like normal `forward` functions and return a tuple with their output and a callback to handle the backward pass. However, the converters will send and receive different data during the backward pass. | โ€Ž | Forward | Backward | | ---------- | --------------------------------------------- | --------------------------------------------- | | **Input** | Thinc Framework | Framework Thinc | | **Output** | Framework Thinc | Thinc Framework | To convert arrays, you can use the `xp2` and `2xp` utility functions which translate to and from `numpy` and `cupy` arrays. | Framework | To numpy / cupy | From numpy / cupy | | -------------- | ----------------------------------------------- | ----------------------------------------------- | | **PyTorch** | [`xp2torch`](/docs/api-util#xp2torch) | [`torch2xp`](/docs/api-util#torch2xp) | | **TensorFlow** | [`xp2tensorflow`](/docs/api-util#xp2tensorflow) | [`tensorflow2xp`](/docs/api-util#tensorflow2xp) | | **MXNet** | [`xp2mxnet`](/docs/api-util#xp2mxnet) | [`mxnet2xp`](/docs/api-util#mxnet2xp) | ### convert_inputs {#convert_inputs tag="function"} The [`ArgsKwargs`](/docs/api-types#argskwargs) object is a little dataclass that represents the tuple `(args, kwargs)`. Whatever you put in the `ArgsKwargs` you return from your `convert_inputs` function will be passed directly into PyTorch/TensorFlow/etc. In the backward pass, the shim will return a callback with the gradients from PyTorch, in matching positions on another `ArgsKwargs` object, and you'll then return an object that matches the original input, to pass the gradient back down the Thinc model. | Argument | Type | Description | | ----------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | | `model` | Model | The wrapper layer. | | `inputs` | Any | The input to the layer. | | `is_train` | bool | A flag indicating training context. | | **RETURNS** | Tuple[ArgsKwargs, Callable[[ArgsKwargs], Any] | Inputs to the `PyTorchShim`, and a callback that receives the input gradients from PyTorch and returns the converted gradients. | ### convert_outputs {#convert_outputs tag="function"} For the output, the converter will receive a tuple that contains the original input (i.e. whatever was passed into `convert_inputs`, and the output from the PyTorch/TensorFlow/etc. layer. The input is provided because the output may not contain all the information you need to manage the conversion. The `convert_output` function should return the output object for the rest of the network, converting via the `2xp` helpers as necessary, along with the un-convert callback. The un-convert callback will receive a gradient object from the Thinc layer above it in the network, and will return an `ArgsKwargs` object that will be passed into [`torch.autograd.backward`](https://pytorch.org/docs/stable/autograd.html#torch.autograd.backward) and the TensorFlow model and [`tensorflow.GradientTape.watch`](https://www.tensorflow.org/api_docs/python/tf/GradientTape#watch) respectively. | Argument | Type | Description | | --------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | convert_outputs | Model | The wrapper layer. | | `outputs` | Tuple[Any, Any] | A tuple of the original inputs and the PyTorch model's outputs. | | **RETURNS** | Tuple[Any, Callable[[Any], ArgsKwargs]] | A tuple of the PyTorch outputs, and a callback to un-convert the gradient for PyTorch that takes the output gradients from Thinc and returns the output gradients for PyTorch. | The converter functions are designed to allow the `PyTorchWrapper` and `TensorFlowWrapper` to **handle the vast majority of cases** you might face, but if you do face a situation they don't cover, you can always just write a distinct wrapper layer to handle your custom logic. ### More specific PyTorch layers {#pytorch-layers} Thinc also includes some more specific PyTorch layers for common use-cases. The [`PyTorchLSTM`](/docs/api-layers#lstm) layer creates and wraps the [`torch.nn.LSTM`](https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM) class, making creation particularly easy. The [`PyTorchRNNWrapper`](/docs/api-layers#pytorchwrapper) provides a little more flexibility, allowing you to pass in a custom sequence model that has the same inputs and output behavior as a [`torch.nn.RNN`](https://pytorch.org/docs/stable/nn.html#torch.nn.RNN) object. ### Avoiding memory contention (experimental) {#memory-contention} If you use the `PyTorchWrapper` for part of your network while using Thinc's layers for other parts, you may find yourself running out of GPU memory unexpectedly. This can occur because both PyTorch and `cupy` reserve their own **internal memory pools**, and the two libraries do not communicate with each other. When PyTorch needs more memory, it can only ask the device โ€“ so you may get an out-of-memory error even though `cupy`'s pool has plenty of spare memory available. The best solution to this problem is to **reroute the memory requests** so that only one library is in charge. Specifically, `cupy` offers a [`cupy.cuda.set_allocator`](https://docs-cupy.chainer.org/en/stable/reference/generated/cupy.cuda.set_allocator.html) function, which should allow a custom allocator to be created that requests its memory via PyTorch. Thinc provides a handy shortcut for this via the [`set_gpu_allocator`](/docs/api-backends#set_gpu_allocator) helper function. - gpu_memory thinc-9.0.0/website/docs/usage-models.md000066400000000000000000001411161461023342500201320ustar00rootroot00000000000000--- title: Defining and Using Models next: /docs/usage-training --- Thinc's model-definition API is based on functional programming. The library provides a compact set of useful [combinator functions](/docs/api-layers#combinators), which combine layers together in different ways. It's also very easy to write your own combinators, to implement custom logic. Thinc also provides [shim classes](/docs/usage-frameworks) that let you wrap models from other libraries, allowing you to use them within Thinc. There are a few great advantages to Thinc's approach: there's **less syntax to remember**, complex models can be defined **very concisely**, we can perform **shape inference** to save you from passing in redundant values, and we're able to perform sophisticated **network validation**, making it easier to raise errors early if there's a problem with your network. Thinc's approach does come with some disadvantages, however. If you write custom combinators, you'll have to take care to **pass your gradients through** correctly during the backward pass. Thinc also doesn't try to perform sophisticated graph optimizations, so "native" Thinc models may be slower than PyTorch or TensorFlow. That's where the [shim layers](/docs/usage-frameworks) come in: you can use Thinc to make all the **data manipulation and preprocessing** operations easy and readable, and then call into TensorFlow or PyTorch for the expensive part of your model, such as your transformer layers or BiLSTM. - intro - intro_model - basic_cnn_tagger - transformers_tagger --- ## Composing models {#composing} Thinc follows a **functional-programming approach** to model definition. Its approach is especially effective for complicated network architectures, and use-cases where different data-types need to be passed through the network to reach specific subcomponents. However, individual Thinc components are often less performant than implementations from other libraries, so we suggest the use of wrapper objects around performance-sensitive components such as LSTM or transformer encoders. You then use Thinc to wire these building blocks together in complicated ways, taking advantage of the type checking, configuration system and concise syntax to make your code easier to write, read and maintain. For instance, let's say you want a simple three-layer network, where you apply two fully-connected layers, each with a non-linear activation function, and then an output layer with a softmax activation. Thinc provides creation functions that pair weights + activation with optional dropout and layer normalization, and the feed-forward relationship is expressed using the [`chain`](/docs/api-layers#chain) combinator. So the three layer network would be: ```python ### Simple model model = chain( Relu(nO=hidden_width, dropout=0.2), Relu(nO=hidden_width, dropout=0.2), Softmax(nO=n_classes) ) ``` The [`chain`](/docs/api-layers#chain) function is similar to the `Sequential` class in PyTorch and Keras: it expresses a **feed-forward relationship** between the layers you pass in. We refer to wiring functions like `chain` as [**combinators**](/docs/api-layers#combinators). While most libraries provide a few combinators, Thinc takes this general approach a bit further. Instead of expressing operations over data, you'll often create your network by expressing operations over functions. This is what we mean when we say Thinc favors a "functional" as opposed to "imperative" approach. ```python ### Imperative {small="true"} def multiply_reshape_sum(linear, X, pieces=4): Y = linear.forward(X) Y = Y.reshape((Y.shape[0], -1, pieces)) Y = Y.sum(axis=-1) return Y ``` ```python ### Functional {small="true"} multiply_reshape_sum = chain( linear, reshape(lambda Y, pieces: (X.shape[0], -1, pieces), {"pieces": 4}), reduce_sum(axis=-1) ) ``` In the **imperative** code above, you write a function that takes a batch of data, do some things to it, and return the result. The **functional** code is one step more abstract: you define the function using a relationship (`chain`) and pass in functions to do each step. This approach is confusing at first, but we promise it pays off once the network gets more complicated, especially when combined with the option to define your own infix notation through operator overloading. ```python ### Tagger with multi-feature embedding and CNN encoding from thinc.api import HashEmbed, Maxout, Softmax, expand_window from thinc.api import residual, with_array, clone, chain, concatenate width = 128 depth = 4 n_tags = 17 def MultiEmbed(width): return concatenate( HashEmbed(width, 4000, column=0), HashEmbed(width // 2, 2000, column=1), HashEmbed(width // 2, 2000, column=2), HashEmbed(width // 2, 2000, column=3), ) def Hidden(nO, dropout=0.2): return Maxout(nO, pieces=3, normalize=True, dropout=dropout) def CNN(width): return residual(chain(expand_window(1), Hidden(width))) model = with_array( chain( MultiEmbed(width), Hidden(width), clone(CNN(width), depth), Softmax(n_tags) ) ) ``` The example above shows the definition of a tagger model with a **multi-feature CNN token-to-vector encoder**, similar to the one we used in [spaCy](https://spacy.io) v2.x. Multiple numeric ID features are extracted for each word, and each feature is separately embedded. The separate vectors are concatenated and passed through a hidden layer, and then several convolutional layers are applied for contextual encoding. Each CNN layer performs a "sequence-to-column" transformation, where a window of surrounding words is concatenated to each vector. A hidden layer then maps the result back to the original dimensionality. Residual connections and layer normalization are used to assist convergence. ### Overloading operators {#operators} The [`Model.define_operators`](/docs/api-model#define_operators) classmethod allows you to bind arbitrary binary functions to Python operators, for use in any `Model` instance. The method can (and should) be used as a contextmanager, so that the overloading is limited to the immediate block. This allows concise and expressive model definitions, using custom infix notations. ```python from thinc.api import Model, chain, Relu, Softmax with Model.define_operators({">>": chain}): model = Relu(512) >> Relu(512) >> Softmax() ``` `Model.define_operators` takes a dict of operators mapped to functions, typically [combinators](/docs/api-layers#combinators). Each function should expect two arguments, one of which is a [`Model`](/docs/api-model) instance. The second argument can be any type, but will usually be another model. Within the block you can now use the defined operators to compose layers โ€“ for instance, `a >> b` is equivalent to `chain(a, b)`. The overloading is cleaned up again at the end of the block. The following operators are supported: `+`, `-`, `*`, `@`, `/`, `//`, `%`, `**`, `<<`, `>>`, `&`, `^` and `|`. If your models are very complicated, operator overloading can make your code **more concise and readable**, while also making it easier to change things and experiment with different architectures. Here's the same CNN-based tagger, written with operator overloading. ```python ### with operator overloading from thinc.api import Model, HashEmbed, Maxout, Softmax, expand_window from thinc.api import residual, with_array, clone, chain, concatenate width = 128 depth = 4 n_tags = 17 def Hidden(nO, dropout=0.2): return Maxout(nO, pieces=3, normalize=True, dropout=dropout) with Model.define_operators({">>": chain, "**": clone, "|": concatenate}): model = with_array( ( HashEmbed(width, 4000, column=0) | HashEmbed(width // 2, 2000, column=1) | HashEmbed(width // 2, 2000, column=2) | HashEmbed(width // 2, 2000, column=3) ) >> Hidden(width) >> residual(expand_window(1) >> Hidden(width)) ** depth >> Softmax(n_tags) ) ``` You won't always want to use operator overloading, but sometimes it's the best way to show how information flows through the network. It can also help you toggle debugging, logging or other configuration over individual components. For instance, you might set up your operators so that you can write `LSTM(width, width) @ 4` to set logging level 4 over just that component. Note that the binding is defined at the beginning of each block, so you're free to bind operators to your own functions, allowing you to define something like a local domain-specific language. ### Initialization and data validation {#validation} After defining your model, you can call [`Model.initialize`](/docs/api-model#initialize) to initialize the weights, calculate unset dimensions, set attributes or perform any other setup that's required. Combinators are in charge of initializing their child layers. `Model.initialize` takes an optional **sample of input and output data** that's used to **infer missing shapes** and **validate your network**. If possible, you should always provide at least _some_ data to ensure all dimensions are set and to spot potential problems early on. If a layer receives an unexpected data type, Thinc will raise a [`DataValidationError`](/docs/api-util#errors) โ€“ like in this case where a [`Linear`](/docs/api-layers#linear) layer that expects a 2d array is initialized with a 3d array: ```python ### Invalid data {small="true"} from thinc.api import Linear import numpy X = numpy.zeros((1, 1, 1), dtype="f") model = Linear(1, 2) model.initialize(X=X) ``` ``` ### Error {small="true"} Data validation error in 'linear' X: <class 'numpy.ndarray'> Y: <class 'NoneType'> X wrong array dimensions (expected 2, got 3) ``` During initialization, the inputs and outputs that pass through the model are checked against the **signature** of the layer's `forward` function. If a layer's forward pass annotates the input as `X: Floats2d` but receives a 3d array of floats, an error is raised. Similarly, if the forward pass annotates its return value as `-> Tuple[List[FloatsXd], Callable]` but the model is initialized with an array as the output data sample, you'll also see an error. Because each layer is only responsible for itself (and its direct children), data validation also works out-of-the-box for complex and nested networks. That's also where it's most powerful, since it lets you detect problems as the data is transformed. In this example, the [`Relu`](/docs/api-layers#relu) layer outputs a 2d array, but the [`ParametricAttention`](/docs/api-layers#parametricattention) layer expects a [ragged array](/docs/api-types#ragged) of data and lengths. ```python ### Invalid network {small="true"} X = [numpy.zeros((4, 75), dtype="f")] Y = numpy.zeros((1,), dtype="f") model = chain( list2ragged(), reduce_sum(), Relu(12, dropout=0.5), # -> Floats2d ParametricAttention(12) ) model.initialize(X=X, Y=Y) ``` ``` ### Error {small="true"} Data validation error in 'para-attn' X: <class 'numpy.ndarray'> Y: <class 'NoneType'> X instance of Ragged expected ``` Note that if a layer accepts multiple types, the data will be validated against each type and if it doesn't match any of them, you'll see an error describing **all mismatches**. For instance, `with_array` accepts a ragged array, a padded array, a 2d array or a list of 2d arrays. If you pass in a 3d array, which is invalid, the error will look like this: ```python ### Invalid data {small="true"} from thinc.api import with_array, Linear import numpy X = numpy.zeros((1, 1, 1), dtype="f") model = with_array(Linear()) model.initialize(X=X) ``` ``` ### Error {small="true"} Data validation error in 'with_array-linear' X: <class 'numpy.ndarray'> Y: <class 'numpy.ndarray'> X instance of Padded expected X instance of Ragged expected X value is not a valid list X wrong array dimensions (expected 2, got 3) ``` To take advantage of runtime validation, [config validation](/docs/usage-config#registry) and [static type checking](/docs/usage-type-checking), you should **add type hints** to any custom layers, wrappers and functions you define. Type hints are optional, though, and if no types are provided, the data won't be validated and any inputs will be accepted. --- ## Defining new layers {#new-layers} Thinc favors a **composition rather than inheritance** approach to creating custom sublayers: the base [`Model`](/docs/api-model) class should be all you need. You can define new layers by simply passing in different data, especially the **forward** function, which is where you'll implement the layer's actual logic. You'll usually want to make a function to put the pieces together. We refer to such functions as **constructors**. The constructor is responsible for defining the layer. Parameter allocation and initialization takes place in an optional `init` function, which is called by `model.initialize`. ```python ### Layer definition model = Model( "layer-name", # string name of layer forward, # forward function init=init, # optional initialize function dims={"nO": 128, "nI": None}, # optional dimensions params={"W": None, "b": None}, # optional parameters attrs={"my_attr": True}, # optional non-parameter attributes refs={}, # optional references to other layers layers=[], # child layers shims=[] # child shims ) ``` ### Constructor functions {#constructor-functions} Thinc layers are almost always instances of [`Model`](/docs/api-model). You usually don't need to create a subclass, although you can if you prefer. Because layers usually reuse the same `Model` class, the constructor takes on some responsibilities for defining the layer, even if all the data isn't available. The `refs`, `params` and `dim` dictionaries are all mappings from string names to optional values (where "optional" means you can make the value `None`). You should use `None` to indicate the full set of names that should be present once the layer is fully initialized. However, you cannot pass `None` values for missing child layers or shims: these lists do not support `None` values. Dimension, attribute and parameter names are identified using strings. Thinc's built-in layers use the [convention](#naming-conventions) that `"nI"` refers to the model's input width, and `"nO"` refers to the model's output width. You should usually try to provide these, unless they are undefined for your model (for instance, if your model accepts an arbitrary unsized object like a database connector, it doesn't make sense to provide an `"nI"` dimension.) Your constructor should define all dimensions and parameters you want to attach to the model, mapping them to `None` if the values aren't available yet. You'll usually map parameters to `None`, and only allocate them in your `init` function. ```python from thinc.api import Model def random_chain(child_layer1: Model, child_layer2: Model, prob: float = 0.2) -> Model: """Randomly invert the order of two layers during training.""" return Model( "random_order", random_chain_forward, init=init, attrs={"prob": prob}, layers=[child_layer1, child_layer2], ) ``` Many model instances will have one or more **child layers**. For composite models that have several distinct parts, you should usually write your creation functions to receive instances of the child layers, rather than settings to construct it. This will make your layer more modular, and let you take better advantage of Thinc's config system. You can add or remove child layers after creation via the [`Model.layers`](/docs/api-model#properties) list property, but you should usually prefer to set up the child layers on creation if possible. In complicated networks, sometimes you need to refer back to specific parts of the model. For instance, you might want to access the embedding layer of a network directly. The `refs` dict lets you create named references to nodes. You can have nodes referring to their siblings or parents, so long as you don't try to serialize only that component: when you call [`Model.to_bytes`](/docs/api-model#to_bytes) or [`Model.to_disk`](/docs/api-model#to_disk), all of the reference targets must be somewhere within the model's tree. Under the hood, references are implemented using Python's weakref feature, to avoid circular dependencies. For instance, let's say you needed each child layer in the `random_order` example above to refer to each other. You could do this by setting node references for them: ```python child_layer1.set_ref("sibling", child_layer2) child_layer2.set_ref("sibling", child_layer1) ``` If you call `model.to_bytes`, both references will be within the tree, so there will be no problem. But you would not be able to call `child_layer1.to_bytes` or `child_layer2.to_bytes`, as the link targets aren't reachable from [`Model.walk`](/docs/api-model#walk). Thinc's built-in layers follow a naming convention where combinators and stateless transformations are created from `snake_case` functions, while weights layers or higher level components are created from `CamelCased` names. This naming reflects the general usage purpose of the layer, rather than the details of exactly what top-level container is returned. Constructing models via functions allows your code to do some things that would be difficult or impossible with an API that exposes `__init__` methods directly, because it's difficult to return a different object instance from a class constructor. For instance, Thinc's `Relu` layer accepts the options `dropout` and `normalize`. These operations are implemented as separate layers, so the constructor uses the `chain` combinator to put everything together. You should feel free to take this type of approach in your own constructors too: you can design the components of your network to be smaller reusable pieces, while making the user-facing API refer to larger units. ### The forward function and backprop callback {#weights-layers-forward} Writing the forward function is the main part of writing a new layer --- it's where the computation actually takes place. The forward function is passed into [`Model.__init__`](/docs/api-model#init), and then kept as a reference within the model instance. You won't normally call your forward function directly. It will usually be invoked indirectly, via the [`__call__`](/docs/api-model#call), [`predict`](/docs/api-model#predict) and [`begin_update`](/docs/api-model#begin_update) methods. The implementation of the `Model` class is pretty straightforward, so you can have a look at the code to see how it all fits together. Because the `forward` function is invoked within the `Model` instance, it needs to stick to a strict signature. Your forward function needs to accept **exactly three arguments**: the model instance, the input data and a flag indicating whether the model is being invoked for training, or for prediction. It needs to return a tuple with the output, and the backprop callback. ```python ### Forward function for a Linear layer def linear_forward(model: Model, X, is_train): W = model.get_param("W") b = model.get_param("b") Y = X @ W.T + b def backprop(dY): model.inc_grad("b", dY.sum(axis=0)) model.inc_grad("W", dY.T @ X) return dY @ W return Y, backprop ``` | Argument | Type | Description | | ----------- | ----------------------------- | --------------------------------------------------- | | ย `model` | Model | The model instance. | | `X` | Any | The inputs. | | `is_train` | bool | Whether the model is running in a training context. | | **RETURNS** | Tuple[Any, Callable] | The output and the backprop callback. | The model won't invoke your forward function with any extra positional or keyword arguments, so you'll normally attach what you need to the model, as `params`, `dims`, `attrs`, `layers`, `shims` or `refs`. At the beginning of your function, you'll fetch what you need from the model and carry out your computation. For example, the `random_chain_forward` function retrieves its child layers and the `prob` attribute, uses them to compute the output, and then returns it along with the `backprop` callback. The `backprop` callback uses some results from the `forward`'s scope (specifically the two child callbacks and the `prob` attribute), and returns the gradient of the input. ```python def random_chain_forward(model: Model, X, is_train: bool): child_layer1 = model.layers[0] child_layer2 = model.layers[1] prob = model.get_attr("prob") is_reversed = is_train and prob >= random.random() if is_reversed: Y, get_dX = child_layer2(X, is_train) Z, get_dY = child_layer1(Y, is_train) else: Y, get_dX = child_layer1(X, is_train) Z, get_dY = child_layer2(Y, is_train) def backprop(dZ): dY = get_dY(dZ) dX = get_dX(dY) return dX return Z, backprop ``` Instead of defining the `forward` function separately, it's sometimes more elegant to write it as a closure within the constructor. This is especially helpful for quick utilities and transforms. If you don't otherwise need a setting to be accessible from a model or serialized with it, you can simply reference it from the outer scope, rather than passing it in as an attribute. You should avoid referencing child layers in this way, however, as you do need to pass the child layers into the `layers` list โ€“ otherwise they will be not part of the model's tree. ```python def random_chain(child_layer1, child_layer2, prob=0.2): ... def random_chain_forward(model: Model, X, is_train: bool): # You can define the `forward` function as a closure. If so, it's fine # to use attributes from the outer scope, but child layers should be # retrieved from the model. child_layer1, child_layer2 = model.layers is_reversed = is_train and prob >= random.random() ... ... ``` Another way to pass data from the constructor into the forward function is partial function application. This is the best approach for static data that will be reliably available at creation and does not need to be serialized. Partial application is also the best way to establish temporary buffers for your forward function to reuse. Reusable buffers can be helpful for performance tuning to prevent repeat additional memory allocation. There are a few constraints that well-behaved forward functions should follow in order to make them interoperate better with other layers, and to help your code work smoothly in distributed settings. Many of these considerations are less relevant for quick hacks or experimentation, but even if everything stays between you and your editor, you're likely to find your code easier to work with and reason about if you keep these rules in mind, as they all amount to "avoid unnecessary side-effects". - **Params can be read-only.** The `model.get_params` method is allowed to return read-only arrays, or copies of the internal data. You should not assume that in-place changes to the params will have any effect. - **Inputs can be read-only.** You should avoid writing to input variables, but if it's _really_ necessary for efficiency, you should at least check the `array.flags["WRITEABLE"]` attribute, and make a copy if necessary. Equally, if it's crucial for your layer that variables are not written to, use `array.setflags(write=False)` to prevent any shenanigans. - **Writeable variables might get written to.** You'll often want to reference a variable returned by your forward function inside your backprop callback, as otherwise you'd have to recompute it. However, after your function has returned, the caller might write to the array, changing it out from under you. If the data is small, the best solution is to make a copy of variables you want to retain. If you're really worried about efficiency, you can set the array to read-only using `array.set_flags(write=False)`. - **Avoid calls to [`Model.set_param`](/docs/api-model#set_param).** If you do _have_ to change the params during the forward function or the backprop callback, `set_param` is the best way to do it โ€“ but you should try to prefer other designs, as other code may not expect params to change during forward or backprop. - **Don't call [`Model.set_dim`](/docs/api-model#set_dim).** There's not really a need to do this, and you're likely to cause a lot of problems for other layers. If the parent layer checks a child dimension and then invokes it, the parent should not have to double check that the dimensions of the child have changed. - **It's okay to update the [`Model.attrs`](/docs/api-model#properties).** If you do need to change state during the forward pass (for instance, for batch normalization), `model.attrs["some_attr"] = new_value` is the best approach. Of course, all else being equal, side-effects are worse than no side-effects โ€“ but sometimes it's just what you need to do. Consequently, your layer should expect that child layers are allowed to modify or set attrs during their forward or backward functions. You can avoid any of the read-only stuff by following a policy of never modifying your inputs, and always making a copy of your outputs if you need to retain them. This is the most conservative approach, and for most situations it's what we would recommend โ€“ it ensures your layer will work well even when combined with other layers that aren't written carefully. However, you'll sometimes be writing code where it's reasonable to worry about unnecessary copies. In these situations, the read-only flags work sort of like traffic rules. If everyone cooperates, you can go faster, but if someone forgets to indicate, there might be a crash. ### Writing the backprop callback {#backprop} Your `forward` function must return a callback to compute gradients of the parameters and weights during training. The callback must accept inputs that match the outputs of the forward pass and return outputs that match the inputs to the forward pass (the specifics of "matching" might differ between types, but for arrays, assume it means the same shape and type). If the forward function is `Y = forward(X)`, then the backprop callback should be `dX = backprop(dY)`, with `X.shape == dX.shape` and `Y.shape == dY.shape`. #### A more technical explanation Thinc's `forward` functions behave like functions transformed by JAX's [`jax.vjp`](https://jax.readthedocs.io/en/latest/jax.html#jax.vjp) function. Some readers may prefer their more technical description, which is that the `forward` function returns: A`(primals_out, vjpfun)` pair, where `primals_out` is `fun(*primals)`. `vjpfun` is a function from a cotangent vector with the same shape as `primals_out` to a tuple of cotangent vectors with the same shape as `primals`, representing the vector-Jacobian product of `fun` evaluated at `primals`. Your backprop callback will often refer to variables in the outer scope. This allows you to easily **reuse state from the forward pass**. The Python runtime will increment the reference count of all variables that your backprop callback references, and then decrement the reference counts once the callback is destroyed. We can see this working by attaching a `__del__` method to some classes, which show when the objects are being destroyed. ```python ### {small="true"} class Thing: def __del__(self): print("Deleted thing") class Other: def __del__(self): print("Deleted other") def outer(): thing = Thing() other = Other() def inner(): return thing return inner ``` ```python >>> callback = outer() Deleted other >>> callback = None Deleted thing ``` This behavior makes managing memory very easy: objects you reference will be kept alive, and objects you don't are eligible to be freed. You should therefore avoid unnecessary references if possible. For instance, if you only need the shape of an array, it is better to assign that to a local variable, rather than accessing it via the parent array. Your backprop callback is not guaranteed to be called, so you should not rely on it to compute side-effects. It is also valid for code to execute the backprop callback more than once, so your function should be prepared for that. However, it is not valid to call the backprop callback if the forward function was executed with `is_train=False`, so you can implement predict-only optimizations. It is also invalid for layers to change each others' parameters or dimensions during execution, so your function does not need to be prepared for that. Thinc does leave you with the responsibility for **calculating the gradients correctly**. If you do not get them right, your layer will not learn correctly. If you're having trouble, you might find [Thinc's built-in layers](https://github.com/explosion/thinc/blob/master/thinc/layers) a helpful reference, as they show how the backward pass should look for a number of different situations. They also serve as examples for how we would suggest you structure your code to make calculating the backward pass easier. Naming is especially important: you need to see the order of steps in the forward pass and unwind them in reverse. For complex cases, it also helps a lot to break out calculations into **helper functions that return a backprop callback**. Then your outer layer can simply call the callbacks in reverse. It also helps to follow a consistent naming scheme for these callbacks. We usually either name our callbacks by the result returned (like `get_dX)`, or the variable that you'll pass in (like `bp_dY`). Frustratingly, your layer might still limp on even with a mistake in the gradient calculation, making the problem hard to detect. As is often the case in programming, almost correct is the worst kind of incorrect. Often it's best to check your work with some tooling. Both [JAX](https://jax.readthedocs.io/en/latest/) and [Tangent](https://github.com/google/tangent) are very helpful for this. Often you'll write layers that are not meaningfully differentiable, or for which you do not need the gradients of the inputs. For instance, you might have a layer that lower-cases textual inputs. In these cases, the backprop callback should return **some appropriate falsy value** of the same type as the input to avoid raising spurious type errors. For instance, if the input is a list of strings, you would return an empty list; if the input is an array, you can return an empty array. ### The initialize function {#weights-layers-init} The last function you may need to define is the initializer, or "init", function. Like the `forward` function, your `init` function will be stored on the model instance, and then called by the [`Model.initialize`](/docs/api-model#initialize) method. You do not have to expect that the function will be called in other situations. Your `init` function will be called with an instance of your model and two optional arguments, which may provide an example batch of inputs (`X`) and an example batch of outputs (`Y`). The arguments may be provided positionally or by keyword (so the naming is significant: you must call the arguments `X` and `Y`). Your model can use the provided example data to **help calculate unset dimensions**, assist with parameter initialization, or calculate attributes. It is valid for your construction function to return your model with missing information, hoping that the information will be filled in later or at initialization via the example data. If the example data is not provided and you're left with unset dimensions or other incomplete state, you should raise an error. It is up to you to decide how you should handle receiving conflict information at construction and initialization time. Sometimes it will be better to overwrite the construction data, and other times it will be better to raise an error. ```python ### Initialize function def random_chain_init(model, X=None, Y=None): if X is not None and model.has_dim("nI") is None: model.set_dim("nI", X.shape[1]) if Y is not None and model.has_dim("nO") is None: model.set_dim("nO", Y.shape[1]) for child_layer in model.layers: child_layer.initialize(X=X, Y=Y) ``` The `model.initialize` method will not call your `init` function with any extra arguments, but you will often want to parameterize your `init` with settings from the constructor. This is especially common for weight initialization: there are many possible schemes, and the choice is often an important hyper-parameter. While you can communicate this information via the `attrs` dict, our favorite solution is to use [`functools.partial`](https://docs.python.org/3.6/library/functools.html#functools.partial). Partial function application lets you fill in a function's arguments at two different times, instead of doing it all at once --- which is exactly what we need here. This lets you write the `init` function with extra arguments, which you provide at creation time when the information is available. ```python ### Passing init args using partial {highlight="1,10,16"} from functools import partial from thinc.api import Model def constructor(nO=None, initial_value=1): return Model( "my-model", forward, dims={"nO": nO}, params={"b": None}, init=partial(init, initial_value=initial_value) ) def forward(model, X, is_train): ... def init(initial_value, model, X=None, Y=None): if Y is not None and model.has_dim("nO") is None: model.set_dim("nO", None) if not model.get_dim("nO"): raise ValueError(f"Cannot initialize {model.name}: dimension nO unset") b = model.ops.alloc1f(model.get_dim("nO")) b += initial_value model.set_param("b", b) ``` You can find real examples of the partial-application pattern in [`thinc.layers`](https://github.com/explosion/thinc/blob/master/thinc/layers). The [`Relu`](https://github.com/explosion/thinc/blob/master/thinc/layers/relu.py), [`Mish`](https://github.com/explosion/thinc/blob/master/thinc/layers/mish.py) and [`Maxout`](https://github.com/explosion/thinc/blob/master/thinc/layers/maxout.py) layers provide straightforward examples, among others. A call to [`Model.initialize`](/docs/api-model#initialize) will trigger subsequent calls down the model tree, as **each layer is responsible for calling the initialize method of each of its children** (although not necessarily in order). Prior to training, you can rely on your model's `init` function being called at least once in between the constructor and the first execution of your forward function. It is invalid for a parent to not call `initialize` on one of its children, and it is invalid to start training without calling `Model.initialize` first. However, it _is_ valid to create a layer and then load its state back with [`Model.from_dict`](/docs/api-model#from_dict), [`Model.from_bytes`](/docs/api-model#from_bytes) or [`Model.from_disk`](/docs/api-model#from_disk) without calling `model.initialize` first. This means that you should not write any side-effects in your `init` function that will not be replicated by deserialization. Deserialization will restore dimensions, parameters, node references and serializable attributes, but it will not replicate any changes you have made to the layer's node structure, such as changes to the `model.layers` list. You should therefore avoid making those changes within the `init`, or your model will not deserialize correctly. It is valid for your `init` function to be called **more than once**. This usually happens because the same model instance occurs twice within a a tree (which is allowed). Your `initialize` function should therefore be prepared to run twice. If you're simply setting dimensions and allocating and initializing parameters, having the init function run will generally be unproblematic. However, in special situations you may need to call external setup code, in which case having your `init` function run twice could be problematic. The best solution would probably be to set a global variable, possibly using the `model.id` attribute to allow the `init` to run once per model instance. You could also use partial function application to attach the flag in a mutable argument variable. ### Inspecting and updating model state {#model-state} As you build more complicated models, you'll often need to inspect your model in various ways. This is especially important when you're writing your own layers. Here's a quick summary of the different types of information you can attach and query. | | | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [`Model.id`](/docs/api-model#attributes) | A numeric identifier, to distinguish different model instances. During [`Model.__init__`](/docs/api-model#init), the `Model.global_id` class attribute is incremented and the next value is used for the `model.id` value. | | [`Model.name`](/docs/api-model#attributes) | A string name for the model. | | [`Model.layers`](/docs/api-model#properties) [`Model.walk`](/docs/api-model#walk) | List the immediate sublayers of a model, or iterate over the model's whole subtree (including the model itself). | | [`Model.shims`](/docs/api-model#properties) | Wrappers for external libraries, such as PyTorch and TensorFlow. [`Shim`](/docs/api-model#shim) objects hold a reference to the external object, and provide a consistent interface for Thinc to work with, while also letting Thinc treat them separately from `Model` instances for the purpose of serialization and optimization. | | [`Model.has_dim`](/docs/api-model#has_dim) [`Model.get_dim`](/docs/api-model#get_dim) [`Model.set_dim`](/docs/api-model#set_dim) [`Model.dim_names`](/docs/api-model#properties) | Check, get, set and list the layer's **dimensions**. A dimension is an integer value that affects a model's parameters or the shape of its input data. | | [`Model.has_param`](/docs/api-model#has_param) [`Model.get_param`](/docs/api-model#get_param) [`Model.set_param`](/docs/api-model#set_param) [`Model.param_names`](/docs/api-model#properties) | Check, get, set and list the layer's **weights parameters**. A parameter is an array that can have a gradient and can be optimized. | | [`Model.has_grad`](/docs/api-model#has_grad) [`Model.get_grad`](/docs/api-model#get_grad) [`Model.set_grad`](/docs/api-model#set_grad) [`Model.inc_grad`](/docs/api-model#inc_grad) [`Model.grad_names`](/docs/api-model#properties) | Check, get, set, increment and list the layer's **weights gradients**. A gradient is an array of the same shape as a weights parameter, that increments values used to update the parameter during training. | | [`Model.has_ref`](/docs/api-model#has_ref) [`Model.get_ref`](/docs/api-model#get_ref) [`Model.set_ref`](/docs/api-model#set_ref) [`Model.ref_names`](/docs/api-model#properties) | Check, get, set and list the layer's **node references**. A node reference lets you easily refer to particular nodes within your model's subtree. For instance, if you want to expose the embedding table from your model, you can add a reference to it. | | [`Model.attrs`](/docs/api-model#properties) | A dict of the layer's **attributes**. Attributes are other information the layer needs, such as configuration or settings. You should ensure that attribute values you set are either JSON-serializable, or support a `to_bytes` method, or the attribute will prevent model serialization. | ### Naming conventions {#naming-conventions} Thinc names dimensions and parameters with strings, so you can use arbitrary names on your models. For the built-in [layers and combinators](/docs/api-layers), we use the following conventions: | | | | ---- | -------------------------------------------------------------------------- | | `nO` | The width of output arrays from the layer. | | `nI` | The width of input arrays from the layer. | | `nP` | Number of "pieces". Used in the [`Maxout`](/docs/api-layers#maxput) layer. | | `W` | A 2-dimensional weights parameter, for connection weights. | | `b` | A 1-dimensional weights parameter, for biases. | | `E` | A 2-dimensional weights parameter, for an embedding table. | --- ## Serializing models and data {#serializing} Of course, training a model isn't very useful without a way to save out the weights and load them back in later. Thinc supports **three ways of saving and loading your model**: 1. The most flexible is to use the [`Model.to_bytes`](/docs/api-model#to_bytes) method, which saves the model state to a byte string, serialized using the `msgpack` library. The result can then be loaded back using the [`Model.from_bytes`](/docs/api-model#from_bytes) method. 2. The [`Model.to_disk`](/docs/api-model#to_disk) method works similarly, except the result is saved to a path you provide instead. The result can be loaded back using the [`Model.from_disk`](/docs/api-model#from_disk) method. 3. Pickle the `Model` instance. This should work, but is not our recommendation for most use-cases. Pickle is inefficient in both time and space, does not work reliably across Python versions or platforms, and is not suitable for untrusted inputs, as unpickling an object allows arbitrary code execution by design. The `from_bytes` and `from_disk` methods are intended to be relatively safe: unlike formats such as Pickle, untrusted inputs are not intended to allow arbitrary code execution. This means you have to create the `Model` object yourself first, and then use that object to load in the state. To make this easier, you'll usually want to put your model creation code inside a function, and then **register it**. The [registry](/docs/api-config#registry) allows you to look up the function by name later, so you can pass along all the details to recreate your model in one message. Check out our [guide on the config system](/docs/usage-config) for more details. ### Serializing attributes {#serializing-attrs} When you call [`Model.to_bytes`](/docs/api-model#to_bytes) or [`Model.to_disk`](/docs/api-model#to_disk), the model and its layers, weights, parameters and attributes will be serialized to a byte string. Calling [`Model.from_bytes`](/docs/api-model#from_bytes) or [`Model.from_disk`](/docs/api-model#from_disk) lets you load a model back in. By default, Thinc uses MessagePack, which works out-of-the-box for all JSON-serializable data types. The `serialize_attr` and `deserialize_attr` functions that Thinc uses under the hood are [single-dispatch generic functions](https://docs.python.org/3/library/functools.html#functools.singledispatch). This means that you can **register different versions** of them that are chosen based on the **value and type of the attribute**. For example, let's say your model takes attributes that are [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/frame.html) objects: ```python ### Model with custom attrs {highlight="4"} from thinc.api import Model import pandas as pd attrs = {"df": pd.DataFrame([10, 20, 30], columns=["a"])} model = Model("custom-model", lambda X: (X, lambda dY: dY), attrs=attrs) ``` To tell Thinc how to save and load them, you can use the `@serialize_attr.register` and `@deserialize_attr.register` decorators with the type `pd.DataFrame`. Whenever Thinc encounters an attribute value that's a dataframe, it will use these functions to serialize and deserialize it. ```python ### Custom attr serialization {highlight="5-6,11-12"} from thinc.api import serialize_attr, deserialize_attr import pandas as pd import numpy @serialize_attr.register(pd.DataFrame) def serialize_dataframe(_, value, name, model): """Serialize the value (a dataframe) to bytes.""" rec = value.to_records(index=False) return rec.tostring() @deserialize_attr.register(pd.DataFrame) def deserialize_dataframe(_, value, name, model): """Deserialize bytes to a dataframe.""" rec = numpy.frombuffer(value, dtype="i") return pd.DataFrame().from_records(rec) ``` The first argument of the function is always an instance of the attribute. This is used to decide which function to call. The `value` is the value to save or load โ€“ a dataframe to serialize or the bytestring to deserialize. The functions also give you access to the string name of the current attribute and the `Model` instance. This is useful if you need additional information or if you want to perform other side-effects when loading the data back in. For example, you could check if the model has another attribute specifying the data type of the array and use that when loading back the data: ```python ### {highlight="4-5"} @deserialize_attr.register(pd.DataFrame) def deserialize_dataframe(_, value, name, model): """Deserialize bytes to a dataframe.""" dtype = model.attrs.get("dtype", "i") rec = numpy.frombuffer(value, dtype=dtype) return pd.DataFrame().from_records(rec) ``` Since the attribute value is used to decide which serialization and deserialization function to use, make sure that your model defines **default values** for its attributes. This way, the correct function will be called when you run `model.from_bytes` or `model.from_disk` to load in the data. ```diff - attrs = {"df": None} + attrs = {"df": pd.DataFrame([10, 20, 30], columns=["a"])} model = Model("custom-model", lambda X: (X, lambda dY: dY), attrs=attrs) ``` thinc-9.0.0/website/docs/usage-sequences.md000066400000000000000000000333471461023342500206500ustar00rootroot00000000000000--- title: Variable-length sequences teaser: Dataclasses for ragged, padded, paired and list-based sequences next: /docs/usage-type-checking --- Thinc's built-in layers support several ways to **encode variable-length sequence data**. The encodings are designed to avoid losing information, so you can compose operations smoothly and easily build hierarchical models over structured inputs. This page provides a summary of the different formats, their advantages and disadvantages, and a summary of which built-in layers accept and return them. There's no restrictions on what objects your own models can accept and return, so you're free to invent your own data types. ## Background and motivation {#background} The [`numpy.ndarray`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html) object represents a multi-dimensional table of data. In the simplest case, there's only one dimension, or "axis", so the size of the array is equal to its length: ```python array1d = numpy.ndarray((10,)) assert array1d.size == 10 assert array1d.shape == (10,) ``` To make a two-dimensional array, we can instead write `array2d = numpy.ndarray((10, 16))`. This will be a table with 10 rows and 16 columns, and a total size of 160 items. However, the `ndarray` object does not have a native way to represent data with a **variable number of columns per row**. If the last row of your data only has 15 items rather than 16, you cannot create a two-dimensional array with only 159 items, where rows one to nine have 16 columns and the last row has 15 columns. The limitation makes a lot of sense: the rest of the `numpy` API presents operations defined in terms of regularly-shaped arrays, and there's often no obvious generalization to irregularly shaped data. While you could not represent the 159 items in a two-dimensional array, there's no reason why you couldn't keep the data together in a flat format, all in one dimension. You could keep track of the intended number of columns separately, and reshape the data to do various operations according to your intended definitions. This is essentially the approach that Thinc takes for variable-length sequences. Inputs very often are irregularly shaped. For instance, texts vary in length, often significantly. You might also want to represent your texts hierarchically: each word can be seen as a variable-length sequence of characters, each sentence a variable-length sequence of words, each paragraph a variable-length sequence of sentences, and each text a variable-length sequence of paragraphs. A single, padded `ndarray` is a poor choice for this type of hierarchical representation, as each dimension would need to be padded to its longest item. If the longest word in your batch is 10 characters, you will need to use 10 characters for every word. If the longest sentence in your batch has 40 words, every sentence will need to be 40 words. The inefficiency will be multiplied along each dimension, so that the vast majority of the final structure is empty space. Unfortunately, there is no single best solution that is most efficient for every situation. It depends on the shapes of the data, and the hardware being used. On GPU devices, it is often better to use **padded representations**, so long as there is only padding along one dimension. However, on CPU, **denser representations** are often more efficient, as maintaining parallelism is less important. Different libraries also introduce different considerations. For [JAX](https://github.com/google/jax), operations over irregularly-sized arrays are extremely expensive, as a new kernel will need to be compiled for every combination of shapes you provide. Thinc therefore provides a number of **different sequence formats**, with utility layers that convert between them. Thinc also provides layers that represent reversible transformations. The [`with_*` layers](/docs/api-layers#with_array) accept a layer as an argument, and transform inputs on the way into the layer, and then perform the opposite transformation on the way out. For instance, the [`with_padded`](/docs/api-layers#with_padded) wrapper will allow you to temporarily convert to a [`Padded`](/docs/api-types#padded) representation, for the scope of the layer being wrapped. --- ## Padded {#padded} The [`Padded`](/docs/api-types#padded) dataclass represents a **padded batch of sequences** sorted by descending length. The data is formatted in "sequence major" format, i.e. the first dimension represents the sequence position, and the second dimension represents the batch index. The `Padded` type uses three auxiliary integer arrays, to keep track of the actual sequence lengths and the original positions, so that the original structure can be restored. The third auxiliary array, `size_at_t`, allows the padded batch to be sliced to currently active sequences at different time steps. Although the underlying data is sequence-major, the `Padded` dataclass supports **getting items** or **slices along the batch dimension**: you can write `padded[1:3]` to retrieve a `Padded` object with sequence items one and two. The `Padded` format is well-suited for LSTM and other RNN models. ```python ### Example from thinc.api import get_current_ops, Padded ops = get_current_ops() sequences = [ ops.alloc2f(7, 5) + 1, ops.alloc2f(2, 5) + 2, ops.alloc2f(4, 5) + 3, ] padded = ops.list2padded(sequences) assert padded.data.shape == (7, 3, 5) # Data from sequence 0 is first, as it was the longest assert padded.data[:, 0] == 1 # Data from sequence 2 is second, and it's padded on dimension 0 assert padded.data[:4, 1] == 3 # Data from sequence 1 is third, also padded on dimension 0 assert padded.data[:2, 2] == 2 # Original positions assert list(padded.indices) == [0, 2, 1] # Slices refer to batch index. assert isinstance(padded[0], Padded) assert padded[0].data.shape == (7, 1, 5) ``` | | | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | **Operations** | [`Ops.list2padded`](/docs/api-backends#list2padded), [`Ops.padded2list`](/docs/api-backends#padded2list) | | **Transforms** | [`padded2list`](/docs/api-layers#padded2list), [`list2padded`](/docs/api-layers#list2padded), [`with_padded`](/docs/api-layers#with_padded) | | **Layers** | [`LSTM`](/docs/api-layers#lstm), [`PyTorchLSTM`](/docs/api-layers#lstm) | ## Ragged {#ragged} The [`Ragged`](/docs/api-types#ragged) dataclass represents a **concatenated batch of sequences**. An auxiliary array is used to keep track of the lengths. The `Ragged` format is memory efficient, and is efficient for some operations. However, it is not supported directly by most underlying operations. Per-sequence operations such as sequence transposition and matrix multiplication are relatively expensive, but Thinc does support custom CPU and CUDA kernels for more efficient reduction (aka. pooling) operation on ragged arrays. The `Ragged` format makes it easy to ignore the sequence structure of your data for some operations, such as word embeddings or feed-forward layers. These layers do not accept the `Ragged` object directly, but you can wrap the layer using the [`with_array`](/docs/api-layers#with_array) transform to make them compatible without requiring copy operations. The `with_array` transform will pass the underlying array data into the layer, and return the outputs as a `Ragged` object so that the sequence information remains available to the rest of your network. ```python ### Example from thinc.api import get_current_ops, Ragged, Linear, list2ragged ops = get_current_ops() sequences = [ ops.alloc2f(7, 5) + 1, ops.alloc2f(2, 5) + 2, ops.alloc2f(4, 5) + 3, ] list2ragged_model = list2ragged() ragged = list2ragged_model.predict(sequences) assert ragged.data.shape == (13, 5) # This will always be true: assert ragged.data.shape[0] == ragged.lengths.sum() # Data from sequence 0 is in the first 7 rows, followed by seqs 1 and 2 assert (ragged.data[:7] == 1).all() assert (ragged.data[7:2] == 2).all() assert (ragged.data[9:] == 3).all() # Indexing gets the batch item, and returns a Ragged object ragged[0].data.shape == (7, 5) # You can pass the data straight into dense layers model = Linear(6, 5).initialize() output = model.predict(ragged.data) ragged_out = Ragged(output, ragged.lengths) # Internally, data is reshaped to 2d. The original shape is accessible at the # the dataXd property. sequences3d = [ops.alloc3f(5, 6, 7), ops.alloc3f(10, 6, 7)] ragged3d = list2ragged_model.predict(sequences3d) ragged3d.data.shape == (15, 13) ragged3d.dataXd.shape == (15, 6, 7) ``` | | | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Operations** | [`Ops.ragged2list`](/docs/api-backends#ragged2list), [`Ops.list2ragged`](/docs/api-backends#list2ragged), [`Ops.reduce_sum`](/docs/api-backends#reduce_sum), [`Ops.reduce_mean`](/docs/api-backends#reduce_sum), [`Ops.reduce_max`](/docs/api-backends#reduce_sum) | | **Transforms** | [`with_ragged`](/docs/api-layers#with_ragged), [`ragged2list`](/docs/api-layers#ragged2list), [`list2ragged`](/docs/api-layers#list2ragged) | | **Layers** | [`reduce_sum`](/docs/api-layers#reduce_sum), [`reduce_mean`](/docs/api-layers#reduce_mean), [`reduce_max`](/docs/api-layers#reduce_max) | ## List[ArrayXd] {#list-array} A list of arrays is often the most convenient input and output format for sequence data, especially for runtime usage of the model. However, most mathematical operations require the data to be passed in **as a single array**, so you will usually need to transform the array list into another format to pass it into various layers. A common pattern is to use `list2padded` or `list2ragged` as the first layer of your network, and `ragged2list` or `padded2list` as the final layer. You could then opt to strip these from the network during training, so that you can make the transformation just once at the beginning of training. However, this does mean that you'll be training on the same batches of data in each epoch, which may lead to lower accuracies. | | | | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Operations** | [`Ops.ragged2list`](/docs/api-backends#ragged2list), [`Ops.list2ragged`](/docs/api-backends#list2ragged) , [`Ops.padded2list`](/docs/api-backends#padded2list), [`Ops.list2padded`](/docs/api-backends#list2padded) | | **Transforms** | [`ragged2list`](/docs/api-layers#ragged2list), [`list2ragged`](/docs/api-layers#list2ragged), [`padded2list`](/docs/api-layers#padded2list), [`list2padded`](/docs/api-layers#list2padded), [`with_ragged`](/docs/api-layers#with_ragged), [`with_padded`](/docs/api-layers#with_padded) | | **Layers** | [`reduce_sum`](/docs/api-layers#reduce_sum), [`reduce_mean`](/docs/api-layers#reduce_mean), [`reduce_max`](/docs/api-layers#reduce_max) | ## List[List[Any]] {#nested-list} Nested lists are a useful format for many types of **hierarchically structured data**. Often you'll need to write your own layers for these situations, but Thinc does have a helpful utility tool, the `with_flatten` transform. This transform can be applied around a layer in your network, and the layer will be called with a flattened representation of your list data. The outputs are then repackaged into lists, with arrays divided as needed. | | | | -------------- | ----------------------------------------------- | | **Transforms** | [`with_flatten`](/docs/api-layers#with_flatten) | ## Array {#array} Most Thinc layers that work on sequences do **not** expect plain arrays, because the array does not include any representation of where the sequences begin and end, which makes the semantics of some operations unclear. For instance, there's no way to accurately do mean pooling on an array of padded sequences without knowing where the sequences actually end. Max pooling is often also difficult, depending on the padding value. If the array represents sequences, you should **maintain the metadata** to treat it as an intelligible sequence. thinc-9.0.0/website/docs/usage-training.md000066400000000000000000000254351461023342500204670ustar00rootroot00000000000000--- title: Training Models next: /docs/usage-frameworks --- Thinc provides a fairly minimalistic approach to training, leaving you in control to write the training loop. The library provides a few utilities for minibatching, hyperparameter scheduling, loss functions and weight initialization, but does not provide abstractions for data loading, progress tracking or hyperparameter optimization. ## The training loop {#training-loop} Thinc assumes that your model will be trained using some form of **minibatched stochastic gradient descent**. On each step of a standard training loop, you'll loop over batches of your data and call [`Model.begin_update`](/docs/api-model#begin_update) on the inputs of the batch, which will return a batch of predictions and a backpropagation callback. You'll then calculate the gradient of the loss with respect to the output, and provide it to the backprop callback which will increment the gradients of the model parameters as a side-effect. You can then pass an optimizer function into the [`Model.finish_update`](/docs/api-model#finish_update) method to update the weights. ```python ### Basic training loop for i in range(10): for X, Y in train_batches: Yh, backprop = model.begin_update(X) loss, dYh = get_loss_and_gradient(Yh, Y) backprop(dYh) model.finish_update(optimizer) ``` You'll usually want to make some additions to the loop to save out model checkpoints periodically, and to calculate and report progress statistics. Thinc also provides ready access to **lower-level details**, making it easy to experiment with arbitrary training variations. You can accumulate the gradients over multiple batches before calling the optimizer, call the `backprop` callback multiple times (or not at all if the update is small), and inject arbitrary code to change or report gradients for particular layers. The implementation is quite transparent, so you'll find it easy to implement such arbitrary modifications if you need to. ## Batching {#batching} A "minibatch" (or simply "batch" โ€“ we use the terms interchangeably) is just a group of samples that you update or predict over together. Batching the data is very important: most neural network models converge much faster and achieve better accuracy when the gradients are calculated using multiple samples. Thinc implements two batching helpers via the backend object [`Ops`](/docs/api-backend#ops), typically used via `model.ops`. They should cover the most common batching needs for training and evaluation. 1. [`minibatch`](/docs/api-backends#minibatch): Iterate slices from a sequence, optionally shuffled. 2. [`multibatch`](/docs/api-backends#multibatch): Minibatch one or more sequences and yield lists with one batch per sequence. ```python ### Example batches = model.ops.minibatch(128, data, shuffle=True) batches = model.ops.multibatch(128, train_X, train_Y, shuffle=True) ``` The batching methods take sequences of data and process them as a stream. They return a [`SizedGenerator`](/docs/api-types#sizedgenerator), a simple custom dataclass for generators that has a `__len__` and can repeatedly call the generator function. This also means that the batching works nicely with progress bars like [`tqdm`](https://github.com/tqdm/tqdm) and similar tools out-of-the-box. ```python ### With progress bar {highlight="1,4"} from tqdm import tqdm data = model.ops.multibatch(128, train_X, train_Y, shuffle=True) for X, Y in tqdm(data, leave=False): Yh, backprop = model.begin_update(X) ``` [`SizedGenerator`](/docs/api-types#sizedgenerator) objects hold a reference to the generator function and **call it repeatedly**, i.e. every time the sized generator is executed. This also means that the sized generator is **never consumed**. If you like, you can define it once outside your training loop, and on each iteration, the data will be **rebatched and reshuffled**. ```python ### Option 1 for i in range(10): for X, Y in model.ops.multibatch(128, train_X, train_Y, shuffle=True): # Update the model here for X, Y in model.ops.multibatch(128, dev_X, dev_Y): # Evaluate the model here ``` ```python ### Option 2 train_data = model.ops.multibatch(128, train_X, train_Y, shuffle=True) dev_data = model.ops.multibatch(128, dev_X, dev_Y) for i in range(10): for X, Y in train_data: # Update the model here for X, Y in dev_data: # Evaluate the model here ``` The `minibatch` and `multibatch` methods also support a `buffer` argument, which may be useful to promote better parallelism. If you're using an engine that supports asynchronous execution, such as PyTorch or [JAX](https://github.com/google/jax), an unbuffered stream could cause the engine to block unnecessarily. If you think this may be a problem, try setting a higher buffer, e.g. `buffer=500`, and see if it solves the problem. You could also simply consume the entire generator, by calling `list()` on it. Finally, `minibatch` and `multibatch` support **variable length batching**, based on a schedule you can provide as the `batch_size` argument. Simply pass in an iterable. Variable length batching is non-standard, but we regularly use it for some of [spaCy](https://spacy.io)'s models, especially the parser and entity recognizer. ```python from thinc.api import compounding batch_size = compounding(1.0, 16.0, 1.001) train_data = model.ops.multibatch(batch_size, train_X, train_Y, shuffle=True) ``` ![](images/schedules_custom2.svg) ```ini ### config {small="true"} [batch_size] @schedules = "compounding.v1" start = 1.0 stop = 16.0 compound = 1.001 ``` ```python ### Usage {small="true"} from thinc.api import Config, registry config = Config().from_str("./config.cfg") resolved = registry.resolve(config) batch_size = resolved["batch_size"] ``` --- ## Evaluation {#evaluation} Thinc does not provide utilities for calculating accuracy scores over either individual samples or whole datasets. In most situations, you will make a loop over batches of your inputs and targets, **calculate the accuracy** on the batch of data, and then **keep a tally of the scores**. ```python def evaluate(model, batch_size, Xs, Ys): correct = 0. total = 0. for X, Y in model.ops.multibatch(batch_size, Xs, Ys): correct += (model.predict(X).argmax(axis=0) == Y.argmax(axis=0)).sum() total += X.shape[0] return correct / total ``` During evaluation, take care to run your model **in a prediction context** (as opposed to a training context), by using either the [`Model.predict`](/docs/api-model#predict) method, or by passing the `is_train=False` flag to [`Model.__call__`](/docs/api-model#call). Some layers may behave differently during training and prediction in order to provide regularization. Dropout layers are the most common example. --- ## Loss calculators {#losses} When training your Thinc models, the most important loss calculation is not a scalar loss, but rather the **gradient of the loss with respect to your model output**. That's the figure you have to pass into the backprop callback. You actually don't need to calculate the scalar loss at all, although it's often helpful as a diagnostic statistic. Thinc provides a few [helpers for common loss functions](/docs/api-losses). Each helper is provided as a class, so you can pass in any settings or hyperparameters that your loss might require. The helper class can be used as a callable object, in which case it will return both the scalar loss and the gradient of the loss with respect to the outputs. You can also call the `get_grad` method to just get the gradients, or the `get_loss` method to just get the scalar loss. ```python ### Example {small="true"} from thinc.api import CategoricalCrossentropy loss_calc = CategoricalCrossentropy() grad, loss = loss_calc(guesses, truths) ``` ```ini ### config.cfg {small="true"} [loss] @losses = "CategoricalCrossentropy.v1" normalize = true ``` --- ## Setting learning rate schedules {#schedules} A common trick for stochastic gradient descent is to **vary the learning rate or other hyperparameters** over the course of training. Since there are many possible ways to vary the learning rate, Thinc lets you implement hyperparameter schedules as instances of the [`Schedule`](/docs/api-schedules#schedule) class. Thinc also provides a number of [popular schedules](/docs/api-schedules) built-in. You can use schedules directly, by calling the schedule with the `step` keyword argument and using it to update hyperparameters in your training loop. Since schedules are particularly common for optimization settings, the [`Optimizer`](/docs/api-optimizer) object accepts floats, lists, iterators, and [`Schedule`](/docs/api-schedules#schedule) instances for most of its parameters. When you call [`Optimizer.step_schedules`](/docs/api-optimizer#step_schedules), the optimizer will increase its step count and pass it to the schedules. For instance, this is how one creates an instance of the `Adam` optimizer with a custom learning rate schedule: ```python ### Custom learning rate schedule from thinc.api import Adam, Schedule def cycle(): values = [0.001, 0.01, 0.1] all_values = values + list(reversed(values)) return Schedule("cycle", _cycle_schedule, attrs={"all_values": all_values}) def _cycle_schedule(schedule: Schedule, step: int, **kwargs) -> float: all_values = schedule.attrs["all_values"] return all_values[step % len(all_values)] optimizer = Adam(learn_rate=cycle()) assert optimizer.learn_rate(optimizer.step) == 0.001 optimizer.step_schedules() assert optimizer.learn_rate(optimizer.step) == 0.01 optimizer.step_schedules() assert optimizer.learn_rate(optimizer.step) == 0.1 ``` ![](images/schedules_custom1.svg) You'll often want to describe your optimization schedules in your configuration file. That's also very easy: you can use the [`@thinc.registry.schedules`](/docs/api-config#registry) decorator to register your function, and then refer to it in your config as the `learn_rate` argument of the optimizer. Check out the [documentation on config files](/docs/usage-config) for more examples. ```python ### Registered function {small="true"} @thinc.registry.schedules("cycle.v1") def cycle(values): all_values = values + list(reversed(values)) return Schedule("cycle", _cycle_schedule, attrs={"all_values": all_values}) def _cycle_schedule(schedule: Schedule, step: int, **kwargs) -> float: all_values = schedule.attrs["all_values"] return all_values[step % len(all_values)] ``` ```ini ### config.cfg {small="true"} [optimizer] @optimizers = "Adam.v1" [optimizer.learn_rate] @schedules = "cycle.v1" values = [0.001, 0.01, 0.1] ``` --- ## Distributed training {#distributed} We expect to recommend [Ray](https://ray.io/) for distributed training. Ray offers a clean and simple API that fits well with Thinc's model design. Full support is still under development. thinc-9.0.0/website/docs/usage-type-checking.md000066400000000000000000000467661461023342500214200ustar00rootroot00000000000000--- title: Type Checking teaser: Static type checking and real-time linting for neural network code next: /docs/api-model --- By this point you've probably seen that **Thinc** uses the new Python 3.6+ syntax for [**type hints**](https://docs.python.org/3/library/typing.html) or "type annotations". All the code base is type-annotated and it is recommended that you add at least **some types to your own code**, too. Type annotations can make your numeric code much more explicit, making it easier to come back to later. Type annotations also allow your editor (and many other tools) to perform **type checks** _before_ executing your code. They also power **autocompletion**. For example, if you try to add a `str` and an `int`, your editor will probably warn you that it is an invalid operation, without having to wait until you run the invalid code. It may also tell you that a function expects a `float`, so you don't pass it an invalid type. If your layer is typed as `Model[Floats2d, Ints1d]`, Thinc can tell you if its inputs and outputs are incompatible with the rest of your network. Thinc's type-system won't catch every error. It has no representation for the sizes of your dimensions, so a lot of invalid operations can't be detected until runtime. Sometimes the syntax gets quite ugly, and the error messages are often frustratingly opaque. Nevertheless, we do recommend you try it out, especially for your model definitions and the functions you're registering for the config system. ## Installation and setup {#install} [`mypy`](https://mypy.readthedocs.io/en/stable/) is the "standard" type checker for Python, in fact, that's where these new Python type hints were born. You can install `mypy` from pip or conda. If you use a virtual environment for your project, make sure that you install it in the same environment. ```bash ### pip {small="true"} $ pip install mypy ``` ```bash ### conda {small="true"} $ conda install -c conda-forge mypy ``` Thinc comes with a `mypy` plugin that **extends the normal functionality** to perform additional type checks in code using Thinc. If you installed Thinc, you already have the plugin. To enable the Thinc plugin for `mypy` you just have to create a file `mypy.ini` within your project folder. This will tell `mypy` to use the plugin in the module `thinc.mypy`. If you use [`pydantic`](https://github.com/samuelcolvin/pydantic) for [advanced configuration](/docs/usage-config#advanced-types), you can also enable `pydantic`'s plugin. If you're using Thinc as part of your Python package, you can also add the `[mypy]` section to your package's `setup.cfg`. ```ini ### mypy.ini {small="true"} [mypy] plugins = thinc.mypy ``` ```ini ### mypy.ini {small="true"} [mypy] plugins = thinc.mypy, pydantic.mypy ``` To type check a file or directory, you can now use the `mypy` command: ```bash $ mypy my_file.py ``` ### Setting up linting in your editor {#linting} Real-time linting is especially powerful, as it lets you type-check your code as it leaves your fingers. This often lets you catch errors in their original context, when they're least confusing. It can also save you trips to the documentation. ![Screenshot of mypy linting in Visual Studio Code](images/type_checking2.jpg) | | | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Visual Studio Code** | If you use [Visual Studio Code](https://code.visualstudio.com/), make sure you install the [Python extension](https://code.visualstudio.com/docs/python/python-tutorial#_install-visual-studio-code-and-the-python-extension). Then select the appropriate [environment](https://code.visualstudio.com/docs/python/environments) in your editor. If you installed `mypy` in the same environment and select it in your editor, after adding the `mypy.ini` file (as described above) everything should work. | | **PyCharm** | If you use [PyCharm](https://www.jetbrains.com/pycharm/), make sure you [configure the Python Interpreter](https://www.jetbrains.com/help/pycharm/configuring-python-interpreter.html) for your project. Then [install](https://www.jetbrains.com/help/pycharm/managing-plugins.html) the ["Mypy" plugin](https://plugins.jetbrains.com/plugin/11086-mypy). You may also want to install the ["Mypy โ€‹(Official)" plugin](https://plugins.jetbrains.com/plugin/13348-mypy-official-/). If you installed `mypy` in the same environment/interpreter, after adding the `mypy.ini` file (as described above) and installing the plugin, everything should work. | | **Other editors** | See the [`mypy` docs](https://github.com/python/mypy#ide-linter-integrations-and-pre-commit) for instructions for other editors like Vim, Emacs, Sublime Text and Atom. | To make sure everything is set up correctly, try opening the [`type_checking.py` example](https://github.com/explosion/thinc/blob/master/examples/type_checking.py) script in your editor, or run `mypy type_checking.py` on the command line. You should see several type errors as indicated in the code comments, including errors specific to Thinc. ## Static type checking {#static-type-checking} "Static type checking" means that your editor (or other tools) will check the code using the declared types _before_ running it. Because it is done before running the code, it's called "static". The contrary would be "dynamic" type checking, where checks are performed _at runtime_, while the program is running and the code is being executed. (Thinc also does [runtime validation](/docs/usage-models#validation) by the way!) As editors and similar tools can't just randomly run your code to verify that it's correct, we have these type annotations to help editors check the code and **provide autocompletion**. Even if you never run a type-checker, adding type-annotations to your code can greatly **improve its readability**. Multi-dimensional array libraries like numpy make it easy to write terse, fairly general code โ€“ but when you revisit the code later, it's often very hard to figure out what's happening without executing the code and debugging. ```python ### No types def do_things(A, B): A = A.reshape(A.shape + (B.shape[-1],)) A = A.sum(axis=-1) # Is this last line an error? Maybe they wanted axis=-1? return (B * A).sum() ``` ```python ### Types def do_things(A: Floats2d, B: Floats3d) -> float: A = A.reshape(A.shape + (B.shape[-1],)).sum(axis=-1) # Ah, the function says it returns float --- so this all makes sense. return (B * A).sum() ``` Type annotations provide a relatively concise way to **document** some of the most important information about your code. The same information can be provided in comments, but unless you use a consistent syntax, your type comments will probably be much longer and more distracting than the equivalent annotations. Another advantage of type annotations as documentation is that they can be **queried for more detail**, while with comments, you have to choose the level of detail to provide up-front. Thinc's type annotations take into account `numpy`'s tricky indexing system, and also the semantics of the different reduction operations as different arguments are passed in. This makes it much easier to follow along with steps that might have felt obvious to the author of the code. ```python ### Array shape types from thinc.types import Floats3d, Ints1d def numpy_shapes_pop_quiz(arr1: Floats3d, indices: Ints1d): # How many dimensions do each of these arrays have? q1 = arr1[0] q2 = arr1.mean() q3 = arr1[1:, 0] q4 = arr1[1:, :-1] q5 = arr1.sum(axis=0) q6 = arr1[1:, ..., :-1] q7 = arr1.sum(axis=(0, 1), keepdims=True) q8 = arr1[indices].cumsum() q9 = arr1[indices[indices]].ptp(axis=(-2, -1)) # Run mypy over the snippet to find out your score! reveal_type(q1) reveal_type(q2) reveal_type(q3) reveal_type(q4) reveal_type(q5) reveal_type(q6) reveal_type(q7) reveal_type(q8) reveal_type(q9) ``` [`reveal_type`](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html#when-you-re-puzzled-or-when-things-are-complicated) is a "magic" function that `mypy` detects to log the type of a variable. You don't need to import it, it's global. It doesn't exist in Python, only in `mypy`. If you try to run the code using `reveal_type()` with Python it won't work. --- ## Using Thinc's custom types in your code {#custom-types} ### Array types {#array-types} Thinc relies heavily on the `numpy.ndarray` interface, which was not designed with type checking or type annotations in mind. The `numpy` API is extremely polymorphic, with most common operations returning a variety of output types depending on what combination of arguments are provided. Retrofitting a type system to the interface will always involve some compromise between "correctness" (whether the type-system approves all and only valid numpy code) and "type sanity": whether the type-system is able to infer useful types, so you can catch more bugs with less detailed annotations. Thinc's array types are like the classes from the built-in `typing` module: they are **not runtime types**. You will not create instances of them. You'll only use them with type declarations. This means you can use the same annotations for a number of classes that behave similarly, regardless of their inheritance relationships. While official type-annotations for numpy will likely have to lean towards correctness, Thinc has the luxury of **leaning heavily towards type-sanity**. We accept a few usage limitations, offer type-specific options for a few common operations ([array allocation](/docs/api-backends#alloc), [reshaping](/docs/api-backends#reshape) and [conversion](/docs/api-backends#asarray)), and declare a few usage patterns off-limits (such as passing `dtype` into many methods or functions). | | | | ---------------------------------------------------------- | -------------------------------------------------- | | `Floats1d`, `Floats2d`, `Floats3d`, `Floats4d`, `FloatsXd` | 1d, 2d, 3d, 4d and any-d arrays of floats. | | `Ints1d`, `Ints2d`, `Ints3d`, `Ints4d`, `IntsXd` | 1d, 2d, 3d, 4d and any-d arrays of ints. | | `Array1d`, `Array2d`, `Array3d`, `Array4d`, `ArrayXd` | 1d, 2d, 3d, 4d and any-d arrays of floats or ints. | We also compromise on how much detail the type-system can be expected to represent, setting on two useful distinctions: **broad data type** (ints vs. floats), and **number of dimensions** (1, 2, 3, 4, and many) โ€“ so we have 10 array subtypes in total. Notably, our type-system does not specify actual array shapes. Representing the shapes as well would be fantastic, but it would make the system far more verbose, complex and difficult to work with. ### Generic Model types {#model-types} Thinc also makes use of type-annotations for its model class, by making it a **[generic](https://docs.python.org/3/library/typing.html#generics) with two type parameters**, representing the **layer's input and output types**. Generics let you tell the type-system a little bit more information on a per-instance basis. For instance, the `typing.List` class is a generic: you can write `List[int]` to denote a list of integers, and `List[str]` to denote a list of strings. This helps you declare your interfaces more precisely, and lets the type-system infer types when you later loop over the list, all without having to declare your own subclass. Type-parameters for generics are written between square brackets, and are comma-delimited like function arguments. So to specify that a model takes a list of strings as input and produces a two-dimensional array of integers as output, you would write `Model[List[str], Ints2d]`. You can also under-specify either or both arguments, by writing e.g. `Model[Any, Any]`, `Model[Any, Ints2d]`, etc. If you specify simply `Model`, that is read as syntactic sugar for `Model[Any, Any]`. A common problem at first is that it feels natural to write simply `Model` for code that should be agnostic to input and output types. This generally works as an input annotation, but if you use it as a return type you'll often have problems. ```python ### Sane but wrong {small="true"} def pop_layer(model: Model) -> Model: model.layers.pop(0) return model ``` ```python ### Thanks, I hate it {small="true"} from typing import TypeVar _T = TypeVar("_T", bound=Model) def pop_layer(model: _T) -> _T: model.layers.pop(0) return model ``` The problem is that you need a way to note that the model your function is returning is of the same type as your function's argument. The [`typing.TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar) class provides a (syntactically awkward) solution: if you use the same `TypeVar` in your method definition, that will denote that the **two variables must have the same type**. However, the scoping behavior is very surprising: you can use the same `TypeVar` in _different_ function definitions, and it _won't_ bind the types between them. The behavior with respect to classes and generics is also quite subtle, and mostly left as an exercise to the reader by [the official documentation](https://docs.python.org/3/library/typing.html#typing.TypeVar). Although `TypeVar` will make your days a little bit worse, they are often necessary, and we suggest making peace with having to use them. However, in some situations you can instead use the [`@overload` decorator](https://docs.python.org/3/library/typing.html#typing.overload). This alternative will work whenever you can enumerate a small number of specific types. The `@overload` decorator lets you describe multiple input type to return type mappings for your function, without actually changing the return-type dispatch. It's also more flexible than `TypeVar`s in many situations, as you can express more subtle relationships. We use `@overload` extensively in our array definitions, to represent numpy's polymorphic behavior, so you can find some more complex examples of `@overload` in the `thinc.types` module. ```python ### Type logic with overload @overload def toggle_types(hello: str) -> int: ... @overload def toggle_types(hello: int) -> str: ... def toggle_types(hello: Union[str, int]) -> Union[str, int]: return 1 if isinstance(hello, str) else "hello" ``` ## Tips, tricks & best practices {#tips} - If you're just starting out with type annotations, try just using them in your model-building functions. The type annotations can help you plan your model "top down", so you can see when things aren't lining up even without running the type checker. - If you're using the [`@registry` decorator](/docs/usage-config#registry) to register functions for the config system, you probably want to add type annotations to your declaration. This lets the config system validate the arguments, which can catch a lot of errors. - Writing type-checked code invites slightly different conventions. You'll often want to split interfaces up into several functions, so that the types are a bit more specific. For instance, we made separate [`alloc2f`, `alloc2i`, `alloc3f` etc.](/docs/api-backends#alloc) methods on the `Ops` object, because these return specific types. We only use the generic one for generic code, where the desired type is unknown. - Instead of nested Python containers, try using the [`@dataclass`](https://docs.python.org/3/library/dataclasses.html) decorator to create small, behavior-less struct-like classes. You would have to create a name for the nested format anyway, so it may as well be a useful type. - It sometimes helps to think of the type-checker as trying to _falsify_ your code, rather than trying to _validate_ it. For instance, if you're looking at a particular piece of code, you might see that the variable passed into your function is of a certain type, and the type-checker knows that โ€“ so why does it raise a problem in the function? The answer is that the checker is thinking about _any possible_ input value, according to the type declarations. thinc-9.0.0/website/gatsby-browser.js000066400000000000000000000007721461023342500176050ustar00rootroot00000000000000exports.onRouteUpdate = ({ location }) => { // Fix anchor links, especially if links are opened in new tab if (location.hash) { setTimeout(() => { const el = document.querySelector(`${location.hash}`) if (el) { // Navigate to targeted element el.scrollIntoView() // Force recomputing :target pseudo class with pushState/popState window.location.hash = location.hash } }, 0) } } thinc-9.0.0/website/gatsby-config.js000066400000000000000000000055721461023342500173720ustar00rootroot00000000000000const meta = require('./meta.json') const autoprefixer = require('autoprefixer') const fs = require('fs') const plugins = [ { resolve: `gatsby-plugin-sass`, options: { postCssPlugins: [autoprefixer()], cssLoaderOptions: { localIdentName: process.env.NODE_ENV == 'development' ? '[name]-[local]-[hash:8]' : '[hash:8]', }, }, }, `gatsby-plugin-react-helmet`, { resolve: `gatsby-source-filesystem`, options: { name: `content`, path: `${__dirname}/docs`, }, }, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images`, }, }, { resolve: 'gatsby-plugin-react-svg', options: { rule: { include: /src\/images\/(.*)\.svg/, }, }, }, { resolve: `gatsby-transformer-remark`, options: { plugins: [ `gatsby-remark-copy-linked-files`, `gatsby-remark-unwrap`, { resolve: `gatsby-remark-images`, options: { maxWidth: 790, linkImagesToOriginal: true, showCaptions: true, quality: 80, withWebp: { quality: 80 }, backgroundColor: 'transparent', disableBgImageOnAlpha: true, loading: 'lazy', }, }, `gatsby-remark-custom-attrs`, `gatsby-remark-code-blocks`, { resolve: `gatsby-remark-smartypants`, options: { dashes: 'oldschool', }, }, ], }, }, `gatsby-transformer-sharp`, `gatsby-plugin-sharp`, `gatsby-plugin-sitemap`, { resolve: `gatsby-plugin-manifest`, options: { name: meta.title, short_name: meta.title, start_url: `/`, background_color: meta.theme, theme_color: meta.theme, display: `minimal-ui`, icon: `src/images/icon.png`, }, }, { resolve: `gatsby-plugin-plausible`, options: { domain: meta.domain, }, }, `gatsby-plugin-offline`, ] plugins.push({ resolve: `gatsby-plugin-sass-resources`, options: { resources: ['./src/styles/base.sass'], }, }) if (fs.existsSync('./src/fonts')) { plugins.push({ resolve: `gatsby-plugin-sass-resources`, options: { resources: ['./src/styles/fonts.sass'], }, }) } module.exports = { siteMetadata: meta, plugins, } thinc-9.0.0/website/gatsby-node.js000066400000000000000000000042321461023342500170420ustar00rootroot00000000000000const path = require('path') const { createFilePath } = require('gatsby-source-filesystem') const pageTemplate = path.resolve('src/templates/docs.js') function replacePath(pagePath) { return pagePath === `/` ? pagePath : pagePath.replace(/\/$/, ``) } exports.onCreatePage = ({ page, actions }) => { const { createPage, deletePage } = actions const oldPage = Object.assign({}, page) if (oldPage.path != '/dev-404-page/') { page.path = replacePath(page.path) if (page.path !== oldPage.path) { deletePage(oldPage) createPage(page) } } } exports.onCreateNode = ({ node, actions, getNode }) => { const { createNodeField } = actions if (node.internal.type === 'MarkdownRemark') { const slug = createFilePath({ node, getNode, basePath: 'docs', trailingSlash: false }) createNodeField({ name: 'slug', node, value: `/docs${slug}` }) } } exports.createPages = ({ actions, graphql }) => { const { createPage } = actions return graphql(` { allMarkdownRemark { edges { node { frontmatter { title } fields { slug } } } } } `).then(result => { if (result.errors) { return Promise.reject(result.errors) } const posts = result.data.allMarkdownRemark.edges posts.forEach(({ node }) => { createPage({ path: replacePath(node.fields.slug), component: pageTemplate, context: { slug: node.fields.slug, }, }) }) }) } exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => { const config = getConfig() const miniCssExtractPlugin = config.plugins.find( plugin => plugin.constructor.name === 'MiniCssExtractPlugin' ) if (miniCssExtractPlugin) { miniCssExtractPlugin.options.ignoreOrder = true } actions.replaceWebpackConfig(config) } thinc-9.0.0/website/meta.json000066400000000000000000000047571461023342500161250ustar00rootroot00000000000000{ "title": "Thinc", "slogan": "A refreshing functional take on deep learning", "description": "Thinc is a lightweight type-checked deep learning library for composing models, with support for layers defined in frameworks like PyTorch and TensorFlow.", "siteUrl": "https://thinc.ai", "domain": "thinc.ai", "twitter": "explosion_ai", "github": "explosion/thinc", "email": "contact@explosion.ai", "company": "Explosion", "companyUrl": "https://explosion.ai", "imprintUrl": "https://explosion.ai/legal", "theme": "#291e56", "sidebar": [ { "label": "Get started", "items": [ { "text": "Introduction", "url": "/docs/" }, { "text": "Concept & Design", "url": "/docs/concept" }, { "text": "Installation & Setup", "url": "/docs/install" }, { "text": "Examples & Tutorials", "url": "https://github.com/explosion/thinc/#-selected-examples-and-notebooks" }, { "text": "Backprop 101", "url": "/docs/backprop101" } ] }, { "label": "Usage", "items": [ { "text": "Configuration System", "url": "/docs/usage-config" }, { "text": "Defining & Using Models", "url": "/docs/usage-models" }, { "text": "Training Models", "url": "/docs/usage-training" }, { "text": "PyTorch, TensorFlow etc.", "url": "/docs/usage-frameworks" }, { "text": "Variable-length Sequences", "url": "/docs/usage-sequences" }, { "text": "Type Checking", "url": "/docs/usage-type-checking" } ] }, { "label": "API", "items": [ { "text": "Model", "url": "/docs/api-model" }, { "text": "Layers", "url": "/docs/api-layers" }, { "text": "Optimizers", "url": "/docs/api-optimizers" }, { "text": "Initializers", "url": "/docs/api-initializers" }, { "text": "Schedules", "url": "/docs/api-schedules" }, { "text": "Losses", "url": "/docs/api-loss" }, { "text": "Config & Registry", "url": "/docs/api-config" }, { "text": "Types & Dataclasses", "url": "/docs/api-types" }, { "text": "Backends & Math", "url": "/docs/api-backends" }, { "text": "Utilities & Extras", "url": "/docs/api-util" } ] } ] } thinc-9.0.0/website/package-lock.json000066400000000000000000075610241461023342500175220ustar00rootroot00000000000000{ "name": "thinc.ai", "version": "0.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "thinc.ai", "version": "0.0.1", "dependencies": { "@tippy.js/react": "^2.2.2", "autoprefixer": "^10.4.13", "classnames": "^2.2.6", "gatsby": "^4.18.2", "gatsby-image": "^2.11.0", "gatsby-plugin-google-analytics": "^4.25.0", "gatsby-plugin-manifest": "^4.25.0", "gatsby-plugin-offline": "^5.25.0", "gatsby-plugin-plausible": "^0.0.7", "gatsby-plugin-react-helmet": "^5.25.0", "gatsby-plugin-react-svg": "^3.3.0", "gatsby-plugin-remove-trailing-slashes": "^4.19.0", "gatsby-plugin-sass": "^5.25.0", "gatsby-plugin-sass-resources": "^3.0.1", "gatsby-plugin-sharp": "^4.25.0", "gatsby-plugin-sitemap": "^5.25.0", "gatsby-remark-copy-linked-files": "^5.25.0", "gatsby-remark-images": "^6.25.0", "gatsby-remark-prismjs": "^6.25.0", "gatsby-remark-smartypants": "^5.25.0", "gatsby-remark-unwrap-images": "^1.0.2", "gatsby-source-filesystem": "^4.25.0", "gatsby-transformer-remark": "^5.25.1", "gatsby-transformer-sharp": "^4.25.0", "html-to-react": "^1.3.4", "parse-numeric-range": "0.0.2", "prismjs": "^1.15.0", "react": "^16.8.2", "react-dom": "^16.8.2", "react-helmet": "^5.2.0", "react-jss": "^8.6.1", "rehype-react": "^3.1.0", "remark-react": "^5.0.1", "slugify": "^1.3.6" }, "devDependencies": { "babel-cli": "^6.26.0", "babel-core": "^6.26.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.13", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "json5": "^2.1.0", "md-attr-parser": "^1.2.1", "prettier": "^1.16.4", "unist-util-remove": "^1.0.3", "unist-util-visit": "^1.4.0" }, "engines": { "node": "16" } }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@ardatan/relay-compiler": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", "dependencies": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", "@babel/parser": "^7.14.0", "@babel/runtime": "^7.0.0", "@babel/traverse": "^7.14.0", "@babel/types": "^7.0.0", "babel-preset-fbjs": "^3.4.0", "chalk": "^4.0.0", "fb-watchman": "^2.0.0", "fbjs": "^3.0.0", "glob": "^7.1.1", "immutable": "~3.7.6", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "relay-runtime": "12.0.0", "signedsource": "^1.0.0", "yargs": "^15.3.1" }, "bin": { "relay-compiler": "bin/relay-compiler" }, "peerDependencies": { "graphql": "*" } }, "node_modules/@ardatan/relay-compiler/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@ardatan/relay-compiler/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@ardatan/relay-compiler/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dependencies": { "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { "version": "7.20.10", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.20.12", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", "@babel/generator": "^7.20.7", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-module-transforms": "^7.20.11", "@babel/helpers": "^7.20.7", "@babel/parser": "^7.20.7", "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.12", "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/babel" } }, "node_modules/@babel/core/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@babel/core/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/eslint-parser": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", "semver": "^6.3.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || >=14.0.0" }, "peerDependencies": { "@babel/core": ">=7.11.0", "eslint": "^7.5.0 || ^8.0.0" } }, "node_modules/@babel/eslint-parser/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dependencies": { "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/generator/node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "bin": { "jsesc": "bin/jsesc" }, "engines": { "node": ">=4" } }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dependencies": { "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dependencies": { "@babel/helper-explode-assignable-expression": "^7.18.6", "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.20.12", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/helper-split-export-declaration": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "regexpu-core": "^5.2.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "bin": { "jsesc": "bin/jsesc" } }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regexpu-core": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" } }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regjsgen": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dependencies": { "jsesc": "~0.5.0" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" }, "peerDependencies": { "@babel/core": "^7.4.0-0" } }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-explode-assignable-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", "dependencies": { "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dependencies": { "@babel/template": "^7.18.10", "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dependencies": { "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", "dependencies": { "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dependencies": { "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.10", "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "dependencies": { "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-wrap-function": "^7.18.9", "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-replace-supers": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.7", "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dependencies": { "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "dependencies": { "@babel/types": "^7.20.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dependencies": { "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dependencies": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", "@babel/traverse": "^7.20.5", "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "dependencies": { "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.7", "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dependencies": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/@babel/parser": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-proposal-optional-chaining": "^7.20.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-class-static-block": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "node_modules/@babel/plugin-proposal-dynamic-import": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-json-strings": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-numeric-separator": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.20.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-chaining": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-flow": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-remap-async-to-generator": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-classes": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-classes/node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "engines": { "node": ">=4" } }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/template": "^7.20.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-flow-strip-types": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", "dependencies": { "@babel/helper-plugin-utils": "^7.19.0", "@babel/plugin-syntax-flow": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.18.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dependencies": { "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-function-name": "^7.18.9", "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-literals": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "dependencies": { "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", "dependencies": { "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-simple-access": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "dependencies": { "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-identifier": "^7.19.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "dependencies": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-replace-supers": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-display-name": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-jsx": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz", "integrity": "sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-jsx-development": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", "dependencies": { "@babel/plugin-transform-react-jsx": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "regenerator-transform": "^0.15.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-regenerator/node_modules/regenerator-transform": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-runtime": { "version": "7.19.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.19.0", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-spread": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz", "integrity": "sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw==", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-env": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", "dependencies": { "@babel/compat-data": "^7.20.1", "@babel/helper-compilation-targets": "^7.20.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", "@babel/plugin-proposal-async-generator-functions": "^7.20.1", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-static-block": "^7.18.6", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", "@babel/plugin-proposal-object-rest-spread": "^7.20.2", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.18.6", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.20.0", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-transform-arrow-functions": "^7.18.6", "@babel/plugin-transform-async-to-generator": "^7.18.6", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", "@babel/plugin-transform-block-scoping": "^7.20.2", "@babel/plugin-transform-classes": "^7.20.2", "@babel/plugin-transform-computed-properties": "^7.18.9", "@babel/plugin-transform-destructuring": "^7.20.2", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", "@babel/plugin-transform-for-of": "^7.18.8", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", "@babel/plugin-transform-modules-amd": "^7.19.6", "@babel/plugin-transform-modules-commonjs": "^7.19.6", "@babel/plugin-transform-modules-systemjs": "^7.19.6", "@babel/plugin-transform-modules-umd": "^7.18.6", "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", "@babel/plugin-transform-parameters": "^7.20.1", "@babel/plugin-transform-property-literals": "^7.18.6", "@babel/plugin-transform-regenerator": "^7.18.6", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", "@babel/plugin-transform-spread": "^7.19.0", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", "@babel/types": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", "core-js-compat": "^3.25.1", "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-env/node_modules/core-js-compat": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz", "integrity": "sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==", "dependencies": { "browserslist": "^4.21.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-react": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-transform-react-display-name": "^7.18.6", "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/plugin-transform-react-jsx-development": "^7.18.6", "@babel/plugin-transform-react-pure-annotations": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-typescript": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-transform-typescript": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/runtime": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz", "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==", "dependencies": { "regenerator-runtime": "^0.13.11" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/runtime-corejs3": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz", "integrity": "sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==", "dependencies": { "core-js-pure": "^3.25.1", "regenerator-runtime": "^0.13.11" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/runtime-corejs3/node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/@babel/runtime/node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/@babel/template": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { "version": "7.20.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "engines": { "node": ">=4" } }, "node_modules/@babel/traverse/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@babel/types": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dependencies": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types/node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "engines": { "node": ">=4" } }, "node_modules/@builder.io/partytown": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/@builder.io/partytown/-/partytown-0.5.4.tgz", "integrity": "sha512-qnikpQgi30AS01aFlNQV6l8/qdZIcP76mp90ti+u4rucXHsn4afSKivQXApqxvrQG9+Ibv45STyvHizvxef/7A==", "bin": { "partytown": "bin/partytown.cjs" } }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/@eslint/eslintrc/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.19.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "engines": { "node": ">= 4" } }, "node_modules/@eslint/eslintrc/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@gatsbyjs/parcel-namer-relative-to-cwd": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@gatsbyjs/parcel-namer-relative-to-cwd/-/parcel-namer-relative-to-cwd-1.10.0.tgz", "integrity": "sha512-JSiOxG2SD64joKfcCOdujIpqmhs+k5Ic1sO/hQ83EVF6G9DJJTf8n12rGb2rzPb00TFT4ldb/nWxQRV+kQTlPA==", "dependencies": { "@babel/runtime": "^7.18.0", "@parcel/namer-default": "2.6.2", "@parcel/plugin": "2.6.2", "gatsby-core-utils": "^3.25.0" }, "engines": { "node": ">=14.15.0", "parcel": "2.x" } }, "node_modules/@gatsbyjs/reach-router": { "version": "1.3.9", "resolved": "https://registry.npmjs.org/@gatsbyjs/reach-router/-/reach-router-1.3.9.tgz", "integrity": "sha512-/354IaUSM54xb7K/TxpLBJB94iEAJ3P82JD38T8bLnIDWF+uw8+W/82DKnQ7y24FJcKxtVmG43aiDLG88KSuYQ==", "dependencies": { "invariant": "^2.2.3", "prop-types": "^15.6.1", "react-lifecycles-compat": "^3.0.4" }, "peerDependencies": { "react": "15.x || 16.x || 17.x || 18.x", "react-dom": "15.x || 16.x || 17.x || 18.x" } }, "node_modules/@gatsbyjs/webpack-hot-middleware": { "version": "2.25.3", "resolved": "https://registry.npmjs.org/@gatsbyjs/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz", "integrity": "sha512-ul17OZ8Dlw+ATRbnuU+kwxuAlq9lKbYz/2uBS1FLCdgoPTF1H2heP7HbUbgfMZbfRQNcCG2rMscMnr32ritCDw==", "dependencies": { "ansi-html-community": "0.0.8", "html-entities": "^2.3.3", "strip-ansi": "^6.0.0" } }, "node_modules/@gatsbyjs/webpack-hot-middleware/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/@gatsbyjs/webpack-hot-middleware/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/@graphql-codegen/add": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-3.2.3.tgz", "integrity": "sha512-sQOnWpMko4JLeykwyjFTxnhqjd/3NOG2OyMuvK76Wnnwh8DRrNf2VEs2kmSvLl7MndMlOj7Kh5U154dVcvhmKQ==", "dependencies": { "@graphql-codegen/plugin-helpers": "^3.1.1", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/add/node_modules/@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "dependencies": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/add/node_modules/change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/@graphql-codegen/core": { "version": "2.6.8", "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.8.tgz", "integrity": "sha512-JKllNIipPrheRgl+/Hm/xuWMw9++xNQ12XJR/OHHgFopOg4zmN3TdlRSyYcv/K90hCFkkIwhlHFUQTfKrm8rxQ==", "dependencies": { "@graphql-codegen/plugin-helpers": "^3.1.1", "@graphql-tools/schema": "^9.0.0", "@graphql-tools/utils": "^9.1.1", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/core/node_modules/@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "dependencies": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/core/node_modules/change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/@graphql-codegen/plugin-helpers": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz", "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==", "dependencies": { "@graphql-tools/utils": "^8.8.0", "change-case-all": "1.0.14", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/plugin-helpers/node_modules/@graphql-tools/utils": { "version": "8.13.1", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz", "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==", "dependencies": { "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-codegen/schema-ast": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.6.1.tgz", "integrity": "sha512-5TNW3b1IHJjCh07D2yQNGDQzUpUl2AD+GVe1Dzjqyx/d2Fn0TPMxLsHsKPS4Plg4saO8FK/QO70wLsP7fdbQ1w==", "dependencies": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-tools/utils": "^9.0.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/schema-ast/node_modules/@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "dependencies": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/schema-ast/node_modules/change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/@graphql-codegen/typescript": { "version": "2.8.7", "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.8.7.tgz", "integrity": "sha512-Nm5keWqIgg/VL7fivGmglF548tJRP2ttSmfTMuAdY5GNGTJTVZOzNbIOfnbVEDMMWF4V+quUuSyeUQ6zRxtX1w==", "dependencies": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-codegen/schema-ast": "^2.6.1", "@graphql-codegen/visitor-plugin-common": "2.13.7", "auto-bind": "~4.0.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript-operations": { "version": "2.5.12", "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-2.5.12.tgz", "integrity": "sha512-/w8IgRIQwmebixf514FOQp2jXOe7vxZbMiSFoQqJgEgzrr42joPsgu4YGU+owv2QPPmu4736OcX8FSavb7SLiA==", "dependencies": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-codegen/typescript": "^2.8.7", "@graphql-codegen/visitor-plugin-common": "2.13.7", "auto-bind": "~4.0.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript-operations/node_modules/@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "dependencies": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript-operations/node_modules/change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/@graphql-codegen/typescript/node_modules/@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "dependencies": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript/node_modules/change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/@graphql-codegen/visitor-plugin-common": { "version": "2.13.7", "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.7.tgz", "integrity": "sha512-xE6iLDhr9sFM1qwCGJcCXRu5MyA0moapG2HVejwyAXXLubYKYwWnoiEigLH2b5iauh6xsl6XP8hh9D1T1dn5Cw==", "dependencies": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-tools/optimize": "^1.3.0", "@graphql-tools/relay-operation-optimizer": "^6.5.0", "@graphql-tools/utils": "^9.0.0", "auto-bind": "~4.0.0", "change-case-all": "1.0.15", "dependency-graph": "^0.11.0", "graphql-tag": "^2.11.0", "parse-filepath": "^1.0.2", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/visitor-plugin-common/node_modules/@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "dependencies": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/visitor-plugin-common/node_modules/change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/@graphql-tools/code-file-loader": { "version": "7.3.15", "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.15.tgz", "integrity": "sha512-cF8VNc/NANTyVSIK8BkD/KSXRF64DvvomuJ0evia7tJu4uGTXgDjimTMWsTjKRGOOBSTEbL6TA8e4DdIYq6Udw==", "dependencies": { "@graphql-tools/graphql-tag-pluck": "7.4.2", "@graphql-tools/utils": "9.1.3", "globby": "^11.0.3", "tslib": "^2.4.0", "unixify": "^1.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/graphql-tag-pluck": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.4.2.tgz", "integrity": "sha512-SXM1wR5TExrxocQTxZK5r74jTbg8GxSYLY3mOPCREGz6Fu7PNxMxfguUzGUAB43Mf44Dn8oVztzd2eitv2Qgww==", "dependencies": { "@babel/parser": "^7.16.8", "@babel/plugin-syntax-import-assertions": "7.20.0", "@babel/traverse": "^7.16.8", "@babel/types": "^7.16.8", "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/load": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-7.8.8.tgz", "integrity": "sha512-gMuQdO2jXmI0BNUc1MafxRQTWVMUtuH500pZAQtOdDdNJppV7lJdY6mMhITQ2qnhYDuMrcZPHhIkcftyQfkgUg==", "dependencies": { "@graphql-tools/schema": "9.0.12", "@graphql-tools/utils": "9.1.3", "p-limit": "3.1.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/merge": { "version": "8.3.14", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.14.tgz", "integrity": "sha512-zV0MU1DnxJLIB0wpL4N3u21agEiYFsjm6DI130jqHpwF0pR9HkF+Ni65BNfts4zQelP0GjkHltG+opaozAJ1NA==", "dependencies": { "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/optimize": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.3.1.tgz", "integrity": "sha512-5j5CZSRGWVobt4bgRRg7zhjPiSimk+/zIuColih8E8DxuFOaJ+t0qu7eZS5KXWBkjcd4BPNuhUPpNlEmHPqVRQ==", "dependencies": { "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/relay-operation-optimizer": { "version": "6.5.14", "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.14.tgz", "integrity": "sha512-RAy1fMfXig9X3gIkYnfEmv0mh20vZuAgWDq+zf1MrrsCAP364B+DKrBjLwn3D+4e0PMTlqwmqR0JB5t1VtZn2w==", "dependencies": { "@ardatan/relay-compiler": "12.0.0", "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/schema": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.12.tgz", "integrity": "sha512-DmezcEltQai0V1y96nwm0Kg11FDS/INEFekD4nnVgzBqawvznWqK6D6bujn+cw6kivoIr3Uq//QmU/hBlBzUlQ==", "dependencies": { "@graphql-tools/merge": "8.3.14", "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0", "value-or-promise": "1.0.11" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@graphql-tools/utils": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.1.3.tgz", "integrity": "sha512-bbJyKhs6awp1/OmP+WKA1GOyu9UbgZGkhIj5srmiMGLHohEOKMjW784Sk0BZil1w2x95UPu0WHw6/d/HVCACCg==", "dependencies": { "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", "deprecated": "Moved to 'npm install @sideway/address'" }, "node_modules/@hapi/bourne": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", "deprecated": "This version has been deprecated and is no longer supported or maintained" }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/@hapi/joi": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", "deprecated": "Switch to 'npm install joi'", "dependencies": { "@hapi/address": "2.x.x", "@hapi/bourne": "1.x.x", "@hapi/hoek": "8.x.x", "@hapi/topo": "3.x.x" } }, "node_modules/@hapi/joi/node_modules/@hapi/hoek": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", "deprecated": "This version has been deprecated and is no longer supported or maintained" }, "node_modules/@hapi/joi/node_modules/@hapi/topo": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", "deprecated": "This version has been deprecated and is no longer supported or maintained", "dependencies": { "@hapi/hoek": "^8.3.0" } }, "node_modules/@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", "minimatch": "^3.0.4" }, "engines": { "node": ">=10.10.0" } }, "node_modules/@humanwhocodes/config-array/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@humanwhocodes/config-array/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@lezer/common": { "version": "0.15.12", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" }, "node_modules/@lezer/lr": { "version": "0.15.8", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", "dependencies": { "@lezer/common": "^0.15.0" } }, "node_modules/@lmdb/lmdb-darwin-arm64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.3.tgz", "integrity": "sha512-RXwGZ/0eCqtCY8FLTM/koR60w+MXyvBUpToXiIyjOcBnC81tAlTUHrRUavCEWPI9zc9VgvpK3+cbumPyR8BSuA==", "cpu": [ "arm64" ], "optional": true, "os": [ "darwin" ] }, "node_modules/@lmdb/lmdb-darwin-x64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.3.tgz", "integrity": "sha512-337dNzh5yCdNCTk8kPfoU7jR3otibSlPDGW0vKZT97rKnQMb9tNdto3RtWoGPsQ8hKmlRZpojOJtmwjncq1MoA==", "cpu": [ "x64" ], "optional": true, "os": [ "darwin" ] }, "node_modules/@lmdb/lmdb-linux-arm": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.3.tgz", "integrity": "sha512-mU2HFJDGwECkoD9dHQEfeTG5mp8hNS2BCfwoiOpVPMeapjYpQz9Uw3FkUjRZ4dGHWKbin40oWHuL0bk2bCx+Sg==", "cpu": [ "arm" ], "optional": true, "os": [ "linux" ] }, "node_modules/@lmdb/lmdb-linux-arm64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.3.tgz", "integrity": "sha512-VJw60Mdgb4n+L0fO1PqfB0C7TyEQolJAC8qpqvG3JoQwvyOv6LH7Ib/WE3wxEW9nuHmVz9jkK7lk5HfWWgoO1Q==", "cpu": [ "arm64" ], "optional": true, "os": [ "linux" ] }, "node_modules/@lmdb/lmdb-linux-x64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.3.tgz", "integrity": "sha512-qaReO5aV8griBDsBr8uBF/faO3ieGjY1RY4p8JvTL6Mu1ylLrTVvOONqKFlNaCwrmUjWw5jnf7VafxDAeQHTow==", "cpu": [ "x64" ], "optional": true, "os": [ "linux" ] }, "node_modules/@lmdb/lmdb-win32-x64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.3.tgz", "integrity": "sha512-cK+Elf3RjEzrm3SerAhrFWL5oQAsZSJ/LmjL1joIpTfEP1etJJ9CTRvdaV6XLYAxaEkfdhk/9hOvHLbR9yIhCA==", "cpu": [ "x64" ], "optional": true, "os": [ "win32" ] }, "node_modules/@mapbox/hast-util-table-cell-style": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@mapbox/hast-util-table-cell-style/-/hast-util-table-cell-style-0.1.3.tgz", "integrity": "sha512-QsEsh5YaDvHoMQ2YHdvZy2iDnU3GgKVBTcHf6cILyoWDZtPSdlG444pL/ioPYO/GpXSfODBb9sefEetfC4v9oA==", "dependencies": { "unist-util-visit": "^1.3.0" }, "engines": { "node": ">=4" } }, "node_modules/@mischnic/json-sourcemap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", "integrity": "sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==", "dependencies": { "@lezer/common": "^0.15.7", "@lezer/lr": "^0.15.4", "json5": "^2.2.1" }, "engines": { "node": ">=12.0.0" } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz", "integrity": "sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==", "cpu": [ "arm64" ], "optional": true, "os": [ "darwin" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.2.0.tgz", "integrity": "sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw==", "cpu": [ "x64" ], "optional": true, "os": [ "darwin" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.2.0.tgz", "integrity": "sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg==", "cpu": [ "arm" ], "optional": true, "os": [ "linux" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.2.0.tgz", "integrity": "sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA==", "cpu": [ "arm64" ], "optional": true, "os": [ "linux" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.2.0.tgz", "integrity": "sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw==", "cpu": [ "x64" ], "optional": true, "os": [ "linux" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz", "integrity": "sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA==", "cpu": [ "x64" ], "optional": true, "os": [ "win32" ] }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dependencies": { "eslint-scope": "5.1.1" } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { "node": ">= 8" } }, "node_modules/@parcel/bundler-default": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.6.2.tgz", "integrity": "sha512-XIa3had/MIaTGgRFkHApXwytYs77k4geaNcmlb6nzmAABcYjW1CLYh83Zt0AbzLFsDT9ZcRY3u2UjhNf6efSaw==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/cache": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.6.2.tgz", "integrity": "sha512-hhJ6AsEGybeQZd9c/GYqfcKTgZKQXu3Xih6TlnP3gdR3KZoJOnb40ovHD1yYg4COvfcXThKP1cVJ18J6rcv3IA==", "dependencies": { "@parcel/fs": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/utils": "2.6.2", "lmdb": "2.5.2" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { "@parcel/core": "^2.6.2" } }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-darwin-arm64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", "cpu": [ "arm64" ], "optional": true, "os": [ "darwin" ] }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-darwin-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", "cpu": [ "x64" ], "optional": true, "os": [ "darwin" ] }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-linux-arm": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", "cpu": [ "arm" ], "optional": true, "os": [ "linux" ] }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-linux-arm64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", "cpu": [ "arm64" ], "optional": true, "os": [ "linux" ] }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-linux-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", "integrity": "sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q==", "cpu": [ "x64" ], "optional": true, "os": [ "linux" ] }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-win32-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", "cpu": [ "x64" ], "optional": true, "os": [ "win32" ] }, "node_modules/@parcel/cache/node_modules/lmdb": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", "hasInstallScript": true, "dependencies": { "msgpackr": "^1.5.4", "node-addon-api": "^4.3.0", "node-gyp-build-optional-packages": "5.0.3", "ordered-binary": "^1.2.4", "weak-lru-cache": "^1.2.2" }, "optionalDependencies": { "@lmdb/lmdb-darwin-arm64": "2.5.2", "@lmdb/lmdb-darwin-x64": "2.5.2", "@lmdb/lmdb-linux-arm": "2.5.2", "@lmdb/lmdb-linux-arm64": "2.5.2", "@lmdb/lmdb-linux-x64": "2.5.2", "@lmdb/lmdb-win32-x64": "2.5.2" } }, "node_modules/@parcel/cache/node_modules/node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, "node_modules/@parcel/codeframe": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.6.2.tgz", "integrity": "sha512-oFlHr6HCaYYsB4SHkU+gn9DKtbzvv3/4NdwMX0/6NAKyYVI7inEsXyPGw2Bbd2ZCFatW9QJZUETF0etvh5AEfQ==", "dependencies": { "chalk": "^4.1.0" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/codeframe/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@parcel/codeframe/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@parcel/codeframe/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/@parcel/compressor-raw": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.6.2.tgz", "integrity": "sha512-P3c8jjV5HVs+fNDjhvq7PtHXNm687nit1iwTS5VAt+ScXKhKBhoIJ56q+9opcw0jnXVjAAgZqcRZ50oAJBGdKw==", "dependencies": { "@parcel/plugin": "2.6.2" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/core": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.6.2.tgz", "integrity": "sha512-JlKS3Ux0ngmdooSBbzQLShHJdsapF9E7TGMo1hFaHRquZip/DaqzvysYrgMJlDuCoLArciq5ei7ZKzGeK9zexA==", "dependencies": { "@mischnic/json-sourcemap": "^0.1.0", "@parcel/cache": "2.6.2", "@parcel/diagnostic": "2.6.2", "@parcel/events": "2.6.2", "@parcel/fs": "2.6.2", "@parcel/graph": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/package-manager": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "@parcel/workers": "2.6.2", "abortcontroller-polyfill": "^1.1.9", "base-x": "^3.0.8", "browserslist": "^4.6.6", "clone": "^2.1.1", "dotenv": "^7.0.0", "dotenv-expand": "^5.1.0", "json5": "^2.2.0", "msgpackr": "^1.5.4", "nullthrows": "^1.1.1", "semver": "^5.7.1" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/core/node_modules/dotenv": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", "engines": { "node": ">=6" } }, "node_modules/@parcel/diagnostic": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.6.2.tgz", "integrity": "sha512-3ODSBkKVihENU763z1/1DhGAWFhYWRxOCOShC72KXp+GFnSgGiBsxclu8NBa/N948Rzp8lqQI8U1nLcKkh0O/w==", "dependencies": { "@mischnic/json-sourcemap": "^0.1.0", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/events": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.6.2.tgz", "integrity": "sha512-IaCjOeA5ercdFVi1EZOmUHhGfIysmCUgc2Th9hMugSFO0I3GzRsBcAdP6XPfWm+TV6sQ/qZRfdk/drUxoAupnw==", "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/fs": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.6.2.tgz", "integrity": "sha512-mIhqdF3tjgeoIGqW7Nc/xfM2ClID7o8livwUe5lpQEP+ZaIBiMigXs6ckv3WToCACK+3uylrSD2A/HmlhrxMqQ==", "dependencies": { "@parcel/fs-search": "2.6.2", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "@parcel/watcher": "^2.0.0", "@parcel/workers": "2.6.2" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { "@parcel/core": "^2.6.2" } }, "node_modules/@parcel/fs-search": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/fs-search/-/fs-search-2.6.2.tgz", "integrity": "sha512-4STid1zqtGnmGjHD/2TG2g/zPDiCTtE3IAS24QYH3eiUAz2uoKGgEqd2tZbZ2yI96jtCuIhC1bzVu8Hbykls7w==", "dependencies": { "detect-libc": "^1.0.3" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/graph": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-2.6.2.tgz", "integrity": "sha512-DPH4G/RBFJWayIN2fnhDXqhUw75n7k15YsGzdDKiXuwwz4wMOjoL4cyrI6zOf1SIyh3guRmeTYJ4jjPzwrLYww==", "dependencies": { "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/hash": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/hash/-/hash-2.6.2.tgz", "integrity": "sha512-tFB+cJU1Wqag6WyJgsmx3nx+xhmjcNZqtWh/MtK1lHNnZdDRk6bjr7SapnygBwruz+SmSt5bbdVThcpk2dRCcA==", "dependencies": { "detect-libc": "^1.0.3", "xxhash-wasm": "^0.4.2" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/logger": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.6.2.tgz", "integrity": "sha512-Sz5YGCj1DbEiX0/G8Uw97LLZ0uEK+qtWcRAkHNpJpeMiSqDiRNevxXltz42EcLo+oCh4d4wyiVzwi9mNwzhS/Q==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/events": "2.6.2" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/markdown-ansi": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.6.2.tgz", "integrity": "sha512-N/h9J4eibhc+B+krzvPMzFUWL37GudBIZBa7XSLkcuH6MnYYfh6rrMvhIyyESwk6VkcZNVzAeZrGQqxEs0dHDQ==", "dependencies": { "chalk": "^4.1.0" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/markdown-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@parcel/markdown-ansi/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@parcel/markdown-ansi/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/@parcel/namer-default": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.6.2.tgz", "integrity": "sha512-mp7bx/BQaIuohmZP0uE+gAmDBzzH0Yu8F4yCtE611lc6i0mou+nWRhzyKLNC/ieuI8DB3BFh2QQKeTxJn4W0qg==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/plugin": "2.6.2", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/node-resolver-core": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-2.6.2.tgz", "integrity": "sha512-4b2L5QRYlTybvv3+TIRtwg4PPJXy+cRShCBa8eu1K0Fj297Afe8MOZrcVV+RIr2KPMIRXcIJoqDmOhyci/DynA==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1", "semver": "^5.7.1" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/optimizer-terser": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/optimizer-terser/-/optimizer-terser-2.6.2.tgz", "integrity": "sha512-ZSEVQ3G3zOiVPeHvH+BrHegZybrQj9kWQAaAA92leSqbvf6UaX4xqXbGRg2OttNFtbGYBzIl28Zm4t2SLeUIuA==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1", "terser": "^5.2.0" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/package-manager": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.6.2.tgz", "integrity": "sha512-xGMqTgnwTE3rgzYwUZMKxR8fzmP5iSYz/gj2H8FR3pEmwh/8xCMtNjTSth+hPVGuqgRZ6JxwpfdY/fXdZ61ViQ==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/fs": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "@parcel/workers": "2.6.2", "semver": "^5.7.1" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { "@parcel/core": "^2.6.2" } }, "node_modules/@parcel/packager-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.6.2.tgz", "integrity": "sha512-fm5rKWtaExR0W+UEKWivXNPysRFxuBCdskdxDByb1J1JeGMvp7dJElbi8oXDAQM4MnM5EyG7cg47SlMZNTLm4A==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.6.2", "globals": "^13.2.0", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/packager-js/node_modules/globals": { "version": "13.19.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@parcel/packager-raw": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.6.2.tgz", "integrity": "sha512-Rl3ZkMtMjb+LEvRowijDD8fibUAS6rWK0/vZQMk9cDNYCP2gCpZayLk0HZIGxneeTbosf/0sbngHq4VeRQOnQA==", "dependencies": { "@parcel/plugin": "2.6.2" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/plugin": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.6.2.tgz", "integrity": "sha512-wbbWsM23Pr+8xtLSvf+UopXdVYlpKCCx6PuuZaZcKo+9IcDCWoGXD4M8Kkz14qBmkFn5uM00mULUqmVdSibB2w==", "dependencies": { "@parcel/types": "2.6.2" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/reporter-dev-server": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.6.2.tgz", "integrity": "sha512-5QtL3ETMFL161jehlIK6rjBM+Pqk5cMhr60s9yLYqE1GY4M4gMj+Act+FXViyM6gmMA38cPxDvUsxTKBYXpFCw==", "dependencies": { "@parcel/plugin": "2.6.2", "@parcel/utils": "2.6.2" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/resolver-default": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.6.2.tgz", "integrity": "sha512-Lo5sWb5QkjWvdBr+TdmAF6Mszb/sMldBBatc1osQTkHXCy679VMH+lfyiWxHbwK+F1pmdMeBJpYcMxvrgT8EsA==", "dependencies": { "@parcel/node-resolver-core": "2.6.2", "@parcel/plugin": "2.6.2" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/runtime-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.6.2.tgz", "integrity": "sha512-0S3JFwgvs6FmEx2dHta9R0Sfu8vCnFAm4i7Y4efGHtAcTrF2CHjyiz4/hG+RQGJ70eoWW463Q+8qt6EKbkaOBQ==", "dependencies": { "@parcel/plugin": "2.6.2", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/source-map": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", "dependencies": { "detect-libc": "^1.0.3" }, "engines": { "node": "^12.18.3 || >=14" } }, "node_modules/@parcel/transformer-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.6.2.tgz", "integrity": "sha512-uhXAMTjE/Q61amflV8qVpb73mj+mIdXIMH0cSks1/gDIAxcgIvWvrE14P4TvY6zJ1q1iRJRIRUN6cFSXqjjLSA==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.6.2", "@parcel/workers": "2.6.2", "@swc/helpers": "^0.4.2", "browserslist": "^4.6.6", "detect-libc": "^1.0.3", "nullthrows": "^1.1.1", "regenerator-runtime": "^0.13.7", "semver": "^5.7.1" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { "@parcel/core": "^2.6.2" } }, "node_modules/@parcel/transformer-js/node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/@parcel/transformer-json": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.6.2.tgz", "integrity": "sha512-QGcIIvbPF/u10ihYvQhxXqb2QMXWSzcBxJrOSIXIl74TUGrWX05D5LmjDA/rzm/n/kvRnBkFNP60R/smYb8x+Q==", "dependencies": { "@parcel/plugin": "2.6.2", "json5": "^2.2.0" }, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/types": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.6.2.tgz", "integrity": "sha512-MV8BFpCIs2jMUvK2RHqzkoiuOQ//JIbrD1zocA2YRW3zuPL/iABvbAABJoXpoPCKikVWOoCWASgBfWQo26VvJQ==", "dependencies": { "@parcel/cache": "2.6.2", "@parcel/diagnostic": "2.6.2", "@parcel/fs": "2.6.2", "@parcel/package-manager": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/workers": "2.6.2", "utility-types": "^3.10.0" } }, "node_modules/@parcel/utils": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.6.2.tgz", "integrity": "sha512-Ug7hpRxjgbY5AopW55nY7MmGMVmwmN+ihfCmxJkBUoESTG/3iq8uME7GjyOgW5DkQc2K7q62i8y8N0wCJT1u4Q==", "dependencies": { "@parcel/codeframe": "2.6.2", "@parcel/diagnostic": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/markdown-ansi": "2.6.2", "@parcel/source-map": "^2.0.0", "chalk": "^4.1.0" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/utils/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@parcel/utils/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@parcel/utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/@parcel/watcher": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz", "integrity": "sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw==", "hasInstallScript": true, "dependencies": { "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^3.2.1", "node-gyp-build": "^4.3.0" }, "engines": { "node": ">= 10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/watcher/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/@parcel/watcher/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/@parcel/watcher/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/@parcel/watcher/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/@parcel/watcher/node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/@parcel/workers": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.6.2.tgz", "integrity": "sha512-wBgUjJQm+lDd12fPRUmk09+ujTA9DgwPdqylSFK0OtI/yT6A+2kArUqjp8IwWo2tCJXoMzXBne2XQIWKqMiN4Q==", "dependencies": { "@parcel/diagnostic": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "chrome-trace-event": "^1.0.2", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { "@parcel/core": "^2.6.2" } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", "dependencies": { "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", "find-up": "^5.0.0", "html-entities": "^2.1.0", "loader-utils": "^2.0.4", "schema-utils": "^3.0.0", "source-map": "^0.7.3" }, "engines": { "node": ">= 10.13" }, "peerDependencies": { "@types/webpack": "4.x || 5.x", "react-refresh": ">=0.10.0 <1.0.0", "sockjs-client": "^1.4.0", "type-fest": ">=0.17.0 <4.0.0", "webpack": ">=4.43.0 <6.0.0", "webpack-dev-server": "3.x || 4.x", "webpack-hot-middleware": "2.x", "webpack-plugin-serve": "0.x || 1.x" }, "peerDependenciesMeta": { "@types/webpack": { "optional": true }, "sockjs-client": { "optional": true }, "type-fest": { "optional": true }, "webpack-dev-server": { "optional": true }, "webpack-hot-middleware": { "optional": true }, "webpack-plugin-serve": { "optional": true } } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "engines": { "node": ">= 8" } }, "node_modules/@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@sideway/formula": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@sindresorhus/slugify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-1.1.2.tgz", "integrity": "sha512-V9nR/W0Xd9TSGXpZ4iFUcFGhuOJtZX82Fzxj1YISlbSgKvIiNa7eLEZrT0vAraPOt++KHauIVNYgGRgjc13dXA==", "dependencies": { "@sindresorhus/transliterate": "^0.1.1", "escape-string-regexp": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@sindresorhus/slugify/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@sindresorhus/transliterate": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-0.1.2.tgz", "integrity": "sha512-5/kmIOY9FF32nicXH+5yLNTX4NJ4atl7jRgqAJuIn/iyDFXBktOKDxCvyGE/EzmF4ngSUvjXxQUQlQiZ5lfw+w==", "dependencies": { "escape-string-regexp": "^2.0.0", "lodash.deburr": "^4.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@sindresorhus/transliterate/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "engines": { "node": ">=8" } }, "node_modules/@swc/helpers": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dependencies": { "defer-to-connect": "^2.0.0" }, "engines": { "node": ">=10" } }, "node_modules/@tippy.js/react": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@tippy.js/react/-/react-2.2.3.tgz", "integrity": "sha512-5XYvbQujzDj9r00JYEz/cBtm6DutjOdv2azdco53B+eWF7FDBCQfkLVn87wimfEpmGK0vqRQv/cwFxFcoOP98Q==", "deprecated": "This package has moved to @tippyjs/react (the same but without a dot in the scoped organization) due to issues some shells had with the dot when installing the package.", "dependencies": { "prop-types": "^15.6.2", "tippy.js": "^4.3.4" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "node_modules/@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "engines": { "node": ">=10.13.0" } }, "node_modules/@turist/fetch": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@turist/fetch/-/fetch-7.2.0.tgz", "integrity": "sha512-2x7EGw+6OJ29phunsbGvtxlNmSfcuPcyYudkMbi8gARCP9eJ1CtuMvnVUHL//O9Ixi9SJiug8wNt6lj86pN8XQ==", "dependencies": { "@types/node-fetch": "2" }, "peerDependencies": { "node-fetch": "2" } }, "node_modules/@turist/time": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/@turist/time/-/time-0.0.2.tgz", "integrity": "sha512-qLOvfmlG2vCVw5fo/oz8WAZYlpe5a5OurgTj3diIxJCdjRHpapC+vQCz3er9LV79Vcat+DifBjeAhOAdmndtDQ==" }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "node_modules/@types/common-tags": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.1.tgz", "integrity": "sha512-20R/mDpKSPWdJs5TOpz3e7zqbeCNuMCPhV7Yndk9KU2Rbij2r5W4RzwDPkzC+2lzUqXYu9rFzTktCBnDjHuNQg==" }, "node_modules/@types/component-emitter": { "version": "1.2.11", "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" }, "node_modules/@types/configstore": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-2.1.1.tgz", "integrity": "sha512-YY+hm3afkDHeSM2rsFXxeZtu0garnusBWNG1+7MknmDWQHqcH2w21/xOU9arJUi8ch4qyFklidANLCu3ihhVwQ==" }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, "node_modules/@types/cors": { "version": "2.8.13", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/debug": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz", "integrity": "sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==" }, "node_modules/@types/eslint": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { "version": "3.7.4", "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, "node_modules/@types/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-TiNg8R1kjDde5Pub9F9vCwZA/BNW9HeXP5b9j7Qucqncy/McfPZ6xze/EyBdXS5FhMIGN6Fx3vg75l5KHy3V1Q==" }, "node_modules/@types/glob": { "version": "5.0.37", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.37.tgz", "integrity": "sha512-ATA/xrS7CZ3A2WCPVY4eKdNpybq56zqlTirnHhhyOztZM/lPxJzusOBI3BsaXbu6FrUluqzvMlI4sZ6BDYMlMg==", "dependencies": { "@types/minimatch": "*", "@types/node": "*" } }, "node_modules/@types/hast": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "node_modules/@types/http-proxy": { "version": "1.17.9", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/lodash": { "version": "4.14.191", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" }, "node_modules/@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" }, "node_modules/@types/mkdirp": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" }, "node_modules/@types/node-fetch": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", "dependencies": { "@types/node": "*", "form-data": "^3.0.0" } }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "node_modules/@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/reach__router": { "version": "1.3.11", "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.11.tgz", "integrity": "sha512-j23ChnIEiW8aAP4KT8OVyTXOFr+Ri65BDnwzmfHFO9WHypXYevHFjeil1Cj7YH3emfCE924BwAmgW4hOv7Wg3g==", "dependencies": { "@types/react": "*" } }, "node_modules/@types/react": { "version": "18.0.26", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/rimraf": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.5.tgz", "integrity": "sha512-YyP+VfeaqAyFmXoTh3HChxOQMyjByRMsHU7kc5KOJkSlXudhMhQIALbYV7rHh/l8d2lX3VUQzprrcAgWdRuU8g==", "dependencies": { "@types/glob": "*", "@types/node": "*" } }, "node_modules/@types/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/sharp": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.30.5.tgz", "integrity": "sha512-EhO29617AIBqxoVtpd1qdBanWpspk/kD2B6qTFRJ31Q23Rdf+DNU1xlHSwtqvwq1vgOqBwq1i38SX+HGCymIQg==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-gVC1InwyVrO326wbBZw+AO3u2vRXz/iRWq9jYhpG4W8LXyIgDv3ZmcLQ5Q4Gs+gFMyqx+viFoFT+l3p61QFCmQ==" }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, "node_modules/@types/yoga-layout": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dependencies": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", "regexpp": "^3.1.0", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "@typescript-eslint/parser": "^4.0.0", "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@typescript-eslint/experimental-utils": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dependencies": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", "@typescript-eslint/typescript-estree": "4.33.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "*" } }, "node_modules/@typescript-eslint/parser": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dependencies": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", "@typescript-eslint/typescript-estree": "4.33.0", "debug": "^4.3.1" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, "node_modules/@typescript-eslint/parser/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@typescript-eslint/parser/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/types": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@vercel/webpack-asset-relocator-loader": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.3.tgz", "integrity": "sha512-vizrI18v8Lcb1PmNNUBz7yxPxxXoOeuaVEjTG9MjvDrphjiSxFZrRJ5tIghk+qdLFRCXI5HBCshgobftbmrC5g==", "dependencies": { "resolve": "^1.10.0" } }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/wasm-gen": "1.11.1" } }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/helper-wasm-section": "1.11.1", "@webassemblyjs/wasm-gen": "1.11.1", "@webassemblyjs/wasm-opt": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", "@webassemblyjs/wast-printer": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/ieee754": "1.11.1", "@webassemblyjs/leb128": "1.11.1", "@webassemblyjs/utf8": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", "@webassemblyjs/wasm-gen": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/ieee754": "1.11.1", "@webassemblyjs/leb128": "1.11.1", "@webassemblyjs/utf8": "1.11.1" } }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" } }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "node_modules/abortcontroller-polyfill": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" } }, "node_modules/acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", "peerDependencies": { "acorn": "^8" } }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-loose": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.3.0.tgz", "integrity": "sha512-75lAs9H19ldmW+fAbyqHdjgdCrz0pWGXKmnqFoh8PyVd1L2RIb4RzYrSjmopeqv3E1G3/Pimu6GgLlrGbrkF7w==", "dependencies": { "acorn": "^8.5.0" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "engines": { "node": ">=0.4.0" } }, "node_modules/address": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "engines": { "node": ">= 0.12.0" } }, "node_modules/adjust-sourcemap-loader": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" }, "engines": { "node": ">=8.9" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/anser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/anser/-/anser-2.1.1.tgz", "integrity": "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ==" }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dependencies": { "string-width": "^4.1.0" } }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "engines": { "node": ">=4" } }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "engines": [ "node >= 0.8.0" ], "bin": { "ansi-html": "bin/ansi-html" } }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "engines": { "node": ">=0.10.0" } }, "node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "engines": { "node": ">=0.10.0" } }, "node_modules/anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "optional": true, "dependencies": { "micromatch": "^2.1.5", "normalize-path": "^2.0.0" } }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, "node_modules/application-config-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.1.tgz", "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==" }, "node_modules/arch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dependencies": { "@babel/runtime": "^7.10.2", "@babel/runtime-corejs3": "^7.10.2" }, "engines": { "node": ">=6.0" } }, "node_modules/arity-n": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==" }, "node_modules/arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", "dev": true, "optional": true, "dependencies": { "arr-flatten": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-iterate": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.4.tgz", "integrity": "sha512-sNRaPGh9nnmdC8Zf+pT3UqP8rnWj5Hf9wiFGsX3wUQ2yVSIhO2ShFwCoceIPpB41QF6i2OEmrHmCo36xronCVA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "engines": { "node": ">=8" } }, "node_modules/array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.flatmap": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.tosorted": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0", "get-intrinsic": "^1.1.3" } }, "node_modules/arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "engines": { "node": ">=8" } }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "engines": { "node": ">=8" } }, "node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==" }, "node_modules/async-cache": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/async-cache/-/async-cache-1.1.0.tgz", "integrity": "sha512-YDQc4vBn5NFhY6g6HhVshyi3Fy9+SQ5ePnE7JLDJn1DoL+i7ER+vMwtTNOYk9leZkYMnOwpBCWqyLDPw8Aig8g==", "deprecated": "No longer maintained. Use [lru-cache](http://npm.im/lru-cache) version 7.6 or higher, and provide an asynchronous `fetchMethod` option.", "dependencies": { "lru-cache": "^4.0.0" } }, "node_modules/async-cache/node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "node_modules/async-cache/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, "node_modules/async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true, "optional": true }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "engines": { "node": ">= 4.0.0" } }, "node_modules/atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "bin": { "atob": "bin/atob.js" }, "engines": { "node": ">= 4.5.0" } }, "node_modules/auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/autoprefixer": { "version": "10.4.13", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/autoprefixer" } ], "dependencies": { "browserslist": "^4.21.4", "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" }, "bin": { "autoprefixer": "bin/autoprefixer" }, "engines": { "node": "^10 || ^12 || >=14" }, "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/axe-core": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "engines": { "node": ">=4" } }, "node_modules/axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dependencies": { "follow-redirects": "^1.14.0" } }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" }, "node_modules/babel-cli": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", "integrity": "sha512-wau+BDtQfuSBGQ9PzzFL3REvR9Sxnd4LKwtcHAiPjhugA7K/80vpHXafj+O5bAqJOuSefjOx5ZJnNSR2J1Qw6Q==", "dev": true, "dependencies": { "babel-core": "^6.26.0", "babel-polyfill": "^6.26.0", "babel-register": "^6.26.0", "babel-runtime": "^6.26.0", "commander": "^2.11.0", "convert-source-map": "^1.5.0", "fs-readdir-recursive": "^1.0.0", "glob": "^7.1.2", "lodash": "^4.17.4", "output-file-sync": "^1.1.2", "path-is-absolute": "^1.0.1", "slash": "^1.0.0", "source-map": "^0.5.6", "v8flags": "^2.1.1" }, "bin": { "babel": "bin/babel.js", "babel-doctor": "bin/babel-doctor.js", "babel-external-helpers": "bin/babel-external-helpers.js", "babel-node": "bin/babel-node.js" }, "optionalDependencies": { "chokidar": "^1.6.1" } }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, "dependencies": { "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" } }, "node_modules/babel-core": { "version": "6.26.3", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "dependencies": { "babel-code-frame": "^6.26.0", "babel-generator": "^6.26.0", "babel-helpers": "^6.24.1", "babel-messages": "^6.23.0", "babel-register": "^6.26.0", "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", "convert-source-map": "^1.5.1", "debug": "^2.6.9", "json5": "^0.5.1", "lodash": "^4.17.4", "minimatch": "^3.0.4", "path-is-absolute": "^1.0.1", "private": "^0.1.8", "slash": "^1.0.0", "source-map": "^0.5.7" } }, "node_modules/babel-core/node_modules/json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true, "bin": { "json5": "lib/cli.js" } }, "node_modules/babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.7.0", "@babel/traverse": "^7.7.0", "@babel/types": "^7.7.0", "eslint-visitor-keys": "^1.0.0", "resolve": "^1.12.0" }, "engines": { "node": ">=6" }, "peerDependencies": { "eslint": ">= 4.12.1" } }, "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "peer": true, "engines": { "node": ">=4" } }, "node_modules/babel-extract-comments": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", "dependencies": { "babylon": "^6.18.0" }, "engines": { "node": ">=4" } }, "node_modules/babel-generator": { "version": "6.26.1", "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "dependencies": { "babel-messages": "^6.23.0", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "detect-indent": "^4.0.0", "jsesc": "^1.3.0", "lodash": "^4.17.4", "source-map": "^0.5.7", "trim-right": "^1.0.1" } }, "node_modules/babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", "dev": true, "dependencies": { "babel-helper-explode-assignable-expression": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-builder-react-jsx": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", "integrity": "sha512-02I9jDjnVEuGy2BR3LRm9nPRb/+Ja0pvZVLr1eI5TYAA/dB0Xoc+WBo50+aDfhGDLhlBY1+QURjn9uvcFd8gzg==", "dev": true, "dependencies": { "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "esutils": "^2.0.2" } }, "node_modules/babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", "dev": true, "dependencies": { "babel-helper-hoist-variables": "^6.24.1", "babel-runtime": "^6.22.0", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-define-map": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", "dev": true, "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "lodash": "^4.17.4" } }, "node_modules/babel-helper-explode-assignable-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", "dev": true, "dependencies": { "babel-helper-get-function-arity": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-get-function-arity": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-hoist-variables": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-optimise-call-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-regex": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", "dev": true, "dependencies": { "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "lodash": "^4.17.4" } }, "node_modules/babel-helper-remap-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", "dev": true, "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-helper-replace-supers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", "dev": true, "dependencies": { "babel-helper-optimise-call-expression": "^6.24.1", "babel-messages": "^6.23.0", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-helpers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "node_modules/babel-loader": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dependencies": { "find-cache-dir": "^3.3.1", "loader-utils": "^2.0.0", "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, "engines": { "node": ">= 8.9" }, "peerDependencies": { "@babel/core": "^7.0.0", "webpack": ">=2" } }, "node_modules/babel-loader/node_modules/schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dependencies": { "@types/json-schema": "^7.0.5", "ajv": "^6.12.4", "ajv-keywords": "^3.5.2" }, "engines": { "node": ">= 8.9.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, "node_modules/babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-add-module-exports": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==" }, "node_modules/babel-plugin-check-es2015-constants": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dependencies": { "object.assign": "^4.1.0" } }, "node_modules/babel-plugin-lodash": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz", "integrity": "sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg==", "dependencies": { "@babel/helper-module-imports": "^7.0.0-beta.49", "@babel/types": "^7.0.0-beta.49", "glob": "^7.1.1", "lodash": "^4.17.10", "require-package-name": "^2.0.1" } }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" }, "engines": { "node": ">=10", "npm": ">=6" } }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dependencies": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3", "core-js-compat": "^3.25.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-corejs3/node_modules/core-js-compat": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz", "integrity": "sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==", "dependencies": { "browserslist": "^4.21.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-remove-graphql-queries": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/babel-plugin-remove-graphql-queries/-/babel-plugin-remove-graphql-queries-4.25.0.tgz", "integrity": "sha512-enyqRNRrn7vTG3nwg1V+XhoAJIyUv3ZukQCs5KbHOK+WNDDiGZQzIG+FCiZFACScdZBJWyx7TYRYbOFJZ/KEGg==", "dependencies": { "@babel/runtime": "^7.15.4", "@babel/types": "^7.15.4", "gatsby-core-utils": "^3.25.0" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "@babel/core": "^7.0.0", "gatsby": "^4.0.0-next" } }, "node_modules/babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", "dev": true }, "node_modules/babel-plugin-syntax-class-properties": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", "integrity": "sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==", "dev": true }, "node_modules/babel-plugin-syntax-decorators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", "integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==", "dev": true }, "node_modules/babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", "dev": true }, "node_modules/babel-plugin-syntax-flow": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", "integrity": "sha512-HbTDIoG1A1op7Tl/wIFQPULIBA61tsJ8Ntq2FAhLwuijrzosM/92kAfgU1Q3Kc7DH/cprJg5vDfuTY4QUL4rDA==", "dev": true }, "node_modules/babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", "dev": true }, "node_modules/babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==" }, "node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", "dev": true }, "node_modules/babel-plugin-transform-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", "dev": true, "dependencies": { "babel-helper-remap-async-to-generator": "^6.24.1", "babel-plugin-syntax-async-functions": "^6.8.0", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-class-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==", "dev": true, "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-plugin-syntax-class-properties": "^6.8.0", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "node_modules/babel-plugin-transform-decorators-legacy": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz", "integrity": "sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA==", "dev": true, "dependencies": { "babel-plugin-syntax-decorators": "^6.1.18", "babel-runtime": "^6.2.0", "babel-template": "^6.3.0" } }, "node_modules/babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-block-scoped-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-block-scoping": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", "dev": true, "dependencies": { "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "lodash": "^4.17.4" } }, "node_modules/babel-plugin-transform-es2015-classes": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", "dev": true, "dependencies": { "babel-helper-define-map": "^6.24.1", "babel-helper-function-name": "^6.24.1", "babel-helper-optimise-call-expression": "^6.24.1", "babel-helper-replace-supers": "^6.24.1", "babel-messages": "^6.23.0", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-computed-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-destructuring": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-duplicate-keys": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-for-of": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", "dev": true, "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-modules-amd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", "dev": true, "dependencies": { "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-modules-commonjs": { "version": "6.26.2", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "dependencies": { "babel-plugin-transform-strict-mode": "^6.24.1", "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", "babel-types": "^6.26.0" } }, "node_modules/babel-plugin-transform-es2015-modules-systemjs": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", "dev": true, "dependencies": { "babel-helper-hoist-variables": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-modules-umd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", "dev": true, "dependencies": { "babel-plugin-transform-es2015-modules-amd": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-object-super": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", "dev": true, "dependencies": { "babel-helper-replace-supers": "^6.24.1", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-parameters": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", "dev": true, "dependencies": { "babel-helper-call-delegate": "^6.24.1", "babel-helper-get-function-arity": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-spread": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", "dev": true, "dependencies": { "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-plugin-transform-es2015-template-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-es2015-unicode-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", "dev": true, "dependencies": { "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", "regexpu-core": "^2.0.0" } }, "node_modules/babel-plugin-transform-exponentiation-operator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", "dev": true, "dependencies": { "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", "babel-plugin-syntax-exponentiation-operator": "^6.8.0", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-flow-strip-types": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", "integrity": "sha512-TxIM0ZWNw9oYsoTthL3lvAK3+eTujzktoXJg4ubGvICGbVuXVYv5hHv0XXpz8fbqlJaGYY4q5SVzaSmsg3t4Fg==", "dev": true, "dependencies": { "babel-plugin-syntax-flow": "^6.18.0", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-object-rest-spread": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", "dependencies": { "babel-plugin-syntax-object-rest-spread": "^6.8.0", "babel-runtime": "^6.26.0" } }, "node_modules/babel-plugin-transform-react-display-name": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", "integrity": "sha512-QLYkLiZeeED2PKd4LuXGg5y9fCgPB5ohF8olWUuETE2ryHNRqqnXlEVP7RPuef89+HTfd3syptMGVHeoAu0Wig==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-react-jsx": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", "integrity": "sha512-s+q/Y2u2OgDPHRuod3t6zyLoV8pUHc64i/O7ZNgIOEdYTq+ChPeybcKBi/xk9VI60VriILzFPW+dUxAEbTxh2w==", "dev": true, "dependencies": { "babel-helper-builder-react-jsx": "^6.24.1", "babel-plugin-syntax-jsx": "^6.8.0", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-react-jsx-self": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", "integrity": "sha512-Y3ZHP1nunv0U1+ysTNwLK39pabHj6cPVsfN4TRC7BDBfbgbyF4RifP5kd6LnbuMV9wcfedQMe7hn1fyKc7IzTQ==", "dev": true, "dependencies": { "babel-plugin-syntax-jsx": "^6.8.0", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-react-jsx-source": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", "integrity": "sha512-pcDNDsZ9q/6LJmujQ/OhjeoIlp5Nl546HJ2yiFIJK3mYpgNXhI5/S9mXfVxu5yqWAi7HdI7e/q6a9xtzwL69Vw==", "dev": true, "dependencies": { "babel-plugin-syntax-jsx": "^6.8.0", "babel-runtime": "^6.22.0" } }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" }, "node_modules/babel-plugin-transform-regenerator": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", "dev": true, "dependencies": { "regenerator-transform": "^0.10.0" } }, "node_modules/babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", "dev": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "node_modules/babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", "dev": true, "dependencies": { "babel-runtime": "^6.26.0", "core-js": "^2.5.0", "regenerator-runtime": "^0.10.5" } }, "node_modules/babel-preset-env": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", "dev": true, "dependencies": { "babel-plugin-check-es2015-constants": "^6.22.0", "babel-plugin-syntax-trailing-function-commas": "^6.22.0", "babel-plugin-transform-async-to-generator": "^6.22.0", "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", "babel-plugin-transform-es2015-block-scoping": "^6.23.0", "babel-plugin-transform-es2015-classes": "^6.23.0", "babel-plugin-transform-es2015-computed-properties": "^6.22.0", "babel-plugin-transform-es2015-destructuring": "^6.23.0", "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", "babel-plugin-transform-es2015-for-of": "^6.23.0", "babel-plugin-transform-es2015-function-name": "^6.22.0", "babel-plugin-transform-es2015-literals": "^6.22.0", "babel-plugin-transform-es2015-modules-amd": "^6.22.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", "babel-plugin-transform-es2015-modules-umd": "^6.23.0", "babel-plugin-transform-es2015-object-super": "^6.22.0", "babel-plugin-transform-es2015-parameters": "^6.23.0", "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", "babel-plugin-transform-es2015-spread": "^6.22.0", "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", "babel-plugin-transform-es2015-template-literals": "^6.22.0", "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", "babel-plugin-transform-exponentiation-operator": "^6.22.0", "babel-plugin-transform-regenerator": "^6.22.0", "browserslist": "^3.2.6", "invariant": "^2.2.2", "semver": "^5.3.0" } }, "node_modules/babel-preset-env/node_modules/browserslist": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "dependencies": { "caniuse-lite": "^1.0.30000844", "electron-to-chromium": "^1.3.47" }, "bin": { "browserslist": "cli.js" } }, "node_modules/babel-preset-fbjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", "@babel/plugin-syntax-class-properties": "^7.0.0", "@babel/plugin-syntax-flow": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.0.0", "@babel/plugin-transform-arrow-functions": "^7.0.0", "@babel/plugin-transform-block-scoped-functions": "^7.0.0", "@babel/plugin-transform-block-scoping": "^7.0.0", "@babel/plugin-transform-classes": "^7.0.0", "@babel/plugin-transform-computed-properties": "^7.0.0", "@babel/plugin-transform-destructuring": "^7.0.0", "@babel/plugin-transform-flow-strip-types": "^7.0.0", "@babel/plugin-transform-for-of": "^7.0.0", "@babel/plugin-transform-function-name": "^7.0.0", "@babel/plugin-transform-literals": "^7.0.0", "@babel/plugin-transform-member-expression-literals": "^7.0.0", "@babel/plugin-transform-modules-commonjs": "^7.0.0", "@babel/plugin-transform-object-super": "^7.0.0", "@babel/plugin-transform-parameters": "^7.0.0", "@babel/plugin-transform-property-literals": "^7.0.0", "@babel/plugin-transform-react-display-name": "^7.0.0", "@babel/plugin-transform-react-jsx": "^7.0.0", "@babel/plugin-transform-shorthand-properties": "^7.0.0", "@babel/plugin-transform-spread": "^7.0.0", "@babel/plugin-transform-template-literals": "^7.0.0", "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/babel-preset-fbjs/node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" }, "node_modules/babel-preset-flow": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", "integrity": "sha512-PQZFJXnM3d80Vq4O67OE6EMVKIw2Vmzy8UXovqulNogCtblWU8rzP7Sm5YgHiCg4uejUxzCkHfNXQ4Z6GI+Dhw==", "dev": true, "dependencies": { "babel-plugin-transform-flow-strip-types": "^6.22.0" } }, "node_modules/babel-preset-react": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", "integrity": "sha512-phQe3bElbgF887UM0Dhz55d22ob8czTL1kbhZFwpCE6+R/X9kHktfwmx9JZb+bBSVRGphP5tZ9oWhVhlgjrX3Q==", "dev": true, "dependencies": { "babel-plugin-syntax-jsx": "^6.3.13", "babel-plugin-transform-react-display-name": "^6.23.0", "babel-plugin-transform-react-jsx": "^6.24.1", "babel-plugin-transform-react-jsx-self": "^6.22.0", "babel-plugin-transform-react-jsx-source": "^6.22.0", "babel-preset-flow": "^6.23.0" } }, "node_modules/babel-register": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", "dev": true, "dependencies": { "babel-core": "^6.26.0", "babel-runtime": "^6.26.0", "core-js": "^2.5.0", "home-or-tmp": "^2.0.0", "lodash": "^4.17.4", "mkdirp": "^0.5.1", "source-map-support": "^0.4.15" } }, "node_modules/babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", "dependencies": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" } }, "node_modules/babel-runtime/node_modules/regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "node_modules/babel-template": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", "dev": true, "dependencies": { "babel-runtime": "^6.26.0", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", "lodash": "^4.17.4" } }, "node_modules/babel-traverse": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, "dependencies": { "babel-code-frame": "^6.26.0", "babel-messages": "^6.23.0", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", "debug": "^2.6.8", "globals": "^9.18.0", "invariant": "^2.2.2", "lodash": "^4.17.4" } }, "node_modules/babel-types": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", "dev": true, "dependencies": { "babel-runtime": "^6.26.0", "esutils": "^2.0.2", "lodash": "^4.17.4", "to-fast-properties": "^1.0.3" } }, "node_modules/babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "bin": { "babylon": "bin/babylon.js" } }, "node_modules/backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" }, "node_modules/bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "optional": true, "dependencies": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", "component-emitter": "^1.2.1", "define-property": "^1.0.0", "isobject": "^3.0.1", "mixin-deep": "^1.2.0", "pascalcase": "^0.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/base-x": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", "dependencies": { "safe-buffer": "^5.0.1" } }, "node_modules/base/node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/base/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/base64-arraybuffer": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", "engines": { "node": ">= 0.6.0" } }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "engines": { "node": "^4.5.0 || >= 5.9" } }, "node_modules/better-opn": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", "integrity": "sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==", "dependencies": { "open": "^7.0.3" }, "engines": { "node": ">8.0.0" } }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "engines": { "node": "*" } }, "node_modules/binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, "optional": true, "dependencies": { "file-uri-to-path": "1.0.0" } }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/body-parser/node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", "chalk": "^4.1.0", "cli-boxes": "^2.2.1", "string-width": "^4.2.2", "type-fest": "^0.20.2", "widest-line": "^3.1.0", "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/boxen/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/boxen/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/boxen/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", "dev": true, "optional": true, "dependencies": { "expand-range": "^1.8.1", "preserve": "^0.2.0", "repeat-element": "^1.1.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/brcast": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.2.tgz", "integrity": "sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA==" }, "node_modules/browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" } ], "dependencies": { "caniuse-lite": "^1.0.30001400", "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { "streamsearch": "^1.1.0" }, "engines": { "node": ">=10.16.0" } }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { "node": ">= 0.8" } }, "node_modules/cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "optional": true, "dependencies": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", "get-value": "^2.0.6", "has-value": "^1.0.0", "isobject": "^3.0.1", "set-value": "^2.0.0", "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/cache-base/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/cache-manager": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.11.1.tgz", "integrity": "sha512-XhUuc9eYwkzpK89iNewFwtvcDYMUsvtwzHeyEOPJna/WsVsXcrzsA1ft2M0QqPNunEzLhNCYPo05tEfG+YuNow==", "dependencies": { "async": "1.5.2", "lodash.clonedeep": "4.5.0", "lru-cache": "4.0.0" } }, "node_modules/cache-manager/node_modules/lru-cache": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.0.tgz", "integrity": "sha512-WKhDkjlLwzE8jAQdQlsxLUQTPXLCKX/4cJk6s5AlRtJkDBk0IKH5O51bVDH61K9N4bhbbyvLM6EiOuE8ovApPA==", "dependencies": { "pseudomap": "^1.0.1", "yallist": "^2.0.0" } }, "node_modules/cache-manager/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, "node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "engines": { "node": ">=10.6.0" } }, "node_modules/cacheable-request": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/cacheable-request/node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { "node": ">=6" } }, "node_modules/camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "node_modules/caniuse-lite": { "version": "1.0.30001442", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz", "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" } ] }, "node_modules/capital-case": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "node_modules/ccount": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/change-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", "dependencies": { "camel-case": "^4.1.2", "capital-case": "^1.0.4", "constant-case": "^3.0.4", "dot-case": "^3.0.4", "header-case": "^2.0.4", "no-case": "^3.0.4", "param-case": "^3.0.4", "pascal-case": "^3.1.2", "path-case": "^3.0.4", "sentence-case": "^3.0.4", "snake-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/change-case-all": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.14.tgz", "integrity": "sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "node_modules/character-entities": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-entities-html4": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-reference-invalid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "htmlparser2": "^8.0.1", "parse5": "^7.0.0", "parse5-htmlparser2-tree-adapter": "^7.0.0" }, "engines": { "node": ">= 6" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, "node_modules/cheerio-select": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, "node_modules/chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", "dev": true, "optional": true, "dependencies": { "anymatch": "^1.3.0", "async-each": "^1.0.0", "glob-parent": "^2.0.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", "is-glob": "^2.0.0", "path-is-absolute": "^1.0.0", "readdirp": "^2.0.0" }, "optionalDependencies": { "fsevents": "^1.0.0" } }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "node_modules/class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "optional": true, "dependencies": { "arr-union": "^3.1.0", "define-property": "^0.2.5", "isobject": "^3.0.0", "static-extend": "^0.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/class-utils/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/class-utils/node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dependencies": { "restore-cursor": "^3.1.0" }, "engines": { "node": ">=8" } }, "node_modules/cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "engines": { "node": ">= 10" } }, "node_modules/clipboardy": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", "dependencies": { "arch": "^2.1.1", "execa": "^1.0.0", "is-wsl": "^2.1.1" }, "engines": { "node": ">=8" } }, "node_modules/clipboardy/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" }, "engines": { "node": ">=4.8" } }, "node_modules/clipboardy/node_modules/execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" }, "engines": { "node": ">=6" } }, "node_modules/clipboardy/node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/clipboardy/node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/clipboardy/node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "dependencies": { "path-key": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/clipboardy/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "engines": { "node": ">=4" } }, "node_modules/clipboardy/node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dependencies": { "shebang-regex": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/clipboardy/node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/clipboardy/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "engines": { "node": ">=0.8" } }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", "shallow-clone": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dependencies": { "mimic-response": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dev": true, "optional": true, "dependencies": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" }, "engines": { "node": ">=12.5.0" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" }, "node_modules/colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/comma-separated-tokens": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/common-path-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" }, "node_modules/common-tags": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "engines": { "node": ">=4.0.0" } }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "node_modules/compose-function": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", "dependencies": { "arity-n": "^1.0.4" } }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, "engines": { "node": ">= 0.6" } }, "node_modules/compression": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", "compressible": "~2.0.16", "debug": "2.6.9", "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/compression/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "engines": [ "node >= 0.8" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "node_modules/configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dependencies": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", "make-dir": "^3.0.0", "unique-string": "^2.0.0", "write-file-atomic": "^3.0.0", "xdg-basedir": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, "node_modules/constant-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case": "^2.0.2" } }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { "safe-buffer": "5.2.1" }, "engines": { "node": ">= 0.6" } }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "engines": { "node": ">= 0.6" } }, "node_modules/convert-hrtime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==", "engines": { "node": ">=8" } }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", "hasInstallScript": true }, "node_modules/core-js-compat": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.0.tgz", "integrity": "sha512-YK6fwFjCOKWwGnjFUR3c544YsnA/7DoLL0ysncuOJ4pwbriAtOpvM2bygdlcXbvQCQZ7bBU9CL4t7tGl7ETRpQ==", "dependencies": { "browserslist": "^4.16.3", "semver": "7.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat/node_modules/semver": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "bin": { "semver": "bin/semver.js" } }, "node_modules/core-js-pure": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.1.tgz", "integrity": "sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw==", "hasInstallScript": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dependencies": { "object-assign": "^4", "vary": "^1" }, "engines": { "node": ">= 0.10" } }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" }, "engines": { "node": ">=10" } }, "node_modules/create-gatsby": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/create-gatsby/-/create-gatsby-2.25.0.tgz", "integrity": "sha512-96Kl/6Far2j65/vFv/6Mb9+T+/4oW8hlC3UmdfjgBgUIzTPFmezY1ygPu2dfCKjprWkArB8DpE7EsAaJoRKB1Q==", "dependencies": { "@babel/runtime": "^7.15.4" }, "bin": { "create-gatsby": "cli.js" } }, "node_modules/cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dependencies": { "node-fetch": "2.6.7" } }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "engines": { "node": ">=8" } }, "node_modules/css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", "dependencies": { "inherits": "^2.0.3", "source-map": "^0.6.1", "source-map-resolve": "^0.5.2", "urix": "^0.1.0" } }, "node_modules/css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", "engines": { "node": "^10 || ^12 || >=14" }, "peerDependencies": { "postcss": "^8.0.9" } }, "node_modules/css-loader": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", "dependencies": { "icss-utils": "^5.1.0", "loader-utils": "^2.0.0", "postcss": "^8.2.15", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^3.0.0", "semver": "^7.3.5" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.27.0 || ^5.0.0" } }, "node_modules/css-loader/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/css-loader/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/css-loader/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/css-minimizer-webpack-plugin": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz", "integrity": "sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw==", "dependencies": { "cssnano": "^5.0.0", "jest-worker": "^26.3.0", "p-limit": "^3.0.2", "postcss": "^8.2.9", "schema-utils": "^3.0.0", "serialize-javascript": "^5.0.1", "source-map": "^0.6.1" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^5.0.0" }, "peerDependenciesMeta": { "clean-css": { "optional": true }, "csso": { "optional": true } } }, "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, "node_modules/css-selector-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" }, "node_modules/css-tree": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" }, "engines": { "node": ">=8.0.0" } }, "node_modules/css-tree/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/css-vendor": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", "integrity": "sha512-Vx/Vl3zsHj32Z+WTNzGjd2iSbSIJTYHMmyGUT2nzCjj0Xk4qLfwpQ8nF6TQ5oo3Cf0s/An3DTc7LclH1BkAXbQ==", "dependencies": { "is-in-browser": "^1.0.2" } }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "engines": { "node": ">= 6" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" }, "node_modules/css/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "bin": { "cssesc": "bin/cssesc" }, "engines": { "node": ">=4" } }, "node_modules/cssfilter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" }, "node_modules/cssnano": { "version": "5.1.14", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", "dependencies": { "cssnano-preset-default": "^5.2.13", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/cssnano" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/cssnano-preset-default": { "version": "5.2.13", "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", "dependencies": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", "postcss-colormin": "^5.3.0", "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", "postcss-merge-longhand": "^5.1.7", "postcss-merge-rules": "^5.1.3", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", "postcss-minify-params": "^5.1.4", "postcss-minify-selectors": "^5.2.1", "postcss-normalize-charset": "^5.1.0", "postcss-normalize-display-values": "^5.1.0", "postcss-normalize-positions": "^5.1.1", "postcss-normalize-repeat-style": "^5.1.1", "postcss-normalize-string": "^5.1.0", "postcss-normalize-timing-functions": "^5.1.0", "postcss-normalize-unicode": "^5.1.1", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", "postcss-reduce-initial": "^5.1.1", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/csso": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dependencies": { "css-tree": "^1.1.2" }, "engines": { "node": ">=8.0.0" } }, "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dependencies": { "es5-ext": "^0.10.50", "type": "^1.0.1" } }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, "node_modules/date-fns": { "version": "2.29.3", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", "engines": { "node": ">=0.11" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/date-fns" } }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { "node": ">=0.10.0" } }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "engines": { "node": ">=0.10" } }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dependencies": { "mimic-response": "^3.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decompress-response/node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "engines": { "node": ">=4.0.0" } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "engines": { "node": ">=0.10.0" } }, "node_modules/defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "engines": { "node": ">=10" } }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "engines": { "node": ">=8" } }, "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/define-property/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { "node": ">= 0.8" } }, "node_modules/dependency-graph": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "engines": { "node": ">= 0.6.0" } }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/detab": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", "dependencies": { "repeat-string": "^1.5.4" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", "dev": true, "dependencies": { "repeating": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "bin": { "detect-libc": "bin/detect-libc.js" }, "engines": { "node": ">=0.10" } }, "node_modules/detect-port": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", "dependencies": { "address": "^1.0.1", "debug": "4" }, "bin": { "detect": "bin/detect-port.js", "detect-port": "bin/detect-port.js" } }, "node_modules/detect-port-alt": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", "dependencies": { "address": "^1.0.1", "debug": "^2.6.0" }, "bin": { "detect": "bin/detect-port", "detect-port": "bin/detect-port" }, "engines": { "node": ">= 4.2.1" } }, "node_modules/detect-port/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/detect-port/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/devcert": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/devcert/-/devcert-1.2.2.tgz", "integrity": "sha512-UsLqvtJGPiGwsIZnJINUnFYaWgK7CroreGRndWHZkRD58tPFr3pVbbSyHR8lbh41+azR4jKvuNZ+eCoBZGA5kA==", "dependencies": { "@types/configstore": "^2.1.1", "@types/debug": "^0.0.30", "@types/get-port": "^3.2.0", "@types/glob": "^5.0.34", "@types/lodash": "^4.14.92", "@types/mkdirp": "^0.5.2", "@types/node": "^8.5.7", "@types/rimraf": "^2.0.2", "@types/tmp": "^0.0.33", "application-config-path": "^0.1.0", "command-exists": "^1.2.4", "debug": "^3.1.0", "eol": "^0.9.1", "get-port": "^3.2.0", "glob": "^7.1.2", "is-valid-domain": "^0.1.6", "lodash": "^4.17.4", "mkdirp": "^0.5.1", "password-prompt": "^1.0.4", "rimraf": "^2.6.2", "sudo-prompt": "^8.2.0", "tmp": "^0.0.33", "tslib": "^1.10.0" } }, "node_modules/devcert/node_modules/@types/node": { "version": "8.10.66", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" }, "node_modules/devcert/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/devcert/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/devcert/node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dependencies": { "os-tmpdir": "~1.0.2" }, "engines": { "node": ">=0.6.0" } }, "node_modules/devcert/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dependencies": { "path-type": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=6.0.0" } }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dependencies": { "utila": "~0.4" } }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } ] }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { "domelementtype": "^2.3.0" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/domutils": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.1" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dependencies": { "is-obj": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/dotenv": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", "engines": { "node": ">=10" } }, "node_modules/dotenv-expand": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, "node_modules/duplexer3": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "engines": { "node": ">= 4" } }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dependencies": { "once": "^1.4.0" } }, "node_modules/engine.io": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.2.tgz", "integrity": "sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==", "dependencies": { "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~4.0.0", "ws": "~7.4.2" }, "engines": { "node": ">=10.0.0" } }, "node_modules/engine.io-client": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.4.tgz", "integrity": "sha512-843fqAdKeUMFqKi1sSjnR11tJ4wi8sIefu6+JC1OzkkJBmjtc/gM/rZ53tJfu5Iae/3gApm5veoS+v+gtT0+Fg==", "dependencies": { "base64-arraybuffer": "0.1.4", "component-emitter": "~1.3.0", "debug": "~4.3.1", "engine.io-parser": "~4.0.1", "has-cors": "1.1.0", "parseqs": "0.0.6", "parseuri": "0.0.6", "ws": "~7.4.2", "xmlhttprequest-ssl": "~1.6.2", "yeast": "0.1.2" } }, "node_modules/engine.io-client/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/engine.io-client/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/engine.io-parser": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", "dependencies": { "base64-arraybuffer": "0.1.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/engine.io/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/engine.io/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/enhanced-resolve": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dependencies": { "ansi-colors": "^4.1.1" }, "engines": { "node": ">=8.6" } }, "node_modules/entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "engines": { "node": ">=0.12" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", "bin": { "envinfo": "dist/cli.js" }, "engines": { "node": ">=4" } }, "node_modules/eol": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==" }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "dependencies": { "stackframe": "^1.3.4" } }, "node_modules/es-abstract": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz", "integrity": "sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g==", "dependencies": { "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.0", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.4", "is-array-buffer": "^3.0.0", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", "string.prototype.trimend": "^1.0.6", "string.prototype.trimstart": "^1.0.6", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.9" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", "dependencies": { "get-intrinsic": "^1.1.3", "has": "^1.0.3", "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", "dependencies": { "has": "^1.0.3" } }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es5-ext": { "version": "0.10.62", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "hasInstallScript": true, "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "next-tick": "^1.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "node_modules/es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dependencies": { "d": "^1.0.1", "ext": "^1.1.2" } }, "node_modules/es6-weak-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dependencies": { "d": "1", "es5-ext": "^0.10.46", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "engines": { "node": ">=6" } }, "node_modules/escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "engines": { "node": ">=8" } }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.1.2", "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "progress": "^2.0.0", "regexpp": "^3.1.0", "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-config-react-app": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz", "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==", "dependencies": { "confusing-browser-globals": "^1.0.10" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^4.0.0", "@typescript-eslint/parser": "^4.0.0", "babel-eslint": "^10.0.0", "eslint": "^7.5.0", "eslint-plugin-flowtype": "^5.2.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-jest": "^24.0.0", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-react": "^7.20.3", "eslint-plugin-react-hooks": "^4.0.8", "eslint-plugin-testing-library": "^3.9.0" }, "peerDependenciesMeta": { "eslint-plugin-jest": { "optional": true }, "eslint-plugin-testing-library": { "optional": true } } }, "node_modules/eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dependencies": { "debug": "^3.2.7", "resolve": "^1.20.0" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-import-resolver-node/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/eslint-module-utils": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dependencies": { "debug": "^3.2.7" }, "engines": { "node": ">=4" }, "peerDependenciesMeta": { "eslint": { "optional": true } } }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/eslint-plugin-flowtype": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz", "integrity": "sha512-vcz32f+7TP+kvTUyMXZmCnNujBQZDNmcqPImw8b9PZ+16w1Qdm6ryRuYZYVaG9xRqqmAPr2Cs9FAX5gN+x/bjw==", "dependencies": { "lodash": "^4.17.15", "string-natural-compare": "^3.0.1" }, "engines": { "node": "^10.12.0 || >=12.0.0" }, "peerDependencies": { "eslint": "^7.1.0" } }, "node_modules/eslint-plugin-import": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dependencies": { "array-includes": "^3.1.4", "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", "eslint-module-utils": "^2.7.3", "has": "^1.0.3", "is-core-module": "^2.8.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.values": "^1.1.5", "resolve": "^1.22.0", "tsconfig-paths": "^3.14.1" }, "engines": { "node": ">=4" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-plugin-import/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-plugin-import/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", "dependencies": { "@babel/runtime": "^7.18.9", "aria-query": "^4.2.2", "array-includes": "^3.1.5", "ast-types-flow": "^0.0.7", "axe-core": "^4.4.3", "axobject-query": "^2.2.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "has": "^1.0.3", "jsx-ast-utils": "^3.3.2", "language-tags": "^1.0.5", "minimatch": "^3.1.2", "semver": "^6.3.0" }, "engines": { "node": ">=4.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-plugin-react": { "version": "7.31.11", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flatmap": "^1.3.1", "array.prototype.tosorted": "^1.1.1", "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.6", "object.fromentries": "^2.0.6", "object.hasown": "^1.1.2", "object.values": "^1.1.6", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", "string.prototype.matchall": "^4.0.8" }, "engines": { "node": ">=4" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "engines": { "node": ">=10" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/eslint-plugin-react/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" }, "engines": { "node": ">=8.0.0" } }, "node_modules/eslint-scope/node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { "node": ">=4.0" } }, "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dependencies": { "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { "eslint": ">=5" } }, "node_modules/eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "engines": { "node": ">=10" } }, "node_modules/eslint-webpack-plugin": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.7.0.tgz", "integrity": "sha512-bNaVVUvU4srexGhVcayn/F4pJAz19CWBkKoMx7aSQ4wtTbZQCnG5O9LHCE42mM+JSKOUp7n6vd5CIwzj7lOVGA==", "dependencies": { "@types/eslint": "^7.29.0", "arrify": "^2.0.1", "jest-worker": "^27.5.1", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "schema-utils": "^3.1.1" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0", "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/eslint-webpack-plugin/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/eslint-webpack-plugin/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/eslint-webpack-plugin/node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/eslint-webpack-plugin/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/eslint/node_modules/@babel/code-frame": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dependencies": { "@babel/highlight": "^7.10.4" } }, "node_modules/eslint/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/eslint/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "engines": { "node": ">=4" } }, "node_modules/eslint/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/eslint/node_modules/globals": { "version": "13.19.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "engines": { "node": ">= 4" } }, "node_modules/eslint/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/eslint/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/eslint/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/eslint/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/eslint/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/eslint/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/espree/node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "engines": { "node": ">=4" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } }, "node_modules/event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "node_modules/event-source-polyfill": { "version": "1.0.25", "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.25.tgz", "integrity": "sha512-hQxu6sN1Eq4JjoI7ITdQeGGUN193A2ra83qC0Ltm9I2UJVAten3OFVN6k5RX4YWeCS0BoC8xg/5czOCIHVosQg==" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==", "dev": true, "optional": true, "dependencies": { "is-posix-bracket": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", "dev": true, "optional": true, "dependencies": { "fill-range": "^2.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "engines": { "node": ">=6" } }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.2.0", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", "serve-static": "1.15.0", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/express-graphql": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.12.0.tgz", "integrity": "sha512-DwYaJQy0amdy3pgNtiTDuGGM2BLdj+YO2SgbKoLliCfuHv3VVTt7vNG/ZqK2hRYjtYHE2t2KB705EU94mE64zg==", "dependencies": { "accepts": "^1.3.7", "content-type": "^1.0.4", "http-errors": "1.8.0", "raw-body": "^2.4.1" }, "engines": { "node": ">= 10.x" }, "peerDependencies": { "graphql": "^14.7.0 || ^15.3.0" } }, "node_modules/express-graphql/node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "engines": { "node": ">= 0.6" } }, "node_modules/express-graphql/node_modules/http-errors": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/express-graphql/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "engines": { "node": ">= 0.6" } }, "node_modules/express-graphql/node_modules/toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "engines": { "node": ">=0.6" } }, "node_modules/express-http-proxy": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/express-http-proxy/-/express-http-proxy-1.6.3.tgz", "integrity": "sha512-/l77JHcOUrDUX8V67E287VEUQT0lbm71gdGVoodnlWBziarYKgMcpqT7xvh/HM8Jv52phw8Bd8tY+a7QjOr7Yg==", "dependencies": { "debug": "^3.0.1", "es6-promise": "^4.1.1", "raw-body": "^2.3.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/express-http-proxy/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/express-http-proxy/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/express/node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dependencies": { "type": "^2.7.2" } }, "node_modules/ext/node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" }, "engines": { "node": ">=4" } }, "node_modules/external-editor/node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dependencies": { "os-tmpdir": "~1.0.2" }, "engines": { "node": ">=0.6.0" } }, "node_modules/extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==", "dev": true, "optional": true, "dependencies": { "is-extglob": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" }, "engines": { "node": ">=8.6.0" } }, "node_modules/fast-glob/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/fast-glob/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/fast-glob/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/fast-glob/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fast-glob/node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "engines": { "node": ">= 4.9.1" } }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dependencies": { "bser": "2.1.1" } }, "node_modules/fbjs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.4.tgz", "integrity": "sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==", "dependencies": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", "loose-envify": "^1.0.0", "object-assign": "^4.1.0", "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^0.7.30" } }, "node_modules/fbjs-css-vars": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, "node_modules/fd": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/fd/-/fd-0.0.3.tgz", "integrity": "sha512-iAHrIslQb3U68OcMSP0kkNWabp7sSN6d2TBSb2JO3gcLJVDd4owr/hKM4SFJovFOUeeXeItjYgouEDTMWiVAnA==" }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dependencies": { "escape-string-regexp": "^1.0.5" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dependencies": { "flat-cache": "^3.0.4" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/file-type": { "version": "16.5.4", "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, "optional": true }, "node_modules/filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "engines": { "node": ">=4" } }, "node_modules/filenamify": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dependencies": { "filename-reserved-regex": "^2.0.0", "strip-outer": "^1.0.1", "trim-repeated": "^1.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/filesize": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", "engines": { "node": ">= 0.4.0" } }, "node_modules/fill-range": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "optional": true, "dependencies": { "is-number": "^2.1.0", "isobject": "^2.0.0", "randomatic": "^3.0.0", "repeat-element": "^1.1.2", "repeat-string": "^1.5.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/filter-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flat-cache/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/for-own": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", "dev": true, "optional": true, "dependencies": { "for-in": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", "dependencies": { "@babel/code-frame": "^7.8.3", "@types/json-schema": "^7.0.5", "chalk": "^4.1.0", "chokidar": "^3.4.2", "cosmiconfig": "^6.0.0", "deepmerge": "^4.2.2", "fs-extra": "^9.0.0", "glob": "^7.1.6", "memfs": "^3.1.2", "minimatch": "^3.0.4", "schema-utils": "2.7.0", "semver": "^7.3.2", "tapable": "^1.0.0" }, "engines": { "node": ">=10", "yarn": ">=1.0.0" }, "peerDependencies": { "eslint": ">= 6", "typescript": ">= 2.7", "vue-template-compiler": "*", "webpack": ">= 4" }, "peerDependenciesMeta": { "eslint": { "optional": true }, "vue-template-compiler": { "optional": true } } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.7.2" }, "engines": { "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { "node": ">=10" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "dependencies": { "@types/json-schema": "^7.0.4", "ajv": "^6.12.2", "ajv-keywords": "^3.4.1" }, "engines": { "node": ">= 8.9.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "engines": { "node": ">=6" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", "engines": { "node": "*" }, "funding": { "type": "patreon", "url": "https://www.patreon.com/infusion" } }, "node_modules/fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "dev": true, "optional": true, "dependencies": { "map-cache": "^0.2.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-exists-cached": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", "integrity": "sha512-kSxoARUDn4F2RPXX48UXnaFKwVU7Ivd/6qpzZL29MCDmr9sTvybv4gFCp+qaI4fM9m0z9fgz/yJvi56GAz+BZg==" }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { "node": ">=12" } }, "node_modules/fs-monkey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", "dev": true }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "dependencies": { "bindings": "^1.5.0", "nan": "^2.12.1" }, "engines": { "node": ">= 4.0" } }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/function.prototype.name": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.0", "functions-have-names": "^1.2.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gatsby": { "version": "4.25.2", "resolved": "https://registry.npmjs.org/gatsby/-/gatsby-4.25.2.tgz", "integrity": "sha512-HKSWRdTOK5IBFDDgCKiPXiyszfdTTGZ+pple6My6dQ5a5U+Gn1PpjBIiYj4Me9WJAveQzC7tChsqBVVt7r6few==", "hasInstallScript": true, "dependencies": { "@babel/code-frame": "^7.14.0", "@babel/core": "^7.15.5", "@babel/eslint-parser": "^7.15.4", "@babel/helper-plugin-utils": "^7.14.5", "@babel/parser": "^7.15.5", "@babel/runtime": "^7.15.4", "@babel/traverse": "^7.15.4", "@babel/types": "^7.15.4", "@builder.io/partytown": "^0.5.2", "@gatsbyjs/reach-router": "^1.3.9", "@gatsbyjs/webpack-hot-middleware": "^2.25.2", "@graphql-codegen/add": "^3.1.1", "@graphql-codegen/core": "^2.5.1", "@graphql-codegen/plugin-helpers": "^2.4.2", "@graphql-codegen/typescript": "^2.4.8", "@graphql-codegen/typescript-operations": "^2.3.5", "@graphql-tools/code-file-loader": "^7.2.14", "@graphql-tools/load": "^7.5.10", "@jridgewell/trace-mapping": "^0.3.13", "@nodelib/fs.walk": "^1.2.8", "@parcel/cache": "2.6.2", "@parcel/core": "2.6.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", "@types/http-proxy": "^1.17.7", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", "@vercel/webpack-asset-relocator-loader": "^1.7.0", "acorn-loose": "^8.3.0", "acorn-walk": "^8.2.0", "address": "1.1.2", "anser": "^2.1.0", "autoprefixer": "^10.4.0", "axios": "^0.21.1", "babel-loader": "^8.2.3", "babel-plugin-add-module-exports": "^1.0.4", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-lodash": "^3.3.4", "babel-plugin-remove-graphql-queries": "^4.25.0", "babel-preset-gatsby": "^2.25.0", "better-opn": "^2.1.1", "bluebird": "^3.7.2", "browserslist": "^4.17.5", "cache-manager": "^2.11.1", "chalk": "^4.1.2", "chokidar": "^3.5.3", "common-tags": "^1.8.0", "compression": "^1.7.4", "cookie": "^0.4.1", "core-js": "^3.22.3", "cors": "^2.8.5", "css-loader": "^5.2.7", "css-minimizer-webpack-plugin": "^2.0.0", "css.escape": "^1.5.1", "date-fns": "^2.25.0", "debug": "^3.2.7", "deepmerge": "^4.2.2", "detect-port": "^1.3.0", "devcert": "^1.2.0", "dotenv": "^8.6.0", "enhanced-resolve": "^5.8.3", "error-stack-parser": "^2.1.4", "eslint": "^7.32.0", "eslint-config-react-app": "^6.0.0", "eslint-plugin-flowtype": "^5.10.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-webpack-plugin": "^2.7.0", "event-source-polyfill": "1.0.25", "execa": "^5.1.1", "express": "^4.17.1", "express-graphql": "^0.12.0", "express-http-proxy": "^1.6.3", "fastest-levenshtein": "^1.0.12", "fastq": "^1.13.0", "file-loader": "^6.2.0", "find-cache-dir": "^3.3.2", "fs-exists-cached": "1.0.0", "fs-extra": "^10.1.0", "gatsby-cli": "^4.25.0", "gatsby-core-utils": "^3.25.0", "gatsby-graphiql-explorer": "^2.25.0", "gatsby-legacy-polyfills": "^2.25.0", "gatsby-link": "^4.25.0", "gatsby-page-utils": "^2.25.0", "gatsby-parcel-config": "0.16.0", "gatsby-plugin-page-creator": "^4.25.0", "gatsby-plugin-typescript": "^4.25.0", "gatsby-plugin-utils": "^3.19.0", "gatsby-react-router-scroll": "^5.25.0", "gatsby-script": "^1.10.0", "gatsby-telemetry": "^3.25.0", "gatsby-worker": "^1.25.0", "glob": "^7.2.3", "globby": "^11.1.0", "got": "^11.8.5", "graphql": "^15.7.2", "graphql-compose": "^9.0.7", "graphql-playground-middleware-express": "^1.7.22", "graphql-tag": "^2.12.6", "hasha": "^5.2.2", "invariant": "^2.2.4", "is-relative": "^1.0.0", "is-relative-url": "^3.0.0", "joi": "^17.4.2", "json-loader": "^0.5.7", "latest-version": "5.1.0", "lmdb": "2.5.3", "lodash": "^4.17.21", "md5-file": "^5.0.0", "meant": "^1.0.3", "memoizee": "^0.4.15", "micromatch": "^4.0.4", "mime": "^2.5.2", "mini-css-extract-plugin": "1.6.2", "mitt": "^1.2.0", "moment": "^2.29.1", "multer": "^1.4.5-lts.1", "node-fetch": "^2.6.6", "node-html-parser": "^5.3.3", "normalize-path": "^3.0.0", "null-loader": "^4.0.1", "opentracing": "^0.14.5", "p-defer": "^3.0.0", "parseurl": "^1.3.3", "physical-cpu-count": "^2.0.0", "platform": "^1.3.6", "postcss": "^8.3.11", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^5.3.0", "prompts": "^2.4.2", "prop-types": "^15.7.2", "query-string": "^6.14.1", "raw-loader": "^4.0.2", "react-dev-utils": "^12.0.1", "react-refresh": "^0.14.0", "react-server-dom-webpack": "0.0.0-experimental-c8b778b7f-20220825", "redux": "4.1.2", "redux-thunk": "^2.4.0", "resolve-from": "^5.0.0", "semver": "^7.3.7", "shallow-compare": "^1.2.2", "signal-exit": "^3.0.5", "slugify": "^1.6.1", "socket.io": "3.1.2", "socket.io-client": "3.1.3", "st": "^2.0.0", "stack-trace": "^0.0.10", "string-similarity": "^1.2.2", "strip-ansi": "^6.0.1", "style-loader": "^2.0.0", "terser-webpack-plugin": "^5.2.4", "tmp": "^0.2.1", "true-case-path": "^2.2.1", "type-of": "^2.0.1", "url-loader": "^4.1.1", "uuid": "^8.3.2", "webpack": "^5.61.0", "webpack-dev-middleware": "^4.3.0", "webpack-merge": "^5.8.0", "webpack-stats-plugin": "^1.0.3", "webpack-virtual-modules": "^0.3.2", "xstate": "4.32.1", "yaml-loader": "^0.8.0" }, "bin": { "gatsby": "cli.js" }, "engines": { "node": ">=14.15.0" }, "optionalDependencies": { "gatsby-sharp": "^0.19.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-cli": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-4.25.0.tgz", "integrity": "sha512-CJ2PCsfFmn9Xqc/jg9MFMU1BG5oQGiej1TFFx8GhChJ+kGhi9ANnNM+qo1K4vOmoMnsT4SSGiPAFD10AWFqpAQ==", "hasInstallScript": true, "dependencies": { "@babel/code-frame": "^7.14.0", "@babel/core": "^7.15.5", "@babel/generator": "^7.16.8", "@babel/helper-plugin-utils": "^7.16.7", "@babel/preset-typescript": "^7.16.7", "@babel/runtime": "^7.15.4", "@babel/template": "^7.16.7", "@babel/types": "^7.16.8", "@jridgewell/trace-mapping": "^0.3.13", "@types/common-tags": "^1.8.1", "better-opn": "^2.1.1", "boxen": "^5.1.2", "chalk": "^4.1.2", "clipboardy": "^2.3.0", "common-tags": "^1.8.2", "convert-hrtime": "^3.0.0", "create-gatsby": "^2.25.0", "envinfo": "^7.8.1", "execa": "^5.1.1", "fs-exists-cached": "^1.0.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-telemetry": "^3.25.0", "hosted-git-info": "^3.0.8", "is-valid-path": "^0.1.1", "joi": "^17.4.2", "lodash": "^4.17.21", "node-fetch": "^2.6.6", "opentracing": "^0.14.5", "pretty-error": "^2.1.2", "progress": "^2.0.3", "prompts": "^2.4.2", "redux": "4.1.2", "resolve-cwd": "^3.0.0", "semver": "^7.3.7", "signal-exit": "^3.0.6", "stack-trace": "^0.0.10", "strip-ansi": "^6.0.1", "update-notifier": "^5.1.0", "yargs": "^15.4.1", "yoga-layout-prebuilt": "^1.10.0", "yurnalist": "^2.1.0" }, "bin": { "gatsby": "cli.js" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby-cli/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/gatsby-cli/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/gatsby-cli/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/gatsby-cli/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-cli/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-cli/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-cli/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-cli/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/gatsby-core-utils": { "version": "3.25.0", "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-3.25.0.tgz", "integrity": "sha512-lmMDwbnKpqAi+8WWd7MvCTCx3E0u7j8sbVgydERNCYVxKVpzD/aLCH4WPb4EE9m1H1rSm76w0Z+MaentyB/c/Q==", "dependencies": { "@babel/runtime": "^7.15.4", "ci-info": "2.0.0", "configstore": "^5.0.1", "fastq": "^1.13.0", "file-type": "^16.5.3", "fs-extra": "^10.1.0", "got": "^11.8.5", "import-from": "^4.0.0", "lmdb": "2.5.3", "lock": "^1.1.0", "node-object-hash": "^2.3.10", "proper-lockfile": "^4.1.2", "resolve-from": "^5.0.0", "tmp": "^0.2.1", "xdg-basedir": "^4.0.0" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby-graphiql-explorer": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/gatsby-graphiql-explorer/-/gatsby-graphiql-explorer-2.25.0.tgz", "integrity": "sha512-/NDsaW4x3/KtvzmxYvedhDwUW1kb7gQO6iOhCkillVJSYBd6mPB8aOSulM49fyCT76UXGYFtRaUI8fyOkmpWhg==", "dependencies": { "@babel/runtime": "^7.15.4" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby-image": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/gatsby-image/-/gatsby-image-2.11.0.tgz", "integrity": "sha512-H1va64RgXizYXONhoqB3rAdSqALZi0hkBYqEsc0peVEYzb2maRhEwOchg65hKvp3HT/ahnfrik59epRguYvi/g==", "deprecated": "gatsby-image is now gatsby-plugin-image: https://npm.im/gatsby-plugin-image. This package will no longer receive updates.", "dependencies": { "@babel/runtime": "^7.12.5", "object-fit-images": "^3.2.4", "prop-types": "^15.7.2" }, "engines": { "node": ">=10.13.0" } }, "node_modules/gatsby-legacy-polyfills": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/gatsby-legacy-polyfills/-/gatsby-legacy-polyfills-2.25.0.tgz", "integrity": "sha512-cMeFwMH1FGENo2gNpyTyMYc/CJ7uBGE26n89OGrVVvBMaQegK+CMNZBOh09sLrXUcOp8hSOX2IwzvOlo6CdWpg==", "dependencies": { "@babel/runtime": "^7.15.4", "core-js-compat": "3.9.0" } }, "node_modules/gatsby-link": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-link/-/gatsby-link-4.25.0.tgz", "integrity": "sha512-Fpwk45sUMPvFUAZehNE8SLb3vQyVSxt9YxU++ZZECyukK4A/3Wxk3eIzoNvwfpMfWu6pnAkqcBhIO6KAfvbPGQ==", "dependencies": { "@types/reach__router": "^1.3.10", "gatsby-page-utils": "^2.25.0", "prop-types": "^15.8.1" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "@gatsbyjs/reach-router": "^1.3.5", "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-page-utils": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/gatsby-page-utils/-/gatsby-page-utils-2.25.0.tgz", "integrity": "sha512-TlwS149JCeb3xGANeV8HdcQi9Q8J9hYwlO9jdxLGVIXVGbWIMWFrDuwx382jOOsISGQ3jfByToNulUzO6fiqig==", "dependencies": { "@babel/runtime": "^7.15.4", "bluebird": "^3.7.2", "chokidar": "^3.5.3", "fs-exists-cached": "^1.0.0", "gatsby-core-utils": "^3.25.0", "glob": "^7.2.3", "lodash": "^4.17.21", "micromatch": "^4.0.5" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby-page-utils/node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/gatsby-page-utils/node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { "node": ">=8" } }, "node_modules/gatsby-page-utils/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-page-utils/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/gatsby-page-utils/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-page-utils/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/gatsby-page-utils/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/gatsby-page-utils/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-page-utils/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-page-utils/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-page-utils/node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/gatsby-page-utils/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-page-utils/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/gatsby-parcel-config": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/gatsby-parcel-config/-/gatsby-parcel-config-0.16.0.tgz", "integrity": "sha512-2+hOg6cMBGZ8r+4lN3k+dOWGvku453vbZCAhp6V3RuFYxbWuvDFP7Icr0GCOyZ62utkFr9m7H2U1Wjf4KOHyEQ==", "dependencies": { "@gatsbyjs/parcel-namer-relative-to-cwd": "^1.10.0", "@parcel/bundler-default": "2.6.2", "@parcel/compressor-raw": "2.6.2", "@parcel/namer-default": "2.6.2", "@parcel/optimizer-terser": "2.6.2", "@parcel/packager-js": "2.6.2", "@parcel/packager-raw": "2.6.2", "@parcel/reporter-dev-server": "2.6.2", "@parcel/resolver-default": "2.6.2", "@parcel/runtime-js": "2.6.2", "@parcel/transformer-js": "2.6.2", "@parcel/transformer-json": "2.6.2" }, "engines": { "parcel": "2.x" }, "peerDependencies": { "@parcel/core": "^2.0.0" } }, "node_modules/gatsby-plugin-google-analytics": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-google-analytics/-/gatsby-plugin-google-analytics-4.25.0.tgz", "integrity": "sha512-fbHrViBAbJ0Ch2gcpuJQlGxWoapaNed42k75eR4gCiZPzaTUvCKagJgLG8ro8ukD1rfD594lgLzdSEaYYcH4WQ==", "dependencies": { "@babel/runtime": "^7.15.4", "minimatch": "3.0.4", "web-vitals": "^1.1.2" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-plugin-google-analytics/node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/gatsby-plugin-manifest": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-manifest/-/gatsby-plugin-manifest-4.25.0.tgz", "integrity": "sha512-2n7v+TvhWUMoOJEaeiPDFsf9jvOImKLZpnzxE8e6ZeeoGeDngXSZhkkP3x2UYIknHtZXUUjFJh8BaVBXiB1dSQ==", "dependencies": { "@babel/runtime": "^7.15.4", "gatsby-core-utils": "^3.25.0", "gatsby-plugin-utils": "^3.19.0", "semver": "^7.3.7", "sharp": "^0.30.7" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-plugin-manifest/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-plugin-manifest/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-plugin-manifest/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/gatsby-plugin-offline": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-offline/-/gatsby-plugin-offline-5.25.0.tgz", "integrity": "sha512-WqAcnYvMpL1xwXF5Jf9BXTihLNktuqQHFUX0TPsQVJrmfjSNv4LxhgiWfeUuGiCO881EOHClXnBn6TqxIdS4EA==", "dependencies": { "@babel/runtime": "^7.15.4", "cheerio": "^1.0.0-rc.10", "gatsby-core-utils": "^3.25.0", "glob": "^7.2.3", "idb-keyval": "^3.2.0", "lodash": "^4.17.21", "workbox-build": "^4.3.1" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-plugin-page-creator": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-4.25.0.tgz", "integrity": "sha512-plHek7xHSV9l1bLPa1JAnxzBqP7j2ihCPRwpBk/wIJAR8cG65wjAT+Nu8DKpW0+2/MYill84ns1r2m8g0L/7bg==", "dependencies": { "@babel/runtime": "^7.15.4", "@babel/traverse": "^7.15.4", "@sindresorhus/slugify": "^1.1.2", "chokidar": "^3.5.3", "fs-exists-cached": "^1.0.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-page-utils": "^2.25.0", "gatsby-plugin-utils": "^3.19.0", "gatsby-telemetry": "^3.25.0", "globby": "^11.1.0", "lodash": "^4.17.21" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-plugin-page-creator/node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/gatsby-plugin-page-creator/node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { "node": ">=8" } }, "node_modules/gatsby-plugin-page-creator/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-plugin-page-creator/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/gatsby-plugin-page-creator/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-plugin-page-creator/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/gatsby-plugin-page-creator/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/gatsby-plugin-page-creator/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-plugin-page-creator/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-plugin-page-creator/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-plugin-page-creator/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-plugin-page-creator/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/gatsby-plugin-plausible": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/gatsby-plugin-plausible/-/gatsby-plugin-plausible-0.0.7.tgz", "integrity": "sha512-pWCXsrWal8lWMmZ1wJ2dolbwZZR1CZU1LVR/K1rYC8NeA+uqTLY8h3uH3hFgP5n8jmRRenOSJ9SjWM9OIdCjOA==", "dependencies": { "@babel/runtime": "^7.9.2", "minimatch": "3.0.4", "react": "^16.13.1" }, "peerDependencies": { "gatsby": ">=2.0.0", "react": ">=16.0.0", "react-dom": ">=16.0.0" } }, "node_modules/gatsby-plugin-plausible/node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/gatsby-plugin-react-helmet": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-5.25.0.tgz", "integrity": "sha512-sU/xae/sGuYFcFDpqUxwXnaOmx8xrU2Q+XSULqAapji0uTBhW6al6CJsaPFigi8IOG2bQX8ano2iWWcGF3/GHw==", "dependencies": { "@babel/runtime": "^7.15.4" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "react-helmet": "^5.1.3 || ^6.0.0" } }, "node_modules/gatsby-plugin-react-svg": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-react-svg/-/gatsby-plugin-react-svg-3.3.0.tgz", "integrity": "sha512-kFPElMFu1QCkiFCm1pSrVkOHAeafU6wkD0qCVPs7nL/Txh5KFh0aOO6Feiwvfre1Jo+Eg3lwCuGmgsy9L+4pDg==", "dependencies": { "svg-react-loader": "^0.4.6" }, "peerDependencies": { "gatsby": "^5.0.0 || ^4.0.0 || ^3.0.0 || ^2.0.0" } }, "node_modules/gatsby-plugin-remove-trailing-slashes": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-remove-trailing-slashes/-/gatsby-plugin-remove-trailing-slashes-4.19.0.tgz", "integrity": "sha512-3zyL+6pqQIeAvABi3PbtVi285n9CVCopzLZNiCLN81/xPiCggA1yyNaZVV3eS1ZbOVFlWCAFyEBRl6E6QeI2BQ==", "deprecated": "This plugin's functionality is now built-in to Gatsby. Use the trailingSlash feature: https://gatsby.dev/trailing-slash. This package will no longer receive updates.", "dependencies": { "@babel/runtime": "^7.15.4" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-plugin-sass": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-sass/-/gatsby-plugin-sass-5.25.0.tgz", "integrity": "sha512-e+47Z24DI+Uh3KcUbj/WvTyH4ZPXcC4zlwqhzspv1Ye+xMS1ipTsIelvBuTwiiEWBs6cqdcYAPhn7HoXX/errw==", "dependencies": { "@babel/runtime": "^7.15.4", "resolve-url-loader": "^3.1.4", "sass-loader": "^10.1.1" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "sass": "^1.30.0" } }, "node_modules/gatsby-plugin-sass-resources": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/gatsby-plugin-sass-resources/-/gatsby-plugin-sass-resources-3.0.1.tgz", "integrity": "sha512-C332NqMOd6z0q7F02OmL/Bl7BoJyD73vcfpF22M+qVy3TE9ugL94Pcdpki8s5TUSwJgqgs9qkTuLD+jDphMsWw==", "dependencies": { "@babel/runtime": "^7.0.0", "sass-resources-loader": "^1.3.3", "webpack": "^5.0.0" }, "peerDependencies": { "gatsby": "^4.0.0" } }, "node_modules/gatsby-plugin-sharp": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-4.25.0.tgz", "integrity": "sha512-8XiSKibQyp6pOFHEkEdRCpoDA3Ywcq5PKftNMExZ51MormT0+WqRC7ynuU+0fzktDTbbSyREvblKa+21Id+rRA==", "dependencies": { "@babel/runtime": "^7.15.4", "async": "^3.2.4", "bluebird": "^3.7.2", "debug": "^4.3.4", "filenamify": "^4.3.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-plugin-utils": "^3.19.0", "lodash": "^4.17.21", "probe-image-size": "^7.2.3", "semver": "^7.3.7", "sharp": "^0.30.7" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-plugin-sharp/node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "node_modules/gatsby-plugin-sharp/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/gatsby-plugin-sharp/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-plugin-sharp/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/gatsby-plugin-sharp/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-plugin-sharp/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/gatsby-plugin-sitemap": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-sitemap/-/gatsby-plugin-sitemap-5.25.0.tgz", "integrity": "sha512-0MYinO0MTsOIEd7d2NOCm/JVdFIMgoIEFem/S0gMpuW4rBCpsE6McPmRKGZl2bp277jEhU8ACt4/49nsCA1AoA==", "dependencies": { "@babel/runtime": "^7.15.4", "common-tags": "^1.8.2", "minimatch": "^3.1.2", "sitemap": "^7.0.0" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-plugin-typescript": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-typescript/-/gatsby-plugin-typescript-4.25.0.tgz", "integrity": "sha512-8BTtiVWuIqIEGx/PBBMWd6FYPgel16hT3js7SMo5oI9K4EPsSxRItgRf41MTJGxRR20EhL4e99g2S8x0v1+odA==", "dependencies": { "@babel/core": "^7.15.5", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", "@babel/plugin-proposal-numeric-separator": "^7.14.5", "@babel/plugin-proposal-optional-chaining": "^7.14.5", "@babel/preset-typescript": "^7.15.0", "@babel/runtime": "^7.15.4", "babel-plugin-remove-graphql-queries": "^4.25.0" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-plugin-utils": { "version": "3.19.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-utils/-/gatsby-plugin-utils-3.19.0.tgz", "integrity": "sha512-EZtvgHSU5NPbEn6a4cfSpEGCQ09SfwbhoybHTJKj1clop86HSwOCV2iH8RbCc+X6jbdgHaSZsfsl7zG1h7DBUw==", "dependencies": { "@babel/runtime": "^7.15.4", "fastq": "^1.13.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-sharp": "^0.19.0", "graphql-compose": "^9.0.7", "import-from": "^4.0.0", "joi": "^17.4.2", "mime": "^3.0.0" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "graphql": "^15.0.0" } }, "node_modules/gatsby-plugin-utils/node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "bin": { "mime": "cli.js" }, "engines": { "node": ">=10.0.0" } }, "node_modules/gatsby-react-router-scroll": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-react-router-scroll/-/gatsby-react-router-scroll-5.25.0.tgz", "integrity": "sha512-SFSdezIa5lahCE8ieCLrtLA5tztemGco/rN8si9rI9KHu1h1jPvDhsNqs2g+Z50JrUb1RPfsmxJTmLa5i6MIgQ==", "dependencies": { "@babel/runtime": "^7.15.4", "prop-types": "^15.8.1" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "@gatsbyjs/reach-router": "^1.3.5", "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-remark-copy-linked-files": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-copy-linked-files/-/gatsby-remark-copy-linked-files-5.25.0.tgz", "integrity": "sha512-kF068dZ0U920xNrlKM5BIR1MvgFdVvgR281AJfvn1xOvv/ES3elPj2bqlokbcs1f72dYcNnaJhv3UhYoIdV6Fg==", "dependencies": { "@babel/runtime": "^7.15.4", "cheerio": "^1.0.0-rc.10", "fs-extra": "^10.1.0", "is-relative-url": "^3.0.0", "lodash": "^4.17.21", "path-is-inside": "^1.0.2", "probe-image-size": "^7.2.3", "unist-util-visit": "^2.0.3" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-remark-copy-linked-files/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/gatsby-remark-images": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-images/-/gatsby-remark-images-6.25.0.tgz", "integrity": "sha512-NNJ17OxA8xPFtTHBfWCxAGqU9ciOielWALUlzY1YdCvYl2rcDmw498tjx77wC995yCBkcwe7yfL1tgky9bxdqQ==", "dependencies": { "@babel/runtime": "^7.15.4", "chalk": "^4.1.2", "cheerio": "^1.0.0-rc.10", "gatsby-core-utils": "^3.25.0", "is-relative-url": "^3.0.0", "lodash": "^4.17.21", "mdast-util-definitions": "^4.0.0", "query-string": "^6.14.1", "unist-util-select": "^3.0.4", "unist-util-visit-parents": "^3.1.1" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "gatsby-plugin-sharp": "^4.0.0-next" } }, "node_modules/gatsby-remark-images/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/gatsby-remark-images/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/gatsby-remark-images/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-remark-prismjs": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-prismjs/-/gatsby-remark-prismjs-6.25.0.tgz", "integrity": "sha512-O33q0aQjl3X8nVEFboQ0RKtnHLhhb0BU+ErK0D9MA6w4qSDRmDjFIWDY7nrsBP5QR80V1sjbjr4zBAAdOre/dA==", "dependencies": { "@babel/runtime": "^7.15.4", "parse-numeric-range": "^1.2.0", "unist-util-visit": "^2.0.3" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "prismjs": "^1.15.0" } }, "node_modules/gatsby-remark-prismjs/node_modules/parse-numeric-range": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" }, "node_modules/gatsby-remark-prismjs/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/gatsby-remark-smartypants": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-smartypants/-/gatsby-remark-smartypants-5.25.0.tgz", "integrity": "sha512-HTcDlQkYQ3regRvQYBuGSCTWE6d4l277yGNYOq89yxkn0CSra/FfplLWUakvFrPLQQaQwpXewhUPXSWkp/PTZg==", "dependencies": { "@babel/runtime": "^7.15.4", "retext": "^7.0.1", "retext-smartypants": "^4.0.0", "unist-util-visit": "^2.0.3" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-remark-smartypants/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/gatsby-remark-unwrap-images": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/gatsby-remark-unwrap-images/-/gatsby-remark-unwrap-images-1.0.2.tgz", "integrity": "sha512-kOatDaz6EcYJn6oEx97pim0JkzuN1epacmHuKP9kL7r3+y1dzvNQjrJMtmDZTqC6Q8LhXD2rrFhsYS3SerTHhw==", "dependencies": { "unist-util-remove": "^1.0.1", "unist-util-visit": "^1.4.0" }, "peerDependencies": { "gatsby": ">2.0.0-alpha" } }, "node_modules/gatsby-script": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/gatsby-script/-/gatsby-script-1.10.0.tgz", "integrity": "sha512-8jAtQR0mw3G8sCy6i2D1jfGvUF5d9AIboEQuo9ZEChT4Ep5f+PSRxiWZqSjhKvintAOIeS4QXCJP5Rtp3xZKLg==", "engines": { "node": ">=14.15.0" }, "peerDependencies": { "@gatsbyjs/reach-router": "^1.3.5", "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0", "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^0.0.0" } }, "node_modules/gatsby-sharp": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/gatsby-sharp/-/gatsby-sharp-0.19.0.tgz", "integrity": "sha512-EbI3RNBu2+aaxuMUP/INmoj8vcNAG6BgpFvi1tLeU7/gVTNVQ+7pC/ZYtlVCzSw+faaw7r1ZBMi6F66mNIIz5A==", "dependencies": { "@types/sharp": "^0.30.5", "sharp": "^0.30.7" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby-source-filesystem": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-4.25.0.tgz", "integrity": "sha512-gja4++bPkYpnum4/TxFicr3zRHBArnM2HjT77EE4EuDhdl6qlJYr/heD09LIPN2jdR5gmPwMDjIZnuYZ/6j/aQ==", "dependencies": { "@babel/runtime": "^7.15.4", "chokidar": "^3.5.3", "file-type": "^16.5.4", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "md5-file": "^5.0.0", "mime": "^2.5.2", "pretty-bytes": "^5.4.1", "valid-url": "^1.0.9", "xstate": "4.32.1" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-source-filesystem/node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/gatsby-source-filesystem/node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { "node": ">=8" } }, "node_modules/gatsby-source-filesystem/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-source-filesystem/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/gatsby-source-filesystem/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-source-filesystem/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/gatsby-source-filesystem/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/gatsby-source-filesystem/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-source-filesystem/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-source-filesystem/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-source-filesystem/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby-source-filesystem/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/gatsby-telemetry": { "version": "3.25.0", "resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-3.25.0.tgz", "integrity": "sha512-FGC1yS2evJxTN/Ku9XonCBiqhH6uO6aPjjps65BbL+Xbpct/qfirIFxYG6DhHPrksR0fKOhstJGnQqay74hWdQ==", "hasInstallScript": true, "dependencies": { "@babel/code-frame": "^7.14.0", "@babel/runtime": "^7.15.4", "@turist/fetch": "^7.2.0", "@turist/time": "^0.0.2", "boxen": "^4.2.0", "configstore": "^5.0.1", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "git-up": "^7.0.0", "is-docker": "^2.2.1", "lodash": "^4.17.21", "node-fetch": "^2.6.7" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby-telemetry/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/gatsby-telemetry/node_modules/boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", "chalk": "^3.0.0", "cli-boxes": "^2.2.0", "string-width": "^4.1.0", "term-size": "^2.1.0", "type-fest": "^0.8.1", "widest-line": "^3.1.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gatsby-telemetry/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "engines": { "node": ">=6" } }, "node_modules/gatsby-telemetry/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-telemetry/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby-telemetry/node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "engines": { "node": ">=8" } }, "node_modules/gatsby-transformer-remark": { "version": "5.25.1", "resolved": "https://registry.npmjs.org/gatsby-transformer-remark/-/gatsby-transformer-remark-5.25.1.tgz", "integrity": "sha512-6k3uOnZYsJSgmZIWq9Y+Cqb6pysusCUBYpQY1+V9ofpSRbrZGGfuoCeFKd27x/c0jI5jneuL3NXnxwn/JJK1Ig==", "dependencies": { "@babel/runtime": "^7.15.4", "gatsby-core-utils": "^3.25.0", "gray-matter": "^4.0.3", "hast-util-raw": "^6.0.2", "hast-util-to-html": "^7.1.3", "lodash": "^4.17.21", "mdast-util-to-hast": "^10.2.0", "mdast-util-to-string": "^2.0.0", "mdast-util-toc": "^5.1.0", "remark": "^13.0.0", "remark-footnotes": "^3.0.0", "remark-gfm": "^1.0.0", "remark-parse": "^9.0.0", "remark-retext": "^4.0.0", "remark-stringify": "^9.0.1", "retext-english": "^3.0.4", "sanitize-html": "^1.27.5", "underscore.string": "^3.3.6", "unified": "^9.2.2", "unist-util-remove-position": "^3.0.0", "unist-util-select": "^3.0.4", "unist-util-visit": "^2.0.3" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next" } }, "node_modules/gatsby-transformer-remark/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/gatsby-transformer-sharp": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-transformer-sharp/-/gatsby-transformer-sharp-4.25.0.tgz", "integrity": "sha512-7aqecTvOUFiNB96ij77UnAGJs7Un0TlkpamG//dSl6Nru9EylGz/NW/Eg0vioQyHLCYdMvd5xO8V3BOHJADsnw==", "dependencies": { "@babel/runtime": "^7.15.4", "bluebird": "^3.7.2", "common-tags": "^1.8.2", "fs-extra": "^10.1.0", "gatsby-plugin-utils": "^3.19.0", "probe-image-size": "^7.2.3", "semver": "^7.3.7", "sharp": "^0.30.7" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "gatsby": "^4.0.0-next", "gatsby-plugin-sharp": "^4.0.0-next" } }, "node_modules/gatsby-transformer-sharp/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-transformer-sharp/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/gatsby-transformer-sharp/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/gatsby-worker": { "version": "1.25.0", "resolved": "https://registry.npmjs.org/gatsby-worker/-/gatsby-worker-1.25.0.tgz", "integrity": "sha512-gjp28irgHASihwvMyF5aZMALWGax9mEmcD8VYGo2osRe7p6BZuWi4cSuP9XM9EvytDvIugpnSadmTP01B7LtWg==", "dependencies": { "@babel/core": "^7.15.5", "@babel/runtime": "^7.15.4" }, "engines": { "node": ">=14.15.0" } }, "node_modules/gatsby/node_modules/acorn": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/gatsby/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/gatsby/node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/gatsby/node_modules/babel-preset-gatsby": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/babel-preset-gatsby/-/babel-preset-gatsby-2.25.0.tgz", "integrity": "sha512-KFfSTDAkY87/Myq1KIUk9cVphWZem/08U7ps9Hiotbo6Mge/lL6ggh3xKP9SdR5Le4DLLyIUI7a4ILrAVacYDg==", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.14.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", "@babel/plugin-proposal-optional-chaining": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-classes": "^7.15.4", "@babel/plugin-transform-runtime": "^7.15.0", "@babel/plugin-transform-spread": "^7.14.6", "@babel/preset-env": "^7.15.4", "@babel/preset-react": "^7.14.0", "@babel/runtime": "^7.15.4", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-macros": "^3.1.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "gatsby-core-utils": "^3.25.0", "gatsby-legacy-polyfills": "^2.25.0" }, "engines": { "node": ">=14.15.0" }, "peerDependencies": { "@babel/core": "^7.11.6", "core-js": "^3.0.0" } }, "node_modules/gatsby/node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/gatsby/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/gatsby/node_modules/core-js": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==", "hasInstallScript": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/gatsby/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/gatsby/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/gatsby/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/gatsby/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/gatsby/node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/gatsby/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/gatsby/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/gatsby/node_modules/react-server-dom-webpack": { "version": "0.0.0-experimental-c8b778b7f-20220825", "resolved": "https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-0.0.0-experimental-c8b778b7f-20220825.tgz", "integrity": "sha512-JyCjbp6ZvkH/T0EuVPdceYlC8u5WqWDSJr2KxDvc81H2eJ+7zYUN++IcEycnR2F+HmER8QVgxfotnIx352zi+w==", "dependencies": { "acorn": "^6.2.1", "loose-envify": "^1.1.0", "neo-async": "^2.6.1" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { "react": "0.0.0-experimental-c8b778b7f-20220825", "webpack": "^5.59.0" } }, "node_modules/gatsby/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/gatsby/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/gatsby/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/gatsby/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "engines": { "node": ">=6.9.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" }, "node_modules/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "engines": { "node": ">=4" } }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/git-up": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^8.1.0" } }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "node_modules/github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==", "dev": true, "optional": true, "dependencies": { "glob-parent": "^2.0.0", "is-glob": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==", "dev": true, "optional": true, "dependencies": { "is-glob": "^2.0.0" } }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, "node_modules/global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "dependencies": { "ini": "2.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/global-dirs/node_modules/ini": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "engines": { "node": ">=10" } }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dependencies": { "global-prefix": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/global-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" }, "engines": { "node": ">=6" } }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/globalthis": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dependencies": { "define-properties": "^1.1.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "engines": { "node": ">=8" } }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dependencies": { "get-intrinsic": "^1.1.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/got": { "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" }, "engines": { "node": ">=10.19.0" }, "funding": { "url": "https://github.com/sindresorhus/got?sponsor=1" } }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/graphql": { "version": "15.8.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", "engines": { "node": ">= 10.x" } }, "node_modules/graphql-compose": { "version": "9.0.10", "resolved": "https://registry.npmjs.org/graphql-compose/-/graphql-compose-9.0.10.tgz", "integrity": "sha512-UsVoxfi2+c8WbHl2pEB+teoRRZoY4mbWBoijeLDGpAZBSPChnqtSRjp+T9UcouLCwGr5ooNyOQLoI3OVzU1bPQ==", "dependencies": { "graphql-type-json": "0.3.2" } }, "node_modules/graphql-playground-html": { "version": "1.6.30", "resolved": "https://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.6.30.tgz", "integrity": "sha512-tpCujhsJMva4aqE8ULnF7/l3xw4sNRZcSHu+R00VV+W0mfp+Q20Plvcrp+5UXD+2yS6oyCXncA+zoQJQqhGCEw==", "dependencies": { "xss": "^1.0.6" } }, "node_modules/graphql-playground-middleware-express": { "version": "1.7.23", "resolved": "https://registry.npmjs.org/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.23.tgz", "integrity": "sha512-M/zbTyC1rkgiQjFSgmzAv6umMHOphYLNWZp6Ye5QrD77WfGOOoSqDsVmGUczc2pDkEPEzzGB/bvBO5rdzaTRgw==", "dependencies": { "graphql-playground-html": "^1.6.30" }, "peerDependencies": { "express": "^4.16.2" } }, "node_modules/graphql-tag": { "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", "dependencies": { "tslib": "^2.1.0" }, "engines": { "node": ">=10" }, "peerDependencies": { "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/graphql-type-json": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", "peerDependencies": { "graphql": ">=0.8.0" } }, "node_modules/gray-matter": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" }, "engines": { "node": ">=6.0" } }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dependencies": { "duplexer": "^0.1.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dependencies": { "function-bind": "^1.1.1" }, "engines": { "node": ">= 0.4.0" } }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dependencies": { "get-intrinsic": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dependencies": { "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "dev": true, "optional": true, "dependencies": { "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-value/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "dev": true, "optional": true, "dependencies": { "is-number": "^3.0.0", "kind-of": "^4.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-values/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/has-values/node_modules/is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-values/node_modules/kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "engines": { "node": ">=8" } }, "node_modules/hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dependencies": { "is-stream": "^2.0.0", "type-fest": "^0.8.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/hasha/node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "engines": { "node": ">=8" } }, "node_modules/hast-to-hyperscript": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", "dependencies": { "@types/unist": "^2.0.3", "comma-separated-tokens": "^1.0.0", "property-information": "^5.3.0", "space-separated-tokens": "^1.0.0", "style-to-object": "^0.3.0", "unist-util-is": "^4.0.0", "web-namespaces": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-from-parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", "dependencies": { "@types/parse5": "^5.0.0", "hastscript": "^6.0.0", "property-information": "^5.0.0", "vfile": "^4.0.0", "vfile-location": "^3.2.0", "web-namespaces": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-is-element": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-parse-selector": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-raw": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.1.0.tgz", "integrity": "sha512-5FoZLDHBpka20OlZZ4I/+RBw5piVQ8iI1doEvffQhx5CbCyTtP8UCq8Tw6NmTAMtXgsQxmhW7Ly8OdFre5/YMQ==", "dependencies": { "@types/hast": "^2.0.0", "hast-util-from-parse5": "^6.0.0", "hast-util-to-parse5": "^6.0.0", "html-void-elements": "^1.0.0", "parse5": "^6.0.0", "unist-util-position": "^3.0.0", "unist-util-visit": "^2.0.0", "vfile": "^4.0.0", "web-namespaces": "^1.0.0", "xtend": "^4.0.0", "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-raw/node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, "node_modules/hast-util-raw/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-sanitize": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.3.1.tgz", "integrity": "sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==", "dependencies": { "xtend": "^4.0.1" } }, "node_modules/hast-util-to-html": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz", "integrity": "sha512-yk2+1p3EJTEE9ZEUkgHsUSVhIpCsL/bvT8E5GzmWc+N1Po5gBw+0F8bo7dpxXR0nu0bQVxVZGX2lBGF21CmeDw==", "dependencies": { "ccount": "^1.0.0", "comma-separated-tokens": "^1.0.0", "hast-util-is-element": "^1.0.0", "hast-util-whitespace": "^1.0.0", "html-void-elements": "^1.0.0", "property-information": "^5.0.0", "space-separated-tokens": "^1.0.0", "stringify-entities": "^3.0.1", "unist-util-is": "^4.0.0", "xtend": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-to-parse5": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", "dependencies": { "hast-to-hyperscript": "^9.0.0", "property-information": "^5.0.0", "web-namespaces": "^1.0.0", "xtend": "^4.0.0", "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-whitespace": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hastscript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", "dependencies": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^1.0.0", "hast-util-parse-selector": "^2.0.0", "property-information": "^5.0.0", "space-separated-tokens": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "bin": { "he": "bin/he" } }, "node_modules/header-case": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", "dependencies": { "capital-case": "^1.0.4", "tslib": "^2.0.3" } }, "node_modules/hoist-non-react-statics": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" }, "node_modules/home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", "dev": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/hosted-git-info": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", "dependencies": { "lru-cache": "^6.0.0" }, "engines": { "node": ">=10" } }, "node_modules/hosted-git-info/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/hosted-git-info/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, "node_modules/html-to-react": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.5.0.tgz", "integrity": "sha512-tjihXBgaJZRRYzmkrJZ/Qf9jFayilFYcb+sJxXXE2BVLk2XsNrGeuNCVvhXmvREULZb9dz6NFTBC96DTR/lQCQ==", "dependencies": { "domhandler": "^5.0", "htmlparser2": "^8.0", "lodash.camelcase": "^4.3.0" } }, "node_modules/html-void-elements": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/htmlparser2": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { "type": "github", "url": "https://github.com/sponsors/fb55" } ], "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "entities": "^4.3.0" } }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" }, "engines": { "node": ">=10.19.0" } }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "engines": { "node": ">=10.17.0" } }, "node_modules/hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "engines": { "node": "^10 || ^12 || >= 14" }, "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/idb-keyval": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz", "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==" }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "engines": { "node": ">= 4" } }, "node_modules/immer": { "version": "9.0.17", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.17.tgz", "integrity": "sha512-+hBruaLSQvkPfxRiTLK/mi4vLH+/VQS6z2KJahdoxlleFOI8ARqzOF17uy12eFDlqWmPoygwc5evgwcp+dlHhg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" } }, "node_modules/immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", "engines": { "node": ">=0.8.0" } }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "engines": { "node": ">=4" } }, "node_modules/import-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", "engines": { "node": ">=12.2" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", "engines": { "node": ">=4" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "node_modules/inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.19", "mute-stream": "0.0.8", "run-async": "^2.4.0", "rxjs": "^6.6.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "engines": { "node": ">=8.0.0" } }, "node_modules/inquirer/node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dependencies": { "type-fest": "^0.21.3" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/inquirer/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/inquirer/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/inquirer/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/internal-slot": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "dependencies": { "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" }, "engines": { "node": ">= 0.4" } }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "engines": { "node": ">= 0.10" } }, "node_modules/is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-absolute-url": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "engines": { "node": ">=8" } }, "node_modules/is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "optional": true, "dependencies": { "kind-of": "^6.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", "dependencies": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-array-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "is-typed-array": "^1.1.10" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dependencies": { "has-bigints": "^1.0.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", "dev": true, "optional": true, "dependencies": { "binary-extensions": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "engines": { "node": ">=4" } }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dependencies": { "ci-info": "^2.0.0" }, "bin": { "is-ci": "bin.js" } }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dependencies": { "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "optional": true, "dependencies": { "kind-of": "^6.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-decimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "optional": true, "dependencies": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "bin": { "is-docker": "cli.js" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", "integrity": "sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==", "dev": true, "optional": true, "dependencies": { "is-primitive": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true, "engines": { "node": ">=0.10.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, "node_modules/is-function": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" }, "node_modules/is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", "dependencies": { "is-extglob": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-hexadecimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-in-browser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-invalid-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", "integrity": "sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==", "dependencies": { "is-glob": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-npm": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-number/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "engines": { "node": ">=8" } }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "engines": { "node": ">=8" } }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-plain-object/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", "integrity": "sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dependencies": { "is-unc-path": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-relative-url": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-3.0.0.tgz", "integrity": "sha512-U1iSYRlY2GIMGuZx7gezlB5dp1Kheaym7zKzO1PV06mOihiWTXejLwm4poEJysPyXF+HtK/BEd0DVlcCh30pEA==", "dependencies": { "is-absolute-url": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-root": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", "engines": { "node": ">=6" } }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dependencies": { "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-ssh": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", "dependencies": { "protocols": "^2.0.1" } }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dependencies": { "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typed-array": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dependencies": { "unc-path-regex": "^0.1.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-upper-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/is-valid-domain": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.1.6.tgz", "integrity": "sha512-ZKtq737eFkZr71At8NxOFcP9O1K89gW3DkdrGMpp1upr/ueWjj+Weh4l9AI4rN0Gt8W2M1w7jrG2b/Yv83Ljpg==", "dependencies": { "punycode": "^2.1.1" } }, "node_modules/is-valid-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", "integrity": "sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==", "dependencies": { "is-invalid-path": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dependencies": { "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dependencies": { "is-docker": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dev": true, "optional": true, "dependencies": { "isarray": "1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" }, "node_modules/jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/jest-worker/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/joi": { "version": "17.7.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", "dependencies": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } }, "node_modules/js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==" }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", "dev": true, "bin": { "jsesc": "bin/jsesc" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-loader": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, "engines": { "node": ">=6" } }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/jss": { "version": "9.8.7", "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", "hasInstallScript": true, "dependencies": { "is-in-browser": "^1.1.3", "symbol-observable": "^1.1.0", "warning": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/jss-camel-case": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz", "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==", "dependencies": { "hyphenate-style-name": "^1.0.2" }, "peerDependencies": { "jss": "^9.7.0" } }, "node_modules/jss-compose": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz", "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==", "dependencies": { "warning": "^3.0.0" }, "peerDependencies": { "jss": "^9.0.0" } }, "node_modules/jss-default-unit": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz", "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==", "peerDependencies": { "jss": "^9.4.0" } }, "node_modules/jss-expand": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz", "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg==", "peerDependencies": { "jss": "^9.4.0" } }, "node_modules/jss-extend": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz", "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==", "dependencies": { "warning": "^3.0.0" }, "peerDependencies": { "jss": "^9.7.0" } }, "node_modules/jss-global": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==", "peerDependencies": { "jss": "^9.0.0" } }, "node_modules/jss-nested": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", "dependencies": { "warning": "^3.0.0" }, "peerDependencies": { "jss": "^9.0.0" } }, "node_modules/jss-preset-default": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz", "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==", "dependencies": { "jss-camel-case": "^6.1.0", "jss-compose": "^5.0.0", "jss-default-unit": "^8.0.2", "jss-expand": "^5.3.0", "jss-extend": "^6.2.0", "jss-global": "^3.0.0", "jss-nested": "^6.0.1", "jss-props-sort": "^6.0.0", "jss-template": "^1.0.1", "jss-vendor-prefixer": "^7.0.0" }, "peerDependencies": { "jss": "^9.7.0" } }, "node_modules/jss-props-sort": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==", "peerDependencies": { "jss": "^9.0.0" } }, "node_modules/jss-template": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz", "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==", "dependencies": { "warning": "^3.0.0" }, "peerDependencies": { "jss": "^9.0.0" } }, "node_modules/jss-vendor-prefixer": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", "dependencies": { "css-vendor": "^0.3.8" }, "peerDependencies": { "jss": "^9.0.0" } }, "node_modules/jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", "dependencies": { "array-includes": "^3.1.5", "object.assign": "^4.1.3" }, "engines": { "node": ">=4.0" } }, "node_modules/keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "engines": { "node": ">=0.10.0" } }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "engines": { "node": ">=6" } }, "node_modules/klona": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", "engines": { "node": ">= 8" } }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" }, "node_modules/language-tags": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.7.tgz", "integrity": "sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==", "dependencies": { "language-subtag-registry": "^0.3.20" } }, "node_modules/latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "dependencies": { "package-json": "^6.3.0" }, "engines": { "node": ">=8" } }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", "engines": { "node": ">=10" } }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lmdb": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.3.tgz", "integrity": "sha512-iBA0cb13CobBSoGJLfZgnrykLlfJipDAnvtf+YwIqqzBEsTeQYsXrHaSBkaHd5wCWeabwrNvhjZoFMUrlo+eLw==", "hasInstallScript": true, "dependencies": { "msgpackr": "^1.5.4", "node-addon-api": "^4.3.0", "node-gyp-build-optional-packages": "5.0.3", "ordered-binary": "^1.2.4", "weak-lru-cache": "^1.2.2" }, "optionalDependencies": { "@lmdb/lmdb-darwin-arm64": "2.5.3", "@lmdb/lmdb-darwin-x64": "2.5.3", "@lmdb/lmdb-linux-arm": "2.5.3", "@lmdb/lmdb-linux-arm64": "2.5.3", "@lmdb/lmdb-linux-x64": "2.5.3", "@lmdb/lmdb-win32-x64": "2.5.3" } }, "node_modules/lmdb/node_modules/node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "engines": { "node": ">=6.11.5" } }, "node_modules/loader-utils": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" }, "engines": { "node": ">=8.9.0" } }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lock": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/lock/-/lock-1.1.0.tgz", "integrity": "sha512-NZQIJJL5Rb9lMJ0Yl1JoVr9GSdo4HTPsUEWsSFzB8dE8DSoiLCVavWZPi7Rnlv/o73u6I24S/XYc/NmG4l8EKA==" }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.deburr": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==" }, "node_modules/lodash.every": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", "integrity": "sha512-isF82d+65/sNvQ3aaQAW7LLHnnTxSN/2fm4rhYyuufLzA4VtHz6y6S5vFwe6PQVr2xdqUOyxBbTNKDpnmeu50w==" }, "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==" }, "node_modules/lodash.foreach": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==" }, "node_modules/lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==" }, "node_modules/lodash.maxby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.maxby/-/lodash.maxby-4.6.0.tgz", "integrity": "sha512-QfTqQTwzmKxLy7VZlbx2M/ipWv8DCQ2F5BI/MRxLharOQ5V78yMSuB+JE+EuUM22txYfj09R2Q7hUlEYj7KdNg==" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dependencies": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "node_modules/lodash.templatesettings": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dependencies": { "lodash._reinterpolate": "^3.0.0" } }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "node_modules/longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lower-case-first": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "engines": { "node": ">=8" } }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/lru-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "dependencies": { "es5-ext": "~0.10.2" } }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dependencies": { "semver": "^6.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dependencies": { "p-defer": "^1.0.0" }, "engines": { "node": ">=6" } }, "node_modules/map-age-cleaner/node_modules/p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", "engines": { "node": ">=4" } }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "engines": { "node": ">=0.10.0" } }, "node_modules/map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "dev": true, "optional": true, "dependencies": { "object-visit": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/markdown-table": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", "dependencies": { "repeat-string": "^1.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true, "optional": true }, "node_modules/md-attr-parser": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/md-attr-parser/-/md-attr-parser-1.3.0.tgz", "integrity": "sha512-KTVlfU5Oxo/6kd0YZ2mLP3eWJj+5vzh5mBCxLo3yGl1fzHIgxmtadbE9tHb7TbUBi3XZbl+P0xKeGmakat135w==", "dev": true }, "node_modules/md5-file": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==", "bin": { "md5-file": "cli.js" }, "engines": { "node": ">=10.13.0" } }, "node_modules/mdast-util-definitions": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", "dependencies": { "unist-util-visit": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-find-and-replace": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", "dependencies": { "escape-string-regexp": "^4.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mdast-util-footnote": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz", "integrity": "sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==", "dependencies": { "mdast-util-to-markdown": "^0.6.0", "micromark": "~2.11.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-from-markdown": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^2.0.0", "micromark": "~2.11.0", "parse-entities": "^2.0.0", "unist-util-stringify-position": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-gfm": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", "dependencies": { "mdast-util-gfm-autolink-literal": "^0.1.0", "mdast-util-gfm-strikethrough": "^0.2.0", "mdast-util-gfm-table": "^0.1.0", "mdast-util-gfm-task-list-item": "^0.1.0", "mdast-util-to-markdown": "^0.6.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-gfm-autolink-literal": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", "dependencies": { "ccount": "^1.0.0", "mdast-util-find-and-replace": "^1.1.0", "micromark": "^2.11.3" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-gfm-strikethrough": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", "dependencies": { "mdast-util-to-markdown": "^0.6.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-gfm-table": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", "dependencies": { "markdown-table": "^2.0.0", "mdast-util-to-markdown": "~0.6.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-gfm-task-list-item": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", "dependencies": { "mdast-util-to-markdown": "~0.6.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-to-hast": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "mdast-util-definitions": "^4.0.0", "mdurl": "^1.0.0", "unist-builder": "^2.0.0", "unist-util-generated": "^1.0.0", "unist-util-position": "^3.0.0", "unist-util-visit": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-to-markdown": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", "dependencies": { "@types/unist": "^2.0.0", "longest-streak": "^2.0.0", "mdast-util-to-string": "^2.0.0", "parse-entities": "^2.0.0", "repeat-string": "^1.0.0", "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-to-nlcst": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/mdast-util-to-nlcst/-/mdast-util-to-nlcst-4.0.1.tgz", "integrity": "sha512-Y4ffygj85MTt70STKnEquw6k73jYWJBaYcb4ITAKgSNokZF7fH8rEHZ1GsRY/JaxqUevMaEnsDmkVv5Z9uVRdg==", "dependencies": { "nlcst-to-string": "^2.0.0", "repeat-string": "^1.0.0", "unist-util-position": "^3.0.0", "vfile-location": "^3.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-to-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-toc": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-5.1.0.tgz", "integrity": "sha512-csimbRIVkiqc+PpFeKDGQ/Ck2N4f9FYH3zzBMMJzcxoKL8m+cM0n94xXm0I9eaxHnKdY9n145SGTdyJC7i273g==", "dependencies": { "@types/mdast": "^3.0.3", "@types/unist": "^2.0.3", "extend": "^3.0.2", "github-slugger": "^1.2.1", "mdast-util-to-string": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-toc/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "node_modules/meant": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.3.tgz", "integrity": "sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw==" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } }, "node_modules/mem": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==", "dependencies": { "map-age-cleaner": "^0.1.3", "mimic-fn": "^3.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/mem?sponsor=1" } }, "node_modules/mem/node_modules/mimic-fn": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", "engines": { "node": ">=8" } }, "node_modules/memfs": { "version": "3.4.13", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", "dependencies": { "fs-monkey": "^1.0.3" }, "engines": { "node": ">= 4.0.0" } }, "node_modules/memoizee": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.53", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" } }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "engines": { "node": ">= 8" } }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } }, "node_modules/micromark": { "version": "2.11.4", "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", "funding": [ { "type": "GitHub Sponsors", "url": "https://github.com/sponsors/unifiedjs" }, { "type": "OpenCollective", "url": "https://opencollective.com/unified" } ], "dependencies": { "debug": "^4.0.0", "parse-entities": "^2.0.0" } }, "node_modules/micromark-extension-footnote": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz", "integrity": "sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==", "dependencies": { "micromark": "~2.11.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-extension-gfm": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", "dependencies": { "micromark": "~2.11.0", "micromark-extension-gfm-autolink-literal": "~0.5.0", "micromark-extension-gfm-strikethrough": "~0.6.5", "micromark-extension-gfm-table": "~0.4.0", "micromark-extension-gfm-tagfilter": "~0.3.0", "micromark-extension-gfm-task-list-item": "~0.3.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-extension-gfm-autolink-literal": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", "dependencies": { "micromark": "~2.11.3" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-extension-gfm-strikethrough": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", "dependencies": { "micromark": "~2.11.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-extension-gfm-table": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", "dependencies": { "micromark": "~2.11.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-extension-gfm-tagfilter": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-extension-gfm-task-list-item": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", "dependencies": { "micromark": "~2.11.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/micromark/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==", "dev": true, "optional": true, "dependencies": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", "braces": "^1.8.2", "expand-brackets": "^0.1.4", "extglob": "^0.3.1", "filename-regex": "^2.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.1", "kind-of": "^3.0.2", "normalize-path": "^2.0.1", "object.omit": "^2.0.0", "parse-glob": "^3.0.4", "regex-cache": "^0.4.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/micromatch/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/micromatch/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "bin": { "mime": "cli.js" }, "engines": { "node": ">=4.0.0" } }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "engines": { "node": ">=6" } }, "node_modules/mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "engines": { "node": ">=4" } }, "node_modules/mini-css-extract-plugin": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz", "integrity": "sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0", "webpack-sources": "^1.1.0" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.4.0 || ^5.0.0" } }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/minimist": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/mitt": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==" }, "node_modules/mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "optional": true, "dependencies": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/mixin-deep/node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "dependencies": { "is-plain-object": "^2.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", "engines": { "node": "*" } }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/msgpackr": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.1.tgz", "integrity": "sha512-05fT4J8ZqjYlR4QcRDIhLCYKUOHXk7C/xa62GzMKj74l3up9k2QZ3LgFc6qWdsPHl91QA2WLWqWc8b8t7GLNNw==", "optionalDependencies": { "msgpackr-extract": "^2.2.0" } }, "node_modules/msgpackr-extract": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-2.2.0.tgz", "integrity": "sha512-0YcvWSv7ZOGl9Od6Y5iJ3XnPww8O7WLcpYMDwX+PAA/uXLDtyw94PJv9GLQV/nnp3cWlDhMoyKZIQLrx33sWog==", "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build-optional-packages": "5.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "2.2.0", "@msgpackr-extract/msgpackr-extract-darwin-x64": "2.2.0", "@msgpackr-extract/msgpackr-extract-linux-arm": "2.2.0", "@msgpackr-extract/msgpackr-extract-linux-arm64": "2.2.0", "@msgpackr-extract/msgpackr-extract-linux-x64": "2.2.0", "@msgpackr-extract/msgpackr-extract-win32-x64": "2.2.0" } }, "node_modules/multer": { "version": "1.4.5-lts.1", "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", "dependencies": { "append-field": "^1.0.0", "busboy": "^1.0.0", "concat-stream": "^1.5.2", "mkdirp": "^0.5.4", "object-assign": "^4.1.1", "type-is": "^1.6.4", "xtend": "^4.0.0" }, "engines": { "node": ">= 6.0.0" } }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "node_modules/nan": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", "dev": true, "optional": true }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "optional": true, "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "fragment-cache": "^0.2.1", "is-windows": "^1.0.2", "kind-of": "^6.0.2", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/nanomatch/node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/nanomatch/node_modules/array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/nanomatch/node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/nanomatch/node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "dependencies": { "is-plain-object": "^2.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/needle": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" }, "bin": { "needle": "bin/needle" }, "engines": { "node": ">= 4.4.x" } }, "node_modules/needle/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/needle/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node_modules/nlcst-to-string": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz", "integrity": "sha512-3x3jwTd6UPG7vi5k4GEzvxJ5rDA7hVUIRNHPblKuMVP9Z3xmlsd9cgLcpAMkc5uPOBna82EeshROFhsPkbnTZg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "node_modules/node-abi": { "version": "3.30.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", "dependencies": { "semver": "^7.3.5" }, "engines": { "node": ">=10" } }, "node_modules/node-abi/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/node-abi/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/node-abi/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dependencies": { "whatwg-url": "^5.0.0" }, "engines": { "node": "4.x || >=6.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "peerDependenciesMeta": { "encoding": { "optional": true } } }, "node_modules/node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "node_modules/node-gyp-build-optional-packages": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", "integrity": "sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==", "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "node_modules/node-html-parser": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz", "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==", "dependencies": { "css-select": "^4.2.1", "he": "1.2.0" } }, "node_modules/node-html-parser/node_modules/css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, "node_modules/node-html-parser/node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/node-html-parser/node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { "domelementtype": "^2.2.0" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/node-html-parser/node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/node-html-parser/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node_modules/node-object-hash": { "version": "2.3.10", "resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-2.3.10.tgz", "integrity": "sha512-jY5dPJzw6NHd/KPSfPKJ+IHoFS81/tJ43r34ZeNMXGzCOM8jwQDCD12HYayKIB6MuznrnqIYy2e891NA2g0ibA==", "engines": { "node": ">=0.10.0" } }, "node_modules/node-releases": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" }, "node_modules/normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dependencies": { "remove-trailing-separator": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/not": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dependencies": { "path-key": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dependencies": { "boolbase": "^1.0.0" }, "funding": { "url": "https://github.com/fb55/nth-check?sponsor=1" } }, "node_modules/null-loader": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dev": true, "optional": true, "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", "kind-of": "^3.0.3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/object-copy/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy/node_modules/is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object-copy/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-fit-images": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/object-fit-images/-/object-fit-images-3.2.4.tgz", "integrity": "sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg==" }, "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "engines": { "node": ">= 0.4" } }, "node_modules/object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dev": true, "optional": true, "dependencies": { "isobject": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object-visit/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object.assign": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.entries": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.hasown": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", "dependencies": { "define-properties": "^1.1.4", "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==", "dev": true, "optional": true, "dependencies": { "for-own": "^0.1.4", "is-extendable": "^0.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, "optional": true, "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.pick/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object.values": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dependencies": { "mimic-fn": "^2.1.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/opentracing": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==", "engines": { "node": ">=0.10" } }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/ordered-binary": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", "integrity": "sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==" }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "engines": { "node": ">=0.10.0" } }, "node_modules/output-file-sync": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", "integrity": "sha512-uQLlclru4xpCi+tfs80l3QF24KL81X57ELNMy7W/dox+JTtxUf1bLyQ8968fFCmSqqbokjW0kn+WBIlO+rSkNg==", "dev": true, "dependencies": { "graceful-fs": "^4.1.4", "mkdirp": "^0.5.1", "object-assign": "^4.1.0" } }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "engines": { "node": ">=8" } }, "node_modules/p-defer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz", "integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==", "engines": { "node": ">=8" } }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "engines": { "node": ">=4" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { "node": ">=6" } }, "node_modules/package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dependencies": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" }, "engines": { "node": ">=8" } }, "node_modules/package-json/node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "engines": { "node": ">=6" } }, "node_modules/package-json/node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", "dependencies": { "defer-to-connect": "^1.0.1" }, "engines": { "node": ">=6" } }, "node_modules/package-json/node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^3.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^4.1.0", "responselike": "^1.0.2" }, "engines": { "node": ">=8" } }, "node_modules/package-json/node_modules/cacheable-request/node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-json/node_modules/decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dependencies": { "mimic-response": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/package-json/node_modules/defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, "node_modules/package-json/node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/package-json/node_modules/got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "dependencies": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", "cacheable-request": "^6.0.0", "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", "get-stream": "^4.1.0", "lowercase-keys": "^1.0.1", "mimic-response": "^1.0.1", "p-cancelable": "^1.0.0", "to-readable-stream": "^1.0.0", "url-parse-lax": "^3.0.0" }, "engines": { "node": ">=8.6" } }, "node_modules/package-json/node_modules/got/node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "engines": { "node": ">=0.10.0" } }, "node_modules/package-json/node_modules/json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" }, "node_modules/package-json/node_modules/keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "dependencies": { "json-buffer": "3.0.0" } }, "node_modules/package-json/node_modules/normalize-url": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "engines": { "node": ">=8" } }, "node_modules/package-json/node_modules/p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "engines": { "node": ">=6" } }, "node_modules/package-json/node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "dependencies": { "lowercase-keys": "^1.0.0" } }, "node_modules/package-json/node_modules/responselike/node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "engines": { "node": ">=0.10.0" } }, "node_modules/package-json/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/parse-english": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/parse-english/-/parse-english-4.2.0.tgz", "integrity": "sha512-jw5N6wZUZViIw3VLG/FUSeL3vDhfw5Q2g4E3nYC69Mm5ANbh9ZWd+eligQbeUoyObZM8neynTn3l14e09pjEWg==", "dependencies": { "nlcst-to-string": "^2.0.0", "parse-latin": "^4.0.0", "unist-util-modify-children": "^2.0.0", "unist-util-visit-children": "^1.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/parse-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dependencies": { "character-entities": "^1.0.0", "character-entities-legacy": "^1.0.0", "character-reference-invalid": "^1.0.0", "is-alphanumerical": "^1.0.0", "is-decimal": "^1.0.0", "is-hexadecimal": "^1.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" }, "engines": { "node": ">=0.8" } }, "node_modules/parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==", "dev": true, "optional": true, "dependencies": { "glob-base": "^0.3.0", "is-dotfile": "^1.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-latin": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-4.3.0.tgz", "integrity": "sha512-TYKL+K98dcAWoCw/Ac1yrPviU8Trk+/gmjQVaoWEFDZmVD4KRg6c/80xKqNNFQObo2mTONgF8trzAf2UTwKafw==", "dependencies": { "nlcst-to-string": "^2.0.0", "unist-util-modify-children": "^2.0.0", "unist-util-visit-children": "^1.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/parse-numeric-range": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-0.0.2.tgz", "integrity": "sha512-m6xRZuda9v6EGdnPMIkcyB3/NpdgbMJG8yPAQ0Mwm1nGlm2OE/o6YS0EAxAqv6u4/PKQPp6BNoylZnRb2U2/OA==" }, "node_modules/parse-path": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", "dependencies": { "protocols": "^2.0.0" } }, "node_modules/parse-srcset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, "node_modules/parse-url": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "dependencies": { "parse-path": "^7.0.0" } }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dependencies": { "entities": "^4.4.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", "dependencies": { "domhandler": "^5.0.2", "parse5": "^7.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parseqs": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" }, "node_modules/parseuri": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "engines": { "node": ">= 0.8" } }, "node_modules/pascal-case": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/password-prompt": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", "dependencies": { "ansi-escapes": "^3.1.0", "cross-spawn": "^6.0.5" } }, "node_modules/password-prompt/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" }, "engines": { "node": ">=4.8" } }, "node_modules/password-prompt/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "engines": { "node": ">=4" } }, "node_modules/password-prompt/node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dependencies": { "shebang-regex": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/password-prompt/node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/password-prompt/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/path-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } }, "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dependencies": { "path-root-regex": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "engines": { "node": ">=8" } }, "node_modules/peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", "engines": { "node": ">=8" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Borewit" } }, "node_modules/physical-cpu-count": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", "integrity": "sha512-rxJOljMuWtYlvREBmd6TZYanfcPhNUKtGDZBjBBS8WG1dpN2iwPsRJZgQqN/OtJuiQckdRFOfzogqJClTrsi7g==" }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dependencies": { "find-up": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dependencies": { "find-up": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/pkg-up/node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dependencies": { "locate-path": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-up/node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-up/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dependencies": { "p-limit": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-up/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "engines": { "node": ">=4" } }, "node_modules/platform": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, "node_modules/popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/postcss": { "version": "8.4.21", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" } ], "dependencies": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-calc": { "version": "8.2.4", "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.2" } }, "node_modules/postcss-colormin": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", "dependencies": { "browserslist": "^4.16.6", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-convert-values": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-discard-comments": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", "peerDependencies": { "postcss": "^8.1.4" } }, "node_modules/postcss-loader": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", "dependencies": { "cosmiconfig": "^7.0.0", "klona": "^2.0.4", "semver": "^7.3.4" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "postcss": "^7.0.0 || ^8.0.1", "webpack": "^5.0.0" } }, "node_modules/postcss-loader/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/postcss-loader/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/postcss-loader/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/postcss-merge-longhand": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-merge-rules": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "cssnano-utils": "^3.1.0", "postcss-selector-parser": "^6.0.5" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-minify-font-values": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-minify-gradients": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", "dependencies": { "colord": "^2.9.1", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-minify-params": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", "dependencies": { "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-minify-selectors": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", "dependencies": { "postcss-selector-parser": "^6.0.5" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", "engines": { "node": "^10 || ^12 || >= 14" }, "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/postcss-modules-local-by-default": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" }, "engines": { "node": "^10 || ^12 || >= 14" }, "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/postcss-modules-scope": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dependencies": { "postcss-selector-parser": "^6.0.4" }, "engines": { "node": "^10 || ^12 || >= 14" }, "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dependencies": { "icss-utils": "^5.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" }, "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-display-values": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-positions": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-repeat-style": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-string": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-timing-functions": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-unicode": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-url": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", "dependencies": { "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-whitespace": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-ordered-values": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-reduce-initial": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-reduce-transforms": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-selector-parser": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" }, "engines": { "node": ">=4" } }, "node_modules/postcss-svgo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^2.7.0" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-unique-selectors": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", "dependencies": { "postcss-selector-parser": "^6.0.5" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" }, "engines": { "node": ">=10" } }, "node_modules/prebuild-install/node_modules/detect-libc": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", "engines": { "node": ">=8" } }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "engines": { "node": ">= 0.8.0" } }, "node_modules/prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", "engines": { "node": ">=4" } }, "node_modules/preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=4" } }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "dependencies": { "lodash": "^4.17.20", "renderkid": "^2.0.4" } }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "engines": { "node": ">=6" } }, "node_modules/private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/probe-image-size": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", "dependencies": { "lodash.merge": "^4.6.2", "needle": "^2.5.2", "stream-parser": "~0.3.1" } }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "engines": { "node": ">=0.4.0" } }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dependencies": { "asap": "~2.0.3" } }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" }, "engines": { "node": ">= 6" } }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "node_modules/proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "node_modules/property-information": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", "dependencies": { "xtend": "^4.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/protocols": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "engines": { "node": ">=6" } }, "node_modules/pupa": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dependencies": { "escape-goat": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { "side-channel": "^1.0.4" }, "engines": { "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/query-string": { "version": "6.14.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", "dependencies": { "decode-uri-component": "^0.2.0", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ramda": { "version": "0.21.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz", "integrity": "sha512-HGd5aczYKQXGILB+abY290V7Xz62eFajpa6AtMdwEmQSakJmgSO7ks4eI3HdR34j+X2Vz4Thp9VAJbrCAMbO2w==" }, "node_modules/randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "optional": true, "dependencies": { "is-number": "^4.0.0", "kind-of": "^6.0.0", "math-random": "^1.0.1" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/randomatic/node_modules/is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/raw-body/node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } }, "node_modules/raw-loader": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "cli.js" } }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/react": { "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", "dependencies": { "@babel/code-frame": "^7.16.0", "address": "^1.1.2", "browserslist": "^4.18.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "detect-port-alt": "^1.1.6", "escape-string-regexp": "^4.0.0", "filesize": "^8.0.6", "find-up": "^5.0.0", "fork-ts-checker-webpack-plugin": "^6.5.0", "global-modules": "^2.0.0", "globby": "^11.0.4", "gzip-size": "^6.0.0", "immer": "^9.0.7", "is-root": "^2.1.0", "loader-utils": "^3.2.0", "open": "^8.4.0", "pkg-up": "^3.1.0", "prompts": "^2.4.2", "react-error-overlay": "^6.0.11", "recursive-readdir": "^2.2.2", "shell-quote": "^1.7.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "engines": { "node": ">=14" } }, "node_modules/react-dev-utils/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/react-dev-utils/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/react-dev-utils/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/react-dev-utils/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/react-dev-utils/node_modules/loader-utils": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "engines": { "node": ">= 12.13.0" } }, "node_modules/react-dev-utils/node_modules/open": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/react-dev-utils/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/react-dev-utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/react-dom": { "version": "16.14.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "^0.19.1" }, "peerDependencies": { "react": "^16.14.0" } }, "node_modules/react-error-overlay": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "node_modules/react-fast-compare": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" }, "node_modules/react-helmet": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.1.tgz", "integrity": "sha512-CnwD822LU8NDBnjCpZ4ySh8L6HYyngViTZLfBBb3NjtrpN8m49clH8hidHouq20I51Y6TpCTISCBbqiY5GamwA==", "dependencies": { "object-assign": "^4.1.1", "prop-types": "^15.5.4", "react-fast-compare": "^2.0.2", "react-side-effect": "^1.1.0" }, "peerDependencies": { "react": ">=15.0.0" } }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-jss": { "version": "8.6.1", "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==", "dependencies": { "hoist-non-react-statics": "^2.5.0", "jss": "^9.7.0", "jss-preset-default": "^4.3.0", "prop-types": "^15.6.0", "theming": "^1.3.0" }, "engines": { "node": ">=4" }, "peerDependencies": { "react": ">=0.13" } }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "node_modules/react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/react-side-effect": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-1.2.0.tgz", "integrity": "sha512-v1ht1aHg5k/thv56DRcjw+WtojuuDHFUgGfc+bFHOWsF4ZK6C2V57DO0Or0GPsg6+LSTE0M6Ry/gfzhzSwbc5w==", "dependencies": { "shallowequal": "^1.0.1" }, "peerDependencies": { "react": "^0.13.0 || ^0.14.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "dependencies": { "mute-stream": "~0.0.4" }, "engines": { "node": ">=0.8" } }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/readable-web-to-node-stream": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", "dependencies": { "readable-stream": "^3.6.0" }, "engines": { "node": ">=8" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Borewit" } }, "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "optional": true, "dependencies": { "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", "readable-stream": "^2.0.2" }, "engines": { "node": ">=0.10" } }, "node_modules/readdirp/node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "optional": true, "dependencies": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", "extend-shallow": "^2.0.1", "fill-range": "^4.0.0", "isobject": "^3.0.1", "repeat-element": "^1.1.2", "snapdragon": "^0.8.1", "snapdragon-node": "^2.0.1", "split-string": "^3.0.2", "to-regex": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "dev": true, "optional": true, "dependencies": { "debug": "^2.3.3", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "posix-character-classes": "^0.1.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/expand-brackets/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/expand-brackets/node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "optional": true, "dependencies": { "array-unique": "^0.3.2", "define-property": "^1.0.0", "expand-brackets": "^2.1.4", "extend-shallow": "^2.0.1", "fragment-cache": "^0.2.1", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/extglob/node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "dev": true, "optional": true, "dependencies": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", "repeat-string": "^1.6.1", "to-regex-range": "^2.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/readdirp/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-data-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "dependencies": { "is-plain-object": "^2.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "optional": true, "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "braces": "^2.3.1", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "extglob": "^2.0.4", "fragment-cache": "^0.2.1", "kind-of": "^6.0.2", "nanomatch": "^1.2.9", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/micromatch/node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readdirp/node_modules/to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dev": true, "optional": true, "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dependencies": { "minimatch": "^3.0.5" }, "engines": { "node": ">=6.0.0" } }, "node_modules/redux": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", "dependencies": { "@babel/runtime": "^7.9.2" } }, "node_modules/redux-thunk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", "peerDependencies": { "redux": "^4" } }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dependencies": { "regenerate": "^1.4.2" }, "engines": { "node": ">=4" } }, "node_modules/regenerator-runtime": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==", "dev": true }, "node_modules/regenerator-transform": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "dependencies": { "babel-runtime": "^6.18.0", "babel-types": "^6.19.0", "private": "^0.1.6" } }, "node_modules/regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "optional": true, "dependencies": { "is-equal-shallow": "^0.1.3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "optional": true, "dependencies": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/regex-not/node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/regex-not/node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "dependencies": { "is-plain-object": "^2.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/regex-parser": { "version": "2.2.11", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "functions-have-names": "^1.2.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", "dev": true, "dependencies": { "regenerate": "^1.2.1", "regjsgen": "^0.2.0", "regjsparser": "^0.1.4" } }, "node_modules/registry-auth-token": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", "dependencies": { "rc": "1.2.8" }, "engines": { "node": ">=6.0.0" } }, "node_modules/registry-url": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "dependencies": { "rc": "^1.2.8" }, "engines": { "node": ">=8" } }, "node_modules/regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", "dev": true }, "node_modules/regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", "dev": true, "dependencies": { "jsesc": "~0.5.0" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, "bin": { "jsesc": "bin/jsesc" } }, "node_modules/rehype-react": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-3.1.0.tgz", "integrity": "sha512-7SiLiqNudSGkvhrePkdKqdUvngZqzG+PJhdR5EeIFELz2j2ek4aO5DHbxUXYvaZfqUiBDO2Aeq1OROUmxmu+Vg==", "dependencies": { "@mapbox/hast-util-table-cell-style": "^0.1.3", "has": "^1.0.1", "hast-to-hyperscript": "^5.0.0" } }, "node_modules/rehype-react/node_modules/hast-to-hyperscript": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-5.0.0.tgz", "integrity": "sha512-DLl3eYTz8uwwzEubDUdCChsR5t5b2ne+yvHrA2h58Suq/JnN3+Gsb9Tc4iZoCCsykmFUc6UUpwxTmQXs0akSeg==", "dependencies": { "comma-separated-tokens": "^1.0.0", "property-information": "^4.0.0", "space-separated-tokens": "^1.0.0", "style-to-object": "^0.2.1", "unist-util-is": "^2.0.0", "web-namespaces": "^1.1.2" } }, "node_modules/rehype-react/node_modules/property-information": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-4.2.0.tgz", "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", "dependencies": { "xtend": "^4.0.1" } }, "node_modules/rehype-react/node_modules/style-to-object": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", "dependencies": { "inline-style-parser": "0.1.1" } }, "node_modules/rehype-react/node_modules/unist-util-is": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==" }, "node_modules/relay-runtime": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", "dependencies": { "@babel/runtime": "^7.0.0", "fbjs": "^3.0.0", "invariant": "^2.2.4" } }, "node_modules/remark": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", "dependencies": { "remark-parse": "^9.0.0", "remark-stringify": "^9.0.0", "unified": "^9.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-footnotes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz", "integrity": "sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==", "dependencies": { "mdast-util-footnote": "^0.1.0", "micromark-extension-footnote": "^0.3.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-gfm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", "dependencies": { "mdast-util-gfm": "^0.1.0", "micromark-extension-gfm": "^0.3.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-parse": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", "dependencies": { "mdast-util-from-markdown": "^0.8.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-react": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/remark-react/-/remark-react-5.0.1.tgz", "integrity": "sha512-yHv5WIh47srKfdm794UMIHjNLr6EY2YCzsqvdJ/qvN1Tq1jgyg3q8Zo9pJc4L7BwZOMTia6O2JgrJeOsJfowzA==", "dependencies": { "@mapbox/hast-util-table-cell-style": "^0.1.3", "hast-to-hyperscript": "^6.0.0", "hast-util-sanitize": "^1.0.0", "mdast-util-to-hast": "^4.0.0" } }, "node_modules/remark-react/node_modules/hast-to-hyperscript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-6.0.0.tgz", "integrity": "sha512-QnJbXddVGNJ5v3KegK1MY6luTkNDBcJnCQZcekt7AkES2z4tYy85pbFUXx7Mb0iXZBKfwoVdgfxU12GbmlwbbQ==", "dependencies": { "comma-separated-tokens": "^1.0.0", "property-information": "^5.0.0", "space-separated-tokens": "^1.0.0", "style-to-object": "^0.2.1", "unist-util-is": "^2.0.0", "web-namespaces": "^1.1.2" } }, "node_modules/remark-react/node_modules/mdast-util-definitions": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz", "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==", "dependencies": { "unist-util-visit": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-react/node_modules/mdast-util-to-hast": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-4.0.0.tgz", "integrity": "sha512-yOTZSxR1aPvWRUxVeLaLZ1sCYrK87x2Wusp1bDM/Ao2jETBhYUKITI3nHvgy+HkZW54HuCAhHnS0mTcbECD5Ig==", "dependencies": { "collapse-white-space": "^1.0.0", "detab": "^2.0.0", "mdast-util-definitions": "^1.2.0", "mdurl": "^1.0.1", "trim": "0.0.1", "trim-lines": "^1.0.0", "unist-builder": "^1.0.1", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", "unist-util-visit": "^1.1.0", "xtend": "^4.0.1" } }, "node_modules/remark-react/node_modules/style-to-object": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", "dependencies": { "inline-style-parser": "0.1.1" } }, "node_modules/remark-react/node_modules/unist-builder": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", "dependencies": { "object-assign": "^4.1.0" } }, "node_modules/remark-react/node_modules/unist-util-is": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==" }, "node_modules/remark-retext": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-retext/-/remark-retext-4.0.0.tgz", "integrity": "sha512-cYCchalpf25bTtfXF24ribYvqytPKq0TiEhqQDBHvVEEsApebwruPWP1cTcvTFBidmpXyqzycm+y8ng7Kmvc8Q==", "dependencies": { "mdast-util-to-nlcst": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-stringify": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", "dependencies": { "mdast-util-to-markdown": "^0.6.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" }, "node_modules/renderkid": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", "htmlparser2": "^6.1.0", "lodash": "^4.17.21", "strip-ansi": "^3.0.1" } }, "node_modules/renderkid/node_modules/css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, "node_modules/renderkid/node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/renderkid/node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { "domelementtype": "^2.2.0" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/renderkid/node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/renderkid/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/renderkid/node_modules/htmlparser2": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { "type": "github", "url": "https://github.com/sponsors/fb55" } ], "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", "domutils": "^2.5.2", "entities": "^2.0.0" } }, "node_modules/repeat-element": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "engines": { "node": ">=0.10" } }, "node_modules/repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", "dev": true, "dependencies": { "is-finite": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "node_modules/require-package-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz", "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==" }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dependencies": { "resolve-from": "^5.0.0" }, "engines": { "node": ">=8" } }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "engines": { "node": ">=8" } }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", "deprecated": "https://github.com/lydell/resolve-url#deprecated" }, "node_modules/resolve-url-loader": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.5.tgz", "integrity": "sha512-mgFMCmrV/tA4738EsFmPFE5/MaqSgUMe8LK971kVEKA/RrNVb7+VqFsg/qmKyythf34eyq476qIobP/gfFBGSQ==", "dependencies": { "adjust-sourcemap-loader": "3.0.0", "camelcase": "5.3.1", "compose-function": "3.0.3", "convert-source-map": "1.7.0", "es6-iterator": "2.0.3", "loader-utils": "^1.2.3", "postcss": "7.0.36", "rework": "1.0.1", "rework-visit": "1.0.0", "source-map": "0.6.1" }, "engines": { "node": ">=6.0.0" } }, "node_modules/resolve-url-loader/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/resolve-url-loader/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "engines": { "node": ">=6" } }, "node_modules/resolve-url-loader/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/resolve-url-loader/node_modules/chalk/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/resolve-url-loader/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { "color-name": "1.1.3" } }, "node_modules/resolve-url-loader/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/resolve-url-loader/node_modules/convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dependencies": { "safe-buffer": "~5.1.1" } }, "node_modules/resolve-url-loader/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } }, "node_modules/resolve-url-loader/node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "node_modules/resolve-url-loader/node_modules/loader-utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^1.0.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/resolve-url-loader/node_modules/postcss": { "version": "7.0.36", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dependencies": { "chalk": "^2.4.2", "source-map": "^0.6.1", "supports-color": "^6.1.0" }, "engines": { "node": ">=6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/postcss/" } }, "node_modules/resolve-url-loader/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/resolve-url-loader/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve-url-loader/node_modules/supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/responselike": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dependencies": { "lowercase-keys": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { "node": ">=8" } }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true, "optional": true, "engines": { "node": ">=0.12" } }, "node_modules/retext": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/retext/-/retext-7.0.1.tgz", "integrity": "sha512-N0IaEDkvUjqyfn3/gwxVfI51IxfGzOiVXqPLWnKeCDbiQdxSg0zebzHPxXWnL7TeplAJ+RE4uqrXyYN//s9HjQ==", "dependencies": { "retext-latin": "^2.0.0", "retext-stringify": "^2.0.0", "unified": "^8.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retext-english": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/retext-english/-/retext-english-3.0.4.tgz", "integrity": "sha512-yr1PgaBDde+25aJXrnt3p1jvT8FVLVat2Bx8XeAWX13KXo8OT+3nWGU3HWxM4YFJvmfqvJYJZG2d7xxaO774gw==", "dependencies": { "parse-english": "^4.0.0", "unherit": "^1.0.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retext-latin": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-2.0.4.tgz", "integrity": "sha512-fOoSSoQgDZ+l/uS81oxI3alBghDUPja0JEl0TpQxI6MN+dhM6fLFumPJwMZ4PJTyL5FFAgjlsdv8IX+6IRuwMw==", "dependencies": { "parse-latin": "^4.0.0", "unherit": "^1.0.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retext-smartypants": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-4.0.0.tgz", "integrity": "sha512-Mknd05zuIycr4Z/hNDxA8ktqv7pG7wYdTZc68a2MJF+Ibg/WloR5bbyrEjijwNwHRR+xWsovkLH4OQIz/mghdw==", "dependencies": { "nlcst-to-string": "^2.0.0", "unist-util-visit": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retext-smartypants/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retext-stringify": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-2.0.4.tgz", "integrity": "sha512-xOtx5mFJBoT3j7PBtiY2I+mEGERNniofWktI1cKXvjMEJPOuqve0dghLHO1+gz/gScLn4zqspDGv4kk2wS5kSA==", "dependencies": { "nlcst-to-string": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retext/node_modules/unified": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", "dependencies": { "bail": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "engines": { "node": ">= 4" } }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rework": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", "integrity": "sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw==", "dependencies": { "convert-source-map": "^0.3.3", "css": "^2.0.0" } }, "node_modules/rework-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==" }, "node_modules/rework/node_modules/convert-source-map": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==" }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "engines": { "node": ">=0.12.0" } }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rx": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==" }, "node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dependencies": { "tslib": "^1.9.0" }, "engines": { "npm": ">=2.0.0" } }, "node_modules/rxjs/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dev": true, "optional": true, "dependencies": { "ret": "~0.1.10" } }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "is-regex": "^1.1.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sanitize-html": { "version": "1.27.5", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.27.5.tgz", "integrity": "sha512-M4M5iXDAUEcZKLXkmk90zSYWEtk5NH3JmojQxKxV371fnMh+x9t1rqdmXaGoyEHw3z/X/8vnFhKjGL5xFGOJ3A==", "dependencies": { "htmlparser2": "^4.1.0", "lodash": "^4.17.15", "parse-srcset": "^1.0.2", "postcss": "^7.0.27" } }, "node_modules/sanitize-html/node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/sanitize-html/node_modules/dom-serializer/node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { "domelementtype": "^2.2.0" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/sanitize-html/node_modules/domhandler": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", "dependencies": { "domelementtype": "^2.0.1" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/sanitize-html/node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/sanitize-html/node_modules/domutils/node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { "domelementtype": "^2.2.0" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/sanitize-html/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/sanitize-html/node_modules/htmlparser2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^3.0.0", "domutils": "^2.0.0", "entities": "^2.0.0" } }, "node_modules/sanitize-html/node_modules/picocolors": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" }, "node_modules/sanitize-html/node_modules/postcss": { "version": "7.0.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "dependencies": { "picocolors": "^0.2.1", "source-map": "^0.6.1" }, "engines": { "node": ">=6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/postcss/" } }, "node_modules/sanitize-html/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/sass": { "version": "1.57.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { "sass": "sass.js" }, "engines": { "node": ">=12.0.0" } }, "node_modules/sass-loader": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.4.1.tgz", "integrity": "sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ==", "dependencies": { "klona": "^2.0.4", "loader-utils": "^2.0.0", "neo-async": "^2.6.2", "schema-utils": "^3.0.0", "semver": "^7.3.2" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "fibers": ">= 3.1.0", "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", "sass": "^1.3.0", "webpack": "^4.36.0 || ^5.0.0" }, "peerDependenciesMeta": { "fibers": { "optional": true }, "node-sass": { "optional": true }, "sass": { "optional": true } } }, "node_modules/sass-loader/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/sass-loader/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/sass-loader/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/sass-resources-loader": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/sass-resources-loader/-/sass-resources-loader-1.3.5.tgz", "integrity": "sha512-pCxaoRZxbKxDWhu5ZcsV7/apPYrL/z0F+25C29L4e8pajWM/4jM4hRXSRP4jEWTXo/kYIU9bEXKZZdGfjN90+Q==", "dependencies": { "async": "^2.1.4", "chalk": "^1.1.3", "glob": "^7.1.1", "loader-utils": "^1.0.4" } }, "node_modules/sass-resources-loader/node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dependencies": { "lodash": "^4.17.14" } }, "node_modules/sass-resources-loader/node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "node_modules/sass-resources-loader/node_modules/loader-utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^1.0.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/sass/node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "peer": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/sass/node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "peer": true, "engines": { "node": ">=8" } }, "node_modules/sass/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "peer": true, "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/sass/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "peer": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/sass/node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "peer": true, "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/sass/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/sass/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "peer": true, "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/sass/node_modules/immutable": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==", "peer": true }, "node_modules/sass/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "peer": true, "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/sass/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/sass/node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "peer": true, "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/sass/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/sass/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "peer": true, "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "node_modules/scheduler": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" } }, "node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" }, "engines": { "node": ">=4" } }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "bin": { "semver": "bin/semver" } }, "node_modules/semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "dependencies": { "semver": "^6.3.0" }, "engines": { "node": ">=8" } }, "node_modules/semver-diff/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "bin": { "mime": "cli.js" }, "engines": { "node": ">=4" } }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/sentence-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "node_modules/serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "optional": true, "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dependencies": { "kind-of": "^6.0.2" }, "engines": { "node": ">=8" } }, "node_modules/shallow-compare": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/shallow-compare/-/shallow-compare-1.2.2.tgz", "integrity": "sha512-LUMFi+RppPlrHzbqmFnINTrazo0lPNwhcgzuAXVVcfy/mqPDrQmHAyz5bvV0gDAuRFrk804V0HpQ6u9sZ0tBeg==" }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "node_modules/sharp": { "version": "0.30.7", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.7.tgz", "integrity": "sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==", "hasInstallScript": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.1", "node-addon-api": "^5.0.0", "prebuild-install": "^7.1.1", "semver": "^7.3.7", "simple-get": "^4.0.1", "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" }, "engines": { "node": ">=12.13.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/sharp/node_modules/detect-libc": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", "engines": { "node": ">=8" } }, "node_modules/sharp/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/sharp/node_modules/node-addon-api": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" }, "node_modules/sharp/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/sharp/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/signedsource": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==" }, "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/simple-get": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dependencies": { "is-arrayish": "^0.3.1" } }, "node_modules/simple-swizzle/node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "node_modules/sitemap": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.2.4" }, "bin": { "sitemap": "dist/cli.js" }, "engines": { "node": ">=12.0.0", "npm": ">=5.6.0" } }, "node_modules/sitemap/node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, "node_modules/slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/slugify": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.5.tgz", "integrity": "sha512-8mo9bslnBO3tr5PEVFzMPIWwWnipGS0xVbYf65zxDqfNwmzYn1LpiKNrR6DlClusuvo+hDHd1zKpmfAe83NQSQ==", "engines": { "node": ">=8.0.0" } }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "optional": true, "dependencies": { "base": "^0.11.1", "debug": "^2.2.0", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "map-cache": "^0.2.2", "source-map": "^0.5.6", "source-map-resolve": "^0.5.0", "use": "^3.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "optional": true, "dependencies": { "define-property": "^1.0.0", "isobject": "^3.0.0", "snapdragon-util": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon-node/node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon-node/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.2.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon-util/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/snapdragon-util/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/snapdragon/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/snapdragon/node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/socket.io": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", "dependencies": { "@types/cookie": "^0.4.0", "@types/cors": "^2.8.8", "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.1", "engine.io": "~4.1.0", "socket.io-adapter": "~2.1.0", "socket.io-parser": "~4.0.3" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" }, "node_modules/socket.io-client": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.3.tgz", "integrity": "sha512-4sIGOGOmCg3AOgGi7EEr6ZkTZRkrXwub70bBB/F0JSkMOUFpA77WsL87o34DffQQ31PkbMUIadGOk+3tx1KGbw==", "dependencies": { "@types/component-emitter": "^1.2.10", "backo2": "~1.0.2", "component-emitter": "~1.3.0", "debug": "~4.3.1", "engine.io-client": "~4.1.0", "parseuri": "0.0.6", "socket.io-parser": "~4.0.4" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-client/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/socket.io-client/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/socket.io-parser": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", "dependencies": { "@types/component-emitter": "^1.2.10", "component-emitter": "~1.3.0", "debug": "~4.3.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-parser/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/socket.io-parser/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/socket.io/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/socket.io/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", "urix": "^0.1.0" } }, "node_modules/source-map-support": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "dependencies": { "source-map": "^0.5.6" } }, "node_modules/source-map-url": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "deprecated": "See https://github.com/lydell/source-map-url#deprecated" }, "node_modules/space-separated-tokens": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/split-on-first": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", "engines": { "node": ">=6" } }, "node_modules/split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "optional": true, "dependencies": { "extend-shallow": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/split-string/node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/split-string/node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "dependencies": { "is-plain-object": "^2.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/sponge-case": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/st": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/st/-/st-2.0.0.tgz", "integrity": "sha512-drN+aGYnrZPNYIymmNwIY7LXYJ8MqsqXj4fMRue3FOgGMdGjSX10fhJ3qx0sVQPhcWxhEaN4U/eWM4O4dbYNAw==", "dependencies": { "async-cache": "^1.1.0", "bl": "^4.0.0", "fd": "~0.0.2", "mime": "^2.4.4", "negotiator": "~0.6.2" }, "bin": { "st": "bin/server.js" }, "optionalDependencies": { "graceful-fs": "^4.2.3" } }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "engines": { "node": "*" } }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" }, "node_modules/static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", "dev": true, "optional": true, "dependencies": { "define-property": "^0.2.5", "object-copy": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "dependencies": { "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/static-extend/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/static-extend/node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { "node": ">= 0.8" } }, "node_modules/stream-parser": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", "dependencies": { "debug": "2" } }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "engines": { "node": ">=10.0.0" } }, "node_modules/strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", "engines": { "node": ">=4" } }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" }, "node_modules/string-similarity": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.2.tgz", "integrity": "sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==", "dependencies": { "lodash.every": "^4.6.0", "lodash.flattendeep": "^4.4.0", "lodash.foreach": "^4.5.0", "lodash.map": "^4.6.0", "lodash.maxby": "^4.6.0" } }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/string-width/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "get-intrinsic": "^1.1.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "regexp.prototype.flags": "^1.4.3", "side-channel": "^1.0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimend": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/stringify-entities": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz", "integrity": "sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg==", "dependencies": { "character-entities-html4": "^1.0.0", "character-entities-legacy": "^1.0.0", "xtend": "^4.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", "is-regexp": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/stringify-object/node_modules/is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "engines": { "node": ">=0.10.0" } }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "engines": { "node": ">=4" } }, "node_modules/strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", "engines": { "node": ">=0.10.0" } }, "node_modules/strip-comments": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", "dependencies": { "babel-extract-comments": "^1.0.0", "babel-plugin-transform-object-rest-spread": "^6.26.0" }, "engines": { "node": ">=4" } }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", "engines": { "node": ">=0.10.0" } }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "engines": { "node": ">=6" } }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", "dependencies": { "escape-string-regexp": "^1.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/strtok3": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" }, "engines": { "node": ">=10" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Borewit" } }, "node_modules/style-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/style-to-object": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", "dependencies": { "inline-style-parser": "0.1.1" } }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", "dependencies": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "node_modules/sudo-prompt": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-8.2.5.tgz", "integrity": "sha512-rlBo3HU/1zAJUrkY6jNxDOC9eVYliG6nS4JA8u8KAshITd07tafMc/Br7xQwCSseXwJ2iCcHCE8SNWX3q8Z+kw==" }, "node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "engines": { "node": ">=0.8.0" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/svg-react-loader": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/svg-react-loader/-/svg-react-loader-0.4.6.tgz", "integrity": "sha512-HVEypjWQsQuJdBIPzXGxpmQsQts7QwfQuYgK1rah6BVCMoLNSCh/ESKVNd7/tHq8DkWYHHTyaUMDA1FjqZYrgA==", "dependencies": { "css": "2.2.4", "loader-utils": "1.1.0", "ramda": "0.21.0", "rx": "4.1.0", "traverse": "0.6.6", "xml2js": "0.4.17" } }, "node_modules/svg-react-loader/node_modules/big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "engines": { "node": "*" } }, "node_modules/svg-react-loader/node_modules/emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", "engines": { "node": ">= 0.10" } }, "node_modules/svg-react-loader/node_modules/json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "bin": { "json5": "lib/cli.js" } }, "node_modules/svg-react-loader/node_modules/loader-utils": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha512-gkD9aSEG9UGglyPcDJqY9YBTUtCLKaBK6ihD2VP1d1X60lTfFspNZNulGBBbUZLkPygy4LySYHyxBpq+VhjObQ==", "dependencies": { "big.js": "^3.1.3", "emojis-list": "^2.0.0", "json5": "^0.5.0" }, "engines": { "node": ">=4.0.0" } }, "node_modules/svgo": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", "stable": "^0.1.8" }, "bin": { "svgo": "bin/svgo" }, "engines": { "node": ">=10.13.0" } }, "node_modules/svgo/node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "engines": { "node": ">= 10" } }, "node_modules/svgo/node_modules/css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, "node_modules/svgo/node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/svgo/node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { "domelementtype": "^2.2.0" }, "engines": { "node": ">= 4" }, "funding": { "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/svgo/node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/svgo/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/swap-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", "string-width": "^4.2.3", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/table/node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/table/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/table/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "engines": { "node": ">=6" } }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" }, "engines": { "node": ">=6" } }, "node_modules/tar-stream/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/terser": { "version": "5.16.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" }, "engines": { "node": ">=10" } }, "node_modules/terser-webpack-plugin": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", "dependencies": { "@jridgewell/trace-mapping": "^0.3.14", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", "terser": "^5.14.1" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^5.1.0" }, "peerDependenciesMeta": { "@swc/core": { "optional": true }, "esbuild": { "optional": true }, "uglify-js": { "optional": true } } }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/terser/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/terser/node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/theming": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz", "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==", "dependencies": { "brcast": "^3.0.1", "is-function": "^1.0.1", "is-plain-object": "^2.0.1", "prop-types": "^15.5.8" }, "peerDependencies": { "react": ">=0.15" } }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", "dependencies": { "es5-ext": "~0.10.46", "next-tick": "1" } }, "node_modules/tippy.js": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-4.3.5.tgz", "integrity": "sha512-NDq3efte8nGK6BOJ1dDN1/WelAwfmh3UtIYXXck6+SxLzbIQNZE/cmRSnwScZ/FyiKdIcvFHvYUgqmoGx8CcyA==", "dependencies": { "popper.js": "^1.14.7" } }, "node_modules/title-case": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dependencies": { "rimraf": "^3.0.0" }, "engines": { "node": ">=8.17.0" } }, "node_modules/tmp/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "dev": true, "optional": true, "dependencies": { "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/to-object-path/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "node_modules/to-object-path/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "engines": { "node": ">=6" } }, "node_modules/to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "optional": true, "dependencies": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "regex-not": "^1.0.2", "safe-regex": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/to-regex-range/node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { "node": ">=0.12.0" } }, "node_modules/to-regex/node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/to-regex/node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "dependencies": { "is-plain-object": "^2.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { "node": ">=0.6" } }, "node_modules/token-types": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" }, "engines": { "node": ">=10" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Borewit" } }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" }, "node_modules/trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" }, "node_modules/trim-lines": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.3.tgz", "integrity": "sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", "dependencies": { "escape-string-regexp": "^1.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/true-case-path": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.1", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tsconfig-paths/node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "node_modules/tslib": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dependencies": { "tslib": "^1.8.1" }, "engines": { "node": ">= 6" }, "peerDependencies": { "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dependencies": { "safe-buffer": "^5.0.1" }, "engines": { "node": "*" } }, "node_modules/type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dependencies": { "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" }, "engines": { "node": ">= 0.6" } }, "node_modules/type-of": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-of/-/type-of-2.0.1.tgz", "integrity": "sha512-39wxbwHdQ2sTiBB8wAzKfQ9GN+om8w+sjNWzr+vZJR5AMD5J+J7Yc8AtXnU9r/r2c8XiDZ/smxutDmZehX/qpQ==" }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", "is-typed-array": "^1.1.9" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=4.2.0" } }, "node_modules/ua-parser-js": { "version": "0.7.32", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/ua-parser-js" }, { "type": "paypal", "url": "https://paypal.me/faisalman" } ], "engines": { "node": "*" } }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "engines": { "node": ">=0.10.0" } }, "node_modules/underscore.string": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", "dependencies": { "sprintf-js": "^1.1.1", "util-deprecate": "^1.0.2" }, "engines": { "node": "*" } }, "node_modules/underscore.string/node_modules/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" }, "node_modules/unherit": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", "dependencies": { "inherits": "^2.0.0", "xtend": "^4.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "engines": { "node": ">=4" } }, "node_modules/unified": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", "dependencies": { "bail": "^1.0.0", "extend": "^3.0.0", "is-buffer": "^2.0.0", "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "optional": true, "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dependencies": { "crypto-random-string": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/unist-builder": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-generated": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-is": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-modify-children": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-2.0.0.tgz", "integrity": "sha512-HGrj7JQo9DwZt8XFsX8UD4gGqOsIlCih9opG6Y+N11XqkBGKzHo8cvDi+MfQQgiZ7zXRUiQREYHhjOBHERTMdg==", "dependencies": { "array-iterate": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-position": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-remove": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-1.0.3.tgz", "integrity": "sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g==", "dependencies": { "unist-util-is": "^3.0.0" } }, "node_modules/unist-util-remove-position": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-3.0.0.tgz", "integrity": "sha512-17kIOuolVuK16LMb9KyMJlqdfCtlfQY5FjY3Sdo9iC7F5wqdXhNjMq0PBvMpkVNNnAmHxXssUW+rZ9T2zbP0Rg==", "dependencies": { "unist-util-visit": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-remove-position/node_modules/unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-remove/node_modules/unist-util-is": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" }, "node_modules/unist-util-select": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-3.0.4.tgz", "integrity": "sha512-xf1zCu4okgPqGLdhCDpRnjwBNyv3EqjiXRUbz2SdK1+qnLMB7uXXajfzuBvvbHoQ+JLyp4AEbFCGndmc6S72sw==", "dependencies": { "css-selector-parser": "^1.0.0", "not": "^0.1.0", "nth-check": "^2.0.0", "unist-util-is": "^4.0.0", "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dependencies": { "@types/unist": "^2.0.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-visit": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", "dependencies": { "unist-util-visit-parents": "^2.0.0" } }, "node_modules/unist-util-visit-children": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-1.1.4.tgz", "integrity": "sha512-sA/nXwYRCQVRwZU2/tQWUqJ9JSFM1X3x7JIOsIgSzrFHcfVt6NkzDtKzyxg2cZWkCwGF9CO8x4QNZRJRMK8FeQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-visit-parents": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-visit/node_modules/unist-util-is": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" }, "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", "dependencies": { "unist-util-is": "^3.0.0" } }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "engines": { "node": ">= 10.0.0" } }, "node_modules/unixify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", "dependencies": { "normalize-path": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } }, "node_modules/unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dev": true, "optional": true, "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/unset-value/node_modules/has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", "dev": true, "optional": true, "dependencies": { "get-value": "^2.0.3", "has-values": "^0.1.4", "isobject": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dev": true, "optional": true, "dependencies": { "isarray": "1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/unset-value/node_modules/has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/unset-value/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" } ], "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" }, "bin": { "browserslist-lint": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" } }, "node_modules/update-notifier": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", "dependencies": { "boxen": "^5.0.0", "chalk": "^4.1.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", "is-installed-globally": "^0.4.0", "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", "latest-version": "^5.1.0", "pupa": "^2.1.1", "semver": "^7.3.4", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, "node_modules/update-notifier/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/update-notifier/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/update-notifier/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/update-notifier/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/update-notifier/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/update-notifier/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/upper-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/upper-case-first": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", "deprecated": "Please see https://github.com/lydell/urix#deprecated" }, "node_modules/url-loader": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", "dependencies": { "loader-utils": "^2.0.0", "mime-types": "^2.1.27", "schema-utils": "^3.0.0" }, "engines": { "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "file-loader": "*", "webpack": "^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { "file-loader": { "optional": true } } }, "node_modules/url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dependencies": { "prepend-http": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true, "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha512-aggiKfEEubv3UwRNqTzLInZpAOmKzwdHqEBmW/hBA/mt99eg+b4VrX6i+IRLxU8+WJYfa33rGwRseg4eElUgsQ==", "dev": true, "bin": { "user-home": "cli.js" }, "engines": { "node": ">=0.10.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "node_modules/utility-types": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", "engines": { "node": ">= 4" } }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "node_modules/v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "integrity": "sha512-SKfhk/LlaXzvtowJabLZwD4K6SGRYeoxA7KJeISlUMAB/NT4CBkZjMq3WceX2Ckm4llwqYVo8TICgsDYCBU2tA==", "dev": true, "dependencies": { "user-home": "^1.1.1" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/valid-url": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" }, "node_modules/value-or-promise": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==", "engines": { "node": ">=12" } }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } }, "node_modules/vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/vfile-location": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/vfile-message": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" }, "engines": { "node": ">=10.13.0" } }, "node_modules/weak-lru-cache": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==" }, "node_modules/web-namespaces": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/web-vitals": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.2.tgz", "integrity": "sha512-PFMKIY+bRSXlMxVAQ+m2aw9c/ioUYfDgrYot0YUa+/xa0sakubWhSDyxAKwzymvXVdF4CZI71g06W+mqhzu6ig==" }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { "version": "5.75.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.10.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.9", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.1.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "bin": { "webpack": "bin/webpack.js" }, "engines": { "node": ">=10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependenciesMeta": { "webpack-cli": { "optional": true } } }, "node_modules/webpack-dev-middleware": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz", "integrity": "sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==", "dependencies": { "colorette": "^1.2.2", "mem": "^8.1.1", "memfs": "^3.2.2", "mime-types": "^2.1.30", "range-parser": "^1.2.1", "schema-utils": "^3.0.0" }, "engines": { "node": ">= v10.23.3" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/webpack-merge": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dependencies": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", "dependencies": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" } }, "node_modules/webpack-sources/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { "node": ">=0.10.0" } }, "node_modules/webpack-stats-plugin": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/webpack-stats-plugin/-/webpack-stats-plugin-1.1.1.tgz", "integrity": "sha512-aWwE/YuO2W7VCOyWwyDJ7BRSYRYjeXat+X31YiasMM3FS6/4X9W4Mb9Q0g+jIdVgArr1Mb08sHBJKMT5M9+gVA==" }, "node_modules/webpack-virtual-modules": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.3.2.tgz", "integrity": "sha512-RXQXioY6MhzM4CNQwmBwKXYgBs6ulaiQ8bkNQEl2J6Z+V+s7lgl/wGvaI/I0dLnYKB8cKsxQc17QOAVIphPLDw==", "dependencies": { "debug": "^3.0.0" } }, "node_modules/webpack-virtual-modules/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } }, "node_modules/webpack-virtual-modules/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/webpack/node_modules/@types/estree": { "version": "0.0.51", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, "node_modules/webpack/node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "engines": { "node": ">=10.13.0" } }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "node_modules/which-typed-array": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0", "is-typed-array": "^1.1.10" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dependencies": { "string-width": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/workbox-background-sync": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-broadcast-update": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-build": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", "dependencies": { "@babel/runtime": "^7.3.4", "@hapi/joi": "^15.0.0", "common-tags": "^1.8.0", "fs-extra": "^4.0.2", "glob": "^7.1.3", "lodash.template": "^4.4.0", "pretty-bytes": "^5.1.0", "stringify-object": "^3.3.0", "strip-comments": "^1.0.2", "workbox-background-sync": "^4.3.1", "workbox-broadcast-update": "^4.3.1", "workbox-cacheable-response": "^4.3.1", "workbox-core": "^4.3.1", "workbox-expiration": "^4.3.1", "workbox-google-analytics": "^4.3.1", "workbox-navigation-preload": "^4.3.1", "workbox-precaching": "^4.3.1", "workbox-range-requests": "^4.3.1", "workbox-routing": "^4.3.1", "workbox-strategies": "^4.3.1", "workbox-streams": "^4.3.1", "workbox-sw": "^4.3.1", "workbox-window": "^4.3.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/workbox-build/node_modules/fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "node_modules/workbox-build/node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/workbox-build/node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "engines": { "node": ">= 4.0.0" } }, "node_modules/workbox-cacheable-response": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-core": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==" }, "node_modules/workbox-expiration": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-google-analytics": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", "dependencies": { "workbox-background-sync": "^4.3.1", "workbox-core": "^4.3.1", "workbox-routing": "^4.3.1", "workbox-strategies": "^4.3.1" } }, "node_modules/workbox-navigation-preload": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-precaching": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-range-requests": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-routing": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-strategies": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-streams": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/workbox-sw": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==" }, "node_modules/workbox-window": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", "dependencies": { "workbox-core": "^4.3.1" } }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "engines": { "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "engines": { "node": ">=8" } }, "node_modules/xml2js": { "version": "0.4.17", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", "integrity": "sha512-1O7wk/NTQN0UEOItIYTxK4qP4sMUVU60MbF4Nj0a8jd6eebMXOicVI/KFOEsYKKH4uBpx6XG9ZGZctXK5rtO5Q==", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "^4.1.0" } }, "node_modules/xmlbuilder": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", "integrity": "sha512-oEePiEefhQhAeUnwRnIBLBWmk/fsWWbQ53EEWsRuzECbQ3m5o/Esmq6H47CYYwSLW+Ynt0rS9hd0pd2ogMAWjg==", "dependencies": { "lodash": "^4.0.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/xmlhttprequest-ssl": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", "engines": { "node": ">=0.4.0" } }, "node_modules/xss": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", "dependencies": { "commander": "^2.20.3", "cssfilter": "0.0.10" }, "bin": { "xss": "bin/xss" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/xstate": { "version": "4.32.1", "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.32.1.tgz", "integrity": "sha512-QYUd+3GkXZ8i6qdixnOn28bL3EvA++LONYL/EMWwKlFSh/hiLndJ8YTnz77FDs+JUXcwU7NZJg7qoezoRHc4GQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/xstate" } }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "engines": { "node": ">=0.4" } }, "node_modules/xxhash-wasm": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==" }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "engines": { "node": ">= 6" } }, "node_modules/yaml-loader": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/yaml-loader/-/yaml-loader-0.8.0.tgz", "integrity": "sha512-LjeKnTzVBKWiQBeE2L9ssl6WprqaUIxCSNs5tle8PaDydgu3wVFXTbMfsvF2MSErpy9TDVa092n4q6adYwJaWg==", "dependencies": { "javascript-stringify": "^2.0.1", "loader-utils": "^2.0.0", "yaml": "^2.0.0" }, "engines": { "node": ">= 12.13" } }, "node_modules/yaml-loader/node_modules/yaml": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", "engines": { "node": ">= 14" } }, "node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" }, "engines": { "node": ">=8" } }, "node_modules/yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" }, "engines": { "node": ">=6" } }, "node_modules/yargs-parser/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "engines": { "node": ">=6" } }, "node_modules/yargs/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs/node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, "node_modules/yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==" }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yoga-layout-prebuilt": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", "dependencies": { "@types/yoga-layout": "1.9.2" }, "engines": { "node": ">=8" } }, "node_modules/yurnalist": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/yurnalist/-/yurnalist-2.1.0.tgz", "integrity": "sha512-PgrBqosQLM3gN2xBFIMDLACRTV9c365VqityKKpSTWpwR+U4LAFR3rSVyEoscWlu3EzX9+Y0I86GXUKxpHFl6w==", "dependencies": { "chalk": "^2.4.2", "inquirer": "^7.0.0", "is-ci": "^2.0.0", "read": "^1.0.7", "strip-ansi": "^5.2.0" }, "engines": { "node": ">=4.0.0" } }, "node_modules/yurnalist/node_modules/ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "engines": { "node": ">=6" } }, "node_modules/yurnalist/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/yurnalist/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/yurnalist/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { "color-name": "1.1.3" } }, "node_modules/yurnalist/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/yurnalist/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } }, "node_modules/yurnalist/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } }, "node_modules/yurnalist/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } } }, "dependencies": { "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" } }, "@ardatan/relay-compiler": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", "requires": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", "@babel/parser": "^7.14.0", "@babel/runtime": "^7.0.0", "@babel/traverse": "^7.14.0", "@babel/types": "^7.0.0", "babel-preset-fbjs": "^3.4.0", "chalk": "^4.0.0", "fb-watchman": "^2.0.0", "fbjs": "^3.0.0", "glob": "^7.1.1", "immutable": "~3.7.6", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "relay-runtime": "12.0.0", "signedsource": "^1.0.0", "yargs": "^15.3.1" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "requires": { "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { "version": "7.20.10", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==" }, "@babel/core": { "version": "7.20.12", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", "@babel/generator": "^7.20.7", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-module-transforms": "^7.20.11", "@babel/helpers": "^7.20.7", "@babel/parser": "^7.20.7", "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.12", "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", "semver": "^6.3.0" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@babel/eslint-parser": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", "semver": "^6.3.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@babel/generator": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "requires": { "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" } } }, "@babel/helper-annotate-as-pure": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "requires": { "@babel/helper-explode-assignable-expression": "^7.18.6", "@babel/types": "^7.18.9" } }, "@babel/helper-compilation-targets": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "requires": { "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@babel/helper-create-class-features-plugin": { "version": "7.20.12", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/helper-split-export-declaration": "^7.18.6" } }, "@babel/helper-create-regexp-features-plugin": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "regexpu-core": "^5.2.1" }, "dependencies": { "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" }, "regexpu-core": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "requires": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" } }, "regjsgen": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" }, "regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "requires": { "jsesc": "~0.5.0" } } } }, "@babel/helper-define-polyfill-provider": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "requires": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" }, "@babel/helper-explode-assignable-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-function-name": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "requires": { "@babel/template": "^7.18.10", "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-member-expression-to-functions": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", "requires": { "@babel/types": "^7.20.7" } }, "@babel/helper-module-imports": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-module-transforms": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.10", "@babel/types": "^7.20.7" } }, "@babel/helper-optimise-call-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-plugin-utils": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" }, "@babel/helper-remap-async-to-generator": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-wrap-function": "^7.18.9", "@babel/types": "^7.18.9" } }, "@babel/helper-replace-supers": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.7", "@babel/types": "^7.20.7" } }, "@babel/helper-simple-access": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "requires": { "@babel/types": "^7.20.2" } }, "@babel/helper-skip-transparent-expression-wrappers": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "requires": { "@babel/types": "^7.20.0" } }, "@babel/helper-split-export-declaration": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-string-parser": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" }, "@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helper-validator-option": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" }, "@babel/helper-wrap-function": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "requires": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", "@babel/traverse": "^7.20.5", "@babel/types": "^7.20.5" } }, "@babel/helpers": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "requires": { "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.7", "@babel/types": "^7.20.7" } }, "@babel/highlight": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "requires": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "^1.9.0" } }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { "has-flag": "^3.0.0" } } } }, "@babel/parser": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-proposal-optional-chaining": "^7.20.7" } }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "requires": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-proposal-class-static-block": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", "requires": { "@babel/helper-create-class-features-plugin": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-namespace-from": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "requires": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "requires": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "requires": { "@babel/compat-data": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.20.7" } }, "@babel/plugin-proposal-optional-catch-binding": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "requires": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-proposal-private-property-in-object": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "requires": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-class-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "requires": { "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-syntax-class-static-block": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "requires": { "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "requires": { "@babel/helper-plugin-utils": "^7.8.3" } }, "@babel/plugin-syntax-flow": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-syntax-import-assertions": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "requires": { "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-jsx": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "requires": { "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "requires": { "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-typescript": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "requires": { "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-arrow-functions": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-async-to-generator": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "requires": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-remap-async-to-generator": "^7.18.9" } }, "@babel/plugin-transform-block-scoped-functions": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-block-scoping": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-classes": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" }, "dependencies": { "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" } } }, "@babel/plugin-transform-computed-properties": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/template": "^7.20.7" } }, "@babel/plugin-transform-destructuring": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-dotall-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "requires": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-duplicate-keys": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "requires": { "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-exponentiation-operator": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-flow-strip-types": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", "requires": { "@babel/helper-plugin-utils": "^7.19.0", "@babel/plugin-syntax-flow": "^7.18.6" } }, "@babel/plugin-transform-for-of": { "version": "7.18.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-function-name": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "requires": { "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-function-name": "^7.18.9", "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-literals": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "requires": { "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-member-expression-literals": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-modules-amd": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "requires": { "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-modules-commonjs": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", "requires": { "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-simple-access": "^7.20.2" } }, "@babel/plugin-transform-modules-systemjs": { "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "requires": { "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-identifier": "^7.19.1" } }, "@babel/plugin-transform-modules-umd": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "requires": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "requires": { "@babel/helper-create-regexp-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-new-target": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-object-super": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-replace-supers": "^7.18.6" } }, "@babel/plugin-transform-parameters": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-property-literals": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-react-display-name": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-react-jsx": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz", "integrity": "sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7" } }, "@babel/plugin-transform-react-jsx-development": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", "requires": { "@babel/plugin-transform-react-jsx": "^7.18.6" } }, "@babel/plugin-transform-react-pure-annotations": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-regenerator": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2", "regenerator-transform": "^0.15.1" }, "dependencies": { "regenerator-transform": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "requires": { "@babel/runtime": "^7.8.4" } } } }, "@babel/plugin-transform-reserved-words": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-runtime": { "version": "7.19.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", "requires": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.19.0", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", "semver": "^6.3.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-spread": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "requires": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" } }, "@babel/plugin-transform-sticky-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-template-literals": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "requires": { "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-typeof-symbol": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "requires": { "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-typescript": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz", "integrity": "sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw==", "requires": { "@babel/helper-create-class-features-plugin": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" } }, "@babel/plugin-transform-unicode-escapes": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "requires": { "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-unicode-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "requires": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/preset-env": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", "requires": { "@babel/compat-data": "^7.20.1", "@babel/helper-compilation-targets": "^7.20.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", "@babel/plugin-proposal-async-generator-functions": "^7.20.1", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-static-block": "^7.18.6", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", "@babel/plugin-proposal-object-rest-spread": "^7.20.2", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.18.6", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.20.0", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-transform-arrow-functions": "^7.18.6", "@babel/plugin-transform-async-to-generator": "^7.18.6", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", "@babel/plugin-transform-block-scoping": "^7.20.2", "@babel/plugin-transform-classes": "^7.20.2", "@babel/plugin-transform-computed-properties": "^7.18.9", "@babel/plugin-transform-destructuring": "^7.20.2", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", "@babel/plugin-transform-for-of": "^7.18.8", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", "@babel/plugin-transform-modules-amd": "^7.19.6", "@babel/plugin-transform-modules-commonjs": "^7.19.6", "@babel/plugin-transform-modules-systemjs": "^7.19.6", "@babel/plugin-transform-modules-umd": "^7.18.6", "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", "@babel/plugin-transform-parameters": "^7.20.1", "@babel/plugin-transform-property-literals": "^7.18.6", "@babel/plugin-transform-regenerator": "^7.18.6", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", "@babel/plugin-transform-spread": "^7.19.0", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", "@babel/types": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", "core-js-compat": "^3.25.1", "semver": "^6.3.0" }, "dependencies": { "core-js-compat": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz", "integrity": "sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==", "requires": { "browserslist": "^4.21.4" } }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@babel/preset-modules": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" } }, "@babel/preset-react": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-transform-react-display-name": "^7.18.6", "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/plugin-transform-react-jsx-development": "^7.18.6", "@babel/plugin-transform-react-pure-annotations": "^7.18.6" } }, "@babel/preset-typescript": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-transform-typescript": "^7.18.6" } }, "@babel/runtime": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz", "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==", "requires": { "regenerator-runtime": "^0.13.11" }, "dependencies": { "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" } } }, "@babel/runtime-corejs3": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz", "integrity": "sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==", "requires": { "core-js-pure": "^3.25.1", "regenerator-runtime": "^0.13.11" }, "dependencies": { "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" } } }, "@babel/template": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "requires": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7" } }, "@babel/traverse": { "version": "7.20.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", "requires": { "@babel/code-frame": "^7.18.6", "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "@babel/types": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "requires": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "dependencies": { "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" } } }, "@builder.io/partytown": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/@builder.io/partytown/-/partytown-0.5.4.tgz", "integrity": "sha512-qnikpQgi30AS01aFlNQV6l8/qdZIcP76mp90ti+u4rucXHsn4afSKivQXApqxvrQG9+Ibv45STyvHizvxef/7A==" }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "globals": { "version": "13.19.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "requires": { "type-fest": "^0.20.2" } }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "@gatsbyjs/parcel-namer-relative-to-cwd": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@gatsbyjs/parcel-namer-relative-to-cwd/-/parcel-namer-relative-to-cwd-1.10.0.tgz", "integrity": "sha512-JSiOxG2SD64joKfcCOdujIpqmhs+k5Ic1sO/hQ83EVF6G9DJJTf8n12rGb2rzPb00TFT4ldb/nWxQRV+kQTlPA==", "requires": { "@babel/runtime": "^7.18.0", "@parcel/namer-default": "2.6.2", "@parcel/plugin": "2.6.2", "gatsby-core-utils": "^3.25.0" } }, "@gatsbyjs/reach-router": { "version": "1.3.9", "resolved": "https://registry.npmjs.org/@gatsbyjs/reach-router/-/reach-router-1.3.9.tgz", "integrity": "sha512-/354IaUSM54xb7K/TxpLBJB94iEAJ3P82JD38T8bLnIDWF+uw8+W/82DKnQ7y24FJcKxtVmG43aiDLG88KSuYQ==", "requires": { "invariant": "^2.2.3", "prop-types": "^15.6.1", "react-lifecycles-compat": "^3.0.4" } }, "@gatsbyjs/webpack-hot-middleware": { "version": "2.25.3", "resolved": "https://registry.npmjs.org/@gatsbyjs/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz", "integrity": "sha512-ul17OZ8Dlw+ATRbnuU+kwxuAlq9lKbYz/2uBS1FLCdgoPTF1H2heP7HbUbgfMZbfRQNcCG2rMscMnr32ritCDw==", "requires": { "ansi-html-community": "0.0.8", "html-entities": "^2.3.3", "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } } } }, "@graphql-codegen/add": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-3.2.3.tgz", "integrity": "sha512-sQOnWpMko4JLeykwyjFTxnhqjd/3NOG2OyMuvK76Wnnwh8DRrNf2VEs2kmSvLl7MndMlOj7Kh5U154dVcvhmKQ==", "requires": { "@graphql-codegen/plugin-helpers": "^3.1.1", "tslib": "~2.4.0" }, "dependencies": { "@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "requires": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" } }, "change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } } } }, "@graphql-codegen/core": { "version": "2.6.8", "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.8.tgz", "integrity": "sha512-JKllNIipPrheRgl+/Hm/xuWMw9++xNQ12XJR/OHHgFopOg4zmN3TdlRSyYcv/K90hCFkkIwhlHFUQTfKrm8rxQ==", "requires": { "@graphql-codegen/plugin-helpers": "^3.1.1", "@graphql-tools/schema": "^9.0.0", "@graphql-tools/utils": "^9.1.1", "tslib": "~2.4.0" }, "dependencies": { "@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "requires": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" } }, "change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } } } }, "@graphql-codegen/plugin-helpers": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz", "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==", "requires": { "@graphql-tools/utils": "^8.8.0", "change-case-all": "1.0.14", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" }, "dependencies": { "@graphql-tools/utils": { "version": "8.13.1", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz", "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==", "requires": { "tslib": "^2.4.0" } } } }, "@graphql-codegen/schema-ast": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.6.1.tgz", "integrity": "sha512-5TNW3b1IHJjCh07D2yQNGDQzUpUl2AD+GVe1Dzjqyx/d2Fn0TPMxLsHsKPS4Plg4saO8FK/QO70wLsP7fdbQ1w==", "requires": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-tools/utils": "^9.0.0", "tslib": "~2.4.0" }, "dependencies": { "@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "requires": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" } }, "change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } } } }, "@graphql-codegen/typescript": { "version": "2.8.7", "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.8.7.tgz", "integrity": "sha512-Nm5keWqIgg/VL7fivGmglF548tJRP2ttSmfTMuAdY5GNGTJTVZOzNbIOfnbVEDMMWF4V+quUuSyeUQ6zRxtX1w==", "requires": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-codegen/schema-ast": "^2.6.1", "@graphql-codegen/visitor-plugin-common": "2.13.7", "auto-bind": "~4.0.0", "tslib": "~2.4.0" }, "dependencies": { "@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "requires": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" } }, "change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } } } }, "@graphql-codegen/typescript-operations": { "version": "2.5.12", "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-2.5.12.tgz", "integrity": "sha512-/w8IgRIQwmebixf514FOQp2jXOe7vxZbMiSFoQqJgEgzrr42joPsgu4YGU+owv2QPPmu4736OcX8FSavb7SLiA==", "requires": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-codegen/typescript": "^2.8.7", "@graphql-codegen/visitor-plugin-common": "2.13.7", "auto-bind": "~4.0.0", "tslib": "~2.4.0" }, "dependencies": { "@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "requires": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" } }, "change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } } } }, "@graphql-codegen/visitor-plugin-common": { "version": "2.13.7", "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.7.tgz", "integrity": "sha512-xE6iLDhr9sFM1qwCGJcCXRu5MyA0moapG2HVejwyAXXLubYKYwWnoiEigLH2b5iauh6xsl6XP8hh9D1T1dn5Cw==", "requires": { "@graphql-codegen/plugin-helpers": "^3.1.2", "@graphql-tools/optimize": "^1.3.0", "@graphql-tools/relay-operation-optimizer": "^6.5.0", "@graphql-tools/utils": "^9.0.0", "auto-bind": "~4.0.0", "change-case-all": "1.0.15", "dependency-graph": "^0.11.0", "graphql-tag": "^2.11.0", "parse-filepath": "^1.0.2", "tslib": "~2.4.0" }, "dependencies": { "@graphql-codegen/plugin-helpers": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz", "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==", "requires": { "@graphql-tools/utils": "^9.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.4.0" } }, "change-case-all": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } } } }, "@graphql-tools/code-file-loader": { "version": "7.3.15", "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.15.tgz", "integrity": "sha512-cF8VNc/NANTyVSIK8BkD/KSXRF64DvvomuJ0evia7tJu4uGTXgDjimTMWsTjKRGOOBSTEbL6TA8e4DdIYq6Udw==", "requires": { "@graphql-tools/graphql-tag-pluck": "7.4.2", "@graphql-tools/utils": "9.1.3", "globby": "^11.0.3", "tslib": "^2.4.0", "unixify": "^1.0.0" } }, "@graphql-tools/graphql-tag-pluck": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.4.2.tgz", "integrity": "sha512-SXM1wR5TExrxocQTxZK5r74jTbg8GxSYLY3mOPCREGz6Fu7PNxMxfguUzGUAB43Mf44Dn8oVztzd2eitv2Qgww==", "requires": { "@babel/parser": "^7.16.8", "@babel/plugin-syntax-import-assertions": "7.20.0", "@babel/traverse": "^7.16.8", "@babel/types": "^7.16.8", "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0" } }, "@graphql-tools/load": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-7.8.8.tgz", "integrity": "sha512-gMuQdO2jXmI0BNUc1MafxRQTWVMUtuH500pZAQtOdDdNJppV7lJdY6mMhITQ2qnhYDuMrcZPHhIkcftyQfkgUg==", "requires": { "@graphql-tools/schema": "9.0.12", "@graphql-tools/utils": "9.1.3", "p-limit": "3.1.0", "tslib": "^2.4.0" } }, "@graphql-tools/merge": { "version": "8.3.14", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.14.tgz", "integrity": "sha512-zV0MU1DnxJLIB0wpL4N3u21agEiYFsjm6DI130jqHpwF0pR9HkF+Ni65BNfts4zQelP0GjkHltG+opaozAJ1NA==", "requires": { "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0" } }, "@graphql-tools/optimize": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.3.1.tgz", "integrity": "sha512-5j5CZSRGWVobt4bgRRg7zhjPiSimk+/zIuColih8E8DxuFOaJ+t0qu7eZS5KXWBkjcd4BPNuhUPpNlEmHPqVRQ==", "requires": { "tslib": "^2.4.0" } }, "@graphql-tools/relay-operation-optimizer": { "version": "6.5.14", "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.14.tgz", "integrity": "sha512-RAy1fMfXig9X3gIkYnfEmv0mh20vZuAgWDq+zf1MrrsCAP364B+DKrBjLwn3D+4e0PMTlqwmqR0JB5t1VtZn2w==", "requires": { "@ardatan/relay-compiler": "12.0.0", "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0" } }, "@graphql-tools/schema": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.12.tgz", "integrity": "sha512-DmezcEltQai0V1y96nwm0Kg11FDS/INEFekD4nnVgzBqawvznWqK6D6bujn+cw6kivoIr3Uq//QmU/hBlBzUlQ==", "requires": { "@graphql-tools/merge": "8.3.14", "@graphql-tools/utils": "9.1.3", "tslib": "^2.4.0", "value-or-promise": "1.0.11" } }, "@graphql-tools/utils": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.1.3.tgz", "integrity": "sha512-bbJyKhs6awp1/OmP+WKA1GOyu9UbgZGkhIj5srmiMGLHohEOKMjW784Sk0BZil1w2x95UPu0WHw6/d/HVCACCg==", "requires": { "tslib": "^2.4.0" } }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" }, "@hapi/bourne": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" }, "@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "@hapi/joi": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", "requires": { "@hapi/address": "2.x.x", "@hapi/bourne": "1.x.x", "@hapi/hoek": "8.x.x", "@hapi/topo": "3.x.x" }, "dependencies": { "@hapi/hoek": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" }, "@hapi/topo": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", "requires": { "@hapi/hoek": "^8.3.0" } } } }, "@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "requires": { "@hapi/hoek": "^9.0.0" } }, "@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "requires": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", "minimatch": "^3.0.4" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" }, "@jridgewell/source-map": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", "requires": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" }, "dependencies": { "@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } } } }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "requires": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, "@lezer/common": { "version": "0.15.12", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" }, "@lezer/lr": { "version": "0.15.8", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", "requires": { "@lezer/common": "^0.15.0" } }, "@lmdb/lmdb-darwin-arm64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.3.tgz", "integrity": "sha512-RXwGZ/0eCqtCY8FLTM/koR60w+MXyvBUpToXiIyjOcBnC81tAlTUHrRUavCEWPI9zc9VgvpK3+cbumPyR8BSuA==", "optional": true }, "@lmdb/lmdb-darwin-x64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.3.tgz", "integrity": "sha512-337dNzh5yCdNCTk8kPfoU7jR3otibSlPDGW0vKZT97rKnQMb9tNdto3RtWoGPsQ8hKmlRZpojOJtmwjncq1MoA==", "optional": true }, "@lmdb/lmdb-linux-arm": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.3.tgz", "integrity": "sha512-mU2HFJDGwECkoD9dHQEfeTG5mp8hNS2BCfwoiOpVPMeapjYpQz9Uw3FkUjRZ4dGHWKbin40oWHuL0bk2bCx+Sg==", "optional": true }, "@lmdb/lmdb-linux-arm64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.3.tgz", "integrity": "sha512-VJw60Mdgb4n+L0fO1PqfB0C7TyEQolJAC8qpqvG3JoQwvyOv6LH7Ib/WE3wxEW9nuHmVz9jkK7lk5HfWWgoO1Q==", "optional": true }, "@lmdb/lmdb-linux-x64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.3.tgz", "integrity": "sha512-qaReO5aV8griBDsBr8uBF/faO3ieGjY1RY4p8JvTL6Mu1ylLrTVvOONqKFlNaCwrmUjWw5jnf7VafxDAeQHTow==", "optional": true }, "@lmdb/lmdb-win32-x64": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.3.tgz", "integrity": "sha512-cK+Elf3RjEzrm3SerAhrFWL5oQAsZSJ/LmjL1joIpTfEP1etJJ9CTRvdaV6XLYAxaEkfdhk/9hOvHLbR9yIhCA==", "optional": true }, "@mapbox/hast-util-table-cell-style": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@mapbox/hast-util-table-cell-style/-/hast-util-table-cell-style-0.1.3.tgz", "integrity": "sha512-QsEsh5YaDvHoMQ2YHdvZy2iDnU3GgKVBTcHf6cILyoWDZtPSdlG444pL/ioPYO/GpXSfODBb9sefEetfC4v9oA==", "requires": { "unist-util-visit": "^1.3.0" } }, "@mischnic/json-sourcemap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", "integrity": "sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==", "requires": { "@lezer/common": "^0.15.7", "@lezer/lr": "^0.15.4", "json5": "^2.2.1" } }, "@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz", "integrity": "sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==", "optional": true }, "@msgpackr-extract/msgpackr-extract-darwin-x64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.2.0.tgz", "integrity": "sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw==", "optional": true }, "@msgpackr-extract/msgpackr-extract-linux-arm": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.2.0.tgz", "integrity": "sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg==", "optional": true }, "@msgpackr-extract/msgpackr-extract-linux-arm64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.2.0.tgz", "integrity": "sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA==", "optional": true }, "@msgpackr-extract/msgpackr-extract-linux-x64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.2.0.tgz", "integrity": "sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw==", "optional": true }, "@msgpackr-extract/msgpackr-extract-win32-x64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz", "integrity": "sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA==", "optional": true }, "@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "requires": { "eslint-scope": "5.1.1" } }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "@parcel/bundler-default": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.6.2.tgz", "integrity": "sha512-XIa3had/MIaTGgRFkHApXwytYs77k4geaNcmlb6nzmAABcYjW1CLYh83Zt0AbzLFsDT9ZcRY3u2UjhNf6efSaw==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1" } }, "@parcel/cache": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.6.2.tgz", "integrity": "sha512-hhJ6AsEGybeQZd9c/GYqfcKTgZKQXu3Xih6TlnP3gdR3KZoJOnb40ovHD1yYg4COvfcXThKP1cVJ18J6rcv3IA==", "requires": { "@parcel/fs": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/utils": "2.6.2", "lmdb": "2.5.2" }, "dependencies": { "@lmdb/lmdb-darwin-arm64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", "optional": true }, "@lmdb/lmdb-darwin-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", "optional": true }, "@lmdb/lmdb-linux-arm": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", "optional": true }, "@lmdb/lmdb-linux-arm64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", "optional": true }, "@lmdb/lmdb-linux-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", "integrity": "sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q==", "optional": true }, "@lmdb/lmdb-win32-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", "optional": true }, "lmdb": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", "requires": { "@lmdb/lmdb-darwin-arm64": "2.5.2", "@lmdb/lmdb-darwin-x64": "2.5.2", "@lmdb/lmdb-linux-arm": "2.5.2", "@lmdb/lmdb-linux-arm64": "2.5.2", "@lmdb/lmdb-linux-x64": "2.5.2", "@lmdb/lmdb-win32-x64": "2.5.2", "msgpackr": "^1.5.4", "node-addon-api": "^4.3.0", "node-gyp-build-optional-packages": "5.0.3", "ordered-binary": "^1.2.4", "weak-lru-cache": "^1.2.2" } }, "node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" } } }, "@parcel/codeframe": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.6.2.tgz", "integrity": "sha512-oFlHr6HCaYYsB4SHkU+gn9DKtbzvv3/4NdwMX0/6NAKyYVI7inEsXyPGw2Bbd2ZCFatW9QJZUETF0etvh5AEfQ==", "requires": { "chalk": "^4.1.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "@parcel/compressor-raw": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.6.2.tgz", "integrity": "sha512-P3c8jjV5HVs+fNDjhvq7PtHXNm687nit1iwTS5VAt+ScXKhKBhoIJ56q+9opcw0jnXVjAAgZqcRZ50oAJBGdKw==", "requires": { "@parcel/plugin": "2.6.2" } }, "@parcel/core": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.6.2.tgz", "integrity": "sha512-JlKS3Ux0ngmdooSBbzQLShHJdsapF9E7TGMo1hFaHRquZip/DaqzvysYrgMJlDuCoLArciq5ei7ZKzGeK9zexA==", "requires": { "@mischnic/json-sourcemap": "^0.1.0", "@parcel/cache": "2.6.2", "@parcel/diagnostic": "2.6.2", "@parcel/events": "2.6.2", "@parcel/fs": "2.6.2", "@parcel/graph": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/package-manager": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "@parcel/workers": "2.6.2", "abortcontroller-polyfill": "^1.1.9", "base-x": "^3.0.8", "browserslist": "^4.6.6", "clone": "^2.1.1", "dotenv": "^7.0.0", "dotenv-expand": "^5.1.0", "json5": "^2.2.0", "msgpackr": "^1.5.4", "nullthrows": "^1.1.1", "semver": "^5.7.1" }, "dependencies": { "dotenv": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==" } } }, "@parcel/diagnostic": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.6.2.tgz", "integrity": "sha512-3ODSBkKVihENU763z1/1DhGAWFhYWRxOCOShC72KXp+GFnSgGiBsxclu8NBa/N948Rzp8lqQI8U1nLcKkh0O/w==", "requires": { "@mischnic/json-sourcemap": "^0.1.0", "nullthrows": "^1.1.1" } }, "@parcel/events": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.6.2.tgz", "integrity": "sha512-IaCjOeA5ercdFVi1EZOmUHhGfIysmCUgc2Th9hMugSFO0I3GzRsBcAdP6XPfWm+TV6sQ/qZRfdk/drUxoAupnw==" }, "@parcel/fs": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.6.2.tgz", "integrity": "sha512-mIhqdF3tjgeoIGqW7Nc/xfM2ClID7o8livwUe5lpQEP+ZaIBiMigXs6ckv3WToCACK+3uylrSD2A/HmlhrxMqQ==", "requires": { "@parcel/fs-search": "2.6.2", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "@parcel/watcher": "^2.0.0", "@parcel/workers": "2.6.2" } }, "@parcel/fs-search": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/fs-search/-/fs-search-2.6.2.tgz", "integrity": "sha512-4STid1zqtGnmGjHD/2TG2g/zPDiCTtE3IAS24QYH3eiUAz2uoKGgEqd2tZbZ2yI96jtCuIhC1bzVu8Hbykls7w==", "requires": { "detect-libc": "^1.0.3" } }, "@parcel/graph": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-2.6.2.tgz", "integrity": "sha512-DPH4G/RBFJWayIN2fnhDXqhUw75n7k15YsGzdDKiXuwwz4wMOjoL4cyrI6zOf1SIyh3guRmeTYJ4jjPzwrLYww==", "requires": { "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1" } }, "@parcel/hash": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/hash/-/hash-2.6.2.tgz", "integrity": "sha512-tFB+cJU1Wqag6WyJgsmx3nx+xhmjcNZqtWh/MtK1lHNnZdDRk6bjr7SapnygBwruz+SmSt5bbdVThcpk2dRCcA==", "requires": { "detect-libc": "^1.0.3", "xxhash-wasm": "^0.4.2" } }, "@parcel/logger": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.6.2.tgz", "integrity": "sha512-Sz5YGCj1DbEiX0/G8Uw97LLZ0uEK+qtWcRAkHNpJpeMiSqDiRNevxXltz42EcLo+oCh4d4wyiVzwi9mNwzhS/Q==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/events": "2.6.2" } }, "@parcel/markdown-ansi": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.6.2.tgz", "integrity": "sha512-N/h9J4eibhc+B+krzvPMzFUWL37GudBIZBa7XSLkcuH6MnYYfh6rrMvhIyyESwk6VkcZNVzAeZrGQqxEs0dHDQ==", "requires": { "chalk": "^4.1.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "@parcel/namer-default": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.6.2.tgz", "integrity": "sha512-mp7bx/BQaIuohmZP0uE+gAmDBzzH0Yu8F4yCtE611lc6i0mou+nWRhzyKLNC/ieuI8DB3BFh2QQKeTxJn4W0qg==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/plugin": "2.6.2", "nullthrows": "^1.1.1" } }, "@parcel/node-resolver-core": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-2.6.2.tgz", "integrity": "sha512-4b2L5QRYlTybvv3+TIRtwg4PPJXy+cRShCBa8eu1K0Fj297Afe8MOZrcVV+RIr2KPMIRXcIJoqDmOhyci/DynA==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1", "semver": "^5.7.1" } }, "@parcel/optimizer-terser": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/optimizer-terser/-/optimizer-terser-2.6.2.tgz", "integrity": "sha512-ZSEVQ3G3zOiVPeHvH+BrHegZybrQj9kWQAaAA92leSqbvf6UaX4xqXbGRg2OttNFtbGYBzIl28Zm4t2SLeUIuA==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1", "terser": "^5.2.0" } }, "@parcel/package-manager": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.6.2.tgz", "integrity": "sha512-xGMqTgnwTE3rgzYwUZMKxR8fzmP5iSYz/gj2H8FR3pEmwh/8xCMtNjTSth+hPVGuqgRZ6JxwpfdY/fXdZ61ViQ==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/fs": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "@parcel/workers": "2.6.2", "semver": "^5.7.1" } }, "@parcel/packager-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.6.2.tgz", "integrity": "sha512-fm5rKWtaExR0W+UEKWivXNPysRFxuBCdskdxDByb1J1JeGMvp7dJElbi8oXDAQM4MnM5EyG7cg47SlMZNTLm4A==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.6.2", "globals": "^13.2.0", "nullthrows": "^1.1.1" }, "dependencies": { "globals": { "version": "13.19.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "requires": { "type-fest": "^0.20.2" } } } }, "@parcel/packager-raw": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.6.2.tgz", "integrity": "sha512-Rl3ZkMtMjb+LEvRowijDD8fibUAS6rWK0/vZQMk9cDNYCP2gCpZayLk0HZIGxneeTbosf/0sbngHq4VeRQOnQA==", "requires": { "@parcel/plugin": "2.6.2" } }, "@parcel/plugin": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.6.2.tgz", "integrity": "sha512-wbbWsM23Pr+8xtLSvf+UopXdVYlpKCCx6PuuZaZcKo+9IcDCWoGXD4M8Kkz14qBmkFn5uM00mULUqmVdSibB2w==", "requires": { "@parcel/types": "2.6.2" } }, "@parcel/reporter-dev-server": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.6.2.tgz", "integrity": "sha512-5QtL3ETMFL161jehlIK6rjBM+Pqk5cMhr60s9yLYqE1GY4M4gMj+Act+FXViyM6gmMA38cPxDvUsxTKBYXpFCw==", "requires": { "@parcel/plugin": "2.6.2", "@parcel/utils": "2.6.2" } }, "@parcel/resolver-default": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.6.2.tgz", "integrity": "sha512-Lo5sWb5QkjWvdBr+TdmAF6Mszb/sMldBBatc1osQTkHXCy679VMH+lfyiWxHbwK+F1pmdMeBJpYcMxvrgT8EsA==", "requires": { "@parcel/node-resolver-core": "2.6.2", "@parcel/plugin": "2.6.2" } }, "@parcel/runtime-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.6.2.tgz", "integrity": "sha512-0S3JFwgvs6FmEx2dHta9R0Sfu8vCnFAm4i7Y4efGHtAcTrF2CHjyiz4/hG+RQGJ70eoWW463Q+8qt6EKbkaOBQ==", "requires": { "@parcel/plugin": "2.6.2", "@parcel/utils": "2.6.2", "nullthrows": "^1.1.1" } }, "@parcel/source-map": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", "requires": { "detect-libc": "^1.0.3" } }, "@parcel/transformer-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.6.2.tgz", "integrity": "sha512-uhXAMTjE/Q61amflV8qVpb73mj+mIdXIMH0cSks1/gDIAxcgIvWvrE14P4TvY6zJ1q1iRJRIRUN6cFSXqjjLSA==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/plugin": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.6.2", "@parcel/workers": "2.6.2", "@swc/helpers": "^0.4.2", "browserslist": "^4.6.6", "detect-libc": "^1.0.3", "nullthrows": "^1.1.1", "regenerator-runtime": "^0.13.7", "semver": "^5.7.1" }, "dependencies": { "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" } } }, "@parcel/transformer-json": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.6.2.tgz", "integrity": "sha512-QGcIIvbPF/u10ihYvQhxXqb2QMXWSzcBxJrOSIXIl74TUGrWX05D5LmjDA/rzm/n/kvRnBkFNP60R/smYb8x+Q==", "requires": { "@parcel/plugin": "2.6.2", "json5": "^2.2.0" } }, "@parcel/types": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.6.2.tgz", "integrity": "sha512-MV8BFpCIs2jMUvK2RHqzkoiuOQ//JIbrD1zocA2YRW3zuPL/iABvbAABJoXpoPCKikVWOoCWASgBfWQo26VvJQ==", "requires": { "@parcel/cache": "2.6.2", "@parcel/diagnostic": "2.6.2", "@parcel/fs": "2.6.2", "@parcel/package-manager": "2.6.2", "@parcel/source-map": "^2.0.0", "@parcel/workers": "2.6.2", "utility-types": "^3.10.0" } }, "@parcel/utils": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.6.2.tgz", "integrity": "sha512-Ug7hpRxjgbY5AopW55nY7MmGMVmwmN+ihfCmxJkBUoESTG/3iq8uME7GjyOgW5DkQc2K7q62i8y8N0wCJT1u4Q==", "requires": { "@parcel/codeframe": "2.6.2", "@parcel/diagnostic": "2.6.2", "@parcel/hash": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/markdown-ansi": "2.6.2", "@parcel/source-map": "^2.0.0", "chalk": "^4.1.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "@parcel/watcher": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz", "integrity": "sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw==", "requires": { "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^3.2.1", "node-gyp-build": "^4.3.0" }, "dependencies": { "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" } } } }, "@parcel/workers": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.6.2.tgz", "integrity": "sha512-wBgUjJQm+lDd12fPRUmk09+ujTA9DgwPdqylSFK0OtI/yT6A+2kArUqjp8IwWo2tCJXoMzXBne2XQIWKqMiN4Q==", "requires": { "@parcel/diagnostic": "2.6.2", "@parcel/logger": "2.6.2", "@parcel/types": "2.6.2", "@parcel/utils": "2.6.2", "chrome-trace-event": "^1.0.2", "nullthrows": "^1.1.1" } }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", "requires": { "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", "find-up": "^5.0.0", "html-entities": "^2.1.0", "loader-utils": "^2.0.4", "schema-utils": "^3.0.0", "source-map": "^0.7.3" }, "dependencies": { "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" } } }, "@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "requires": { "@hapi/hoek": "^9.0.0" } }, "@sideway/formula": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" }, "@sindresorhus/slugify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-1.1.2.tgz", "integrity": "sha512-V9nR/W0Xd9TSGXpZ4iFUcFGhuOJtZX82Fzxj1YISlbSgKvIiNa7eLEZrT0vAraPOt++KHauIVNYgGRgjc13dXA==", "requires": { "@sindresorhus/transliterate": "^0.1.1", "escape-string-regexp": "^4.0.0" }, "dependencies": { "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" } } }, "@sindresorhus/transliterate": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-0.1.2.tgz", "integrity": "sha512-5/kmIOY9FF32nicXH+5yLNTX4NJ4atl7jRgqAJuIn/iyDFXBktOKDxCvyGE/EzmF4ngSUvjXxQUQlQiZ5lfw+w==", "requires": { "escape-string-regexp": "^2.0.0", "lodash.deburr": "^4.1.0" }, "dependencies": { "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" } } }, "@swc/helpers": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", "requires": { "tslib": "^2.4.0" } }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "requires": { "defer-to-connect": "^2.0.0" } }, "@tippy.js/react": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@tippy.js/react/-/react-2.2.3.tgz", "integrity": "sha512-5XYvbQujzDj9r00JYEz/cBtm6DutjOdv2azdco53B+eWF7FDBCQfkLVn87wimfEpmGK0vqRQv/cwFxFcoOP98Q==", "requires": { "prop-types": "^15.6.2", "tippy.js": "^4.3.4" } }, "@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, "@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" }, "@turist/fetch": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@turist/fetch/-/fetch-7.2.0.tgz", "integrity": "sha512-2x7EGw+6OJ29phunsbGvtxlNmSfcuPcyYudkMbi8gARCP9eJ1CtuMvnVUHL//O9Ixi9SJiug8wNt6lj86pN8XQ==", "requires": { "@types/node-fetch": "2" } }, "@turist/time": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/@turist/time/-/time-0.0.2.tgz", "integrity": "sha512-qLOvfmlG2vCVw5fo/oz8WAZYlpe5a5OurgTj3diIxJCdjRHpapC+vQCz3er9LV79Vcat+DifBjeAhOAdmndtDQ==" }, "@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "requires": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "@types/common-tags": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.1.tgz", "integrity": "sha512-20R/mDpKSPWdJs5TOpz3e7zqbeCNuMCPhV7Yndk9KU2Rbij2r5W4RzwDPkzC+2lzUqXYu9rFzTktCBnDjHuNQg==" }, "@types/component-emitter": { "version": "1.2.11", "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" }, "@types/configstore": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-2.1.1.tgz", "integrity": "sha512-YY+hm3afkDHeSM2rsFXxeZtu0garnusBWNG1+7MknmDWQHqcH2w21/xOU9arJUi8ch4qyFklidANLCu3ihhVwQ==" }, "@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, "@types/cors": { "version": "2.8.13", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", "requires": { "@types/node": "*" } }, "@types/debug": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz", "integrity": "sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==" }, "@types/eslint": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", "requires": { "@types/estree": "*", "@types/json-schema": "*" } }, "@types/eslint-scope": { "version": "3.7.4", "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "requires": { "@types/eslint": "*", "@types/estree": "*" } }, "@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, "@types/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-TiNg8R1kjDde5Pub9F9vCwZA/BNW9HeXP5b9j7Qucqncy/McfPZ6xze/EyBdXS5FhMIGN6Fx3vg75l5KHy3V1Q==" }, "@types/glob": { "version": "5.0.37", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.37.tgz", "integrity": "sha512-ATA/xrS7CZ3A2WCPVY4eKdNpybq56zqlTirnHhhyOztZM/lPxJzusOBI3BsaXbu6FrUluqzvMlI4sZ6BDYMlMg==", "requires": { "@types/minimatch": "*", "@types/node": "*" } }, "@types/hast": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", "requires": { "@types/unist": "*" } }, "@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "@types/http-proxy": { "version": "1.17.9", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", "requires": { "@types/node": "*" } }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "requires": { "@types/node": "*" } }, "@types/lodash": { "version": "4.14.191", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" }, "@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", "requires": { "@types/unist": "*" } }, "@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" }, "@types/mkdirp": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "requires": { "@types/node": "*" } }, "@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" }, "@types/node-fetch": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", "requires": { "@types/node": "*", "form-data": "^3.0.0" } }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "@types/reach__router": { "version": "1.3.11", "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.11.tgz", "integrity": "sha512-j23ChnIEiW8aAP4KT8OVyTXOFr+Ri65BDnwzmfHFO9WHypXYevHFjeil1Cj7YH3emfCE924BwAmgW4hOv7Wg3g==", "requires": { "@types/react": "*" } }, "@types/react": { "version": "18.0.26", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "requires": { "@types/node": "*" } }, "@types/rimraf": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.5.tgz", "integrity": "sha512-YyP+VfeaqAyFmXoTh3HChxOQMyjByRMsHU7kc5KOJkSlXudhMhQIALbYV7rHh/l8d2lX3VUQzprrcAgWdRuU8g==", "requires": { "@types/glob": "*", "@types/node": "*" } }, "@types/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", "requires": { "@types/node": "*" } }, "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/sharp": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.30.5.tgz", "integrity": "sha512-EhO29617AIBqxoVtpd1qdBanWpspk/kD2B6qTFRJ31Q23Rdf+DNU1xlHSwtqvwq1vgOqBwq1i38SX+HGCymIQg==", "requires": { "@types/node": "*" } }, "@types/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-gVC1InwyVrO326wbBZw+AO3u2vRXz/iRWq9jYhpG4W8LXyIgDv3ZmcLQ5Q4Gs+gFMyqx+viFoFT+l3p61QFCmQ==" }, "@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, "@types/yoga-layout": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" }, "@typescript-eslint/eslint-plugin": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "requires": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", "regexpp": "^3.1.0", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "@typescript-eslint/experimental-utils": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "requires": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", "@typescript-eslint/typescript-estree": "4.33.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "requires": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", "@typescript-eslint/typescript-estree": "4.33.0", "debug": "^4.3.1" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "@typescript-eslint/scope-manager": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "requires": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" } }, "@typescript-eslint/types": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==" }, "@typescript-eslint/typescript-estree": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "requires": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "@typescript-eslint/visitor-keys": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "requires": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" } }, "@vercel/webpack-asset-relocator-loader": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.3.tgz", "integrity": "sha512-vizrI18v8Lcb1PmNNUBz7yxPxxXoOeuaVEjTG9MjvDrphjiSxFZrRJ5tIghk+qdLFRCXI5HBCshgobftbmrC5g==", "requires": { "resolve": "^1.10.0" } }, "@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "requires": { "@webassemblyjs/helper-numbers": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, "@webassemblyjs/floating-point-hex-parser": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" }, "@webassemblyjs/helper-api-error": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" }, "@webassemblyjs/helper-buffer": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" }, "@webassemblyjs/helper-numbers": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "requires": { "@webassemblyjs/floating-point-hex-parser": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" }, "@webassemblyjs/helper-wasm-section": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "requires": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/wasm-gen": "1.11.1" } }, "@webassemblyjs/ieee754": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" }, "@webassemblyjs/wasm-edit": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "requires": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/helper-wasm-section": "1.11.1", "@webassemblyjs/wasm-gen": "1.11.1", "@webassemblyjs/wasm-opt": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", "@webassemblyjs/wast-printer": "1.11.1" } }, "@webassemblyjs/wasm-gen": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "requires": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/ieee754": "1.11.1", "@webassemblyjs/leb128": "1.11.1", "@webassemblyjs/utf8": "1.11.1" } }, "@webassemblyjs/wasm-opt": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "requires": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", "@webassemblyjs/wasm-gen": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1" } }, "@webassemblyjs/wasm-parser": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "requires": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", "@webassemblyjs/ieee754": "1.11.1", "@webassemblyjs/leb128": "1.11.1", "@webassemblyjs/utf8": "1.11.1" } }, "@webassemblyjs/wast-printer": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "requires": { "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" } }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, "@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "abortcontroller-polyfill": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==" }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "requires": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" }, "acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "requires": {} }, "acorn-loose": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.3.0.tgz", "integrity": "sha512-75lAs9H19ldmW+fAbyqHdjgdCrz0pWGXKmnqFoh8PyVd1L2RIb4RzYrSjmopeqv3E1G3/Pimu6GgLlrGbrkF7w==", "requires": { "acorn": "^8.5.0" } }, "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, "address": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" }, "adjust-sourcemap-loader": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", "requires": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" } }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "requires": {} }, "anser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/anser/-/anser-2.1.1.tgz", "integrity": "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ==" }, "ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "requires": { "string-width": "^4.1.0" } }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==" }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" }, "ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==" }, "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "optional": true, "requires": { "micromatch": "^2.1.5", "normalize-path": "^2.0.0" } }, "append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, "application-config-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.1.tgz", "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==" }, "arch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==" }, "arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { "sprintf-js": "~1.0.2" } }, "aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "requires": { "@babel/runtime": "^7.10.2", "@babel/runtime-corejs3": "^7.10.2" } }, "arity-n": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==" }, "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", "dev": true, "optional": true, "requires": { "arr-flatten": "^1.0.1" } }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true, "optional": true }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true, "optional": true }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" } }, "array-iterate": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.4.tgz", "integrity": "sha512-sNRaPGh9nnmdC8Zf+pT3UqP8rnWj5Hf9wiFGsX3wUQ2yVSIhO2ShFwCoceIPpB41QF6i2OEmrHmCo36xronCVA==" }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", "dev": true, "optional": true }, "array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.flatmap": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.tosorted": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0", "get-intrinsic": "^1.1.3" } }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true, "optional": true }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==" }, "async-cache": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/async-cache/-/async-cache-1.1.0.tgz", "integrity": "sha512-YDQc4vBn5NFhY6g6HhVshyi3Fy9+SQ5ePnE7JLDJn1DoL+i7ER+vMwtTNOYk9leZkYMnOwpBCWqyLDPw8Aig8g==", "requires": { "lru-cache": "^4.0.0" }, "dependencies": { "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" } } }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true, "optional": true }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==" }, "autoprefixer": { "version": "10.4.13", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "requires": { "browserslist": "^4.21.4", "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" } }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "axe-core": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==" }, "axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "requires": { "follow-redirects": "^1.14.0" } }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" }, "babel-cli": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", "integrity": "sha512-wau+BDtQfuSBGQ9PzzFL3REvR9Sxnd4LKwtcHAiPjhugA7K/80vpHXafj+O5bAqJOuSefjOx5ZJnNSR2J1Qw6Q==", "dev": true, "requires": { "babel-core": "^6.26.0", "babel-polyfill": "^6.26.0", "babel-register": "^6.26.0", "babel-runtime": "^6.26.0", "chokidar": "^1.6.1", "commander": "^2.11.0", "convert-source-map": "^1.5.0", "fs-readdir-recursive": "^1.0.0", "glob": "^7.1.2", "lodash": "^4.17.4", "output-file-sync": "^1.1.2", "path-is-absolute": "^1.0.1", "slash": "^1.0.0", "source-map": "^0.5.6", "v8flags": "^2.1.1" } }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, "requires": { "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" } }, "babel-core": { "version": "6.26.3", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { "babel-code-frame": "^6.26.0", "babel-generator": "^6.26.0", "babel-helpers": "^6.24.1", "babel-messages": "^6.23.0", "babel-register": "^6.26.0", "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", "convert-source-map": "^1.5.1", "debug": "^2.6.9", "json5": "^0.5.1", "lodash": "^4.17.4", "minimatch": "^3.0.4", "path-is-absolute": "^1.0.1", "private": "^0.1.8", "slash": "^1.0.0", "source-map": "^0.5.7" }, "dependencies": { "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true } } }, "babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "peer": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.7.0", "@babel/traverse": "^7.7.0", "@babel/types": "^7.7.0", "eslint-visitor-keys": "^1.0.0", "resolve": "^1.12.0" }, "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "peer": true } } }, "babel-extract-comments": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", "requires": { "babylon": "^6.18.0" } }, "babel-generator": { "version": "6.26.1", "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { "babel-messages": "^6.23.0", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "detect-indent": "^4.0.0", "jsesc": "^1.3.0", "lodash": "^4.17.4", "source-map": "^0.5.7", "trim-right": "^1.0.1" } }, "babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", "dev": true, "requires": { "babel-helper-explode-assignable-expression": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-helper-builder-react-jsx": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", "integrity": "sha512-02I9jDjnVEuGy2BR3LRm9nPRb/+Ja0pvZVLr1eI5TYAA/dB0Xoc+WBo50+aDfhGDLhlBY1+QURjn9uvcFd8gzg==", "dev": true, "requires": { "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "esutils": "^2.0.2" } }, "babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", "dev": true, "requires": { "babel-helper-hoist-variables": "^6.24.1", "babel-runtime": "^6.22.0", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-helper-define-map": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "lodash": "^4.17.4" } }, "babel-helper-explode-assignable-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-helper-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", "dev": true, "requires": { "babel-helper-get-function-arity": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-helper-get-function-arity": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-helper-hoist-variables": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-helper-optimise-call-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-helper-regex": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", "dev": true, "requires": { "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "lodash": "^4.17.4" } }, "babel-helper-remap-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-helper-replace-supers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", "dev": true, "requires": { "babel-helper-optimise-call-expression": "^6.24.1", "babel-messages": "^6.23.0", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-helpers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "babel-loader": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "requires": { "find-cache-dir": "^3.3.1", "loader-utils": "^2.0.0", "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, "dependencies": { "schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "requires": { "@types/json-schema": "^7.0.5", "ajv": "^6.12.4", "ajv-keywords": "^3.5.2" } } } }, "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-add-module-exports": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==" }, "babel-plugin-check-es2015-constants": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "requires": { "object.assign": "^4.1.0" } }, "babel-plugin-lodash": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz", "integrity": "sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg==", "requires": { "@babel/helper-module-imports": "^7.0.0-beta.49", "@babel/types": "^7.0.0-beta.49", "glob": "^7.1.1", "lodash": "^4.17.10", "require-package-name": "^2.0.1" } }, "babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "requires": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" } }, "babel-plugin-polyfill-corejs2": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "requires": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "babel-plugin-polyfill-corejs3": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "requires": { "@babel/helper-define-polyfill-provider": "^0.3.3", "core-js-compat": "^3.25.1" }, "dependencies": { "core-js-compat": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz", "integrity": "sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==", "requires": { "browserslist": "^4.21.4" } } } }, "babel-plugin-polyfill-regenerator": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "requires": { "@babel/helper-define-polyfill-provider": "^0.3.3" } }, "babel-plugin-remove-graphql-queries": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/babel-plugin-remove-graphql-queries/-/babel-plugin-remove-graphql-queries-4.25.0.tgz", "integrity": "sha512-enyqRNRrn7vTG3nwg1V+XhoAJIyUv3ZukQCs5KbHOK+WNDDiGZQzIG+FCiZFACScdZBJWyx7TYRYbOFJZ/KEGg==", "requires": { "@babel/runtime": "^7.15.4", "@babel/types": "^7.15.4", "gatsby-core-utils": "^3.25.0" } }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", "dev": true }, "babel-plugin-syntax-class-properties": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", "integrity": "sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==", "dev": true }, "babel-plugin-syntax-decorators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", "integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==", "dev": true }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", "dev": true }, "babel-plugin-syntax-flow": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", "integrity": "sha512-HbTDIoG1A1op7Tl/wIFQPULIBA61tsJ8Ntq2FAhLwuijrzosM/92kAfgU1Q3Kc7DH/cprJg5vDfuTY4QUL4rDA==", "dev": true }, "babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", "dev": true }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==" }, "babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", "dev": true }, "babel-plugin-transform-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", "dev": true, "requires": { "babel-helper-remap-async-to-generator": "^6.24.1", "babel-plugin-syntax-async-functions": "^6.8.0", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-class-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", "babel-plugin-syntax-class-properties": "^6.8.0", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "babel-plugin-transform-decorators-legacy": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz", "integrity": "sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA==", "dev": true, "requires": { "babel-plugin-syntax-decorators": "^6.1.18", "babel-runtime": "^6.2.0", "babel-template": "^6.3.0" } }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoping": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", "dev": true, "requires": { "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "lodash": "^4.17.4" } }, "babel-plugin-transform-es2015-classes": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", "dev": true, "requires": { "babel-helper-define-map": "^6.24.1", "babel-helper-function-name": "^6.24.1", "babel-helper-optimise-call-expression": "^6.24.1", "babel-helper-replace-supers": "^6.24.1", "babel-messages": "^6.23.0", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-computed-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-destructuring": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-for-of": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", "dev": true, "requires": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-modules-amd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", "dev": true, "requires": { "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-commonjs": { "version": "6.26.2", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { "babel-plugin-transform-strict-mode": "^6.24.1", "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", "babel-types": "^6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", "dev": true, "requires": { "babel-helper-hoist-variables": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-umd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", "dev": true, "requires": { "babel-plugin-transform-es2015-modules-amd": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-object-super": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", "dev": true, "requires": { "babel-helper-replace-supers": "^6.24.1", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-parameters": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", "dev": true, "requires": { "babel-helper-call-delegate": "^6.24.1", "babel-helper-get-function-arity": "^6.24.1", "babel-runtime": "^6.22.0", "babel-template": "^6.24.1", "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-spread": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", "dev": true, "requires": { "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-template-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-unicode-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", "dev": true, "requires": { "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", "regexpu-core": "^2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", "dev": true, "requires": { "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", "babel-plugin-syntax-exponentiation-operator": "^6.8.0", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-flow-strip-types": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", "integrity": "sha512-TxIM0ZWNw9oYsoTthL3lvAK3+eTujzktoXJg4ubGvICGbVuXVYv5hHv0XXpz8fbqlJaGYY4q5SVzaSmsg3t4Fg==", "dev": true, "requires": { "babel-plugin-syntax-flow": "^6.18.0", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-object-rest-spread": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", "requires": { "babel-plugin-syntax-object-rest-spread": "^6.8.0", "babel-runtime": "^6.26.0" } }, "babel-plugin-transform-react-display-name": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", "integrity": "sha512-QLYkLiZeeED2PKd4LuXGg5y9fCgPB5ohF8olWUuETE2ryHNRqqnXlEVP7RPuef89+HTfd3syptMGVHeoAu0Wig==", "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-react-jsx": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", "integrity": "sha512-s+q/Y2u2OgDPHRuod3t6zyLoV8pUHc64i/O7ZNgIOEdYTq+ChPeybcKBi/xk9VI60VriILzFPW+dUxAEbTxh2w==", "dev": true, "requires": { "babel-helper-builder-react-jsx": "^6.24.1", "babel-plugin-syntax-jsx": "^6.8.0", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-react-jsx-self": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", "integrity": "sha512-Y3ZHP1nunv0U1+ysTNwLK39pabHj6cPVsfN4TRC7BDBfbgbyF4RifP5kd6LnbuMV9wcfedQMe7hn1fyKc7IzTQ==", "dev": true, "requires": { "babel-plugin-syntax-jsx": "^6.8.0", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-react-jsx-source": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", "integrity": "sha512-pcDNDsZ9q/6LJmujQ/OhjeoIlp5Nl546HJ2yiFIJK3mYpgNXhI5/S9mXfVxu5yqWAi7HdI7e/q6a9xtzwL69Vw==", "dev": true, "requires": { "babel-plugin-syntax-jsx": "^6.8.0", "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" }, "babel-plugin-transform-regenerator": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", "dev": true, "requires": { "regenerator-transform": "^0.10.0" } }, "babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" } }, "babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", "dev": true, "requires": { "babel-runtime": "^6.26.0", "core-js": "^2.5.0", "regenerator-runtime": "^0.10.5" } }, "babel-preset-env": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", "dev": true, "requires": { "babel-plugin-check-es2015-constants": "^6.22.0", "babel-plugin-syntax-trailing-function-commas": "^6.22.0", "babel-plugin-transform-async-to-generator": "^6.22.0", "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", "babel-plugin-transform-es2015-block-scoping": "^6.23.0", "babel-plugin-transform-es2015-classes": "^6.23.0", "babel-plugin-transform-es2015-computed-properties": "^6.22.0", "babel-plugin-transform-es2015-destructuring": "^6.23.0", "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", "babel-plugin-transform-es2015-for-of": "^6.23.0", "babel-plugin-transform-es2015-function-name": "^6.22.0", "babel-plugin-transform-es2015-literals": "^6.22.0", "babel-plugin-transform-es2015-modules-amd": "^6.22.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", "babel-plugin-transform-es2015-modules-umd": "^6.23.0", "babel-plugin-transform-es2015-object-super": "^6.22.0", "babel-plugin-transform-es2015-parameters": "^6.23.0", "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", "babel-plugin-transform-es2015-spread": "^6.22.0", "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", "babel-plugin-transform-es2015-template-literals": "^6.22.0", "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", "babel-plugin-transform-exponentiation-operator": "^6.22.0", "babel-plugin-transform-regenerator": "^6.22.0", "browserslist": "^3.2.6", "invariant": "^2.2.2", "semver": "^5.3.0" }, "dependencies": { "browserslist": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "requires": { "caniuse-lite": "^1.0.30000844", "electron-to-chromium": "^1.3.47" } } } }, "babel-preset-fbjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", "requires": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", "@babel/plugin-syntax-class-properties": "^7.0.0", "@babel/plugin-syntax-flow": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.0.0", "@babel/plugin-transform-arrow-functions": "^7.0.0", "@babel/plugin-transform-block-scoped-functions": "^7.0.0", "@babel/plugin-transform-block-scoping": "^7.0.0", "@babel/plugin-transform-classes": "^7.0.0", "@babel/plugin-transform-computed-properties": "^7.0.0", "@babel/plugin-transform-destructuring": "^7.0.0", "@babel/plugin-transform-flow-strip-types": "^7.0.0", "@babel/plugin-transform-for-of": "^7.0.0", "@babel/plugin-transform-function-name": "^7.0.0", "@babel/plugin-transform-literals": "^7.0.0", "@babel/plugin-transform-member-expression-literals": "^7.0.0", "@babel/plugin-transform-modules-commonjs": "^7.0.0", "@babel/plugin-transform-object-super": "^7.0.0", "@babel/plugin-transform-parameters": "^7.0.0", "@babel/plugin-transform-property-literals": "^7.0.0", "@babel/plugin-transform-react-display-name": "^7.0.0", "@babel/plugin-transform-react-jsx": "^7.0.0", "@babel/plugin-transform-shorthand-properties": "^7.0.0", "@babel/plugin-transform-spread": "^7.0.0", "@babel/plugin-transform-template-literals": "^7.0.0", "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" }, "dependencies": { "babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" } } }, "babel-preset-flow": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", "integrity": "sha512-PQZFJXnM3d80Vq4O67OE6EMVKIw2Vmzy8UXovqulNogCtblWU8rzP7Sm5YgHiCg4uejUxzCkHfNXQ4Z6GI+Dhw==", "dev": true, "requires": { "babel-plugin-transform-flow-strip-types": "^6.22.0" } }, "babel-preset-react": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", "integrity": "sha512-phQe3bElbgF887UM0Dhz55d22ob8czTL1kbhZFwpCE6+R/X9kHktfwmx9JZb+bBSVRGphP5tZ9oWhVhlgjrX3Q==", "dev": true, "requires": { "babel-plugin-syntax-jsx": "^6.3.13", "babel-plugin-transform-react-display-name": "^6.23.0", "babel-plugin-transform-react-jsx": "^6.24.1", "babel-plugin-transform-react-jsx-self": "^6.22.0", "babel-plugin-transform-react-jsx-source": "^6.22.0", "babel-preset-flow": "^6.23.0" } }, "babel-register": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", "dev": true, "requires": { "babel-core": "^6.26.0", "babel-runtime": "^6.26.0", "core-js": "^2.5.0", "home-or-tmp": "^2.0.0", "lodash": "^4.17.4", "mkdirp": "^0.5.1", "source-map-support": "^0.4.15" } }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" } } }, "babel-template": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", "dev": true, "requires": { "babel-runtime": "^6.26.0", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", "lodash": "^4.17.4" } }, "babel-traverse": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, "requires": { "babel-code-frame": "^6.26.0", "babel-messages": "^6.23.0", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", "debug": "^2.6.8", "globals": "^9.18.0", "invariant": "^2.2.2", "lodash": "^4.17.4" } }, "babel-types": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", "dev": true, "requires": { "babel-runtime": "^6.26.0", "esutils": "^2.0.2", "lodash": "^4.17.4", "to-fast-properties": "^1.0.3" } }, "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "optional": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", "component-emitter": "^1.2.1", "define-property": "^1.0.0", "isobject": "^3.0.1", "mixin-deep": "^1.2.0", "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^1.0.0" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "base-x": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", "requires": { "safe-buffer": "^5.0.1" } }, "base64-arraybuffer": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==" }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" }, "better-opn": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", "integrity": "sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==", "requires": { "open": "^7.0.3" } }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true, "optional": true }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, "optional": true, "requires": { "file-uri-to-path": "1.0.0" } }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" }, "dependencies": { "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" } } }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", "requires": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", "chalk": "^4.1.0", "cli-boxes": "^2.2.1", "string-width": "^4.2.2", "type-fest": "^0.20.2", "widest-line": "^3.1.0", "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", "dev": true, "optional": true, "requires": { "expand-range": "^1.8.1", "preserve": "^0.2.0", "repeat-element": "^1.1.2" } }, "brcast": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.2.tgz", "integrity": "sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA==" }, "browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { "caniuse-lite": "^1.0.30001400", "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", "update-browserslist-db": "^1.0.9" } }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "requires": { "node-int64": "^0.4.0" } }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "requires": { "streamsearch": "^1.1.0" } }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "optional": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", "get-value": "^2.0.6", "has-value": "^1.0.0", "isobject": "^3.0.1", "set-value": "^2.0.0", "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "cache-manager": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.11.1.tgz", "integrity": "sha512-XhUuc9eYwkzpK89iNewFwtvcDYMUsvtwzHeyEOPJna/WsVsXcrzsA1ft2M0QqPNunEzLhNCYPo05tEfG+YuNow==", "requires": { "async": "1.5.2", "lodash.clonedeep": "4.5.0", "lru-cache": "4.0.0" }, "dependencies": { "lru-cache": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.0.tgz", "integrity": "sha512-WKhDkjlLwzE8jAQdQlsxLUQTPXLCKX/4cJk6s5AlRtJkDBk0IKH5O51bVDH61K9N4bhbbyvLM6EiOuE8ovApPA==", "requires": { "pseudomap": "^1.0.1", "yallist": "^2.0.0" } }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" } } }, "cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" }, "cacheable-request": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" }, "dependencies": { "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "requires": { "pump": "^3.0.0" } } } }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" } }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "requires": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "requires": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "caniuse-lite": { "version": "1.0.30001442", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz", "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==" }, "capital-case": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", "requires": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "ccount": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "change-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", "requires": { "camel-case": "^4.1.2", "capital-case": "^1.0.4", "constant-case": "^3.0.4", "dot-case": "^3.0.4", "header-case": "^2.0.4", "no-case": "^3.0.4", "param-case": "^3.0.4", "pascal-case": "^3.1.2", "path-case": "^3.0.4", "sentence-case": "^3.0.4", "snake-case": "^3.0.4", "tslib": "^2.0.3" } }, "change-case-all": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.14.tgz", "integrity": "sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==", "requires": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "character-entities": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" }, "character-entities-html4": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==" }, "character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" }, "character-reference-invalid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "requires": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "htmlparser2": "^8.0.1", "parse5": "^7.0.0", "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, "cheerio-select": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "requires": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", "dev": true, "optional": true, "requires": { "anymatch": "^1.3.0", "async-each": "^1.0.0", "fsevents": "^1.0.0", "glob-parent": "^2.0.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", "is-glob": "^2.0.0", "path-is-absolute": "^1.0.0", "readdirp": "^2.0.0" } }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "optional": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", "isobject": "^3.0.0", "static-extend": "^0.1.1" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^0.1.0" } }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true } } }, "classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "requires": { "restore-cursor": "^3.1.0" } }, "cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" }, "clipboardy": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", "requires": { "arch": "^2.1.1", "execa": "^1.0.0", "is-wsl": "^2.1.1" }, "dependencies": { "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" } }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "requires": { "pump": "^3.0.0" } }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "requires": { "path-key": "^2.0.0" } }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { "isexe": "^2.0.0" } } } }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" }, "dependencies": { "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } } } }, "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "requires": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", "shallow-clone": "^3.0.0" } }, "clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "requires": { "mimic-response": "^1.0.0" } }, "collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dev": true, "optional": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" } }, "color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "requires": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" }, "colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "requires": { "delayed-stream": "~1.0.0" } }, "comma-separated-tokens": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" }, "command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "common-path-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" }, "common-tags": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "compose-function": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", "requires": { "arity-n": "^1.0.4" } }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "requires": { "mime-db": ">= 1.43.0 < 2" } }, "compression": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", "compressible": "~2.0.16", "debug": "2.6.9", "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", "make-dir": "^3.0.0", "unique-string": "^2.0.0", "write-file-atomic": "^3.0.0", "xdg-basedir": "^4.0.0" } }, "confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, "constant-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", "requires": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case": "^2.0.2" } }, "content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "requires": { "safe-buffer": "5.2.1" } }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-hrtime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==" }, "convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "dev": true, "optional": true }, "core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "core-js-compat": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.0.tgz", "integrity": "sha512-YK6fwFjCOKWwGnjFUR3c544YsnA/7DoLL0ysncuOJ4pwbriAtOpvM2bygdlcXbvQCQZ7bBU9CL4t7tGl7ETRpQ==", "requires": { "browserslist": "^4.16.3", "semver": "7.0.0" }, "dependencies": { "semver": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" } } }, "core-js-pure": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.1.tgz", "integrity": "sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw==" }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "requires": { "object-assign": "^4", "vary": "^1" } }, "cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" } }, "create-gatsby": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/create-gatsby/-/create-gatsby-2.25.0.tgz", "integrity": "sha512-96Kl/6Far2j65/vFv/6Mb9+T+/4oW8hlC3UmdfjgBgUIzTPFmezY1ygPu2dfCKjprWkArB8DpE7EsAaJoRKB1Q==", "requires": { "@babel/runtime": "^7.15.4" } }, "cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "requires": { "node-fetch": "2.6.7" } }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" }, "css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", "requires": { "inherits": "^2.0.3", "source-map": "^0.6.1", "source-map-resolve": "^0.5.2", "urix": "^0.1.0" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, "css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", "requires": {} }, "css-loader": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", "requires": { "icss-utils": "^5.1.0", "loader-utils": "^2.0.0", "postcss": "^8.2.15", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^3.0.0", "semver": "^7.3.5" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "css-minimizer-webpack-plugin": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz", "integrity": "sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw==", "requires": { "cssnano": "^5.0.0", "jest-worker": "^26.3.0", "p-limit": "^3.0.2", "postcss": "^8.2.9", "schema-utils": "^3.0.0", "serialize-javascript": "^5.0.1", "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, "css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "requires": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "css-selector-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" }, "css-tree": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "requires": { "mdn-data": "2.0.14", "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, "css-vendor": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", "integrity": "sha512-Vx/Vl3zsHj32Z+WTNzGjd2iSbSIJTYHMmyGUT2nzCjj0Xk4qLfwpQ8nF6TQ5oo3Cf0s/An3DTc7LclH1BkAXbQ==", "requires": { "is-in-browser": "^1.0.2" } }, "css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" }, "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, "cssfilter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" }, "cssnano": { "version": "5.1.14", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", "requires": { "cssnano-preset-default": "^5.2.13", "lilconfig": "^2.0.3", "yaml": "^1.10.2" } }, "cssnano-preset-default": { "version": "5.2.13", "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", "requires": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", "postcss-colormin": "^5.3.0", "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", "postcss-merge-longhand": "^5.1.7", "postcss-merge-rules": "^5.1.3", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", "postcss-minify-params": "^5.1.4", "postcss-minify-selectors": "^5.2.1", "postcss-normalize-charset": "^5.1.0", "postcss-normalize-display-values": "^5.1.0", "postcss-normalize-positions": "^5.1.1", "postcss-normalize-repeat-style": "^5.1.1", "postcss-normalize-string": "^5.1.0", "postcss-normalize-timing-functions": "^5.1.0", "postcss-normalize-unicode": "^5.1.1", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", "postcss-reduce-initial": "^5.1.1", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" } }, "cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", "requires": {} }, "csso": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "requires": { "css-tree": "^1.1.2" } }, "csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" } }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, "date-fns": { "version": "2.29.3", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { "ms": "2.0.0" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" }, "decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, "decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "requires": { "mimic-response": "^3.1.0" }, "dependencies": { "mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" } } }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" }, "define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "optional": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "dependency-graph": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==" }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "detab": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", "requires": { "repeat-string": "^1.5.4" } }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", "dev": true, "requires": { "repeating": "^2.0.0" } }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==" }, "detect-port": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", "requires": { "address": "^1.0.1", "debug": "4" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "detect-port-alt": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", "requires": { "address": "^1.0.1", "debug": "^2.6.0" } }, "devcert": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/devcert/-/devcert-1.2.2.tgz", "integrity": "sha512-UsLqvtJGPiGwsIZnJINUnFYaWgK7CroreGRndWHZkRD58tPFr3pVbbSyHR8lbh41+azR4jKvuNZ+eCoBZGA5kA==", "requires": { "@types/configstore": "^2.1.1", "@types/debug": "^0.0.30", "@types/get-port": "^3.2.0", "@types/glob": "^5.0.34", "@types/lodash": "^4.14.92", "@types/mkdirp": "^0.5.2", "@types/node": "^8.5.7", "@types/rimraf": "^2.0.2", "@types/tmp": "^0.0.33", "application-config-path": "^0.1.0", "command-exists": "^1.2.4", "debug": "^3.1.0", "eol": "^0.9.1", "get-port": "^3.2.0", "glob": "^7.1.2", "is-valid-domain": "^0.1.6", "lodash": "^4.17.4", "mkdirp": "^0.5.1", "password-prompt": "^1.0.4", "rimraf": "^2.6.2", "sudo-prompt": "^8.2.0", "tmp": "^0.0.33", "tslib": "^1.10.0" }, "dependencies": { "@types/node": { "version": "8.10.66", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "requires": { "os-tmpdir": "~1.0.2" } }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" } } }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "requires": { "path-type": "^4.0.0" } }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "requires": { "esutils": "^2.0.2" } }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "requires": { "utila": "~0.4" } }, "dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "requires": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" }, "domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "requires": { "domelementtype": "^2.3.0" } }, "domutils": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "requires": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.1" } }, "dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "requires": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "requires": { "is-obj": "^2.0.0" } }, "dotenv": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" }, "dotenv-expand": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, "duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, "duplexer3": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==" }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } }, "engine.io": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.2.tgz", "integrity": "sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~4.0.0", "ws": "~7.4.2" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "engine.io-client": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.4.tgz", "integrity": "sha512-843fqAdKeUMFqKi1sSjnR11tJ4wi8sIefu6+JC1OzkkJBmjtc/gM/rZ53tJfu5Iae/3gApm5veoS+v+gtT0+Fg==", "requires": { "base64-arraybuffer": "0.1.4", "component-emitter": "~1.3.0", "debug": "~4.3.1", "engine.io-parser": "~4.0.1", "has-cors": "1.1.0", "parseqs": "0.0.6", "parseuri": "0.0.6", "ws": "~7.4.2", "xmlhttprequest-ssl": "~1.6.2", "yeast": "0.1.2" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "engine.io-parser": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", "requires": { "base64-arraybuffer": "0.1.4" } }, "enhanced-resolve": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "requires": { "ansi-colors": "^4.1.1" } }, "entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" }, "eol": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==" }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "requires": { "is-arrayish": "^0.2.1" } }, "error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "requires": { "stackframe": "^1.3.4" } }, "es-abstract": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz", "integrity": "sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g==", "requires": { "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.0", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.4", "is-array-buffer": "^3.0.0", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", "string.prototype.trimend": "^1.0.6", "string.prototype.trimstart": "^1.0.6", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.9" } }, "es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" }, "es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", "requires": { "get-intrinsic": "^1.1.3", "has": "^1.0.3", "has-tostringtag": "^1.0.0" } }, "es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", "requires": { "has": "^1.0.3" } }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" } }, "es5-ext": { "version": "0.10.62", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "requires": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "next-tick": "^1.1.0" } }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "requires": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "requires": { "d": "^1.0.1", "ext": "^1.1.2" } }, "es6-weak-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "requires": { "d": "1", "es5-ext": "^0.10.46", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "requires": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.1.2", "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "progress": "^2.0.0", "regexpp": "^3.1.0", "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { "@babel/code-frame": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "requires": { "@babel/highlight": "^7.10.4" } }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "requires": { "eslint-visitor-keys": "^1.1.0" }, "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" } } }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "globals": { "version": "13.19.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "requires": { "type-fest": "^0.20.2" } }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "eslint-config-react-app": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz", "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==", "requires": { "confusing-browser-globals": "^1.0.10" } }, "eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "requires": { "debug": "^3.2.7", "resolve": "^1.20.0" }, "dependencies": { "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "eslint-module-utils": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "requires": { "debug": "^3.2.7" }, "dependencies": { "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "eslint-plugin-flowtype": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz", "integrity": "sha512-vcz32f+7TP+kvTUyMXZmCnNujBQZDNmcqPImw8b9PZ+16w1Qdm6ryRuYZYVaG9xRqqmAPr2Cs9FAX5gN+x/bjw==", "requires": { "lodash": "^4.17.15", "string-natural-compare": "^3.0.1" } }, "eslint-plugin-import": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "requires": { "array-includes": "^3.1.4", "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", "eslint-module-utils": "^2.7.3", "has": "^1.0.3", "is-core-module": "^2.8.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.values": "^1.1.5", "resolve": "^1.22.0", "tsconfig-paths": "^3.14.1" }, "dependencies": { "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "requires": { "esutils": "^2.0.2" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } } } }, "eslint-plugin-jsx-a11y": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", "requires": { "@babel/runtime": "^7.18.9", "aria-query": "^4.2.2", "array-includes": "^3.1.5", "ast-types-flow": "^0.0.7", "axe-core": "^4.4.3", "axobject-query": "^2.2.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "has": "^1.0.3", "jsx-ast-utils": "^3.3.2", "language-tags": "^1.0.5", "minimatch": "^3.1.2", "semver": "^6.3.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "eslint-plugin-react": { "version": "7.31.11", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", "requires": { "array-includes": "^3.1.6", "array.prototype.flatmap": "^1.3.1", "array.prototype.tosorted": "^1.1.1", "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.6", "object.fromentries": "^2.0.6", "object.hasown": "^1.1.2", "object.values": "^1.1.6", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", "string.prototype.matchall": "^4.0.8" }, "dependencies": { "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "requires": { "esutils": "^2.0.2" } }, "resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "eslint-plugin-react-hooks": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "requires": {} }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" }, "dependencies": { "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" } } }, "eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "requires": { "eslint-visitor-keys": "^2.0.0" } }, "eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" }, "eslint-webpack-plugin": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.7.0.tgz", "integrity": "sha512-bNaVVUvU4srexGhVcayn/F4pJAz19CWBkKoMx7aSQ4wtTbZQCnG5O9LHCE42mM+JSKOUp7n6vd5CIwzj7lOVGA==", "requires": { "@types/eslint": "^7.29.0", "arrify": "^2.0.1", "jest-worker": "^27.5.1", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "schema-utils": "^3.1.1" }, "dependencies": { "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "requires": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "requires": { "has-flag": "^4.0.0" } } } }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "requires": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" }, "dependencies": { "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" } } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "requires": { "estraverse": "^5.1.0" } }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "requires": { "estraverse": "^5.2.0" } }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "requires": { "d": "1", "es5-ext": "~0.10.14" } }, "event-source-polyfill": { "version": "1.0.25", "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.25.tgz", "integrity": "sha512-hQxu6sN1Eq4JjoI7ITdQeGGUN193A2ra83qC0Ltm9I2UJVAten3OFVN6k5RX4YWeCS0BoC8xg/5czOCIHVosQg==" }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" }, "execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "requires": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==", "dev": true, "optional": true, "requires": { "is-posix-bracket": "^0.1.0" } }, "expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", "dev": true, "optional": true, "requires": { "fill-range": "^2.1.0" } }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" }, "express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.2.0", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", "serve-static": "1.15.0", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" } } }, "express-graphql": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.12.0.tgz", "integrity": "sha512-DwYaJQy0amdy3pgNtiTDuGGM2BLdj+YO2SgbKoLliCfuHv3VVTt7vNG/ZqK2hRYjtYHE2t2KB705EU94mE64zg==", "requires": { "accepts": "^1.3.7", "content-type": "^1.0.4", "http-errors": "1.8.0", "raw-body": "^2.4.1" }, "dependencies": { "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" }, "http-errors": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", "requires": { "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" } }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" } } }, "express-http-proxy": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/express-http-proxy/-/express-http-proxy-1.6.3.tgz", "integrity": "sha512-/l77JHcOUrDUX8V67E287VEUQT0lbm71gdGVoodnlWBziarYKgMcpqT7xvh/HM8Jv52phw8Bd8tY+a7QjOr7Yg==", "requires": { "debug": "^3.0.1", "es6-promise": "^4.1.1", "raw-body": "^2.3.0" }, "dependencies": { "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "requires": { "type": "^2.7.2" }, "dependencies": { "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" } } }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" }, "dependencies": { "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "requires": { "os-tmpdir": "~1.0.2" } } } }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==", "dev": true, "optional": true, "requires": { "is-extglob": "^1.0.0" } }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" }, "dependencies": { "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" } } } }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==" }, "fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "requires": { "reusify": "^1.0.4" } }, "fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "requires": { "bser": "2.1.1" } }, "fbjs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.4.tgz", "integrity": "sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==", "requires": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", "loose-envify": "^1.0.0", "object-assign": "^4.1.0", "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^0.7.30" } }, "fbjs-css-vars": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, "fd": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/fd/-/fd-0.0.3.tgz", "integrity": "sha512-iAHrIslQb3U68OcMSP0kkNWabp7sSN6d2TBSb2JO3gcLJVDd4owr/hKM4SFJovFOUeeXeItjYgouEDTMWiVAnA==" }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "requires": { "flat-cache": "^3.0.4" } }, "file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" } }, "file-type": { "version": "16.5.4", "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", "requires": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, "optional": true }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==", "dev": true, "optional": true }, "filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==" }, "filenamify": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "requires": { "filename-reserved-regex": "^2.0.0", "strip-outer": "^1.0.1", "trim-repeated": "^1.0.0" } }, "filesize": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" }, "fill-range": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "optional": true, "requires": { "is-number": "^2.1.0", "isobject": "^2.0.0", "randomatic": "^3.0.0", "repeat-element": "^1.1.2", "repeat-string": "^1.5.2" } }, "filter-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==" }, "finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "requires": { "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" } }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" }, "dependencies": { "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } } } }, "flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "requires": { "is-callable": "^1.1.3" } }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "dev": true, "optional": true }, "for-own": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", "dev": true, "optional": true, "requires": { "for-in": "^1.0.1" } }, "fork-ts-checker-webpack-plugin": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", "requires": { "@babel/code-frame": "^7.8.3", "@types/json-schema": "^7.0.5", "chalk": "^4.1.0", "chokidar": "^3.4.2", "cosmiconfig": "^6.0.0", "deepmerge": "^4.2.2", "fs-extra": "^9.0.0", "glob": "^7.1.6", "memfs": "^3.1.2", "minimatch": "^3.0.4", "schema-utils": "2.7.0", "semver": "^7.3.2", "tapable": "^1.0.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.7.2" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "requires": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } }, "schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "requires": { "@types/json-schema": "^7.0.4", "ajv": "^6.12.2", "ajv-keywords": "^3.4.1" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "dev": true, "optional": true, "requires": { "map-cache": "^0.2.2" } }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-exists-cached": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", "integrity": "sha512-kSxoARUDn4F2RPXX48UXnaFKwVU7Ivd/6qpzZL29MCDmr9sTvybv4gFCp+qaI4fM9m0z9fgz/yJvi56GAz+BZg==" }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "fs-monkey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" } }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "function.prototype.name": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.0", "functions-have-names": "^1.2.2" } }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, "gatsby": { "version": "4.25.2", "resolved": "https://registry.npmjs.org/gatsby/-/gatsby-4.25.2.tgz", "integrity": "sha512-HKSWRdTOK5IBFDDgCKiPXiyszfdTTGZ+pple6My6dQ5a5U+Gn1PpjBIiYj4Me9WJAveQzC7tChsqBVVt7r6few==", "requires": { "@babel/code-frame": "^7.14.0", "@babel/core": "^7.15.5", "@babel/eslint-parser": "^7.15.4", "@babel/helper-plugin-utils": "^7.14.5", "@babel/parser": "^7.15.5", "@babel/runtime": "^7.15.4", "@babel/traverse": "^7.15.4", "@babel/types": "^7.15.4", "@builder.io/partytown": "^0.5.2", "@gatsbyjs/reach-router": "^1.3.9", "@gatsbyjs/webpack-hot-middleware": "^2.25.2", "@graphql-codegen/add": "^3.1.1", "@graphql-codegen/core": "^2.5.1", "@graphql-codegen/plugin-helpers": "^2.4.2", "@graphql-codegen/typescript": "^2.4.8", "@graphql-codegen/typescript-operations": "^2.3.5", "@graphql-tools/code-file-loader": "^7.2.14", "@graphql-tools/load": "^7.5.10", "@jridgewell/trace-mapping": "^0.3.13", "@nodelib/fs.walk": "^1.2.8", "@parcel/cache": "2.6.2", "@parcel/core": "2.6.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", "@types/http-proxy": "^1.17.7", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", "@vercel/webpack-asset-relocator-loader": "^1.7.0", "acorn-loose": "^8.3.0", "acorn-walk": "^8.2.0", "address": "1.1.2", "anser": "^2.1.0", "autoprefixer": "^10.4.0", "axios": "^0.21.1", "babel-loader": "^8.2.3", "babel-plugin-add-module-exports": "^1.0.4", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-lodash": "^3.3.4", "babel-plugin-remove-graphql-queries": "^4.25.0", "babel-preset-gatsby": "^2.25.0", "better-opn": "^2.1.1", "bluebird": "^3.7.2", "browserslist": "^4.17.5", "cache-manager": "^2.11.1", "chalk": "^4.1.2", "chokidar": "^3.5.3", "common-tags": "^1.8.0", "compression": "^1.7.4", "cookie": "^0.4.1", "core-js": "^3.22.3", "cors": "^2.8.5", "css-loader": "^5.2.7", "css-minimizer-webpack-plugin": "^2.0.0", "css.escape": "^1.5.1", "date-fns": "^2.25.0", "debug": "^3.2.7", "deepmerge": "^4.2.2", "detect-port": "^1.3.0", "devcert": "^1.2.0", "dotenv": "^8.6.0", "enhanced-resolve": "^5.8.3", "error-stack-parser": "^2.1.4", "eslint": "^7.32.0", "eslint-config-react-app": "^6.0.0", "eslint-plugin-flowtype": "^5.10.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-webpack-plugin": "^2.7.0", "event-source-polyfill": "1.0.25", "execa": "^5.1.1", "express": "^4.17.1", "express-graphql": "^0.12.0", "express-http-proxy": "^1.6.3", "fastest-levenshtein": "^1.0.12", "fastq": "^1.13.0", "file-loader": "^6.2.0", "find-cache-dir": "^3.3.2", "fs-exists-cached": "1.0.0", "fs-extra": "^10.1.0", "gatsby-cli": "^4.25.0", "gatsby-core-utils": "^3.25.0", "gatsby-graphiql-explorer": "^2.25.0", "gatsby-legacy-polyfills": "^2.25.0", "gatsby-link": "^4.25.0", "gatsby-page-utils": "^2.25.0", "gatsby-parcel-config": "0.16.0", "gatsby-plugin-page-creator": "^4.25.0", "gatsby-plugin-typescript": "^4.25.0", "gatsby-plugin-utils": "^3.19.0", "gatsby-react-router-scroll": "^5.25.0", "gatsby-script": "^1.10.0", "gatsby-sharp": "^0.19.0", "gatsby-telemetry": "^3.25.0", "gatsby-worker": "^1.25.0", "glob": "^7.2.3", "globby": "^11.1.0", "got": "^11.8.5", "graphql": "^15.7.2", "graphql-compose": "^9.0.7", "graphql-playground-middleware-express": "^1.7.22", "graphql-tag": "^2.12.6", "hasha": "^5.2.2", "invariant": "^2.2.4", "is-relative": "^1.0.0", "is-relative-url": "^3.0.0", "joi": "^17.4.2", "json-loader": "^0.5.7", "latest-version": "5.1.0", "lmdb": "2.5.3", "lodash": "^4.17.21", "md5-file": "^5.0.0", "meant": "^1.0.3", "memoizee": "^0.4.15", "micromatch": "^4.0.4", "mime": "^2.5.2", "mini-css-extract-plugin": "1.6.2", "mitt": "^1.2.0", "moment": "^2.29.1", "multer": "^1.4.5-lts.1", "node-fetch": "^2.6.6", "node-html-parser": "^5.3.3", "normalize-path": "^3.0.0", "null-loader": "^4.0.1", "opentracing": "^0.14.5", "p-defer": "^3.0.0", "parseurl": "^1.3.3", "physical-cpu-count": "^2.0.0", "platform": "^1.3.6", "postcss": "^8.3.11", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^5.3.0", "prompts": "^2.4.2", "prop-types": "^15.7.2", "query-string": "^6.14.1", "raw-loader": "^4.0.2", "react-dev-utils": "^12.0.1", "react-refresh": "^0.14.0", "react-server-dom-webpack": "0.0.0-experimental-c8b778b7f-20220825", "redux": "4.1.2", "redux-thunk": "^2.4.0", "resolve-from": "^5.0.0", "semver": "^7.3.7", "shallow-compare": "^1.2.2", "signal-exit": "^3.0.5", "slugify": "^1.6.1", "socket.io": "3.1.2", "socket.io-client": "3.1.3", "st": "^2.0.0", "stack-trace": "^0.0.10", "string-similarity": "^1.2.2", "strip-ansi": "^6.0.1", "style-loader": "^2.0.0", "terser-webpack-plugin": "^5.2.4", "tmp": "^0.2.1", "true-case-path": "^2.2.1", "type-of": "^2.0.1", "url-loader": "^4.1.1", "uuid": "^8.3.2", "webpack": "^5.61.0", "webpack-dev-middleware": "^4.3.0", "webpack-merge": "^5.8.0", "webpack-stats-plugin": "^1.0.3", "webpack-virtual-modules": "^0.3.2", "xstate": "4.32.1", "yaml-loader": "^0.8.0" }, "dependencies": { "acorn": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "babel-preset-gatsby": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/babel-preset-gatsby/-/babel-preset-gatsby-2.25.0.tgz", "integrity": "sha512-KFfSTDAkY87/Myq1KIUk9cVphWZem/08U7ps9Hiotbo6Mge/lL6ggh3xKP9SdR5Le4DLLyIUI7a4ILrAVacYDg==", "requires": { "@babel/plugin-proposal-class-properties": "^7.14.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", "@babel/plugin-proposal-optional-chaining": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-classes": "^7.15.4", "@babel/plugin-transform-runtime": "^7.15.0", "@babel/plugin-transform-spread": "^7.14.6", "@babel/preset-env": "^7.15.4", "@babel/preset-react": "^7.14.0", "@babel/runtime": "^7.15.4", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-macros": "^3.1.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "gatsby-core-utils": "^3.25.0", "gatsby-legacy-polyfills": "^2.25.0" } }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "core-js": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==" }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "react-server-dom-webpack": { "version": "0.0.0-experimental-c8b778b7f-20220825", "resolved": "https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-0.0.0-experimental-c8b778b7f-20220825.tgz", "integrity": "sha512-JyCjbp6ZvkH/T0EuVPdceYlC8u5WqWDSJr2KxDvc81H2eJ+7zYUN++IcEycnR2F+HmER8QVgxfotnIx352zi+w==", "requires": { "acorn": "^6.2.1", "loose-envify": "^1.1.0", "neo-async": "^2.6.1" } }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "gatsby-cli": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-4.25.0.tgz", "integrity": "sha512-CJ2PCsfFmn9Xqc/jg9MFMU1BG5oQGiej1TFFx8GhChJ+kGhi9ANnNM+qo1K4vOmoMnsT4SSGiPAFD10AWFqpAQ==", "requires": { "@babel/code-frame": "^7.14.0", "@babel/core": "^7.15.5", "@babel/generator": "^7.16.8", "@babel/helper-plugin-utils": "^7.16.7", "@babel/preset-typescript": "^7.16.7", "@babel/runtime": "^7.15.4", "@babel/template": "^7.16.7", "@babel/types": "^7.16.8", "@jridgewell/trace-mapping": "^0.3.13", "@types/common-tags": "^1.8.1", "better-opn": "^2.1.1", "boxen": "^5.1.2", "chalk": "^4.1.2", "clipboardy": "^2.3.0", "common-tags": "^1.8.2", "convert-hrtime": "^3.0.0", "create-gatsby": "^2.25.0", "envinfo": "^7.8.1", "execa": "^5.1.1", "fs-exists-cached": "^1.0.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-telemetry": "^3.25.0", "hosted-git-info": "^3.0.8", "is-valid-path": "^0.1.1", "joi": "^17.4.2", "lodash": "^4.17.21", "node-fetch": "^2.6.6", "opentracing": "^0.14.5", "pretty-error": "^2.1.2", "progress": "^2.0.3", "prompts": "^2.4.2", "redux": "4.1.2", "resolve-cwd": "^3.0.0", "semver": "^7.3.7", "signal-exit": "^3.0.6", "stack-trace": "^0.0.10", "strip-ansi": "^6.0.1", "update-notifier": "^5.1.0", "yargs": "^15.4.1", "yoga-layout-prebuilt": "^1.10.0", "yurnalist": "^2.1.0" }, "dependencies": { "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "gatsby-core-utils": { "version": "3.25.0", "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-3.25.0.tgz", "integrity": "sha512-lmMDwbnKpqAi+8WWd7MvCTCx3E0u7j8sbVgydERNCYVxKVpzD/aLCH4WPb4EE9m1H1rSm76w0Z+MaentyB/c/Q==", "requires": { "@babel/runtime": "^7.15.4", "ci-info": "2.0.0", "configstore": "^5.0.1", "fastq": "^1.13.0", "file-type": "^16.5.3", "fs-extra": "^10.1.0", "got": "^11.8.5", "import-from": "^4.0.0", "lmdb": "2.5.3", "lock": "^1.1.0", "node-object-hash": "^2.3.10", "proper-lockfile": "^4.1.2", "resolve-from": "^5.0.0", "tmp": "^0.2.1", "xdg-basedir": "^4.0.0" } }, "gatsby-graphiql-explorer": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/gatsby-graphiql-explorer/-/gatsby-graphiql-explorer-2.25.0.tgz", "integrity": "sha512-/NDsaW4x3/KtvzmxYvedhDwUW1kb7gQO6iOhCkillVJSYBd6mPB8aOSulM49fyCT76UXGYFtRaUI8fyOkmpWhg==", "requires": { "@babel/runtime": "^7.15.4" } }, "gatsby-image": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/gatsby-image/-/gatsby-image-2.11.0.tgz", "integrity": "sha512-H1va64RgXizYXONhoqB3rAdSqALZi0hkBYqEsc0peVEYzb2maRhEwOchg65hKvp3HT/ahnfrik59epRguYvi/g==", "requires": { "@babel/runtime": "^7.12.5", "object-fit-images": "^3.2.4", "prop-types": "^15.7.2" } }, "gatsby-legacy-polyfills": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/gatsby-legacy-polyfills/-/gatsby-legacy-polyfills-2.25.0.tgz", "integrity": "sha512-cMeFwMH1FGENo2gNpyTyMYc/CJ7uBGE26n89OGrVVvBMaQegK+CMNZBOh09sLrXUcOp8hSOX2IwzvOlo6CdWpg==", "requires": { "@babel/runtime": "^7.15.4", "core-js-compat": "3.9.0" } }, "gatsby-link": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-link/-/gatsby-link-4.25.0.tgz", "integrity": "sha512-Fpwk45sUMPvFUAZehNE8SLb3vQyVSxt9YxU++ZZECyukK4A/3Wxk3eIzoNvwfpMfWu6pnAkqcBhIO6KAfvbPGQ==", "requires": { "@types/reach__router": "^1.3.10", "gatsby-page-utils": "^2.25.0", "prop-types": "^15.8.1" } }, "gatsby-page-utils": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/gatsby-page-utils/-/gatsby-page-utils-2.25.0.tgz", "integrity": "sha512-TlwS149JCeb3xGANeV8HdcQi9Q8J9hYwlO9jdxLGVIXVGbWIMWFrDuwx382jOOsISGQ3jfByToNulUzO6fiqig==", "requires": { "@babel/runtime": "^7.15.4", "bluebird": "^3.7.2", "chokidar": "^3.5.3", "fs-exists-cached": "^1.0.0", "gatsby-core-utils": "^3.25.0", "glob": "^7.2.3", "lodash": "^4.17.21", "micromatch": "^4.0.5" }, "dependencies": { "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } } } }, "gatsby-parcel-config": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/gatsby-parcel-config/-/gatsby-parcel-config-0.16.0.tgz", "integrity": "sha512-2+hOg6cMBGZ8r+4lN3k+dOWGvku453vbZCAhp6V3RuFYxbWuvDFP7Icr0GCOyZ62utkFr9m7H2U1Wjf4KOHyEQ==", "requires": { "@gatsbyjs/parcel-namer-relative-to-cwd": "^1.10.0", "@parcel/bundler-default": "2.6.2", "@parcel/compressor-raw": "2.6.2", "@parcel/namer-default": "2.6.2", "@parcel/optimizer-terser": "2.6.2", "@parcel/packager-js": "2.6.2", "@parcel/packager-raw": "2.6.2", "@parcel/reporter-dev-server": "2.6.2", "@parcel/resolver-default": "2.6.2", "@parcel/runtime-js": "2.6.2", "@parcel/transformer-js": "2.6.2", "@parcel/transformer-json": "2.6.2" } }, "gatsby-plugin-google-analytics": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-google-analytics/-/gatsby-plugin-google-analytics-4.25.0.tgz", "integrity": "sha512-fbHrViBAbJ0Ch2gcpuJQlGxWoapaNed42k75eR4gCiZPzaTUvCKagJgLG8ro8ukD1rfD594lgLzdSEaYYcH4WQ==", "requires": { "@babel/runtime": "^7.15.4", "minimatch": "3.0.4", "web-vitals": "^1.1.2" }, "dependencies": { "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } } } }, "gatsby-plugin-manifest": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-manifest/-/gatsby-plugin-manifest-4.25.0.tgz", "integrity": "sha512-2n7v+TvhWUMoOJEaeiPDFsf9jvOImKLZpnzxE8e6ZeeoGeDngXSZhkkP3x2UYIknHtZXUUjFJh8BaVBXiB1dSQ==", "requires": { "@babel/runtime": "^7.15.4", "gatsby-core-utils": "^3.25.0", "gatsby-plugin-utils": "^3.19.0", "semver": "^7.3.7", "sharp": "^0.30.7" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "gatsby-plugin-offline": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-offline/-/gatsby-plugin-offline-5.25.0.tgz", "integrity": "sha512-WqAcnYvMpL1xwXF5Jf9BXTihLNktuqQHFUX0TPsQVJrmfjSNv4LxhgiWfeUuGiCO881EOHClXnBn6TqxIdS4EA==", "requires": { "@babel/runtime": "^7.15.4", "cheerio": "^1.0.0-rc.10", "gatsby-core-utils": "^3.25.0", "glob": "^7.2.3", "idb-keyval": "^3.2.0", "lodash": "^4.17.21", "workbox-build": "^4.3.1" } }, "gatsby-plugin-page-creator": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-4.25.0.tgz", "integrity": "sha512-plHek7xHSV9l1bLPa1JAnxzBqP7j2ihCPRwpBk/wIJAR8cG65wjAT+Nu8DKpW0+2/MYill84ns1r2m8g0L/7bg==", "requires": { "@babel/runtime": "^7.15.4", "@babel/traverse": "^7.15.4", "@sindresorhus/slugify": "^1.1.2", "chokidar": "^3.5.3", "fs-exists-cached": "^1.0.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-page-utils": "^2.25.0", "gatsby-plugin-utils": "^3.19.0", "gatsby-telemetry": "^3.25.0", "globby": "^11.1.0", "lodash": "^4.17.21" }, "dependencies": { "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } } } }, "gatsby-plugin-plausible": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/gatsby-plugin-plausible/-/gatsby-plugin-plausible-0.0.7.tgz", "integrity": "sha512-pWCXsrWal8lWMmZ1wJ2dolbwZZR1CZU1LVR/K1rYC8NeA+uqTLY8h3uH3hFgP5n8jmRRenOSJ9SjWM9OIdCjOA==", "requires": { "@babel/runtime": "^7.9.2", "minimatch": "3.0.4", "react": "^16.13.1" }, "dependencies": { "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } } } }, "gatsby-plugin-react-helmet": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-5.25.0.tgz", "integrity": "sha512-sU/xae/sGuYFcFDpqUxwXnaOmx8xrU2Q+XSULqAapji0uTBhW6al6CJsaPFigi8IOG2bQX8ano2iWWcGF3/GHw==", "requires": { "@babel/runtime": "^7.15.4" } }, "gatsby-plugin-react-svg": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-react-svg/-/gatsby-plugin-react-svg-3.3.0.tgz", "integrity": "sha512-kFPElMFu1QCkiFCm1pSrVkOHAeafU6wkD0qCVPs7nL/Txh5KFh0aOO6Feiwvfre1Jo+Eg3lwCuGmgsy9L+4pDg==", "requires": { "svg-react-loader": "^0.4.6" } }, "gatsby-plugin-remove-trailing-slashes": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-remove-trailing-slashes/-/gatsby-plugin-remove-trailing-slashes-4.19.0.tgz", "integrity": "sha512-3zyL+6pqQIeAvABi3PbtVi285n9CVCopzLZNiCLN81/xPiCggA1yyNaZVV3eS1ZbOVFlWCAFyEBRl6E6QeI2BQ==", "requires": { "@babel/runtime": "^7.15.4" } }, "gatsby-plugin-sass": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-sass/-/gatsby-plugin-sass-5.25.0.tgz", "integrity": "sha512-e+47Z24DI+Uh3KcUbj/WvTyH4ZPXcC4zlwqhzspv1Ye+xMS1ipTsIelvBuTwiiEWBs6cqdcYAPhn7HoXX/errw==", "requires": { "@babel/runtime": "^7.15.4", "resolve-url-loader": "^3.1.4", "sass-loader": "^10.1.1" } }, "gatsby-plugin-sass-resources": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/gatsby-plugin-sass-resources/-/gatsby-plugin-sass-resources-3.0.1.tgz", "integrity": "sha512-C332NqMOd6z0q7F02OmL/Bl7BoJyD73vcfpF22M+qVy3TE9ugL94Pcdpki8s5TUSwJgqgs9qkTuLD+jDphMsWw==", "requires": { "@babel/runtime": "^7.0.0", "sass-resources-loader": "^1.3.3", "webpack": "^5.0.0" } }, "gatsby-plugin-sharp": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-4.25.0.tgz", "integrity": "sha512-8XiSKibQyp6pOFHEkEdRCpoDA3Ywcq5PKftNMExZ51MormT0+WqRC7ynuU+0fzktDTbbSyREvblKa+21Id+rRA==", "requires": { "@babel/runtime": "^7.15.4", "async": "^3.2.4", "bluebird": "^3.7.2", "debug": "^4.3.4", "filenamify": "^4.3.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-plugin-utils": "^3.19.0", "lodash": "^4.17.21", "probe-image-size": "^7.2.3", "semver": "^7.3.7", "sharp": "^0.30.7" }, "dependencies": { "async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "gatsby-plugin-sitemap": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-sitemap/-/gatsby-plugin-sitemap-5.25.0.tgz", "integrity": "sha512-0MYinO0MTsOIEd7d2NOCm/JVdFIMgoIEFem/S0gMpuW4rBCpsE6McPmRKGZl2bp277jEhU8ACt4/49nsCA1AoA==", "requires": { "@babel/runtime": "^7.15.4", "common-tags": "^1.8.2", "minimatch": "^3.1.2", "sitemap": "^7.0.0" } }, "gatsby-plugin-typescript": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-typescript/-/gatsby-plugin-typescript-4.25.0.tgz", "integrity": "sha512-8BTtiVWuIqIEGx/PBBMWd6FYPgel16hT3js7SMo5oI9K4EPsSxRItgRf41MTJGxRR20EhL4e99g2S8x0v1+odA==", "requires": { "@babel/core": "^7.15.5", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", "@babel/plugin-proposal-numeric-separator": "^7.14.5", "@babel/plugin-proposal-optional-chaining": "^7.14.5", "@babel/preset-typescript": "^7.15.0", "@babel/runtime": "^7.15.4", "babel-plugin-remove-graphql-queries": "^4.25.0" } }, "gatsby-plugin-utils": { "version": "3.19.0", "resolved": "https://registry.npmjs.org/gatsby-plugin-utils/-/gatsby-plugin-utils-3.19.0.tgz", "integrity": "sha512-EZtvgHSU5NPbEn6a4cfSpEGCQ09SfwbhoybHTJKj1clop86HSwOCV2iH8RbCc+X6jbdgHaSZsfsl7zG1h7DBUw==", "requires": { "@babel/runtime": "^7.15.4", "fastq": "^1.13.0", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "gatsby-sharp": "^0.19.0", "graphql-compose": "^9.0.7", "import-from": "^4.0.0", "joi": "^17.4.2", "mime": "^3.0.0" }, "dependencies": { "mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" } } }, "gatsby-react-router-scroll": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-react-router-scroll/-/gatsby-react-router-scroll-5.25.0.tgz", "integrity": "sha512-SFSdezIa5lahCE8ieCLrtLA5tztemGco/rN8si9rI9KHu1h1jPvDhsNqs2g+Z50JrUb1RPfsmxJTmLa5i6MIgQ==", "requires": { "@babel/runtime": "^7.15.4", "prop-types": "^15.8.1" } }, "gatsby-remark-copy-linked-files": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-copy-linked-files/-/gatsby-remark-copy-linked-files-5.25.0.tgz", "integrity": "sha512-kF068dZ0U920xNrlKM5BIR1MvgFdVvgR281AJfvn1xOvv/ES3elPj2bqlokbcs1f72dYcNnaJhv3UhYoIdV6Fg==", "requires": { "@babel/runtime": "^7.15.4", "cheerio": "^1.0.0-rc.10", "fs-extra": "^10.1.0", "is-relative-url": "^3.0.0", "lodash": "^4.17.21", "path-is-inside": "^1.0.2", "probe-image-size": "^7.2.3", "unist-util-visit": "^2.0.3" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "gatsby-remark-images": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-images/-/gatsby-remark-images-6.25.0.tgz", "integrity": "sha512-NNJ17OxA8xPFtTHBfWCxAGqU9ciOielWALUlzY1YdCvYl2rcDmw498tjx77wC995yCBkcwe7yfL1tgky9bxdqQ==", "requires": { "@babel/runtime": "^7.15.4", "chalk": "^4.1.2", "cheerio": "^1.0.0-rc.10", "gatsby-core-utils": "^3.25.0", "is-relative-url": "^3.0.0", "lodash": "^4.17.21", "mdast-util-definitions": "^4.0.0", "query-string": "^6.14.1", "unist-util-select": "^3.0.4", "unist-util-visit-parents": "^3.1.1" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "gatsby-remark-prismjs": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-prismjs/-/gatsby-remark-prismjs-6.25.0.tgz", "integrity": "sha512-O33q0aQjl3X8nVEFboQ0RKtnHLhhb0BU+ErK0D9MA6w4qSDRmDjFIWDY7nrsBP5QR80V1sjbjr4zBAAdOre/dA==", "requires": { "@babel/runtime": "^7.15.4", "parse-numeric-range": "^1.2.0", "unist-util-visit": "^2.0.3" }, "dependencies": { "parse-numeric-range": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" }, "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "gatsby-remark-smartypants": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/gatsby-remark-smartypants/-/gatsby-remark-smartypants-5.25.0.tgz", "integrity": "sha512-HTcDlQkYQ3regRvQYBuGSCTWE6d4l277yGNYOq89yxkn0CSra/FfplLWUakvFrPLQQaQwpXewhUPXSWkp/PTZg==", "requires": { "@babel/runtime": "^7.15.4", "retext": "^7.0.1", "retext-smartypants": "^4.0.0", "unist-util-visit": "^2.0.3" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "gatsby-remark-unwrap-images": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/gatsby-remark-unwrap-images/-/gatsby-remark-unwrap-images-1.0.2.tgz", "integrity": "sha512-kOatDaz6EcYJn6oEx97pim0JkzuN1epacmHuKP9kL7r3+y1dzvNQjrJMtmDZTqC6Q8LhXD2rrFhsYS3SerTHhw==", "requires": { "unist-util-remove": "^1.0.1", "unist-util-visit": "^1.4.0" } }, "gatsby-script": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/gatsby-script/-/gatsby-script-1.10.0.tgz", "integrity": "sha512-8jAtQR0mw3G8sCy6i2D1jfGvUF5d9AIboEQuo9ZEChT4Ep5f+PSRxiWZqSjhKvintAOIeS4QXCJP5Rtp3xZKLg==", "requires": {} }, "gatsby-sharp": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/gatsby-sharp/-/gatsby-sharp-0.19.0.tgz", "integrity": "sha512-EbI3RNBu2+aaxuMUP/INmoj8vcNAG6BgpFvi1tLeU7/gVTNVQ+7pC/ZYtlVCzSw+faaw7r1ZBMi6F66mNIIz5A==", "requires": { "@types/sharp": "^0.30.5", "sharp": "^0.30.7" } }, "gatsby-source-filesystem": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-4.25.0.tgz", "integrity": "sha512-gja4++bPkYpnum4/TxFicr3zRHBArnM2HjT77EE4EuDhdl6qlJYr/heD09LIPN2jdR5gmPwMDjIZnuYZ/6j/aQ==", "requires": { "@babel/runtime": "^7.15.4", "chokidar": "^3.5.3", "file-type": "^16.5.4", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "md5-file": "^5.0.0", "mime": "^2.5.2", "pretty-bytes": "^5.4.1", "valid-url": "^1.0.9", "xstate": "4.32.1" }, "dependencies": { "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { "fill-range": "^7.0.1" } }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } } } }, "gatsby-telemetry": { "version": "3.25.0", "resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-3.25.0.tgz", "integrity": "sha512-FGC1yS2evJxTN/Ku9XonCBiqhH6uO6aPjjps65BbL+Xbpct/qfirIFxYG6DhHPrksR0fKOhstJGnQqay74hWdQ==", "requires": { "@babel/code-frame": "^7.14.0", "@babel/runtime": "^7.15.4", "@turist/fetch": "^7.2.0", "@turist/time": "^0.0.2", "boxen": "^4.2.0", "configstore": "^5.0.1", "fs-extra": "^10.1.0", "gatsby-core-utils": "^3.25.0", "git-up": "^7.0.0", "is-docker": "^2.2.1", "lodash": "^4.17.21", "node-fetch": "^2.6.7" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "requires": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", "chalk": "^3.0.0", "cli-boxes": "^2.2.0", "string-width": "^4.1.0", "term-size": "^2.1.0", "type-fest": "^0.8.1", "widest-line": "^3.1.0" } }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, "gatsby-transformer-remark": { "version": "5.25.1", "resolved": "https://registry.npmjs.org/gatsby-transformer-remark/-/gatsby-transformer-remark-5.25.1.tgz", "integrity": "sha512-6k3uOnZYsJSgmZIWq9Y+Cqb6pysusCUBYpQY1+V9ofpSRbrZGGfuoCeFKd27x/c0jI5jneuL3NXnxwn/JJK1Ig==", "requires": { "@babel/runtime": "^7.15.4", "gatsby-core-utils": "^3.25.0", "gray-matter": "^4.0.3", "hast-util-raw": "^6.0.2", "hast-util-to-html": "^7.1.3", "lodash": "^4.17.21", "mdast-util-to-hast": "^10.2.0", "mdast-util-to-string": "^2.0.0", "mdast-util-toc": "^5.1.0", "remark": "^13.0.0", "remark-footnotes": "^3.0.0", "remark-gfm": "^1.0.0", "remark-parse": "^9.0.0", "remark-retext": "^4.0.0", "remark-stringify": "^9.0.1", "retext-english": "^3.0.4", "sanitize-html": "^1.27.5", "underscore.string": "^3.3.6", "unified": "^9.2.2", "unist-util-remove-position": "^3.0.0", "unist-util-select": "^3.0.4", "unist-util-visit": "^2.0.3" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "gatsby-transformer-sharp": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/gatsby-transformer-sharp/-/gatsby-transformer-sharp-4.25.0.tgz", "integrity": "sha512-7aqecTvOUFiNB96ij77UnAGJs7Un0TlkpamG//dSl6Nru9EylGz/NW/Eg0vioQyHLCYdMvd5xO8V3BOHJADsnw==", "requires": { "@babel/runtime": "^7.15.4", "bluebird": "^3.7.2", "common-tags": "^1.8.2", "fs-extra": "^10.1.0", "gatsby-plugin-utils": "^3.19.0", "probe-image-size": "^7.2.3", "semver": "^7.3.7", "sharp": "^0.30.7" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "gatsby-worker": { "version": "1.25.0", "resolved": "https://registry.npmjs.org/gatsby-worker/-/gatsby-worker-1.25.0.tgz", "integrity": "sha512-gjp28irgHASihwvMyF5aZMALWGax9mEmcD8VYGo2osRe7p6BZuWi4cSuP9XM9EvytDvIugpnSadmTP01B7LtWg==", "requires": { "@babel/core": "^7.15.5", "@babel/runtime": "^7.15.4" } }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.3" } }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" }, "get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" } }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "dev": true, "optional": true }, "git-up": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", "requires": { "is-ssh": "^1.4.0", "parse-url": "^8.1.0" } }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==", "dev": true, "optional": true, "requires": { "glob-parent": "^2.0.0", "is-glob": "^2.0.0" } }, "glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==", "dev": true, "optional": true, "requires": { "is-glob": "^2.0.0" } }, "glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, "global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "requires": { "ini": "2.0.0" }, "dependencies": { "ini": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" } } }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "requires": { "global-prefix": "^3.0.0" } }, "global-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "requires": { "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" }, "dependencies": { "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { "isexe": "^2.0.0" } } } }, "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "globalthis": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "requires": { "define-properties": "^1.1.3" } }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" }, "dependencies": { "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" } } }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "requires": { "get-intrinsic": "^1.1.3" } }, "got": { "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "requires": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "graphql": { "version": "15.8.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==" }, "graphql-compose": { "version": "9.0.10", "resolved": "https://registry.npmjs.org/graphql-compose/-/graphql-compose-9.0.10.tgz", "integrity": "sha512-UsVoxfi2+c8WbHl2pEB+teoRRZoY4mbWBoijeLDGpAZBSPChnqtSRjp+T9UcouLCwGr5ooNyOQLoI3OVzU1bPQ==", "requires": { "graphql-type-json": "0.3.2" } }, "graphql-playground-html": { "version": "1.6.30", "resolved": "https://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.6.30.tgz", "integrity": "sha512-tpCujhsJMva4aqE8ULnF7/l3xw4sNRZcSHu+R00VV+W0mfp+Q20Plvcrp+5UXD+2yS6oyCXncA+zoQJQqhGCEw==", "requires": { "xss": "^1.0.6" } }, "graphql-playground-middleware-express": { "version": "1.7.23", "resolved": "https://registry.npmjs.org/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.23.tgz", "integrity": "sha512-M/zbTyC1rkgiQjFSgmzAv6umMHOphYLNWZp6Ye5QrD77WfGOOoSqDsVmGUczc2pDkEPEzzGB/bvBO5rdzaTRgw==", "requires": { "graphql-playground-html": "^1.6.30" } }, "graphql-tag": { "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", "requires": { "tslib": "^2.1.0" } }, "graphql-type-json": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", "requires": {} }, "gray-matter": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", "requires": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "requires": { "duplexer": "^0.1.2" } }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "requires": { "function-bind": "^1.1.1" } }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "requires": { "ansi-regex": "^2.0.0" } }, "has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, "has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-property-descriptors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "requires": { "get-intrinsic": "^1.1.1" } }, "has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "requires": { "has-symbols": "^1.0.2" } }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "dev": true, "optional": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "dev": true, "optional": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" }, "dependencies": { "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" }, "hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "requires": { "is-stream": "^2.0.0", "type-fest": "^0.8.0" }, "dependencies": { "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, "hast-to-hyperscript": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", "requires": { "@types/unist": "^2.0.3", "comma-separated-tokens": "^1.0.0", "property-information": "^5.3.0", "space-separated-tokens": "^1.0.0", "style-to-object": "^0.3.0", "unist-util-is": "^4.0.0", "web-namespaces": "^1.0.0" } }, "hast-util-from-parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", "requires": { "@types/parse5": "^5.0.0", "hastscript": "^6.0.0", "property-information": "^5.0.0", "vfile": "^4.0.0", "vfile-location": "^3.2.0", "web-namespaces": "^1.0.0" } }, "hast-util-is-element": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==" }, "hast-util-parse-selector": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" }, "hast-util-raw": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.1.0.tgz", "integrity": "sha512-5FoZLDHBpka20OlZZ4I/+RBw5piVQ8iI1doEvffQhx5CbCyTtP8UCq8Tw6NmTAMtXgsQxmhW7Ly8OdFre5/YMQ==", "requires": { "@types/hast": "^2.0.0", "hast-util-from-parse5": "^6.0.0", "hast-util-to-parse5": "^6.0.0", "html-void-elements": "^1.0.0", "parse5": "^6.0.0", "unist-util-position": "^3.0.0", "unist-util-visit": "^2.0.0", "vfile": "^4.0.0", "web-namespaces": "^1.0.0", "xtend": "^4.0.0", "zwitch": "^1.0.0" }, "dependencies": { "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "hast-util-sanitize": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.3.1.tgz", "integrity": "sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==", "requires": { "xtend": "^4.0.1" } }, "hast-util-to-html": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz", "integrity": "sha512-yk2+1p3EJTEE9ZEUkgHsUSVhIpCsL/bvT8E5GzmWc+N1Po5gBw+0F8bo7dpxXR0nu0bQVxVZGX2lBGF21CmeDw==", "requires": { "ccount": "^1.0.0", "comma-separated-tokens": "^1.0.0", "hast-util-is-element": "^1.0.0", "hast-util-whitespace": "^1.0.0", "html-void-elements": "^1.0.0", "property-information": "^5.0.0", "space-separated-tokens": "^1.0.0", "stringify-entities": "^3.0.1", "unist-util-is": "^4.0.0", "xtend": "^4.0.0" } }, "hast-util-to-parse5": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", "requires": { "hast-to-hyperscript": "^9.0.0", "property-information": "^5.0.0", "web-namespaces": "^1.0.0", "xtend": "^4.0.0", "zwitch": "^1.0.0" } }, "hast-util-whitespace": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==" }, "hastscript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", "requires": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^1.0.0", "hast-util-parse-selector": "^2.0.0", "property-information": "^5.0.0", "space-separated-tokens": "^1.0.0" } }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "header-case": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", "requires": { "capital-case": "^1.0.4", "tslib": "^2.0.3" } }, "hoist-non-react-statics": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.1" } }, "hosted-git-info": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", "requires": { "lru-cache": "^6.0.0" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, "html-to-react": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.5.0.tgz", "integrity": "sha512-tjihXBgaJZRRYzmkrJZ/Qf9jFayilFYcb+sJxXXE2BVLk2XsNrGeuNCVvhXmvREULZb9dz6NFTBC96DTR/lQCQ==", "requires": { "domhandler": "^5.0", "htmlparser2": "^8.0", "lodash.camelcase": "^4.3.0" } }, "html-void-elements": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==" }, "htmlparser2": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "requires": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "entities": "^4.3.0" } }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "requires": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, "hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "requires": {} }, "idb-keyval": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz", "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==" }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" }, "immer": { "version": "9.0.17", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.17.tgz", "integrity": "sha512-+hBruaLSQvkPfxRiTLK/mi4vLH+/VQS6z2KJahdoxlleFOI8ARqzOF17uy12eFDlqWmPoygwc5evgwcp+dlHhg==" }, "immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==" }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "dependencies": { "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" } } }, "import-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==" }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==" }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "requires": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.19", "mute-stream": "0.0.8", "run-async": "^2.4.0", "rxjs": "^6.6.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "dependencies": { "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "requires": { "type-fest": "^0.21.3" } }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" } } }, "internal-slot": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "requires": { "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" } }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "requires": { "loose-envify": "^1.0.0" } }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "requires": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" } }, "is-absolute-url": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "optional": true, "requires": { "kind-of": "^6.0.0" } }, "is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" }, "is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", "requires": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" } }, "is-array-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "is-typed-array": "^1.1.10" } }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "requires": { "has-bigints": "^1.0.1" } }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", "dev": true, "optional": true, "requires": { "binary-extensions": "^1.0.0" } }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" } }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "requires": { "ci-info": "^2.0.0" } }, "is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "optional": true, "requires": { "kind-of": "^6.0.0" } }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "requires": { "has-tostringtag": "^1.0.0" } }, "is-decimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } }, "is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", "integrity": "sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==", "dev": true, "optional": true }, "is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==", "dev": true, "optional": true, "requires": { "is-primitive": "^2.0.0" } }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" }, "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==" }, "is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-function": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", "requires": { "is-extglob": "^1.0.0" } }, "is-hexadecimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" }, "is-in-browser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" }, "is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "requires": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" } }, "is-invalid-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", "integrity": "sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==", "requires": { "is-glob": "^2.0.0" } }, "is-lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", "requires": { "tslib": "^2.0.3" } }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" }, "is-npm": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==" }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "requires": { "has-tostringtag": "^1.0.0" } }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { "isobject": "^3.0.1" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", "integrity": "sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==", "dev": true, "optional": true }, "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==", "dev": true, "optional": true }, "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" } }, "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "requires": { "is-unc-path": "^1.0.0" } }, "is-relative-url": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-3.0.0.tgz", "integrity": "sha512-U1iSYRlY2GIMGuZx7gezlB5dp1Kheaym7zKzO1PV06mOihiWTXejLwm4poEJysPyXF+HtK/BEd0DVlcCh30pEA==", "requires": { "is-absolute-url": "^3.0.0" } }, "is-root": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" }, "is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "requires": { "call-bind": "^1.0.2" } }, "is-ssh": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", "requires": { "protocols": "^2.0.1" } }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, "is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "requires": { "has-tostringtag": "^1.0.0" } }, "is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "requires": { "has-symbols": "^1.0.2" } }, "is-typed-array": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" } }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "requires": { "unc-path-regex": "^0.1.2" } }, "is-upper-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", "requires": { "tslib": "^2.0.3" } }, "is-valid-domain": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.1.6.tgz", "integrity": "sha512-ZKtq737eFkZr71At8NxOFcP9O1K89gW3DkdrGMpp1upr/ueWjj+Weh4l9AI4rN0Gt8W2M1w7jrG2b/Yv83Ljpg==", "requires": { "punycode": "^2.1.1" } }, "is-valid-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", "integrity": "sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==", "requires": { "is-invalid-path": "^0.1.0" } }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "requires": { "call-bind": "^1.0.2" } }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "requires": { "is-docker": "^2.0.0" } }, "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dev": true, "optional": true, "requires": { "isarray": "1.0.0" } }, "javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" }, "jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "requires": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, "dependencies": { "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "joi": { "version": "17.7.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==" }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", "dev": true }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "json-loader": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "requires": { "graceful-fs": "^4.1.6", "universalify": "^2.0.0" } }, "jss": { "version": "9.8.7", "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", "requires": { "is-in-browser": "^1.1.3", "symbol-observable": "^1.1.0", "warning": "^3.0.0" } }, "jss-camel-case": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz", "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==", "requires": { "hyphenate-style-name": "^1.0.2" } }, "jss-compose": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz", "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==", "requires": { "warning": "^3.0.0" } }, "jss-default-unit": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz", "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==", "requires": {} }, "jss-expand": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz", "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg==", "requires": {} }, "jss-extend": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz", "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==", "requires": { "warning": "^3.0.0" } }, "jss-global": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==", "requires": {} }, "jss-nested": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", "requires": { "warning": "^3.0.0" } }, "jss-preset-default": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz", "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==", "requires": { "jss-camel-case": "^6.1.0", "jss-compose": "^5.0.0", "jss-default-unit": "^8.0.2", "jss-expand": "^5.3.0", "jss-extend": "^6.2.0", "jss-global": "^3.0.0", "jss-nested": "^6.0.1", "jss-props-sort": "^6.0.0", "jss-template": "^1.0.1", "jss-vendor-prefixer": "^7.0.0" } }, "jss-props-sort": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==", "requires": {} }, "jss-template": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz", "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==", "requires": { "warning": "^3.0.0" } }, "jss-vendor-prefixer": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", "requires": { "css-vendor": "^0.3.8" } }, "jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", "requires": { "array-includes": "^3.1.5", "object.assign": "^4.1.3" } }, "keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "requires": { "json-buffer": "3.0.1" } }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" }, "klona": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" }, "language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" }, "language-tags": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.7.tgz", "integrity": "sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==", "requires": { "language-subtag-registry": "^0.3.20" } }, "latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "requires": { "package-json": "^6.3.0" } }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "lmdb": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.3.tgz", "integrity": "sha512-iBA0cb13CobBSoGJLfZgnrykLlfJipDAnvtf+YwIqqzBEsTeQYsXrHaSBkaHd5wCWeabwrNvhjZoFMUrlo+eLw==", "requires": { "@lmdb/lmdb-darwin-arm64": "2.5.3", "@lmdb/lmdb-darwin-x64": "2.5.3", "@lmdb/lmdb-linux-arm": "2.5.3", "@lmdb/lmdb-linux-arm64": "2.5.3", "@lmdb/lmdb-linux-x64": "2.5.3", "@lmdb/lmdb-win32-x64": "2.5.3", "msgpackr": "^1.5.4", "node-addon-api": "^4.3.0", "node-gyp-build-optional-packages": "5.0.3", "ordered-binary": "^1.2.4", "weak-lru-cache": "^1.2.2" }, "dependencies": { "node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" } } }, "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" }, "loader-utils": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "requires": { "p-locate": "^5.0.0" } }, "lock": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/lock/-/lock-1.1.0.tgz", "integrity": "sha512-NZQIJJL5Rb9lMJ0Yl1JoVr9GSdo4HTPsUEWsSFzB8dE8DSoiLCVavWZPi7Rnlv/o73u6I24S/XYc/NmG4l8EKA==" }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.deburr": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==" }, "lodash.every": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", "integrity": "sha512-isF82d+65/sNvQ3aaQAW7LLHnnTxSN/2fm4rhYyuufLzA4VtHz6y6S5vFwe6PQVr2xdqUOyxBbTNKDpnmeu50w==" }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==" }, "lodash.foreach": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==" }, "lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==" }, "lodash.maxby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.maxby/-/lodash.maxby-4.6.0.tgz", "integrity": "sha512-QfTqQTwzmKxLy7VZlbx2M/ipWv8DCQ2F5BI/MRxLharOQ5V78yMSuB+JE+EuUM22txYfj09R2Q7hUlEYj7KdNg==" }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "requires": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "requires": { "lodash._reinterpolate": "^3.0.0" } }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "requires": { "tslib": "^2.0.3" } }, "lower-case-first": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", "requires": { "tslib": "^2.0.3" } }, "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "requires": { "yallist": "^3.0.2" } }, "lru-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "requires": { "es5-ext": "~0.10.2" } }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "requires": { "semver": "^6.0.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "requires": { "p-defer": "^1.0.0" }, "dependencies": { "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==" } } }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "dev": true, "optional": true, "requires": { "object-visit": "^1.0.0" } }, "markdown-table": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", "requires": { "repeat-string": "^1.0.0" } }, "math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true, "optional": true }, "md-attr-parser": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/md-attr-parser/-/md-attr-parser-1.3.0.tgz", "integrity": "sha512-KTVlfU5Oxo/6kd0YZ2mLP3eWJj+5vzh5mBCxLo3yGl1fzHIgxmtadbE9tHb7TbUBi3XZbl+P0xKeGmakat135w==", "dev": true }, "md5-file": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==" }, "mdast-util-definitions": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", "requires": { "unist-util-visit": "^2.0.0" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "mdast-util-find-and-replace": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", "requires": { "escape-string-regexp": "^4.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" }, "dependencies": { "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" } } }, "mdast-util-footnote": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz", "integrity": "sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==", "requires": { "mdast-util-to-markdown": "^0.6.0", "micromark": "~2.11.0" } }, "mdast-util-from-markdown": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^2.0.0", "micromark": "~2.11.0", "parse-entities": "^2.0.0", "unist-util-stringify-position": "^2.0.0" } }, "mdast-util-gfm": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", "requires": { "mdast-util-gfm-autolink-literal": "^0.1.0", "mdast-util-gfm-strikethrough": "^0.2.0", "mdast-util-gfm-table": "^0.1.0", "mdast-util-gfm-task-list-item": "^0.1.0", "mdast-util-to-markdown": "^0.6.1" } }, "mdast-util-gfm-autolink-literal": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", "requires": { "ccount": "^1.0.0", "mdast-util-find-and-replace": "^1.1.0", "micromark": "^2.11.3" } }, "mdast-util-gfm-strikethrough": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", "requires": { "mdast-util-to-markdown": "^0.6.0" } }, "mdast-util-gfm-table": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", "requires": { "markdown-table": "^2.0.0", "mdast-util-to-markdown": "~0.6.0" } }, "mdast-util-gfm-task-list-item": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", "requires": { "mdast-util-to-markdown": "~0.6.0" } }, "mdast-util-to-hast": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "mdast-util-definitions": "^4.0.0", "mdurl": "^1.0.0", "unist-builder": "^2.0.0", "unist-util-generated": "^1.0.0", "unist-util-position": "^3.0.0", "unist-util-visit": "^2.0.0" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "mdast-util-to-markdown": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", "requires": { "@types/unist": "^2.0.0", "longest-streak": "^2.0.0", "mdast-util-to-string": "^2.0.0", "parse-entities": "^2.0.0", "repeat-string": "^1.0.0", "zwitch": "^1.0.0" } }, "mdast-util-to-nlcst": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/mdast-util-to-nlcst/-/mdast-util-to-nlcst-4.0.1.tgz", "integrity": "sha512-Y4ffygj85MTt70STKnEquw6k73jYWJBaYcb4ITAKgSNokZF7fH8rEHZ1GsRY/JaxqUevMaEnsDmkVv5Z9uVRdg==", "requires": { "nlcst-to-string": "^2.0.0", "repeat-string": "^1.0.0", "unist-util-position": "^3.0.0", "vfile-location": "^3.1.0" } }, "mdast-util-to-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" }, "mdast-util-toc": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-5.1.0.tgz", "integrity": "sha512-csimbRIVkiqc+PpFeKDGQ/Ck2N4f9FYH3zzBMMJzcxoKL8m+cM0n94xXm0I9eaxHnKdY9n145SGTdyJC7i273g==", "requires": { "@types/mdast": "^3.0.3", "@types/unist": "^2.0.3", "extend": "^3.0.2", "github-slugger": "^1.2.1", "mdast-util-to-string": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit": "^2.0.0" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "meant": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.3.tgz", "integrity": "sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw==" }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "mem": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==", "requires": { "map-age-cleaner": "^0.1.3", "mimic-fn": "^3.1.0" }, "dependencies": { "mimic-fn": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" } } }, "memfs": { "version": "3.4.13", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", "requires": { "fs-monkey": "^1.0.3" } }, "memoizee": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "requires": { "d": "^1.0.1", "es5-ext": "^0.10.53", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" } }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromark": { "version": "2.11.4", "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", "requires": { "debug": "^4.0.0", "parse-entities": "^2.0.0" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "micromark-extension-footnote": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz", "integrity": "sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==", "requires": { "micromark": "~2.11.0" } }, "micromark-extension-gfm": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", "requires": { "micromark": "~2.11.0", "micromark-extension-gfm-autolink-literal": "~0.5.0", "micromark-extension-gfm-strikethrough": "~0.6.5", "micromark-extension-gfm-table": "~0.4.0", "micromark-extension-gfm-tagfilter": "~0.3.0", "micromark-extension-gfm-task-list-item": "~0.3.0" } }, "micromark-extension-gfm-autolink-literal": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", "requires": { "micromark": "~2.11.3" } }, "micromark-extension-gfm-strikethrough": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", "requires": { "micromark": "~2.11.0" } }, "micromark-extension-gfm-table": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", "requires": { "micromark": "~2.11.0" } }, "micromark-extension-gfm-tagfilter": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==" }, "micromark-extension-gfm-task-list-item": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", "requires": { "micromark": "~2.11.0" } }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==", "dev": true, "optional": true, "requires": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", "braces": "^1.8.2", "expand-brackets": "^0.1.4", "extglob": "^0.3.1", "filename-regex": "^2.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.1", "kind-of": "^3.0.2", "normalize-path": "^2.0.1", "object.omit": "^2.0.0", "parse-glob": "^3.0.4", "regex-cache": "^0.4.2" }, "dependencies": { "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { "mime-db": "1.52.0" } }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "mini-css-extract-plugin": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz", "integrity": "sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==", "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0", "webpack-sources": "^1.1.0" } }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, "mitt": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==" }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "optional": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "requires": { "minimist": "^1.2.6" } }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "msgpackr": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.1.tgz", "integrity": "sha512-05fT4J8ZqjYlR4QcRDIhLCYKUOHXk7C/xa62GzMKj74l3up9k2QZ3LgFc6qWdsPHl91QA2WLWqWc8b8t7GLNNw==", "requires": { "msgpackr-extract": "^2.2.0" } }, "msgpackr-extract": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-2.2.0.tgz", "integrity": "sha512-0YcvWSv7ZOGl9Od6Y5iJ3XnPww8O7WLcpYMDwX+PAA/uXLDtyw94PJv9GLQV/nnp3cWlDhMoyKZIQLrx33sWog==", "optional": true, "requires": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "2.2.0", "@msgpackr-extract/msgpackr-extract-darwin-x64": "2.2.0", "@msgpackr-extract/msgpackr-extract-linux-arm": "2.2.0", "@msgpackr-extract/msgpackr-extract-linux-arm64": "2.2.0", "@msgpackr-extract/msgpackr-extract-linux-x64": "2.2.0", "@msgpackr-extract/msgpackr-extract-win32-x64": "2.2.0", "node-gyp-build-optional-packages": "5.0.3" } }, "multer": { "version": "1.4.5-lts.1", "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", "requires": { "append-field": "^1.0.0", "busboy": "^1.0.0", "concat-stream": "^1.5.2", "mkdirp": "^0.5.4", "object-assign": "^4.1.1", "type-is": "^1.6.4", "xtend": "^4.0.0" } }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "nan": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", "dev": true, "optional": true }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "fragment-cache": "^0.2.1", "is-windows": "^1.0.2", "kind-of": "^6.0.2", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "dependencies": { "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, "optional": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true, "optional": true }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "needle": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" }, "dependencies": { "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "nlcst-to-string": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz", "integrity": "sha512-3x3jwTd6UPG7vi5k4GEzvxJ5rDA7hVUIRNHPblKuMVP9Z3xmlsd9cgLcpAMkc5uPOBna82EeshROFhsPkbnTZg==" }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "requires": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "node-abi": { "version": "3.30.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", "requires": { "semver": "^7.3.5" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "requires": { "whatwg-url": "^5.0.0" } }, "node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" }, "node-gyp-build-optional-packages": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", "integrity": "sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==" }, "node-html-parser": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz", "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==", "requires": { "css-select": "^4.2.1", "he": "1.2.0" }, "dependencies": { "css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "requires": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } }, "domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "requires": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" } } }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node-object-hash": { "version": "2.3.10", "resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-2.3.10.tgz", "integrity": "sha512-jY5dPJzw6NHd/KPSfPKJ+IHoFS81/tJ43r34ZeNMXGzCOM8jwQDCD12HYayKIB6MuznrnqIYy2e891NA2g0ibA==" }, "node-releases": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "requires": { "remove-trailing-separator": "^1.0.1" } }, "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" }, "normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "not": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "requires": { "path-key": "^3.0.0" } }, "nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "requires": { "boolbase": "^1.0.0" } }, "null-loader": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" } }, "nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dev": true, "optional": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", "kind-of": "^3.0.3" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^0.1.0" } }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" } }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" } }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true } } }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "object-fit-images": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/object-fit-images/-/object-fit-images-3.2.4.tgz", "integrity": "sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg==" }, "object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dev": true, "optional": true, "requires": { "isobject": "^3.0.0" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "object.assign": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, "object.entries": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, "object.fromentries": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, "object.hasown": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", "requires": { "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==", "dev": true, "optional": true, "requires": { "for-own": "^0.1.4", "is-extendable": "^0.1.1" } }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, "optional": true, "requires": { "isobject": "^3.0.1" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "object.values": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } }, "on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } }, "onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "requires": { "mimic-fn": "^2.1.0" } }, "open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "requires": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "opentracing": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==" }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "requires": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.3" } }, "ordered-binary": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", "integrity": "sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==" }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" }, "output-file-sync": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", "integrity": "sha512-uQLlclru4xpCi+tfs80l3QF24KL81X57ELNMy7W/dox+JTtxUf1bLyQ8968fFCmSqqbokjW0kn+WBIlO+rSkNg==", "dev": true, "requires": { "graceful-fs": "^4.1.4", "mkdirp": "^0.5.1", "object-assign": "^4.1.0" } }, "p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" }, "p-defer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz", "integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "requires": { "yocto-queue": "^0.1.0" } }, "p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "requires": { "p-limit": "^3.0.2" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "requires": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" }, "dependencies": { "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", "requires": { "defer-to-connect": "^1.0.1" } }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^3.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^4.1.0", "responselike": "^1.0.2" }, "dependencies": { "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "requires": { "pump": "^3.0.0" } } } }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "requires": { "mimic-response": "^1.0.0" } }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "requires": { "pump": "^3.0.0" } }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "requires": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", "cacheable-request": "^6.0.0", "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", "get-stream": "^4.1.0", "lowercase-keys": "^1.0.1", "mimic-response": "^1.0.1", "p-cancelable": "^1.0.0", "to-readable-stream": "^1.0.0", "url-parse-lax": "^3.0.0" }, "dependencies": { "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" } } }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "requires": { "json-buffer": "3.0.0" } }, "normalize-url": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "requires": { "lowercase-keys": "^1.0.0" }, "dependencies": { "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" } } }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "requires": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "requires": { "callsites": "^3.0.0" } }, "parse-english": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/parse-english/-/parse-english-4.2.0.tgz", "integrity": "sha512-jw5N6wZUZViIw3VLG/FUSeL3vDhfw5Q2g4E3nYC69Mm5ANbh9ZWd+eligQbeUoyObZM8neynTn3l14e09pjEWg==", "requires": { "nlcst-to-string": "^2.0.0", "parse-latin": "^4.0.0", "unist-util-modify-children": "^2.0.0", "unist-util-visit-children": "^1.0.0" } }, "parse-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "requires": { "character-entities": "^1.0.0", "character-entities-legacy": "^1.0.0", "character-reference-invalid": "^1.0.0", "is-alphanumerical": "^1.0.0", "is-decimal": "^1.0.0", "is-hexadecimal": "^1.0.0" } }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "requires": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" } }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==", "dev": true, "optional": true, "requires": { "glob-base": "^0.3.0", "is-dotfile": "^1.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.0" } }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "parse-latin": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-4.3.0.tgz", "integrity": "sha512-TYKL+K98dcAWoCw/Ac1yrPviU8Trk+/gmjQVaoWEFDZmVD4KRg6c/80xKqNNFQObo2mTONgF8trzAf2UTwKafw==", "requires": { "nlcst-to-string": "^2.0.0", "unist-util-modify-children": "^2.0.0", "unist-util-visit-children": "^1.0.0" } }, "parse-numeric-range": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-0.0.2.tgz", "integrity": "sha512-m6xRZuda9v6EGdnPMIkcyB3/NpdgbMJG8yPAQ0Mwm1nGlm2OE/o6YS0EAxAqv6u4/PKQPp6BNoylZnRb2U2/OA==" }, "parse-path": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", "requires": { "protocols": "^2.0.0" } }, "parse-srcset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, "parse-url": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "requires": { "parse-path": "^7.0.0" } }, "parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "requires": { "entities": "^4.4.0" } }, "parse5-htmlparser2-tree-adapter": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", "requires": { "domhandler": "^5.0.2", "parse5": "^7.0.0" } }, "parseqs": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" }, "parseuri": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "pascal-case": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "requires": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", "dev": true, "optional": true }, "password-prompt": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", "requires": { "ansi-escapes": "^3.1.0", "cross-spawn": "^6.0.5" }, "dependencies": { "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { "isexe": "^2.0.0" } } } }, "path-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "requires": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "requires": { "path-root-regex": "^0.1.0" } }, "path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==" }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" }, "physical-cpu-count": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", "integrity": "sha512-rxJOljMuWtYlvREBmd6TZYanfcPhNUKtGDZBjBBS8WG1dpN2iwPsRJZgQqN/OtJuiQckdRFOfzogqJClTrsi7g==" }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "requires": { "find-up": "^4.0.0" }, "dependencies": { "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { "p-locate": "^4.1.0" } }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { "p-limit": "^2.2.0" } } } }, "pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "requires": { "find-up": "^3.0.0" }, "dependencies": { "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "requires": { "locate-path": "^3.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "requires": { "p-limit": "^2.0.0" } }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" } } }, "platform": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, "popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true, "optional": true }, "postcss": { "version": "8.4.21", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "postcss-calc": { "version": "8.2.4", "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", "requires": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" } }, "postcss-colormin": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", "requires": { "browserslist": "^4.16.6", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" } }, "postcss-convert-values": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", "requires": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" } }, "postcss-discard-comments": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", "requires": {} }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", "requires": {} }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", "requires": {} }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", "requires": {} }, "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", "requires": {} }, "postcss-loader": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", "requires": { "cosmiconfig": "^7.0.0", "klona": "^2.0.4", "semver": "^7.3.4" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "postcss-merge-longhand": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", "requires": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" } }, "postcss-merge-rules": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", "requires": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "cssnano-utils": "^3.1.0", "postcss-selector-parser": "^6.0.5" } }, "postcss-minify-font-values": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-minify-gradients": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", "requires": { "colord": "^2.9.1", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" } }, "postcss-minify-params": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", "requires": { "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" } }, "postcss-minify-selectors": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", "requires": { "postcss-selector-parser": "^6.0.5" } }, "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", "requires": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" } }, "postcss-modules-scope": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "requires": { "postcss-selector-parser": "^6.0.4" } }, "postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "requires": { "icss-utils": "^5.0.0" } }, "postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", "requires": {} }, "postcss-normalize-display-values": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-positions": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-repeat-style": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-string": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-timing-functions": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-unicode": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", "requires": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-url": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", "requires": { "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-whitespace": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-ordered-values": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", "requires": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" } }, "postcss-reduce-initial": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", "requires": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" } }, "postcss-reduce-transforms": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-selector-parser": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "postcss-svgo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", "requires": { "postcss-value-parser": "^4.2.0", "svgo": "^2.7.0" } }, "postcss-unique-selectors": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", "requires": { "postcss-selector-parser": "^6.0.5" } }, "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", "requires": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "dependencies": { "detect-libc": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" } } }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==" }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==", "dev": true, "optional": true }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" }, "pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "requires": { "lodash": "^4.17.20", "renderkid": "^2.0.4" } }, "prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, "probe-image-size": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", "requires": { "lodash.merge": "^4.6.2", "needle": "^2.5.2", "stream-parser": "~0.3.1" } }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "requires": { "asap": "~2.0.3" } }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "requires": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", "requires": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "property-information": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", "requires": { "xtend": "^4.0.0" } }, "protocols": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "pupa": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "requires": { "escape-goat": "^2.0.0" } }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "requires": { "side-channel": "^1.0.4" } }, "query-string": { "version": "6.14.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", "requires": { "decode-uri-component": "^0.2.0", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" } }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" }, "ramda": { "version": "0.21.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz", "integrity": "sha512-HGd5aczYKQXGILB+abY290V7Xz62eFajpa6AtMdwEmQSakJmgSO7ks4eI3HdR34j+X2Vz4Thp9VAJbrCAMbO2w==" }, "randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "optional": true, "requires": { "is-number": "^4.0.0", "kind-of": "^6.0.0", "math-random": "^1.0.1" }, "dependencies": { "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true, "optional": true } } }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "requires": { "safe-buffer": "^5.1.0" } }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "dependencies": { "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" } } }, "raw-loader": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" } }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "dependencies": { "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" } } }, "react": { "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" } }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", "requires": { "@babel/code-frame": "^7.16.0", "address": "^1.1.2", "browserslist": "^4.18.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "detect-port-alt": "^1.1.6", "escape-string-regexp": "^4.0.0", "filesize": "^8.0.6", "find-up": "^5.0.0", "fork-ts-checker-webpack-plugin": "^6.5.0", "global-modules": "^2.0.0", "globby": "^11.0.4", "gzip-size": "^6.0.0", "immer": "^9.0.7", "is-root": "^2.1.0", "loader-utils": "^3.2.0", "open": "^8.4.0", "pkg-up": "^3.1.0", "prompts": "^2.4.2", "react-error-overlay": "^6.0.11", "recursive-readdir": "^2.2.2", "shell-quote": "^1.7.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "dependencies": { "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "loader-utils": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" }, "open": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", "requires": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } } } }, "react-dom": { "version": "16.14.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "^0.19.1" } }, "react-error-overlay": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "react-fast-compare": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" }, "react-helmet": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.1.tgz", "integrity": "sha512-CnwD822LU8NDBnjCpZ4ySh8L6HYyngViTZLfBBb3NjtrpN8m49clH8hidHouq20I51Y6TpCTISCBbqiY5GamwA==", "requires": { "object-assign": "^4.1.1", "prop-types": "^15.5.4", "react-fast-compare": "^2.0.2", "react-side-effect": "^1.1.0" } }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-jss": { "version": "8.6.1", "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==", "requires": { "hoist-non-react-statics": "^2.5.0", "jss": "^9.7.0", "jss-preset-default": "^4.3.0", "prop-types": "^15.6.0", "theming": "^1.3.0" } }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==" }, "react-side-effect": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-1.2.0.tgz", "integrity": "sha512-v1ht1aHg5k/thv56DRcjw+WtojuuDHFUgGfc+bFHOWsF4ZK6C2V57DO0Or0GPsg6+LSTE0M6Ry/gfzhzSwbc5w==", "requires": { "shallowequal": "^1.0.1" } }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "requires": { "mute-stream": "~0.0.4" } }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, "readable-web-to-node-stream": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", "requires": { "readable-stream": "^3.6.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "optional": true, "requires": { "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", "readable-stream": "^2.0.2" }, "dependencies": { "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, "optional": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true, "optional": true }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", "extend-shallow": "^2.0.1", "fill-range": "^4.0.0", "isobject": "^3.0.1", "repeat-element": "^1.1.2", "snapdragon": "^0.8.1", "snapdragon-node": "^2.0.1", "split-string": "^3.0.2", "to-regex": "^3.0.1" } }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "dev": true, "optional": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "posix-character-classes": "^0.1.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^0.1.0" } }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" } }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true } } }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "optional": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", "expand-brackets": "^2.1.4", "extend-shallow": "^2.0.1", "fragment-cache": "^0.2.1", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "dependencies": { "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^1.0.0" } } } }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "dev": true, "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", "repeat-string": "^1.6.1", "to-regex-range": "^2.1.0" } }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "requires": { "is-plain-object": "^2.0.4" } }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "braces": "^2.3.1", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "extglob": "^2.0.4", "fragment-cache": "^0.2.1", "kind-of": "^6.0.2", "nanomatch": "^1.2.9", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" }, "dependencies": { "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } } } }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dev": true, "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" } } } }, "recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "requires": { "minimatch": "^3.0.5" } }, "redux": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", "requires": { "@babel/runtime": "^7.9.2" } }, "redux-thunk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", "requires": {} }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "regenerate-unicode-properties": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "requires": { "regenerate": "^1.4.2" } }, "regenerator-runtime": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==", "dev": true }, "regenerator-transform": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "requires": { "babel-runtime": "^6.18.0", "babel-types": "^6.19.0", "private": "^0.1.6" } }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "optional": true, "requires": { "is-equal-shallow": "^0.1.3" } }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "optional": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" }, "dependencies": { "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "regex-parser": { "version": "2.2.11", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "functions-have-names": "^1.2.2" } }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", "dev": true, "requires": { "regenerate": "^1.2.1", "regjsgen": "^0.2.0", "regjsparser": "^0.1.4" } }, "registry-auth-token": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", "requires": { "rc": "1.2.8" } }, "registry-url": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "requires": { "rc": "^1.2.8" } }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", "dev": true }, "regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", "dev": true, "requires": { "jsesc": "~0.5.0" }, "dependencies": { "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true } } }, "rehype-react": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-3.1.0.tgz", "integrity": "sha512-7SiLiqNudSGkvhrePkdKqdUvngZqzG+PJhdR5EeIFELz2j2ek4aO5DHbxUXYvaZfqUiBDO2Aeq1OROUmxmu+Vg==", "requires": { "@mapbox/hast-util-table-cell-style": "^0.1.3", "has": "^1.0.1", "hast-to-hyperscript": "^5.0.0" }, "dependencies": { "hast-to-hyperscript": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-5.0.0.tgz", "integrity": "sha512-DLl3eYTz8uwwzEubDUdCChsR5t5b2ne+yvHrA2h58Suq/JnN3+Gsb9Tc4iZoCCsykmFUc6UUpwxTmQXs0akSeg==", "requires": { "comma-separated-tokens": "^1.0.0", "property-information": "^4.0.0", "space-separated-tokens": "^1.0.0", "style-to-object": "^0.2.1", "unist-util-is": "^2.0.0", "web-namespaces": "^1.1.2" } }, "property-information": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-4.2.0.tgz", "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", "requires": { "xtend": "^4.0.1" } }, "style-to-object": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", "requires": { "inline-style-parser": "0.1.1" } }, "unist-util-is": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==" } } }, "relay-runtime": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", "requires": { "@babel/runtime": "^7.0.0", "fbjs": "^3.0.0", "invariant": "^2.2.4" } }, "remark": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", "requires": { "remark-parse": "^9.0.0", "remark-stringify": "^9.0.0", "unified": "^9.1.0" } }, "remark-footnotes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz", "integrity": "sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==", "requires": { "mdast-util-footnote": "^0.1.0", "micromark-extension-footnote": "^0.3.0" } }, "remark-gfm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", "requires": { "mdast-util-gfm": "^0.1.0", "micromark-extension-gfm": "^0.3.0" } }, "remark-parse": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", "requires": { "mdast-util-from-markdown": "^0.8.0" } }, "remark-react": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/remark-react/-/remark-react-5.0.1.tgz", "integrity": "sha512-yHv5WIh47srKfdm794UMIHjNLr6EY2YCzsqvdJ/qvN1Tq1jgyg3q8Zo9pJc4L7BwZOMTia6O2JgrJeOsJfowzA==", "requires": { "@mapbox/hast-util-table-cell-style": "^0.1.3", "hast-to-hyperscript": "^6.0.0", "hast-util-sanitize": "^1.0.0", "mdast-util-to-hast": "^4.0.0" }, "dependencies": { "hast-to-hyperscript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-6.0.0.tgz", "integrity": "sha512-QnJbXddVGNJ5v3KegK1MY6luTkNDBcJnCQZcekt7AkES2z4tYy85pbFUXx7Mb0iXZBKfwoVdgfxU12GbmlwbbQ==", "requires": { "comma-separated-tokens": "^1.0.0", "property-information": "^5.0.0", "space-separated-tokens": "^1.0.0", "style-to-object": "^0.2.1", "unist-util-is": "^2.0.0", "web-namespaces": "^1.1.2" } }, "mdast-util-definitions": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz", "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==", "requires": { "unist-util-visit": "^1.0.0" } }, "mdast-util-to-hast": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-4.0.0.tgz", "integrity": "sha512-yOTZSxR1aPvWRUxVeLaLZ1sCYrK87x2Wusp1bDM/Ao2jETBhYUKITI3nHvgy+HkZW54HuCAhHnS0mTcbECD5Ig==", "requires": { "collapse-white-space": "^1.0.0", "detab": "^2.0.0", "mdast-util-definitions": "^1.2.0", "mdurl": "^1.0.1", "trim": "0.0.1", "trim-lines": "^1.0.0", "unist-builder": "^1.0.1", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", "unist-util-visit": "^1.1.0", "xtend": "^4.0.1" } }, "style-to-object": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", "requires": { "inline-style-parser": "0.1.1" } }, "unist-builder": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", "requires": { "object-assign": "^4.1.0" } }, "unist-util-is": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==" } } }, "remark-retext": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-retext/-/remark-retext-4.0.0.tgz", "integrity": "sha512-cYCchalpf25bTtfXF24ribYvqytPKq0TiEhqQDBHvVEEsApebwruPWP1cTcvTFBidmpXyqzycm+y8ng7Kmvc8Q==", "requires": { "mdast-util-to-nlcst": "^4.0.0" } }, "remark-stringify": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", "requires": { "mdast-util-to-markdown": "^0.6.0" } }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" }, "renderkid": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", "requires": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", "htmlparser2": "^6.1.0", "lodash": "^4.17.21", "strip-ansi": "^3.0.1" }, "dependencies": { "css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "requires": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } }, "domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "requires": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "htmlparser2": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", "domutils": "^2.5.2", "entities": "^2.0.0" } } } }, "repeat-element": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true, "optional": true }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" }, "repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", "dev": true, "requires": { "is-finite": "^1.0.0" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "require-package-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz", "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==" }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "requires": { "resolve-from": "^5.0.0" } }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" }, "resolve-url-loader": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.5.tgz", "integrity": "sha512-mgFMCmrV/tA4738EsFmPFE5/MaqSgUMe8LK971kVEKA/RrNVb7+VqFsg/qmKyythf34eyq476qIobP/gfFBGSQ==", "requires": { "adjust-sourcemap-loader": "3.0.0", "camelcase": "5.3.1", "compose-function": "3.0.3", "convert-source-map": "1.7.0", "es6-iterator": "2.0.3", "loader-utils": "^1.2.3", "postcss": "7.0.36", "rework": "1.0.1", "rework-visit": "1.0.0", "source-map": "0.6.1" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "^1.9.0" } }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "dependencies": { "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { "has-flag": "^3.0.0" } } } }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "requires": { "safe-buffer": "~5.1.1" } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } }, "loader-utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^1.0.1" } }, "postcss": { "version": "7.0.36", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", "supports-color": "^6.1.0" } }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "requires": { "has-flag": "^3.0.0" } } } }, "responselike": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "requires": { "lowercase-keys": "^2.0.0" } }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true, "optional": true }, "retext": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/retext/-/retext-7.0.1.tgz", "integrity": "sha512-N0IaEDkvUjqyfn3/gwxVfI51IxfGzOiVXqPLWnKeCDbiQdxSg0zebzHPxXWnL7TeplAJ+RE4uqrXyYN//s9HjQ==", "requires": { "retext-latin": "^2.0.0", "retext-stringify": "^2.0.0", "unified": "^8.0.0" }, "dependencies": { "unified": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", "requires": { "bail": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" } } } }, "retext-english": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/retext-english/-/retext-english-3.0.4.tgz", "integrity": "sha512-yr1PgaBDde+25aJXrnt3p1jvT8FVLVat2Bx8XeAWX13KXo8OT+3nWGU3HWxM4YFJvmfqvJYJZG2d7xxaO774gw==", "requires": { "parse-english": "^4.0.0", "unherit": "^1.0.4" } }, "retext-latin": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-2.0.4.tgz", "integrity": "sha512-fOoSSoQgDZ+l/uS81oxI3alBghDUPja0JEl0TpQxI6MN+dhM6fLFumPJwMZ4PJTyL5FFAgjlsdv8IX+6IRuwMw==", "requires": { "parse-latin": "^4.0.0", "unherit": "^1.0.4" } }, "retext-smartypants": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-4.0.0.tgz", "integrity": "sha512-Mknd05zuIycr4Z/hNDxA8ktqv7pG7wYdTZc68a2MJF+Ibg/WloR5bbyrEjijwNwHRR+xWsovkLH4OQIz/mghdw==", "requires": { "nlcst-to-string": "^2.0.0", "unist-util-visit": "^2.0.0" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "retext-stringify": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-2.0.4.tgz", "integrity": "sha512-xOtx5mFJBoT3j7PBtiY2I+mEGERNniofWktI1cKXvjMEJPOuqve0dghLHO1+gz/gScLn4zqspDGv4kk2wS5kSA==", "requires": { "nlcst-to-string": "^2.0.0" } }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "rework": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", "integrity": "sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw==", "requires": { "convert-source-map": "^0.3.3", "css": "^2.0.0" }, "dependencies": { "convert-source-map": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==" } } }, "rework-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==" }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" } }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "requires": { "queue-microtask": "^1.2.2" } }, "rx": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==" }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "requires": { "tslib": "^1.9.0" }, "dependencies": { "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" } } }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dev": true, "optional": true, "requires": { "ret": "~0.1.10" } }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "is-regex": "^1.1.4" } }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sanitize-html": { "version": "1.27.5", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.27.5.tgz", "integrity": "sha512-M4M5iXDAUEcZKLXkmk90zSYWEtk5NH3JmojQxKxV371fnMh+x9t1rqdmXaGoyEHw3z/X/8vnFhKjGL5xFGOJ3A==", "requires": { "htmlparser2": "^4.1.0", "lodash": "^4.17.15", "parse-srcset": "^1.0.2", "postcss": "^7.0.27" }, "dependencies": { "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" }, "dependencies": { "domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } } } }, "domhandler": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", "requires": { "domelementtype": "^2.0.1" } }, "domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "requires": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" }, "dependencies": { "domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } } } }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "htmlparser2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^3.0.0", "domutils": "^2.0.0", "entities": "^2.0.0" } }, "picocolors": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" }, "postcss": { "version": "7.0.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "requires": { "picocolors": "^0.2.1", "source-map": "^0.6.1" } }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, "sass": { "version": "1.57.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", "peer": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, "dependencies": { "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "peer": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "peer": true }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "peer": true, "requires": { "fill-range": "^7.0.1" } }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "peer": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "peer": true, "requires": { "to-regex-range": "^5.0.1" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true, "peer": true }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "peer": true, "requires": { "is-glob": "^4.0.1" } }, "immutable": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==", "peer": true }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "peer": true, "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "peer": true }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "peer": true, "requires": { "is-extglob": "^2.1.1" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "peer": true }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "peer": true, "requires": { "picomatch": "^2.2.1" } } } }, "sass-loader": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.4.1.tgz", "integrity": "sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ==", "requires": { "klona": "^2.0.4", "loader-utils": "^2.0.0", "neo-async": "^2.6.2", "schema-utils": "^3.0.0", "semver": "^7.3.2" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "sass-resources-loader": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/sass-resources-loader/-/sass-resources-loader-1.3.5.tgz", "integrity": "sha512-pCxaoRZxbKxDWhu5ZcsV7/apPYrL/z0F+25C29L4e8pajWM/4jM4hRXSRP4jEWTXo/kYIU9bEXKZZdGfjN90+Q==", "requires": { "async": "^2.1.4", "chalk": "^1.1.3", "glob": "^7.1.1", "loader-utils": "^1.0.4" }, "dependencies": { "async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "requires": { "lodash": "^4.17.14" } }, "json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } }, "loader-utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^1.0.1" } } } }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "scheduler": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" } }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "requires": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", "requires": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "requires": { "semver": "^6.3.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" }, "dependencies": { "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "sentence-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", "requires": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "requires": { "randombytes": "^2.1.0" } }, "serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.18.0" } }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" } }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "requires": { "kind-of": "^6.0.2" } }, "shallow-compare": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/shallow-compare/-/shallow-compare-1.2.2.tgz", "integrity": "sha512-LUMFi+RppPlrHzbqmFnINTrazo0lPNwhcgzuAXVVcfy/mqPDrQmHAyz5bvV0gDAuRFrk804V0HpQ6u9sZ0tBeg==" }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "sharp": { "version": "0.30.7", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.7.tgz", "integrity": "sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==", "requires": { "color": "^4.2.3", "detect-libc": "^2.0.1", "node-addon-api": "^5.0.0", "prebuild-install": "^7.1.1", "semver": "^7.3.7", "simple-get": "^4.0.1", "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" }, "dependencies": { "detect-libc": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "node-addon-api": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "requires": { "shebang-regex": "^3.0.0" } }, "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "shell-quote": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==" }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" } }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "signedsource": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==" }, "simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "requires": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "requires": { "is-arrayish": "^0.3.1" }, "dependencies": { "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" } } }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "sitemap": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", "requires": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.2.4" }, "dependencies": { "@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" } } }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } } } }, "slugify": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.5.tgz", "integrity": "sha512-8mo9bslnBO3tr5PEVFzMPIWwWnipGS0xVbYf65zxDqfNwmzYn1LpiKNrR6DlClusuvo+hDHd1zKpmfAe83NQSQ==" }, "snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "requires": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "optional": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "map-cache": "^0.2.2", "source-map": "^0.5.6", "source-map-resolve": "^0.5.0", "use": "^3.1.0" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^0.1.0" } }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" } }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true } } }, "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "optional": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^1.0.0" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "optional": true, "requires": { "kind-of": "^3.2.0" }, "dependencies": { "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "socket.io": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", "requires": { "@types/cookie": "^0.4.0", "@types/cors": "^2.8.8", "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.1", "engine.io": "~4.1.0", "socket.io-adapter": "~2.1.0", "socket.io-parser": "~4.0.3" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "socket.io-adapter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" }, "socket.io-client": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.3.tgz", "integrity": "sha512-4sIGOGOmCg3AOgGi7EEr6ZkTZRkrXwub70bBB/F0JSkMOUFpA77WsL87o34DffQQ31PkbMUIadGOk+3tx1KGbw==", "requires": { "@types/component-emitter": "^1.2.10", "backo2": "~1.0.2", "component-emitter": "~1.3.0", "debug": "~4.3.1", "engine.io-client": "~4.1.0", "parseuri": "0.0.6", "socket.io-parser": "~4.0.4" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "socket.io-parser": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", "requires": { "@types/component-emitter": "^1.2.10", "component-emitter": "~1.3.0", "debug": "~4.3.1" }, "dependencies": { "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, "source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "requires": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", "urix": "^0.1.0" } }, "source-map-support": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { "source-map": "^0.5.6" } }, "source-map-url": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" }, "space-separated-tokens": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" }, "split-on-first": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "optional": true, "requires": { "extend-shallow": "^3.0.0" }, "dependencies": { "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "sponge-case": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", "requires": { "tslib": "^2.0.3" } }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "st": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/st/-/st-2.0.0.tgz", "integrity": "sha512-drN+aGYnrZPNYIymmNwIY7LXYJ8MqsqXj4fMRue3FOgGMdGjSX10fhJ3qx0sVQPhcWxhEaN4U/eWM4O4dbYNAw==", "requires": { "async-cache": "^1.1.0", "bl": "^4.0.0", "fd": "~0.0.2", "graceful-fs": "^4.2.3", "mime": "^2.4.4", "negotiator": "~0.6.2" } }, "stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" }, "stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", "dev": true, "optional": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, "optional": true, "requires": { "is-descriptor": "^0.1.0" } }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" } }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "optional": true } } }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "stream-parser": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", "requires": { "debug": "2" } }, "streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" }, "strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==" }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, "string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" }, "string-similarity": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.2.tgz", "integrity": "sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==", "requires": { "lodash.every": "^4.6.0", "lodash.flattendeep": "^4.4.0", "lodash.foreach": "^4.5.0", "lodash.map": "^4.6.0", "lodash.maxby": "^4.6.0" } }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "dependencies": { "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } } } }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4", "get-intrinsic": "^1.1.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "regexp.prototype.flags": "^1.4.3", "side-channel": "^1.0.4" } }, "string.prototype.trimend": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, "string.prototype.trimstart": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, "stringify-entities": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz", "integrity": "sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg==", "requires": { "character-entities-html4": "^1.0.0", "character-entities-legacy": "^1.0.0", "xtend": "^4.0.0" } }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "requires": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", "is-regexp": "^1.0.0" }, "dependencies": { "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" } } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "requires": { "ansi-regex": "^2.0.0" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" }, "strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==" }, "strip-comments": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", "requires": { "babel-extract-comments": "^1.0.0", "babel-plugin-transform-object-rest-spread": "^6.26.0" } }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==" }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", "requires": { "escape-string-regexp": "^1.0.2" } }, "strtok3": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "requires": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "style-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" } }, "style-to-object": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", "requires": { "inline-style-parser": "0.1.1" } }, "stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", "requires": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" } }, "sudo-prompt": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-8.2.5.tgz", "integrity": "sha512-rlBo3HU/1zAJUrkY6jNxDOC9eVYliG6nS4JA8u8KAshITd07tafMc/Br7xQwCSseXwJ2iCcHCE8SNWX3q8Z+kw==" }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==" }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "svg-react-loader": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/svg-react-loader/-/svg-react-loader-0.4.6.tgz", "integrity": "sha512-HVEypjWQsQuJdBIPzXGxpmQsQts7QwfQuYgK1rah6BVCMoLNSCh/ESKVNd7/tHq8DkWYHHTyaUMDA1FjqZYrgA==", "requires": { "css": "2.2.4", "loader-utils": "1.1.0", "ramda": "0.21.0", "rx": "4.1.0", "traverse": "0.6.6", "xml2js": "0.4.17" }, "dependencies": { "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==" }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==" }, "loader-utils": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha512-gkD9aSEG9UGglyPcDJqY9YBTUtCLKaBK6ihD2VP1d1X60lTfFspNZNulGBBbUZLkPygy4LySYHyxBpq+VhjObQ==", "requires": { "big.js": "^3.1.3", "emojis-list": "^2.0.0", "json5": "^0.5.0" } } } }, "svgo": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "requires": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", "stable": "^0.1.8" }, "dependencies": { "commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" }, "css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "requires": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } }, "domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "requires": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" } } }, "swap-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", "requires": { "tslib": "^2.0.3" } }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "requires": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", "string-width": "^4.2.3", "strip-ansi": "^6.0.1" }, "dependencies": { "ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } } } }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" }, "terser": { "version": "5.16.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", "requires": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } } } }, "terser-webpack-plugin": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", "requires": { "@jridgewell/trace-mapping": "^0.3.14", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", "terser": "^5.14.1" }, "dependencies": { "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "requires": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "requires": { "randombytes": "^2.1.0" } }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "requires": { "has-flag": "^4.0.0" } } } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "theming": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz", "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==", "requires": { "brcast": "^3.0.1", "is-function": "^1.0.1", "is-plain-object": "^2.0.1", "prop-types": "^15.5.8" } }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", "requires": { "es5-ext": "~0.10.46", "next-tick": "1" } }, "tippy.js": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-4.3.5.tgz", "integrity": "sha512-NDq3efte8nGK6BOJ1dDN1/WelAwfmh3UtIYXXck6+SxLzbIQNZE/cmRSnwScZ/FyiKdIcvFHvYUgqmoGx8CcyA==", "requires": { "popper.js": "^1.14.7" } }, "title-case": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", "requires": { "tslib": "^2.0.3" } }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "requires": { "rimraf": "^3.0.0" }, "dependencies": { "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } } } }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", "dev": true }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "dev": true, "optional": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true, "optional": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, "optional": true, "requires": { "is-buffer": "^1.1.5" } } } }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "optional": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "regex-not": "^1.0.2", "safe-regex": "^1.1.0" }, "dependencies": { "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "optional": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { "is-number": "^7.0.0" }, "dependencies": { "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" } } }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "token-types": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", "requires": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" }, "trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" }, "trim-lines": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.3.tgz", "integrity": "sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA==" }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", "requires": { "escape-string-regexp": "^1.0.2" } }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", "dev": true }, "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" }, "true-case-path": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { "json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } } } }, "tslib": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "requires": { "tslib": "^1.8.1" }, "dependencies": { "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" } } }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "requires": { "safe-buffer": "^5.0.1" } }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "requires": { "prelude-ls": "^1.2.1" } }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "type-of": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-of/-/type-of-2.0.1.tgz", "integrity": "sha512-39wxbwHdQ2sTiBB8wAzKfQ9GN+om8w+sjNWzr+vZJR5AMD5J+J7Yc8AtXnU9r/r2c8XiDZ/smxutDmZehX/qpQ==" }, "typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "requires": { "call-bind": "^1.0.2", "for-each": "^0.3.3", "is-typed-array": "^1.1.9" } }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "requires": { "is-typedarray": "^1.0.0" } }, "typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "peer": true }, "ua-parser-js": { "version": "0.7.32", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==" }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "requires": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==" }, "underscore.string": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", "requires": { "sprintf-js": "^1.1.1", "util-deprecate": "^1.0.2" }, "dependencies": { "sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" } } }, "unherit": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", "requires": { "inherits": "^2.0.0", "xtend": "^4.0.0" } }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" }, "unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "requires": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" } }, "unicode-match-property-value-ecmascript": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" }, "unified": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", "requires": { "bail": "^1.0.0", "extend": "^3.0.0", "is-buffer": "^2.0.0", "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" } }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "optional": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" } }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "requires": { "crypto-random-string": "^2.0.0" } }, "unist-builder": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==" }, "unist-util-generated": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==" }, "unist-util-is": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" }, "unist-util-modify-children": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-2.0.0.tgz", "integrity": "sha512-HGrj7JQo9DwZt8XFsX8UD4gGqOsIlCih9opG6Y+N11XqkBGKzHo8cvDi+MfQQgiZ7zXRUiQREYHhjOBHERTMdg==", "requires": { "array-iterate": "^1.0.0" } }, "unist-util-position": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==" }, "unist-util-remove": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-1.0.3.tgz", "integrity": "sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g==", "requires": { "unist-util-is": "^3.0.0" }, "dependencies": { "unist-util-is": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" } } }, "unist-util-remove-position": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-3.0.0.tgz", "integrity": "sha512-17kIOuolVuK16LMb9KyMJlqdfCtlfQY5FjY3Sdo9iC7F5wqdXhNjMq0PBvMpkVNNnAmHxXssUW+rZ9T2zbP0Rg==", "requires": { "unist-util-visit": "^2.0.0" }, "dependencies": { "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } } } }, "unist-util-select": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-3.0.4.tgz", "integrity": "sha512-xf1zCu4okgPqGLdhCDpRnjwBNyv3EqjiXRUbz2SdK1+qnLMB7uXXajfzuBvvbHoQ+JLyp4AEbFCGndmc6S72sw==", "requires": { "css-selector-parser": "^1.0.0", "not": "^0.1.0", "nth-check": "^2.0.0", "unist-util-is": "^4.0.0", "zwitch": "^1.0.0" } }, "unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "requires": { "@types/unist": "^2.0.2" } }, "unist-util-visit": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", "requires": { "unist-util-visit-parents": "^2.0.0" }, "dependencies": { "unist-util-is": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" }, "unist-util-visit-parents": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", "requires": { "unist-util-is": "^3.0.0" } } } }, "unist-util-visit-children": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-1.1.4.tgz", "integrity": "sha512-sA/nXwYRCQVRwZU2/tQWUqJ9JSFM1X3x7JIOsIgSzrFHcfVt6NkzDtKzyxg2cZWkCwGF9CO8x4QNZRJRMK8FeQ==" }, "unist-util-visit-parents": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" }, "unixify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", "requires": { "normalize-path": "^2.1.1" } }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dev": true, "optional": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" }, "dependencies": { "has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", "dev": true, "optional": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", "isobject": "^2.0.0" }, "dependencies": { "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dev": true, "optional": true, "requires": { "isarray": "1.0.0" } } } }, "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", "dev": true, "optional": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "optional": true } } }, "update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" } }, "update-notifier": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", "requires": { "boxen": "^5.0.0", "chalk": "^4.1.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", "is-installed-globally": "^0.4.0", "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", "latest-version": "^5.1.0", "pupa": "^2.1.1", "semver": "^7.3.4", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "upper-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", "requires": { "tslib": "^2.0.3" } }, "upper-case-first": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", "requires": { "tslib": "^2.0.3" } }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "requires": { "punycode": "^2.1.0" } }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==" }, "url-loader": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", "requires": { "loader-utils": "^2.0.0", "mime-types": "^2.1.27", "schema-utils": "^3.0.0" } }, "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "requires": { "prepend-http": "^2.0.0" } }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true, "optional": true }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha512-aggiKfEEubv3UwRNqTzLInZpAOmKzwdHqEBmW/hBA/mt99eg+b4VrX6i+IRLxU8+WJYfa33rGwRseg4eElUgsQ==", "dev": true }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "utility-types": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "integrity": "sha512-SKfhk/LlaXzvtowJabLZwD4K6SGRYeoxA7KJeISlUMAB/NT4CBkZjMq3WceX2Ckm4llwqYVo8TICgsDYCBU2tA==", "dev": true, "requires": { "user-home": "^1.1.1" } }, "valid-url": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" }, "value-or-promise": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==" }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" } }, "vfile-location": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==" }, "vfile-message": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" } }, "warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", "requires": { "loose-envify": "^1.0.0" } }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "weak-lru-cache": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==" }, "web-namespaces": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" }, "web-vitals": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.2.tgz", "integrity": "sha512-PFMKIY+bRSXlMxVAQ+m2aw9c/ioUYfDgrYot0YUa+/xa0sakubWhSDyxAKwzymvXVdF4CZI71g06W+mqhzu6ig==" }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "webpack": { "version": "5.75.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.10.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.9", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.1.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "dependencies": { "@types/estree": { "version": "0.0.51", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, "webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" } } }, "webpack-dev-middleware": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz", "integrity": "sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==", "requires": { "colorette": "^1.2.2", "mem": "^8.1.1", "memfs": "^3.2.2", "mime-types": "^2.1.30", "range-parser": "^1.2.1", "schema-utils": "^3.0.0" } }, "webpack-merge": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "requires": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" } }, "webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, "webpack-stats-plugin": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/webpack-stats-plugin/-/webpack-stats-plugin-1.1.1.tgz", "integrity": "sha512-aWwE/YuO2W7VCOyWwyDJ7BRSYRYjeXat+X31YiasMM3FS6/4X9W4Mb9Q0g+jIdVgArr1Mb08sHBJKMT5M9+gVA==" }, "webpack-virtual-modules": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.3.2.tgz", "integrity": "sha512-RXQXioY6MhzM4CNQwmBwKXYgBs6ulaiQ8bkNQEl2J6Z+V+s7lgl/wGvaI/I0dLnYKB8cKsxQc17QOAVIphPLDw==", "requires": { "debug": "^3.0.0" }, "dependencies": { "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "requires": { "isexe": "^2.0.0" } }, "which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" } }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "which-typed-array": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0", "is-typed-array": "^1.1.10" } }, "widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "requires": { "string-width": "^4.0.0" } }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, "workbox-background-sync": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-broadcast-update": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-build": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", "requires": { "@babel/runtime": "^7.3.4", "@hapi/joi": "^15.0.0", "common-tags": "^1.8.0", "fs-extra": "^4.0.2", "glob": "^7.1.3", "lodash.template": "^4.4.0", "pretty-bytes": "^5.1.0", "stringify-object": "^3.3.0", "strip-comments": "^1.0.2", "workbox-background-sync": "^4.3.1", "workbox-broadcast-update": "^4.3.1", "workbox-cacheable-response": "^4.3.1", "workbox-core": "^4.3.1", "workbox-expiration": "^4.3.1", "workbox-google-analytics": "^4.3.1", "workbox-navigation-preload": "^4.3.1", "workbox-precaching": "^4.3.1", "workbox-range-requests": "^4.3.1", "workbox-routing": "^4.3.1", "workbox-strategies": "^4.3.1", "workbox-streams": "^4.3.1", "workbox-sw": "^4.3.1", "workbox-window": "^4.3.1" }, "dependencies": { "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "requires": { "graceful-fs": "^4.1.6" } }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, "workbox-cacheable-response": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-core": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==" }, "workbox-expiration": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-google-analytics": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", "requires": { "workbox-background-sync": "^4.3.1", "workbox-core": "^4.3.1", "workbox-routing": "^4.3.1", "workbox-strategies": "^4.3.1" } }, "workbox-navigation-preload": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-precaching": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-range-requests": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-routing": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-strategies": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-streams": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", "requires": { "workbox-core": "^4.3.1" } }, "workbox-sw": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==" }, "workbox-window": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", "requires": { "workbox-core": "^4.3.1" } }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "requires": {} }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, "xml2js": { "version": "0.4.17", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", "integrity": "sha512-1O7wk/NTQN0UEOItIYTxK4qP4sMUVU60MbF4Nj0a8jd6eebMXOicVI/KFOEsYKKH4uBpx6XG9ZGZctXK5rtO5Q==", "requires": { "sax": ">=0.6.0", "xmlbuilder": "^4.1.0" } }, "xmlbuilder": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", "integrity": "sha512-oEePiEefhQhAeUnwRnIBLBWmk/fsWWbQ53EEWsRuzECbQ3m5o/Esmq6H47CYYwSLW+Ynt0rS9hd0pd2ogMAWjg==", "requires": { "lodash": "^4.0.0" } }, "xmlhttprequest-ssl": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==" }, "xss": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", "requires": { "commander": "^2.20.3", "cssfilter": "0.0.10" } }, "xstate": { "version": "4.32.1", "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.32.1.tgz", "integrity": "sha512-QYUd+3GkXZ8i6qdixnOn28bL3EvA++LONYL/EMWwKlFSh/hiLndJ8YTnz77FDs+JUXcwU7NZJg7qoezoRHc4GQ==" }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "xxhash-wasm": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==" }, "y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yaml-loader": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/yaml-loader/-/yaml-loader-0.8.0.tgz", "integrity": "sha512-LjeKnTzVBKWiQBeE2L9ssl6WprqaUIxCSNs5tle8PaDydgu3wVFXTbMfsvF2MSErpy9TDVa092n4q6adYwJaWg==", "requires": { "javascript-stringify": "^2.0.1", "loader-utils": "^2.0.0", "yaml": "^2.0.0" }, "dependencies": { "yaml": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==" } } }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" }, "dependencies": { "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { "p-locate": "^4.1.0" } }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { "p-limit": "^2.2.0" } } } }, "yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" }, "dependencies": { "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" } } }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==" }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, "yoga-layout-prebuilt": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", "requires": { "@types/yoga-layout": "1.9.2" } }, "yurnalist": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/yurnalist/-/yurnalist-2.1.0.tgz", "integrity": "sha512-PgrBqosQLM3gN2xBFIMDLACRTV9c365VqityKKpSTWpwR+U4LAFR3rSVyEoscWlu3EzX9+Y0I86GXUKxpHFl6w==", "requires": { "chalk": "^2.4.2", "inquirer": "^7.0.0", "is-ci": "^2.0.0", "read": "^1.0.7", "strip-ansi": "^5.2.0" }, "dependencies": { "ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "^1.9.0" } }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { "ansi-regex": "^4.1.0" } }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { "has-flag": "^3.0.0" } } } }, "zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" } } } thinc-9.0.0/website/package.json000066400000000000000000000052451461023342500165630ustar00rootroot00000000000000{ "name": "thinc.ai", "private": true, "description": "Thinc website", "version": "0.0.1", "author": "Explosion ", "dependencies": { "@tippy.js/react": "^2.2.2", "autoprefixer": "^10.4.13", "classnames": "^2.2.6", "gatsby": "^4.18.2", "gatsby-image": "^2.11.0", "gatsby-plugin-google-analytics": "^4.25.0", "gatsby-plugin-manifest": "^4.25.0", "gatsby-plugin-offline": "^5.25.0", "gatsby-plugin-plausible": "^0.0.7", "gatsby-plugin-react-helmet": "^5.25.0", "gatsby-plugin-react-svg": "^3.3.0", "gatsby-plugin-remove-trailing-slashes": "^4.19.0", "gatsby-plugin-sass": "^5.25.0", "gatsby-plugin-sass-resources": "^3.0.1", "gatsby-plugin-sharp": "^4.25.0", "gatsby-plugin-sitemap": "^5.25.0", "gatsby-remark-copy-linked-files": "^5.25.0", "gatsby-remark-images": "^6.25.0", "gatsby-remark-prismjs": "^6.25.0", "gatsby-remark-smartypants": "^5.25.0", "gatsby-remark-unwrap-images": "^1.0.2", "gatsby-source-filesystem": "^4.25.0", "gatsby-transformer-remark": "^5.25.1", "gatsby-transformer-sharp": "^4.25.0", "html-to-react": "^1.3.4", "parse-numeric-range": "0.0.2", "prismjs": "^1.15.0", "react": "^16.8.2", "react-dom": "^16.8.2", "react-helmet": "^5.2.0", "react-jss": "^8.6.1", "rehype-react": "^3.1.0", "remark-react": "^5.0.1", "slugify": "^1.3.6" }, "scripts": { "deploy": "npm run fonts:fetch && npm run build", "build": "gatsby build", "dev": "gatsby develop", "lint": "eslint src", "clear": "rm -rf .cache", "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\"", "fonts:fetch": "wget -O fonts.zip $SECRET_FONTS_URL; unzip fonts.zip -d ./src/fonts; rm fonts.zip" }, "devDependencies": { "babel-cli": "^6.26.0", "babel-core": "^6.26.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.13", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "json5": "^2.1.0", "md-attr-parser": "^1.2.1", "prettier": "^1.16.4", "unist-util-remove": "^1.0.3", "unist-util-visit": "^1.4.0" }, "repository": { "type": "git", "url": "https://github.com/explosion/thinc" }, "engines": { "node": "16" } } thinc-9.0.0/website/plugins/000077500000000000000000000000001461023342500157505ustar00rootroot00000000000000thinc-9.0.0/website/plugins/gatsby-remark-code-blocks/000077500000000000000000000000001461023342500227035ustar00rootroot00000000000000thinc-9.0.0/website/plugins/gatsby-remark-code-blocks/index.js000066400000000000000000000047311461023342500243550ustar00rootroot00000000000000/** * Support titles, line highlights and more for code blocks */ const visit = require('unist-util-visit') const parseAttr = require('md-attr-parser') const defaultOptions = { defaultPrefix: '###', prefixMap: { javascript: '///', jsx: '///', }, languageAliases: {}, githubRegex: /^https:\/\/(github|raw.githubusercontent).com/, prompts: ['$'], } module.exports = ({ markdownAST }, userOptions = {}) => { const options = Object.assign({}, defaultOptions, userOptions) visit(markdownAST, 'code', node => { if (node.value) { const langName = node.lang || 'none' const lang = options.languageAliases[langName] || langName const prefix = options.prefixMap[lang] || options.defaultPrefix const lines = node.value.split('\n') let attrs = { lang } const firstLine = lines[0].trim() if (firstLine && firstLine.startsWith(prefix)) { const title = firstLine.slice(prefix.length).trim() attrs.title = title // Check for attributes in title, e.g. {executable="true"} const parsed = title.split(/\{(.*?)\}/) if (parsed.length >= 2 && parsed[1]) { const { prop } = parseAttr(parsed[1]) attrs = { ...attrs, ...prop, title: parsed[0].trim(), lang } } // Overwrite the code text with the rest of the lines node.value = lines.slice(1).join('\n') } else if (firstLine && options.githubRegex.test(firstLine)) { // GitHub URL attrs.github = 'true' } // If it's a bash code block and single line, check for prompts if (lang === 'bash') { const [trueFirstLine, ...trueLines] = node.value.split('\n') for (let prompt of options.prompts) { if (trueFirstLine.startsWith(prompt)) { const content = [trueFirstLine.slice(prompt.length).trim(), ...trueLines] attrs.prompt = prompt node.value = content.join('\n') break } } } const data = node.data || (node.data = {}) const hProps = data.hProperties || (data.hProperties = {}) node.data.hProperties = Object.assign({}, hProps, attrs) } }) return markdownAST } thinc-9.0.0/website/plugins/gatsby-remark-code-blocks/package.json000066400000000000000000000003351461023342500251720ustar00rootroot00000000000000{ "name": "gatsby-remark-code-blocks", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } thinc-9.0.0/website/plugins/gatsby-remark-custom-attrs/000077500000000000000000000000001461023342500231635ustar00rootroot00000000000000thinc-9.0.0/website/plugins/gatsby-remark-custom-attrs/index.js000066400000000000000000000041331461023342500246310ustar00rootroot00000000000000/** * Simplified implementation of remark-attr that allows custom attributes on * nodes *inline* via the following syntax: {#some-id key="value"}. Extracting * them inline is slightly hackier (at least in this implementation), but it * makes the resulting markup valid and compatible with formatters like * Prettier, which do not allow additional content right below headlines. * Based on: https://github.com/arobase-che/remark-attr */ const visit = require('unist-util-visit') const parseAttr = require('md-attr-parser') const defaultOptions = { elements: ['heading'], } module.exports = ({ markdownAST }, userOptions = {}) => { const options = Object.assign({}, defaultOptions, userOptions) visit(markdownAST, null, node => { if (options.elements.includes(node.type)) { if ( node.children && node.children.length && node.children[node.children.length - 1].type === 'text' && node.children[node.children.length - 1].value ) { if (node.children.length > 1 && node.children.every(el => el.type === 'text')) { // If headlines contain escaped characters, e.g. // Doc.\_\_init\_\_, it will be split into several nodes const mergedText = node.children.map(el => el.value).join('') node.children[0].value = mergedText node.children = [node.children[0]] } const lastIdx = node.children.length - 1 const parsed = node.children[lastIdx].value.split(/\{(.*?)\}/) if (parsed.length >= 2 && parsed[1]) { const text = parsed[0] const { prop } = parseAttr(parsed[1]) const data = node.data || (node.data = {}) const hProps = data.hProperties || (data.hProperties = {}) node.data.hProperties = Object.assign({}, hProps, prop) node.children[lastIdx].value = text } } } }) return markdownAST } thinc-9.0.0/website/plugins/gatsby-remark-custom-attrs/package.json000066400000000000000000000003361461023342500254530ustar00rootroot00000000000000{ "name": "gatsby-remark-custom-attrs", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } thinc-9.0.0/website/plugins/gatsby-remark-unwrap/000077500000000000000000000000001461023342500220325ustar00rootroot00000000000000thinc-9.0.0/website/plugins/gatsby-remark-unwrap/index.js000066400000000000000000000015701461023342500235020ustar00rootroot00000000000000/** * Unwrap elements and remove outer

* Fork of: https://github.com/xuopled/gatsby-remark-unwrap-images */ const visit = require('unist-util-visit') const remove = require('unist-util-remove') const defaultOptions = { elements: ['image', 'html'], } function isWrapped(child, elements = []) { return elements.includes(child.type) || (child.type === 'text' && child.value === '\n') } module.exports = ({ markdownAST }, userOptions = {}) => { const options = Object.assign({}, defaultOptions, userOptions) const elements = options.elements || [] visit(markdownAST, 'paragraph', (node, index, parent) => { const wrapped = node.children.every(child => isWrapped(child, elements)) if (!wrapped) return remove(node, 'text') parent.children.splice(index, 1, ...node.children) return index }) return markdownAST } thinc-9.0.0/website/plugins/gatsby-remark-unwrap/package.json000066400000000000000000000003301461023342500243140ustar00rootroot00000000000000{ "name": "gatsby-remark-unwrap", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } thinc-9.0.0/website/src/000077500000000000000000000000001461023342500150565ustar00rootroot00000000000000thinc-9.0.0/website/src/components/000077500000000000000000000000001461023342500172435ustar00rootroot00000000000000thinc-9.0.0/website/src/components/box.js000066400000000000000000000013131461023342500203670ustar00rootroot00000000000000import React from 'react' import classNames from 'classnames' import * as classes from '../styles/box.module.sass' export const Box = ({ Component = 'section', id, className, children }) => ( {children} ) export const Infobox = ({ variant, children }) => { const infoboxClassNames = classNames(classes.infobox, { [classes.warning]: variant === 'warning', [classes.danger]: variant === 'danger', }) return ( {variant ? '!' : 'i'} {children} ) } thinc-9.0.0/website/src/components/code.js000066400000000000000000000150661461023342500205230ustar00rootroot00000000000000import React, { useState, useEffect, Fragment } from 'react' import classNames from 'classnames' import highlightCode from 'gatsby-remark-prismjs/highlight-code.js' import rangeParser from 'parse-numeric-range' import Icon from './icon' import Link from './link' import { H5 } from './typography' import { isString, htmlToReact, isTrue, getStringChildren } from '../util' import CUSTOM_TYPES from '../../docs/_type_links.json' import * as classes from '../styles/code.module.sass' const GITHUB_URL_SPLIT_PATH = 'thinc/' const DEFAULT_TYPE_URL = CUSTOM_TYPES.__default__ function getGitHubPath(url) { if (!url.includes(GITHUB_URL_SPLIT_PATH)) { return url.split('github.com/').slice(-1) } const path = url.split(`/${GITHUB_URL_SPLIT_PATH}`).slice(-1) return `${GITHUB_URL_SPLIT_PATH}${path}` } function linkType(el, showLink = true) { if (!isString(el) || !el.length) return el const elStr = el.trim() if (!elStr) return el const typeUrl = CUSTOM_TYPES[elStr] const url = typeUrl == true ? DEFAULT_TYPE_URL : typeUrl const ws = el[0] == ' ' return url && showLink ? ( {ws && ' '} {elStr} ) : ( el ) } export const InlineCode = ({ wrap, prompt, className, children, ...props }) => { const codeClassNames = classNames(classes.inlineCode, className, { [classes.wrap]: wrap || (isString(children) && children.length >= 20), }) return ( {children} ) } export const Kbd = ({ children }) => {children} export const Pre = ({ children, className, ...props }) => (
        {children}
    
) export const CodeComponent = ({ lang = 'none', highlight, github = false, children, className, ...props }) => { const codeText = Array.isArray(children) ? children.join('') : children || '' const isGitHub = isTrue(github) if (isGitHub) { return } const highlightRange = highlight ? rangeParser.parse(highlight).filter(n => n > 0) : [] const html = lang === 'none' ? codeText : highlightCode(lang, codeText, {}, highlightRange) return } const CodeWrapper = ({ title, html, lang = 'none', small = false, wrap = false, prompt, className, children, ...props }) => { const codeClassNames = classNames(className, `language-${lang}`, { [classes.small]: isTrue(small), [classes.wrap]: isTrue(wrap), }) const tagClassNames = classNames(classes.titleTag, { [classes.titleTagSmall]: isTrue(small), }) return ( <> {title && ( {title} )} {children} {htmlToReact(html)} ) } const GitHubCode = React.memo(({ url, lang }) => { const errorMsg = `Can't fetch code example from GitHub :( Please use the link above to view the example. If you've come across a broken link, we always appreciate a pull request to the repository, or a report on the issue tracker. Thanks!` const [initialized, setInitialized] = useState(false) const [code, setCode] = useState(errorMsg) const rawUrl = url .replace('github.com', 'raw.githubusercontent.com') .replace('/blob', '') .replace('/tree', '') useEffect(() => { if (!initialized) { setCode(null) fetch(rawUrl) .then(res => res.text().then(text => ({ text, ok: res.ok }))) .then(({ text, ok }) => { setCode(ok ? text : errorMsg) }) .catch(err => { setCode(errorMsg) console.error(err) }) setInitialized(true) } }, [initialized, rawUrl, errorMsg]) const html = lang === 'none' || !code ? code : highlightCode(lang, code) const title = ( View on GitHub ) return (
{' '} {getGitHubPath(url)}
) }) export const CodeBlock = props => (
        
    
) export const TypeAnnotation = ({ lang = 'python', link = true, children }) => { const showLink = isTrue(link) const code = Array.isArray(children) ? children.join('') : children || '' const html = lang === 'none' || !code ? code : highlightCode(lang, code) const result = htmlToReact(html) const elements = Array.isArray(result) ? result : [result] const annotClassNames = classNames( 'type-annotation', `language-${lang}`, classes.typeAnnotation, { [classes.wrap]: code.length >= 20, } ) return ( {elements.map((el, i) => ( {linkType(el, showLink)} ))} ) } export const Ndarray = ({ shape, link = true, children }) => { const strChildren = getStringChildren(children) const html = highlightCode('python', strChildren) const result = htmlToReact(html) const elements = Array.isArray(result) ? result : [result] return ( {elements.map((el, i) => ( {linkType(el, isTrue(link))} ))} {' '} {shape && ( {`(${shape})`} )} ) } export const CodeScreenshot = ({ width, children }) => (
{children}
) thinc-9.0.0/website/src/components/dropdown.js000066400000000000000000000013641461023342500214410ustar00rootroot00000000000000import React from 'react' import classNames from 'classnames' import { navigate } from 'gatsby' import * as classes from '../styles/dropdown.module.sass' const Dropdown = ({ defaultValue, className, onChange, children }) => { const defaultOnChange = ({ target }) => { const isExternal = /((http(s?)):\/\/|mailto:)/gi.test(target.value) if (isExternal) { window.location.href = target.value } else { navigate(target.value) } } return ( ) } export default Dropdown thinc-9.0.0/website/src/components/footer.js000066400000000000000000000036361461023342500211070ustar00rootroot00000000000000import React from 'react' import { graphql, StaticQuery } from 'gatsby' import classNames from 'classnames' import Link from './link' import Icon from './icon' import * as classes from '../styles/footer.module.sass' export default ({ className }) => ( { const { twitter, github, company, companyUrl, imprintUrl } = site.siteMetadata return (
  • © 2017- {new Date().getFullYear()}{' '} {company}
  • Legal & Imprint
) }} /> ) const query = graphql` query { site { siteMetadata { company companyUrl imprintUrl email twitter github } } } ` thinc-9.0.0/website/src/components/grid.js000066400000000000000000000005261461023342500205310ustar00rootroot00000000000000import React from 'react' import classNames from 'classnames' import * as classes from '../styles/grid.module.sass' export default ({ layout = 'auto', children }) => { const gridClassNames = classNames(classes.root, { [classes.feature]: layout === 'feature', }) return
{children}
} thinc-9.0.0/website/src/components/icon.js000066400000000000000000000030111461023342500205240ustar00rootroot00000000000000import React from 'react' import classNames from 'classnames' import * as classes from '../styles/icon.module.sass' import TwitterIcon from '../images/icons/twitter.svg' import GitHubIcon from '../images/icons/github.svg' import ArrowRightIcon from '../images/icons/arrow-right.svg' import YesIcon from '../images/icons/yes.svg' import NoIcon from '../images/icons/no.svg' import CubeIcon from '../images/icons/cube.svg' import FileIcon from '../images/icons/file.svg' const ICONS = { twitter: TwitterIcon, github: GitHubIcon, right: ArrowRightIcon, yes: YesIcon, no: NoIcon, cube: CubeIcon, file: FileIcon, } export default ({ name, size = 16, alt = null, className, ...props }) => { const SvgIcon = ICONS[name] if (!SvgIcon) throw Error(`Invalid icon name: '${name}'`) const style = { minWidth: size } const iconClassNames = classNames(classes.root, className, { [classes.red]: name === 'no', [classes.green]: name === 'yes', }) const altTexts = { yes: 'yes', no: 'no' } return ( ) } export const Emoji = ({ alt, children }) => { const attrs = alt ? { role: 'img', 'aria-label': alt } : { 'aria-hidden': true } return ( {children} ) } thinc-9.0.0/website/src/components/landing.js000066400000000000000000000074641461023342500212300ustar00rootroot00000000000000import React from 'react' import classNames from 'classnames' import { graphql, StaticQuery } from 'gatsby' import Img from 'gatsby-image' import { InlineCode as DefaultInlineCode } from '../components/code' import Link, { Button } from '../components/link' import { H3 } from '../components/typography' import { Emoji } from '../components/icon' import ExplosionLogo from '../images/logos/explosion.svg' import Logo from '../images/logo.svg' import * as classes from '../styles/landing.module.sass' const headerQuery = graphql` query { site { siteMetadata { company companyUrl } } headerTopLeft: file(relativePath: { eq: "landing_top-left.png" }) { ...headerImage } headerTopRight: file(relativePath: { eq: "landing_top-right.png" }) { ...headerImage } } ` export const headerImage = graphql` fragment headerImage on File { childImageSharp { fluid(maxWidth: 1200, quality: 100) { ...GatsbyImageSharpFluid } } } ` export const Header = ({ logo = true, logoLink, companyLogo = true, children }) => { const logoSvg = return ( { const { company, companyUrl } = data.site.siteMetadata return (
{companyLogo && ( )}
{logo && logoLink ? ( {logoSvg} ) : ( logoSvg )}
{children}
) }} /> ) } export const InlineCode = props => export const Section = ({ title, to, buttonText = 'Read more', narrow = false, className, children, }) => { const sectionClassNames = classNames(classes.section, className, { [classes.sectionNarrow]: narrow, }) return (
{title && (

{title}

)} {children} {to && ( )}
) } export const Feature = ({ title, emoji, children }) => (

{emoji && {emoji}} {title}

{children}
) export const FeatureGrid = ({ children }) =>
{children}
thinc-9.0.0/website/src/components/layout.js000066400000000000000000000004141461023342500211150ustar00rootroot00000000000000import React from 'react' import SEO from './seo' const Layout = ({ title, description, className, children }) => ( <>
{children}
) export default Layout thinc-9.0.0/website/src/components/link.js000066400000000000000000000037461461023342500205500ustar00rootroot00000000000000import React from 'react' import { Link as GatsbyLink } from 'gatsby' import classNames from 'classnames' import Icon from './icon' import * as classes from '../styles/link.module.sass' const internalRegex = /(http(s?)):\/\/(explosion.ai|prodi.gy|spacy.io|irl.spacy.io|support.prodi.gy)/gi const Link = ({ type, ...props }) => { // This is a workaround for the gatsby-remark-copy-linked-files, which // only recognizes
elements, not a custom