diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..bf3241a2d9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.{js,d.ts,json,html,md,sh}] +charset = utf-8 +indent_style = space +indent_size = 2 diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000000..17a489a8c3 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# upgrade to prettier 3 +0355483c301dba5e215e2c3d113125a274444e38 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000000..936cae52b0 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,105 @@ +# Have a question? + +Please ask questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/immutable.js) instead of opening a Github Issue. There are more people on Stack Overflow who +can answer questions, and good answers can be searchable and canonical. + +# Issues + +We use GitHub issues to track bugs. Please ensure your bug description is clear +and has sufficient instructions to be able to reproduce the issue. + +The absolute best way to report a bug is to submit a pull request including a +new failing test which describes the bug. When the bug is fixed, your pull +request can then be merged! + +The next best way to report a bug is to provide a reduced test case on jsFiddle +or jsBin or produce exact code inline in the issue which will reproduce the bug. + +# Code of Conduct + +Immutable.js is maintained within the [Contributor Covenant's Code of Conduct](https://www.contributor-covenant.org/version/2/0/code_of_conduct/). + +# Pull Requests + +All active development of Immutable JS happens on GitHub. We actively welcome +your [pull requests](https://help.github.com/articles/creating-a-pull-request). + +1. Fork the repo and create your branch from `master`. +2. Install all dependencies. (`npm install`) +3. If you've added code, add tests. +4. If you've changed APIs, update the documentation. +5. Build generated JS, run tests and ensure your code passes lint. (`npm run test`) +6. If you haven't already, complete the Contributor License Agreement ("CLA"). + +## Documentation + +Documentation for Immutable.js (hosted at http://immutable-js.github.io/immutable-js) +is developed in `pages/`. Run `npm start` to get a local copy in your browser +while making edits. + +## Coding Style + +- 2 spaces for indentation (no tabs) +- 80 character line length strongly preferred. +- Prefer `'` over `"` +- ES6 Harmony when possible. +- Use semicolons; +- Trailing commas, +- Avd abbr wrds. + +# Functionality Testing + +Run the following command to build the library and test functionality: + +```bash +npm run test +``` + +## Performance Regression Testing + +Performance tests run against master and your feature branch. +Make sure to commit your changes in your local feature branch before proceeding. + +These commands assume you have a remote named `upstream` amd that you do not already have a local `master` branch: + +```bash +git fetch upstream +git checkout -b master upstream/master +``` + +These commands build `dist` and commit `dist/immutable.js` to `master` so that the regression tests can run. +```bash +npm run test +git add dist/immutable.js -f +git commit -m 'perf test prerequisite.' +``` + +Switch back to your feature branch, and run the following command to run regression tests: + +```bash +npm run test +npm run perf +``` + +Sample output: + +```bash +> immutable@4.0.0-rc.9 perf ~/github.com/immutable-js/immutable-js +> node ./resources/bench.js + +List > builds from array of 2 + Old: 678,974 683,071 687,218 ops/sec + New: 669,012 673,553 678,157 ops/sec + compare: 1 -1 + diff: -1.4% + rme: 0.64% +``` + +## TypeScript version support + +TypeScript version does support the same version as [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) versions. Immutable "may" work with older versions, but no support will be provided. + +## License + +By contributing to Immutable.js, you agree that your contributions will be +licensed under its MIT license. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..4cf7679033 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [jdeniau, Methuselah96] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..3387aa797e --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,42 @@ + + +### What happened + + + +### How to reproduce + + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..29c1b4a5d3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,139 @@ +name: CI + +on: + push: + branches: + - main + - 5.x + - 6.x + pull_request: ~ + +jobs: + lint: + name: 'Lint' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + - run: npm ci + - run: npm run lint + - run: npm run check-git-clean + + type-check: + name: 'Type Check' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + - uses: actions/cache@v4 + with: + path: ~/.dts + key: ${{ runner.OS }}-dts-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-dts- + - run: npm ci + - run: npm run type-check + - run: npm run check-git-clean + + test: + name: 'Build & Unit Test & Type Test' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + - name: 'Install dependencies' + run: npm ci + + - name: 'Build JS files' + run: npm run build + + - name: 'Ensure all files are builded' + run: npm run check-build-output + + - name: 'Run unit tests' + run: npm run test:unit + + - name: 'Test types' + run: npm run test:types -- --target 4.5,5.0,current + + - run: npx size-limit + - run: npm run check-git-clean + + website: + name: 'Build Website' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + - run: npm ci + - run: NODE_OPTIONS=--openssl-legacy-provider npm run website:build + - run: npm run check-git-clean + + publish: + name: 'Publish' + needs: [lint, type-check, test, website] + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + - run: npm ci + - run: npm run build + - run: NODE_OPTIONS=--openssl-legacy-provider npm run website:build + - name: Push NPM Branch + if: github.ref == 'refs/heads/main' + uses: peaceiris/actions-gh-pages@v3 + with: + enable_jekyll: true + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./npm + publish_branch: npm + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' + - name: Publish Docs + if: github.ref == 'refs/heads/main' + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./website/out + cname: immutable-js.com + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' diff --git a/.github/workflows/output_diff.yml b/.github/workflows/output_diff.yml new file mode 100644 index 0000000000..74690ee3cd --- /dev/null +++ b/.github/workflows/output_diff.yml @@ -0,0 +1,62 @@ +name: CI + +on: + pull_request: + branches: + - main + - init-migrate-to-ts + # run only if there is ts files in the PR + paths: + - 'src/**/*.ts' + +jobs: + diff: + name: 'Output diff' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + path: 'pr' + + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.base.sha }} + path: 'main' + + - uses: actions/setup-node@v4 + with: + node-version: '20' + + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + + - name: 'Install PR branch dependencies' + run: npm ci + working-directory: pr + + - name: 'Install main branch dependencies' + run: npm ci + working-directory: main + + - name: 'Build PR branch' + run: npm run build + working-directory: pr + + - name: 'Build main branch' + run: npm run build + working-directory: main + + - name: 'Execute prettier and remove ts-expect-error on PR dist' + run: npx terser dist/immutable.es.js --comments false | npx prettier --parser=babel > dist/immutable.es.prettier.js + + working-directory: pr + + - name: 'Execute prettier main dist' + run: npx terser dist/immutable.es.js --comments false | npx prettier --parser=babel > dist/immutable.es.prettier.js + working-directory: main + + - name: 'Output diff' + run: diff --unified --ignore-blank-lines --ignore-all-space main/dist/immutable.es.prettier.js pr/dist/immutable.es.prettier.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..ad6d4d72ad --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,39 @@ +name: Release + +on: + workflow_dispatch: ~ + release: + types: [published] + +jobs: + build: + name: 'Build & Publish to NPM' + permissions: + contents: read + id-token: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + - uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.OS }}-node- + - run: npm ci + - run: npm run build + - name: 'Determine NPM tag: latest or next depending if we are on a prerelease or not (version with hyphen should be a prerelease)' + id: npm_tag + run: | + VERSION=$(node -p "require('./package.json').version") + if [[ $VERSION == *-* ]]; then + echo "TAG=next" >> "$GITHUB_OUTPUT" + else + echo "TAG=latest" >> "$GITHUB_OUTPUT" + fi + - run: cd npm && npm publish --provenance --tag ${{ steps.npm_tag.outputs.TAG }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 5de07b1848..972b88d8e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,18 @@ .*.haste_cache.* node_modules -old npm-debug.log +yarn-error.log .DS_Store *~ *.swp +.idea +*.iml TODO +/website/.next +/website/out +/website/public/sitemap*.xml +/website/public/robots.txt +/gh-pages +/npm +/dist +/coverage \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..3b56666703 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +dist +type-definitions/flow-tests/ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..544138be45 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..9df8e0fce0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,703 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +Dates are formatted as YYYY-MM-DD. + +## Unreleased + +## 5.1.2 + +- Revert previous assertion as it introduced a regression [#2102](https://github.com/immutable-js/immutable-js/pull/2102) by [@giggo1604](https://github.com/giggo1604) +- Merge should work with empty record [#2103](https://github.com/immutable-js/immutable-js/pull/2103) by [@jdeniau](https://github.com/jdeniau) + +## 5.1.1 + +- Fix type copying + +## 5.1.0 + +- Add shuffle to list [#2066](https://github.com/immutable-js/immutable-js/pull/2066) by [@mazerty](https://github.com/mazerty) +- TypeScript: Better getIn `RetrievePath` [#2070](https://github.com/immutable-js/immutable-js/pull/2070) by [@jdeniau](https://github.com/jdeniau) +- Fix #1915 "Converting a Seq to a list causes RangeError (max call size exceeded)" by @alexvictoor in [#2038](https://github.com/immutable-js/immutable-js/pull/2038) +- TypeScript: Fix proper typings for Seq.concat() [#2040](https://github.com/immutable-js/immutable-js/pull/2040) by [@alexvictoor](https://github.com/alexvictoor) +- Fix Uncaught "TypeError: keyPath.slice is not a function" for ArrayLike method [#2065](https://github.com/immutable-js/immutable-js/pull/2065) by [@jdeniau](https://github.com/jdeniau) + +### Internal + +- Upgrade typescript and typescript-eslint [#2046](https://github.com/immutable-js/immutable-js/pull/2046) by [@jdeniau](https://github.com/jdeniau) +- Upgrade to rollup 4 [#2049](https://github.com/immutable-js/immutable-js/pull/2049) by [@jdeniau](https://github.com/jdeniau) +- Start migrating codebase to TypeScript without any runtime change nor .d.ts change: + - allow TS files to be compiled in src dir [#2054](https://github.com/immutable-js/immutable-js/pull/2054) by [@jdeniau](https://github.com/jdeniau) +- add exception for code that should not happen in updateIn [#2074](https://github.com/immutable-js/immutable-js/pull/2074) by [@jdeniau](https://github.com/jdeniau) +- Reformat Range.toString for readability [#2075](https://github.com/immutable-js/immutable-js/pull/2075) by [@Ustin.Vaskin](https://github.com/ustinvaskin) + +## [5.0.3] + +- Fix List.VNode.removeAfter() / removeBefore() issue on some particular case [#2030](https://github.com/immutable-js/immutable-js/pull/2030) by [@alexvictoor](https://github.com/alexvictoor) + +## [5.0.2] + +- Fix wrong path for esm module after fix in 5.0.1 + +## [5.0.1] + +- Fix circular dependency issue with ESM build by @iambumblehead in [#2035](https://github.com/immutable-js/immutable-js/pull/2035) by [@iambumblehead](https://github.com/iambumblehead) + +## [5.0.0] + +### Breaking changes + +To sum up, the **big** change in 5.0 is a Typescript change related to `Map` that is typed closer to the JS object. This is a huge change for TS users, but do not impact the runtime behavior. (see [Improve TypeScript definition for `Map`](#typescript-break-improve-typescript-definition-for-map) for more details) + +Other breaking changes are: + +#### [BREAKING] Remove deprecated methods: + +_Released in 5.0.0-rc.1_ + +- `Map.of('k', 'v')`: use `Map([ [ 'k', 'v' ] ])` or `Map({ k: 'v' })` +- `Collection.isIterable`: use `isIterable` directly +- `Collection.isKeyed`: use `isKeyed` directly +- `Collection.isIndexed`: use `isIndexed` directly +- `Collection.isAssociative`: use `isAssociative` directly +- `Collection.isOrdered`: use `isOrdered` directly + +#### [BREAKING] `OrdererMap` and `OrderedSet` hashCode implementation has been fixed + +_Released in 5.0.0-rc.1_ + +Fix issue implementation of `hashCode` for `OrdererMap` and `OrderedSet` where equal objects might not return the same `hashCode`. + +Changed in [#2005](https://github.com/immutable-js/immutable-js/pull/2005) + +#### [BREAKING] Range function needs at least two defined parameters + +_Released in 5.0.0-beta.5_ + +Range with `undefined` would end in an infinite loop. Now, you need to define at least the start and end values. + +If you need an infinite range, you can use `Range(0, Infinity)`. + +Changed in [#1967](https://github.com/immutable-js/immutable-js/pull/1967) by [@jdeniau](https://github.com/jdeniau) + +#### [Minor BC break] Remove default export + +_Released in 5.0.0-beta.1_ + +Immutable does not export a default object containing all it's API anymore. +As a drawback, you can not `immport Immutable` directly: + +```diff +- import Immutable from 'immutable'; ++ import { List, Map } from 'immutable'; + +- const l = Immutable.List([Immutable.Map({ a: 'A' })]); ++ const l = List([Map({ a: 'A' })]); +``` + +If you want the non-recommanded, but shorter migration path, you can do this: + +```diff +- import Immutable from 'immutable'; ++ import * as Immutable from 'immutable'; + + const l = Immutable.List([Immutable.Map({ a: 'A' })]); +``` + +#### [TypeScript Break] Improve TypeScript definition for `Map` + +_Released in 5.0.0-beta.1_ + +> If you do use TypeScript, then this change does not impact you : no runtime change here. +> But if you use Map with TypeScript, this is a HUGE change ! +> Imagine the following code + +```ts +const m = Map({ length: 3, 1: 'one' }); +``` + +This was previously typed as `Map` + +and return type of `m.get('length')` or `m.get('inexistant')` was typed as `string | number | undefined`. + +This made `Map` really unusable with TypeScript. + +Now the Map is typed like this: + +```ts +MapOf<{ + length: number; + 1: string; +}>; +``` + +and the return type of `m.get('length')` is typed as `number`. + +The return of `m.get('inexistant')` throw the TypeScript error: + +> Argument of type '"inexistant"' is not assignable to parameter of type '1 | "length" + +##### If you want to keep the old definition + +**This is a minor BC for TS users**, so if you want to keep the old definition, you can declare you Map like this: + +```ts +const m = Map({ length: 3, 1: 'one' }); +``` + +##### If you need to type the Map with a larger definition + +You might want to declare a wider definition, you can type your Map like this: + +```ts +type MyMapType = { + length: number; + 1: string | null; + optionalProperty?: string; +}; +const m = Map({ length: 3, 1: 'one' }); +``` + +Keep in mind that the `MapOf` will try to be consistant with the simple TypeScript object, so you can not do this: + +```ts +Map({ a: 'a' }).set('b', 'b'); +Map({ a: 'a' }).delete('a'); +``` + +Like a simple object, it will only work if the type is forced: + +```ts +Map<{ a: string; b?: string }>({ a: 'a' }).set('b', 'b'); // b is forced in type and optional +Map<{ a?: string }>({ a: 'a' }).delete('a'); // you can only delete an optional key +``` + +##### Are all `Map` methods implemented ? + +For now, only `get`, `getIn`, `set`, `update`, `delete`, `remove`, `toJS`, `toJSON` methods are implemented. All other methods will fallback to the basic `Map` definition. Other method definition will be added later, but as some might be really complex, we prefer the progressive enhancement on the most used functions. + +### Fixes + +- Fix type inference for first() and last() [#2001](https://github.com/immutable-js/immutable-js/pull/2001) by [@butchler](https://github.com/butchler) +- Fix issue with empty list that is a singleton [#2004](https://github.com/immutable-js/immutable-js/pull/2004) by [@jdeniau](https://github.com/jdeniau) +- Map and Set sort and sortBy return type [#2013](https://github.com/immutable-js/immutable-js/pull/2013) by [@jdeniau](https://github.com/jdeniau) + +### Internal + +- [Internal] Migrating TS type tests from dtslint to [TSTyche](https://tstyche.org/) [#1988](https://github.com/immutable-js/immutable-js/pull/1988) and [#1991](https://github.com/immutable-js/immutable-js/pull/1991) by [@mrazauskas](https://github.com/mrazauskas). + Special thanks to [@arnfaldur](https://github.com/arnfaldur) that migrated every type tests to tsd just before that. +- [internal] Upgrade to rollup 3.x [#1965](https://github.com/immutable-js/immutable-js/pull/1965) by [@jdeniau](https://github.com/jdeniau) +- [internal] upgrade tooling (TS, eslint) and documentation packages: #1971, #1972, #1973, #1974, #1975, #1976, #1977, #1978, #1979, #1980, #1981 + +## [4.3.7] - 2024-07-22 + +- Fix issue with slice negative of filtered sequence [#2006](https://github.com/immutable-js/immutable-js/pull/2006) by [@jdeniau](https://github.com/jdeniau) + +## [4.3.6] - 2024-05-13 + +- Fix `Repeat().equals(undefined)` incorrectly returning true [#1994](https://github.com/immutable-js/immutable-js/pull/1994) by [@butchler](https://github.com/butchler) + +## [4.3.5] - 2024-01-16 + +- Upgrade to TS 5.1 [#1972](https://github.com/immutable-js/immutable-js/pull/1972) by [@jdeniau](https://github.com/jdeniau) +- Fix Set.fromKeys types with Map constructor in TS 5.0 [#1971](https://github.com/immutable-js/immutable-js/pull/1971) by [@jdeniau](https://github.com/jdeniau) +- Fix Read the Docs link on readme [#1970](https://github.com/immutable-js/immutable-js/pull/1970) by [@joshding](https://github.com/joshding) + +## [4.3.4] - 2023-08-25 + +- Rollback toJS type due to circular reference error [#1958](https://github.com/immutable-js/immutable-js/pull/1958) by [@jdeniau](https://github.com/jdeniau) + +## [4.3.3] - 2023-08-23 + +- [typescript] manage to handle toJS circular reference. [#1932](https://github.com/immutable-js/immutable-js/pull/1932) by [@jdeniau](https://github.com/jdeniau) +- [doc] Add install instructions for pnpm and Bun [#1952](https://github.com/immutable-js/immutable-js/pull/1952) by [@colinhacks](https://github.com/colinhacks) and [#1953](https://github.com/immutable-js/immutable-js/pull/1953) by [@menglingyu659](https://github.com/menglingyu659) + +## [4.3.2] - 2023-08-01 + +- [TypeScript] Fix isOrderedSet type [#1948](https://github.com/immutable-js/immutable-js/pull/1948) + +## [4.3.1] - 2023-07-11 + +- Faster and implementation of `some` [#1944](https://github.com/immutable-js/immutable-js/pull/1944) +- [internal] remove unused exports [#1928](https://github.com/immutable-js/immutable-js/pull/1928) + +## [4.3.0] - 2023-03-10 + +- Introduce Comparator and PairSorting [#1937](https://github.com/immutable-js/immutable-js/pull/1937) by [@https://github.com/giancosta86](https://github.com/giancosta86) +- [TypeScript] Fix fromJS declaration for greater compatibility [#1936](https://github.com/immutable-js/immutable-js/pull/1936) + +## [4.2.4] - 2023-02-06 + +- [TypeScript] Improve type infererence for from JS by [KSXGitHub](https://github.com/KSXGitHub) [#1927](https://github.com/immutable-js/immutable-js/pull/1927) + +## [4.2.3] - 2023-02-02 + +- [TypeScript] `groupBy` return either a `Map` or an `OrderedMap`: make the type more precise than base `Collection` [#1924](https://github.com/immutable-js/immutable-js/pull/1924) + +## [4.2.2] - 2023-01-02 + +- [Flow] Add type for `partition` method [#1920](https://github.com/immutable-js/immutable-js/pull/1920) by [Dagur](https://github.com/Dagur) + +## [4.2.1] - 2022-12-23 + +- [Typescript] rollback some of the change on `toJS` to avoir circular reference + +## [4.2.0] - 2022-12-22 + +- [TypeScript] Better type for toJS [#1917](https://github.com/immutable-js/immutable-js/pull/1917) by [jdeniau](https://github.com/jdeniau) + - [TS Minor Break] tests are ran with TS > 4.5 only. It was tested with TS > 2.1 previously, but we want to level up TS types with recent features. TS 4.5 has been released more than one year before this release. If it does break your implementation (it might not), you should probably consider upgrading to the latest TS version. +- Added a `partition` method to all containers [#1916](https://github.com/immutable-js/immutable-js/pull/1916) by [johnw42](https://github.com/johnw42) + +## [4.1.0] - 2022-05-23 + +- Accept Symbol as Map key. [#1859](https://github.com/immutable-js/immutable-js/pull/1859) by [jdeniau](https://github.com/jdeniau) +- Optimize contructors without arguments [#1887](https://github.com/immutable-js/immutable-js/pull/1887) by [marianoguerra](https://github.com/marianoguerra) +- Fix Flow removeIn types [#1902](https://github.com/immutable-js/immutable-js/pull/1902) by [nifgraup](https://github.com/nifgraup) +- Fix bug in Record.equals when comparing against Map [#1903](https://github.com/immutable-js/immutable-js/pull/1903) by [jmtoung](https://github.com/jmtoung) + +## [4.0.0] - 2021-09-30 + +This release brings new functionality and many fixes. + +1. [Key changes](#key-changes) +1. [Note for users of v4.0.0-rc.12](#note-for-users-of-v400-rc12) +1. [Breaking changes](#breaking) +1. [New](#new) +1. [Fixed](#fixed) + +### Key changes + +- New members have joined the team +- The project has been relicensed as MIT +- Better TypeScript and Flow type definitions +- A brand-new documentation lives at [immutable-js.com](https://immutable-js.com/) and can show multiple versions +- Behavior of `merge` and `mergeDeep` has changed +- `Iterable` is renamed to [Collection](https://immutable-js.com/docs/latest@main/Collection/) +- [Records](https://immutable-js.com/docs/latest@main/Record/) no longer extend from Collections +- All collection types now implement the [ES6 iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol) +- New methods: + - [toJSON()]() + - [wasAltered()]() + - [Collection.Indexed.zipAll()]() + - [Map.deleteAll()]() + +
   Diff of changed API (click to expand) + +```diff ++ Collection.[Symbol.iterator] ++ Collection.toJSON ++ Collection.update ++ Collection.Indexed.[Symbol.iterator] ++ Collection.Indexed.toJSON ++ Collection.Indexed.update ++ Collection.Indexed.zipAll ++ Collection.Keyed.[Symbol.iterator] ++ Collection.Keyed.toJSON ++ Collection.Keyed.update ++ Collection.Set.[Symbol.iterator] ++ Collection.Set.toJSON ++ Collection.Set.update +- Collection.size +- Collection.Indexed.size +- Collection.Keyed.size +- Collection.Set.size + ++ List.[Symbol.iterator] ++ List.toJSON ++ List.wasAltered ++ List.zipAll +- List.mergeDeep +- List.mergeDeepWith +- List.mergeWith + ++ Map.[Symbol.iterator] ++ Map.deleteAll ++ Map.toJSON ++ Map.wasAltered + ++ OrderedMap.[Symbol.iterator] ++ OrderedMap.deleteAll ++ OrderedMap.toJSON ++ OrderedMap.wasAltered ++ OrderedSet.[Symbol.iterator] ++ OrderedSet.toJSON ++ OrderedSet.update ++ OrderedSet.wasAltered ++ OrderedSet.zip ++ OrderedSet.zipAll ++ OrderedSet.zipWith + ++ Record.[Symbol.iterator] ++ Record.asImmutable ++ Record.asMutable ++ Record.clear ++ Record.delete ++ Record.deleteIn ++ Record.merge ++ Record.mergeDeep ++ Record.mergeDeepIn ++ Record.mergeDeepWith ++ Record.mergeIn ++ Record.mergeWith ++ Record.set ++ Record.setIn ++ Record.toJSON ++ Record.update ++ Record.updateIn ++ Record.wasAltered ++ Record.withMutations ++ Record.Factory.displayName +- Record.butLast +- Record.concat +- Record.count +- Record.countBy +- Record.entries +- Record.entrySeq +- Record.every +- Record.filter +- Record.filterNot +- Record.find +- Record.findEntry +- Record.findKey +- Record.findLast +- Record.findLastEntry +- Record.findLastKey +- Record.first +- Record.flatMap +- Record.flatten +- Record.flip +- Record.forEach +- Record.groupBy +- Record.includes +- Record.isEmpty +- Record.isSubset +- Record.isSuperset +- Record.join +- Record.keyOf +- Record.keySeq +- Record.keys +- Record.last +- Record.lastKeyOf +- Record.map +- Record.mapEntries +- Record.mapKeys +- Record.max +- Record.maxBy +- Record.min +- Record.minBy +- Record.reduce +- Record.reduceRight +- Record.rest +- Record.reverse +- Record.skip +- Record.skipLast +- Record.skipUntil +- Record.skipWhile +- Record.slice +- Record.some +- Record.sort +- Record.sortBy +- Record.take +- Record.takeLast +- Record.takeUntil +- Record.takeWhile +- Record.toArray +- Record.toIndexedSeq +- Record.toKeyedSeq +- Record.toList +- Record.toMap +- Record.toOrderedMap +- Record.toOrderedSet +- Record.toSet +- Record.toSetSeq +- Record.toStack +- Record.valueSeq +- Record.values + ++ Seq.[Symbol.iterator] ++ Seq.toJSON ++ Seq.update ++ Seq.Indexed.[Symbol.iterator] ++ Seq.Indexed.toJSON ++ Seq.Indexed.update ++ Seq.Indexed.zipAll ++ Seq.Keyed.[Symbol.iterator] ++ Seq.Keyed.toJSON ++ Seq.Keyed.update ++ Seq.Set.[Symbol.iterator] ++ Seq.Set.toJSON ++ Seq.Set.update + ++ Set.[Symbol.iterator] ++ Set.toJSON ++ Set.update ++ Set.wasAltered + ++ Stack.[Symbol.iterator] ++ Stack.toJSON ++ Stack.update ++ Stack.wasAltered ++ Stack.zipAll + ++ ValueObject.equals ++ ValueObject.hashCode + +- Iterable.* +- Iterable.Indexed.* +- Iterable.Keyed.* +- Iterable.Set.* +``` + +
+ +### Note for users of v4.0.0-rc.12 + +There were mostly bugfixes and improvements since RC 12. Upgrading should be painless for most users. +However, there is **one breaking change**: The behavior of `merge` and `mergeDeep` has changed. See below for details. + +### BREAKING + +#### [merge()]() + +- No longer use value-equality within `merge()` ([#1391](https://github.com/immutable-js/immutable-js/pull/1391)) + + > This rectifies an inconsistent behavior between `x.merge(y)` and `x.mergeDeep(y)` where merge would + > use `===` on leaf values to determine return-self optimizations, while mergeDeep would use `is()`. + > This improves consistency across the library and avoids a possible performance pitfall. + +- No longer deeply coerce argument to merge() ([#1339](https://github.com/immutable-js/immutable-js/pull/1339)) + > Previously, the argument provided to `merge()` was deeply converted to Immutable collections via `fromJS()`. + > This was the only function in the library which calls `fromJS()` indirectly, + > and it was surprising and made it difficult to understand what the result of `merge()` would be. + > Now, the value provided to `merge()` is only shallowly converted to an Immutable collection, similar to + > related methods in the library. This may change the behavior of your calls to `merge()`. + +#### [mergeDeep()]() + +- Replace incompatible collections when merging nested data ([#1840](https://github.com/immutable-js/immutable-js/pull/1840)) + + > It will no longer merge lists of tuples into maps. For more information see + > [#1840](https://github.com/immutable-js/immutable-js/pull/1840) and the updated `mergeDeep()` documentation. + +- Concat Lists when merging deeply ([#1344](https://github.com/immutable-js/immutable-js/pull/1344)) + > Previously, calling `map.mergeDeep()` with a value containing a `List` would replace the values in the + > original List. This has always been confusing, and does not properly treat `List` as a monoid. + > Now, `List.merge` is simply an alias for `List.concat`, and `map.mergeDeep()` will concatenate deeply-found lists + > instead of replacing them. + +#### [Seq](https://immutable-js.com/docs/latest@main/Seq/) + +- Remove IteratorSequence. Do not attempt to detect iterators in `Seq()`. ([#1589](https://github.com/immutable-js/immutable-js/pull/1589)) + + > Iterables can still be provided to `Seq()`, and _most_ Iterators are also + > Iterables, so this change should not affect the vast majority of uses. + > For more information, see PR #1589 + +- Remove `Seq.of()` (#1311, #1310) + > This method has been removed since it cannot be correctly typed. It's recommended to convert + > `Seq.of(1, 2, 3)` to `Seq([1, 2, 3])`. + +#### [isImmutable()]() + +- `isImmutable()` now returns true for collections currently within a `withMutations()` call. ([#1374](https://github.com/immutable-js/immutable-js/pull/1374)) + + > Previously, `isImmutable()` did double-duty of both determining if a value was a Collection or Record + > from this library as well as if it was outside a `withMutations()` call. + > This latter case caused confusion and was rarely used. + +#### [toArray()]() + +- KeyedCollection.toArray() returns array of tuples. ([#1340](https://github.com/immutable-js/immutable-js/pull/1340)) + + > Previously, calling `toArray()` on a keyed collection (incl `Map` and `OrderedMap`) would + > discard keys and return an Array of values. This has always been confusing, and differs from `Array.from()`. + > Now, calling `toArray()` on a keyed collection will return an Array of `[key, value]` tuples, matching + > the behavior of `Array.from()`. + +#### [concat()]() + +- `list.concat()` now has a slightly more efficient implementation and `map.concat()` is an alias for `map.merge()`. ([#1373](https://github.com/immutable-js/immutable-js/pull/1373)) + + > In rare cases, this may affect use of `map.concat()` which expected slightly different behavior from `map.merge()`. + +#### [Collection](https://immutable-js.com/docs/latest@main/Collection/), formerly `Iterable` + +- The `Iterable` class has been renamed to `Collection`, and `isIterable()` has been renamed to `isCollection()`. + Aliases with the existing names exist to make transitioning code easier. + +#### [Record](https://immutable-js.com/docs/latest@main/Record/) + +- Record is no longer an Immutable Collection type. + - Now `isCollection(myRecord)` returns `false` instead of `true`. + - The sequence API (such as `map`, `filter`, `forEach`) no longer exist on Records. + - `delete()` and `clear()` no longer exist on Records. + +#### Other breaking changes + +- **Potentially Breaking:** Improve hash speed and avoid collision for common values ([#1629](https://github.com/immutable-js/immutable-js/pull/1629)) + + > Causes some hash values to change, which could impact the order of iteration of values in some Maps + > (which are already advertised as unordered, but highlighting just to be safe) + +- Node buffers no longer considered value-equal ([#1437](https://github.com/immutable-js/immutable-js/pull/1437)) + +- Plain Objects and Arrays are no longer considered opaque values ([#1369](https://github.com/immutable-js/immutable-js/pull/1369)) + + > This changes the behavior of a few common methods with respect to plain Objects and Arrays where these were + > previously considered opaque to `merge()` and `setIn()`, they now are treated as collections and can be merged + > into and updated (persistently). This offers an exciting alternative to small Lists and Records. + +- The "predicate" functions, `isCollection`, `isKeyed`, `isIndexed`, `isAssociative` have been moved from `Iterable.` to the top level exports. + +- The `toJSON()` method performs a shallow conversion (previously it was an alias for `toJS()`, which remains a deep conversion). + +- Some minor implementation details have changed, which may require updates to libraries which deeply integrate with Immutable.js's private APIs. + +- The Cursor API is officially deprecated. Use [immutable-cursor](https://github.com/redbadger/immutable-cursor) instead. + +- **Potentially Breaking:** [TypeScript] Remove `Iterable` as tuple from Map constructor types ([#1626](https://github.com/immutable-js/immutable-js/pull/1626)) + > Typescript allowed constructing a Map with a list of List instances, assuming each was a key, value pair. + > While this runtime behavior still works, this type led to more issues than it solved, so it has been removed. + > (Note, this may break previous v4 rcs, but is not a change against v3) + +### New + +- Update TypeScript and Flow definitions: + - The Flowtype and TypeScript type definitions have been completely rewritten with much higher quality and accuracy, + taking advantage of the latest features from both tools. + - Simplified TypeScript definition files to support all UMD use cases ([#1854](https://github.com/immutable-js/immutable-js/pull/1854)) + - Support Typescript 3 ([#1593](https://github.com/immutable-js/immutable-js/pull/1593)) + - Support Typescript strictNullChecks ([#1168](https://github.com/immutable-js/immutable-js/pull/1168)) + - Flow types to be compatible with the latest version 0.160.0 + - Enable flow strict ([#1580](https://github.com/immutable-js/immutable-js/pull/1580)) + + + +- Add "sideEffects: false" to package.json ([#1661](https://github.com/immutable-js/immutable-js/pull/1661)) + +- Use ES standard for iterator method reuse ([#1867](https://github.com/immutable-js/immutable-js/pull/1867)) + +- Generalize `fromJS()` and `Seq()` to support Sets ([#1865](https://github.com/immutable-js/immutable-js/pull/1865)) + +- Top level predicate functions ([#1600](https://github.com/immutable-js/immutable-js/pull/1600)) + + > New functions are exported from the `immutable` module: + > `isSeq()`, `isList()`, `isMap()`, `isOrderedMap()`, `isStack()`, `isSet()`, `isOrderedSet()`, and `isRecord()`. + +- Improve performance of toJS ([#1581](https://github.com/immutable-js/immutable-js/pull/1581)) + + > Cursory test is >10% faster than both v3.8.2 and v4.0.0-rc.7, + > and corrects the regression since v4.0.0-rc.9. + +- Added optional `notSetValue` in `first()` and `last()` ([#1556](https://github.com/immutable-js/immutable-js/pull/1556)) + +- Make `isArrayLike` check more precise to avoid false positives ([#1520](https://github.com/immutable-js/immutable-js/pull/1520)) + +- `map()` for List, Map, and Set returns itself for no-ops ([#1455](https://github.com/immutable-js/immutable-js/pull/1455)) (5726bd1) + +- Hash functions as objects, allowing functions as values in collections ([#1485](https://github.com/immutable-js/immutable-js/pull/1485)) + +- Functional API for `get()`, `set()`, and more which support both Immutable.js collections and plain Objects and Arrays ([#1369](https://github.com/immutable-js/immutable-js/pull/1369)) + +- Relicensed as MIT ([#1320](https://github.com/immutable-js/immutable-js/pull/1320)) + +- Support for Transducers! ([ee9c68f1](https://github.com/immutable-js/immutable-js/commit/ee9c68f1d43da426498ee009ecea37aa2ef77cb8)) + +- Add new method, `zipAll()` ([#1195](https://github.com/immutable-js/immutable-js/pull/1195)) + +- Bundle and distribute an "es module" so Webpack and Rollup can use tree-shaking for smaller builds ([#1204](https://github.com/immutable-js/immutable-js/pull/1204)) + +- Warn instead of throw when `getIn()` has a bad path ([668f2236](https://github.com/immutable-js/immutable-js/commit/668f2236642c97bd4e7d8dfbf62311f497a6ac18)) + +- A new predicate function `isValueObject()` helps to detect objects which implement `equals()` and `hashCode()`, + and type definitions now define the interface `ValueObject` which you can implement in your own code to create objects which + behave as values and can be keys in Maps or entries in Sets. + +- Using `fromJS()` with a "reviver" function now provides access to the key path to each translated value. ([#1118](https://github.com/immutable-js/immutable-js/pull/1118)) + +### Fixed + +- Fix issue with IE11 and missing Symbol.iterator ([#1850](https://github.com/immutable-js/immutable-js/pull/1850)) + +- Fix ordered set with map ([#1663](https://github.com/immutable-js/immutable-js/pull/1663)) + +- Do not modify iter during List.map and Map.map ([#1649](https://github.com/immutable-js/immutable-js/pull/1649)) + +- Fix ordered map delete all ([#1777](https://github.com/immutable-js/immutable-js/pull/1777)) + +- Hash symbols as objects ([#1753](https://github.com/immutable-js/immutable-js/pull/1753)) + +- Fix returning a Record in merge() when Record is empty ([#1785](https://github.com/immutable-js/immutable-js/pull/1785)) + +- Fix for RC~12: Records from different factories aren't equal ([#1734](https://github.com/immutable-js/immutable-js/issues/1734)) + +- "too much recursion" error when creating a Record type from an instance of another Record ([#1690](https://github.com/immutable-js/immutable-js/pull/1690)) + +- Fix glob for npm format script on Windows ([#18](https://github.com/immutable-js-oss/immutable-js/pull/18)) + +- Remove deprecated cursor API ([#13](https://github.com/immutable-js-oss/immutable-js/issues/13)) + +- Add missing es exports ([#1740](https://github.com/immutable-js/immutable-js/pull/1740)) + +- Support nulls in genTypeDefData.js ([#185](https://github.com/immutable-js/immutable-js/pull/185)) + +- Support isPlainObj in IE11 and other esoteric parameters [f3a6d5ce](https://github.com/immutable-js/immutable-js/pull/1833/commits/f3a6d5ce75bb9d60b87074240838f5429e896b60) + +- `Set.map` produces valid underlying map ([#1606](https://github.com/immutable-js/immutable-js/pull/1606)) + +- Support isPlainObj with `constructor` key ([#1627](https://github.com/immutable-js/immutable-js/pull/1627)) + +- `groupBy` no longer returns a mutable Map instance ([#1602](https://github.com/immutable-js/immutable-js/pull/1602)) + +- Fix issue where refs can recursively collide, corrupting `.size` ([#1598](https://github.com/immutable-js/immutable-js/pull/1598)) + +- Throw error in `mergeWith()` method if missing the required `merger` function ([#1543](https://github.com/immutable-js/immutable-js/pull/1543)) + +- Update `isPlainObj()` to workaround Safari bug and allow cross-realm values ([#1557](https://github.com/immutable-js/immutable-js/pull/1557)) + +- Fix missing "& T" to some methods in RecordInstance ([#1464](https://github.com/immutable-js/immutable-js/pull/1464)) + +- Make notSetValue optional for typed Records ([#1461](https://github.com/immutable-js/immutable-js/pull/1461)) (a1029bb) + +- Export type of RecordInstance ([#1434](https://github.com/immutable-js/immutable-js/pull/1434)) + +- Fix Record `size` check in merge() ([#1521](https://github.com/immutable-js/immutable-js/pull/1521)) + +- Fix Map#concat being not defined ([#1402](https://github.com/immutable-js/immutable-js/pull/1402)) + + + + + +- `getIn()` no longer throws when encountering a missing path ([#1361](https://github.com/immutable-js/immutable-js/pull/1361)) + + + +- Do not throw when printing value that cannot be coerced to primitive ([#1334](https://github.com/immutable-js/immutable-js/pull/1334)) + + + + + +- Do not throw from hasIn ([#1319](https://github.com/immutable-js/immutable-js/pull/1319)) + +- Long hash codes no longer cause an infinite loop ([#1175](https://github.com/immutable-js/immutable-js/pull/1175)) + +- `slice()` which should return an empty set could return a full set or vice versa (#1245, #1287) + +- Ensure empty slices do not throw when iterated ([#1220](https://github.com/immutable-js/immutable-js/pull/1220)) + +- Error during equals check on Record with undefined or null ([#1208](https://github.com/immutable-js/immutable-js/pull/1208)) + +- Fix size of count() after filtering or flattening ([#1171](https://github.com/immutable-js/immutable-js/pull/1171)) + +## [3.8.2] - 2017-10-05 + +Released in 2017, still the most commonly used release. + +[unreleased]: https://github.com/immutable-js/immutable-js/compare/v4.0.0-rc.15...HEAD +[4.0.0]: https://github.com/immutable-js/immutable-js/compare/v3.8.2...v4.0.0-rc.15 +[3.8.2]: https://github.com/immutable-js/immutable-js/compare/3.7.6...v3.8.2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 51e89d1a24..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,61 +0,0 @@ -# Contributing to Immutable JS - -We want to make contributing to this project as easy and transparent as -possible. Hopefully this document makes the process for contributing clear and -answers any questions you may have. If not, feel free to open an -[Issue](https://github.com/facebook/immutable-js/issues). - -## Pull Requests - -All active development of Immutable JS happens on GitHub. We actively welcome -your [pull requests](https://help.github.com/articles/creating-a-pull-request). - - 1. Fork the repo and create your branch from `master`. - 2. Install all dependencies. (`npm install`) - 3. Install the grunt CLI tools. (`npm install -g grunt-cli`) - 4. If you've added code, add tests. - 5. If you've changed APIs, update the documentation. - 6. Build generated JS, run tests and ensure your code passes lint. (`grunt`) - 7. Be sure to commit the generated JS in `/dist`. - 8. If you haven't already, complete the Contributor License Agreement ("CLA"). - -## Contributor License Agreement ("CLA") - -In order to accept your pull request, we need you to submit a CLA. You only need -to do this once to work on any of Facebook's open source projects. - -Complete your CLA here: - -## `master` is unsafe - -We will do our best to keep `master` in good shape, with tests passing at all -times. But in order to move fast, we might make API changes that your -application might not be compatible with. We will do our best to communicate -these changes and always [version](http://semver.org/) appropriately so you can -lock into a specific version if need be. If any of this is worrysome to you, -just use [npm](https://www.npmjs.org/package/immutable). - -## Issues - -We use GitHub issues to track public bugs and requests. Please ensure your bug -description is clear and has sufficient instructions to be able to reproduce the -issue. The best way is to provide a reduced test case on jsFiddle or jsBin. - -Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe -disclosure of security bugs. In those cases, please go through the process -outlined on that page and do not file a public issue. - -## Coding Style - -* 2 spaces for indentation (no tabs) -* 80 character line length strongly preferred. -* Prefer `'` over `"` -* ES6 Harmony when possible. -* Use semicolons; -* Trailing commas, -* Avd abbr wrds. - -## License - -By contributing to Immutable JS, you agree that your contributions will be -licensed under its BSD license. diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 1b71ee32d0..0000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,164 +0,0 @@ -/** - * - * grunt lint Lint all source javascript - * grunt clean Clean dist folder - * grunt build Build dist javascript - * grunt test Test dist javascript - * grunt default Lint, Build then Test - * - */ -module.exports = function(grunt) { - grunt.initConfig({ - jshint: { - options: { - asi: true, - curly: false, - eqeqeq: true, - eqnull: true, - esnext: true, - expr: true, - forin: true, - freeze: true, - immed: true, - indent: 2, - iterator: true, - noarg: true, - node: true, - noempty: true, - nonstandard: true, - trailing: true, - undef: true, - unused: 'vars', - }, - all: ['src/**/*.js'] - }, - clean: { - build: ['dist/*'] - }, - smash: { - build: { - files: [{ - src: 'src/Immutable.js', - dest: 'dist/Immutable' - }] - } - }, - copy: { - build: { - files: [{ - expand: true, - cwd: 'type-definitions', - src: ['**/*.d.ts'], - dest: 'dist/' - }] - } - }, - jest: { - options: { - testPathPattern: /.*/ - } - }, - stats: { - build: {} - } - }); - - - var fs = require('fs'); - var smash = require('smash'); - var traceur = require('traceur'); - var uglify = require('uglify-js'); - - grunt.registerMultiTask('smash', function () { - var done = this.async(); - this.files.map(function (file) { - var unTransformed = ''; - smash(file.src).on('data', function (data) { - unTransformed += data; - }).on('end', function () { - var transformed = traceur.compile(unTransformed, { - filename: file.src[0] - }); - if (transformed.error) { - throw transformed.error; - } - var transformed = fs.readFileSync('resources/traceur-runtime.js', {encoding: 'utf8'}) + transformed.js; - var wrapped = fs.readFileSync('resources/universal-module.js', {encoding: 'utf8'}) - .replace('%MODULE%', transformed); - - var copyright = fs.readFileSync('resources/COPYRIGHT'); - - fs.writeFileSync(file.dest + '.js', copyright + wrapped); - - var result = uglify.minify(wrapped, { - fromString: true, - mangle: { - toplevel: true - }, - compress: { - comparisons: true, - pure_getters: true, - unsafe: true - }, - output: { - max_line_len: 2048, - }, - reserved: ['module', 'define', 'Immutable'] - }); - - fs.writeFileSync(file.dest + '.min.js', copyright + result.code); - done(); - }); - }); - }); - - - var exec = require('child_process').exec; - - grunt.registerMultiTask('stats', function () { - var done = this.async(); - exec('cat dist/Immutable.js | wc -c', function (error, out) { - if (error) throw new Error(error); - var rawBytes = parseInt(out); - console.log(' Concatenated: ' + - (rawBytes + ' bytes').cyan); - exec('gzip -c dist/Immutable.js | wc -c', function (error, out) { - if (error) throw new Error(error); - var zippedBytes = parseInt(out); - var pctOfA = Math.floor(10000 * (1 - (zippedBytes / rawBytes))) / 100; - console.log(' Compressed: ' + - (zippedBytes + ' bytes').cyan + ' ' + - (pctOfA + '%').green); - exec('cat dist/Immutable.min.js | wc -c', function (error, out) { - if (error) throw new Error(error); - var minifiedBytes = parseInt(out); - var pctOfA = Math.floor(10000 * (1 - (minifiedBytes / rawBytes))) / 100; - console.log(' Minified: ' + - (minifiedBytes + ' bytes').cyan + ' ' + - (pctOfA + '%').green); - exec('gzip -c dist/Immutable.min.js | wc -c', function (error, out) { - if (error) throw new Error(error); - var zippedMinBytes = parseInt(out); - var pctOfA = Math.floor(10000 * (1 - (zippedMinBytes / rawBytes))) / 100; - console.log(' Min\'d & Cmprs\'d: ' + - (zippedMinBytes + ' bytes').cyan + ' ' + - (pctOfA + '%').green); - done(); - }) - }) - }) - }) - }); - - - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-jest'); - grunt.loadNpmTasks('grunt-release'); - - grunt.registerTask('lint', 'Lint all source javascript', ['jshint']); - grunt.registerTask('build', 'Build distributed javascript', ['clean', 'smash', 'copy']); - grunt.registerTask('test', 'Test built javascript', ['jest']); - grunt.registerTask('default', 'Lint, build and test.', ['lint', 'build', 'stats', 'test']); -} diff --git a/LICENSE b/LICENSE index 88886b237f..1e3c4f39c0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,30 +1,21 @@ -BSD License +MIT License -For Immutable JS software +Copyright (c) 2014-present, Lee Byron and other contributors. -Copyright (c) 2014, Facebook, Inc. All rights reserved. +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: -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +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. diff --git a/PATENTS b/PATENTS deleted file mode 100644 index ec43047b7b..0000000000 --- a/PATENTS +++ /dev/null @@ -1,23 +0,0 @@ -Additional Grant of Patent Rights - -"Software" means the Immutable JS software distributed by Facebook, Inc. - -Facebook hereby grants you a perpetual, worldwide, royalty-free, non-exclusive, -irrevocable (subject to the termination provision below) license under any -rights in any patent claims owned by Facebook, to make, have made, use, sell, -offer to sell, import, and otherwise transfer the Software. For avoidance of -doubt, no license is granted under Facebook’s rights in any patent claims that -are infringed by (i) modifications to the Software made by you or a third party, -or (ii) the Software in combination with any software or other technology -provided by you or a third party. - -The license granted hereunder will terminate, automatically and without notice, -for anyone that makes any claim (including by filing any lawsuit, assertion or -other action) alleging (a) direct, indirect, or contributory infringement or -inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or -affiliates, whether or not such claim is related to the Software, (ii) by any -party if such claim arises in whole or in part from any software, product or -service of Facebook or any of its subsidiaries or affiliates, whether or not -such claim is related to the Software, or (iii) by any party relating to the -Software; or (b) that any right in any patent claim of Facebook is invalid or -unenforceable. diff --git a/README.md b/README.md index 18f558a095..b9216576fa 100644 --- a/README.md +++ b/README.md @@ -1,327 +1,536 @@ -Immutable Data Collections -========================== +# Immutable collections for JavaScript -Immutable data cannot be changed once created, leading to much simpler -application development and enabling techniques from functional programming such -as lazy evaluation. Immutable JS provides a lazy `Sequence`, allowing efficient -chaining of sequence methods like `map` and `filter` without creating -intermediate representations. +[![Build Status](https://github.com/immutable-js/immutable-js/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/immutable-js/immutable-js/actions/workflows/ci.yml?query=branch%3Amain) [Chat on slack](https://immutable-js.slack.com) -`immutable` provides `Sequence`, `Range`, `Repeat`, `Map`, `OrderedMap`, `Set` -and `Vector` by using lazy sequences and [hash maps tries](http://en.wikipedia.org/wiki/Hash_array_mapped_trie). -They achieve efficiency by using structural sharing and minimizing the need to -copy or cache data. +[Read the docs](https://immutable-js.com/docs/) and eat your vegetables. +Docs are automatically generated from [README.md][] and [immutable.d.ts][]. +Please contribute! Also, don't miss the [wiki][] which contains articles on +additional specific topics. Can't find something? Open an [issue][]. -Getting started ---------------- +**Table of contents:** + +- [Introduction](#introduction) +- [Getting started](#getting-started) +- [The case for Immutability](#the-case-for-immutability) +- [JavaScript-first API](#javascript-first-api) +- [Nested Structures](#nested-structures) +- [Equality treats Collections as Values](#equality-treats-collections-as-values) +- [Batching Mutations](#batching-mutations) +- [Lazy Seq](#lazy-seq) +- [Additional Tools and Resources](#additional-tools-and-resources) +- [Contributing](#contributing) + +## Introduction + +[Immutable][] data cannot be changed once created, leading to much simpler +application development, no defensive copying, and enabling advanced memoization +and change detection techniques with simple logic. [Persistent][] data presents +a mutative API which does not update the data in-place, but instead always +yields new updated data. + +Immutable.js provides many Persistent Immutable data structures including: +`List`, `Stack`, `Map`, `OrderedMap`, `Set`, `OrderedSet` and `Record`. + +These data structures are highly efficient on modern JavaScript VMs by using +structural sharing via [hash maps tries][] and [vector tries][] as popularized +by Clojure and Scala, minimizing the need to copy or cache data. + +Immutable.js also provides a lazy `Seq`, allowing efficient +chaining of collection methods like `map` and `filter` without creating +intermediate representations. Create some `Seq` with `Range` and `Repeat`. + +Want to hear more? Watch the presentation about Immutable.js: + +[![Immutable Data and React](website/public/Immutable-Data-and-React-YouTube.png)](https://youtu.be/I7IdS-PbEgI) + +[README.md]: https://github.com/immutable-js/immutable-js/blob/main/README.md +[immutable.d.ts]: https://github.com/immutable-js/immutable-js/blob/main/type-definitions/immutable.d.ts +[wiki]: https://github.com/immutable-js/immutable-js/wiki +[issue]: https://github.com/immutable-js/immutable-js/issues +[Persistent]: https://en.wikipedia.org/wiki/Persistent_data_structure +[Immutable]: https://en.wikipedia.org/wiki/Immutable_object +[hash maps tries]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie +[vector tries]: https://hypirion.com/musings/understanding-persistent-vector-pt-1 + +## Getting started Install `immutable` using npm. ```shell +# using npm npm install immutable + +# using Yarn +yarn add immutable + +# using pnpm +pnpm add immutable + +# using Bun +bun add immutable ``` Then require it into any module. -```javascript -var Immutable = require('immutable'); -var map = Immutable.Map({a:1, b:2, c:3}); + + +```js +const { Map } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3 }); +const map2 = map1.set('b', 50); +map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50 ``` ### Browser -To use `immutable` from a browser, download [dist/Immutable.min.js](./dist/Immutable.min.js). +Immutable.js has no dependencies, which makes it predictable to include in a Browser. + +It's highly recommended to use a module bundler like [webpack](https://webpack.js.org/), +[rollup](https://rollupjs.org/), or +[browserify](https://browserify.org/). The `immutable` npm module works +without any additional consideration. All examples throughout the documentation +will assume use of this kind of tool. -Then, add it as a script tag to your page: +Alternatively, Immutable.js may be directly included as a script tag. Download +or link to a CDN such as [CDNJS](https://cdnjs.com/libraries/immutable) +or [jsDelivr](https://www.jsdelivr.com/package/npm/immutable). + +Use a script tag to directly add `Immutable` to the global scope: ```html - + ``` -Or use an AMD loader (such as [RequireJS](http://requirejs.org/)): +Or use an AMD-style loader (such as [RequireJS](https://requirejs.org/)): -```javascript -require(['./Immutable.min.js'], function (Immutable) { - var map = Immutable.Map({a:1, b:2, c:3}); - map = map.set('b', 20); - map.get('b'); // 20 +```js +require(['./immutable.min.js'], function (Immutable) { + var map1 = Immutable.Map({ a: 1, b: 2, c: 3 }); + var map2 = map1.set('b', 50); + map1.get('b'); // 2 + map2.get('b'); // 50 }); ``` -### TypeScript +### Flow & TypeScript + Use these Immutable collections and sequences as you would use native -collections in your [TypeScript](http://typescriptlang.org) programs while still taking +collections in your [Flowtype](https://flowtype.org/) or [TypeScript](https://typescriptlang.org) programs while still taking advantage of type generics, error detection, and auto-complete in your IDE. -Just add a reference with a relative path to the type declarations at the top -of your file. +Installing `immutable` via npm brings with it type definitions for Flow (v0.55.0 or higher) +and TypeScript (v4.5 or higher), so you shouldn't need to do anything at all! + +#### Using TypeScript with Immutable.js v4+ + +Immutable.js type definitions embrace ES2015. While Immutable.js itself supports +legacy browsers and environments, its type definitions require TypeScript's 2015 +lib. Include either `"target": "es2015"` or `"lib": "es2015"` in your +`tsconfig.json`, or provide `--target es2015` or `--lib es2015` to the +`tsc` command. + + -```javascript -/// -import Immutable = require('immutable'); -var map: Immutable.Map; -map = Immutable.Map({a:1, b:2, c:3}); -map = map.set('b', 20); -map.get('b'); // 20 +```js +const { Map } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3 }); +const map2 = map1.set('b', 50); +map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50 ``` +#### Using TypeScript with Immutable.js v3 and earlier: -The case for Immutability -------------------------- +Previous versions of Immutable.js include a reference file which you can include +via relative path to the type definitions at the top of your file. + +```js +/// +import { Map } from 'immutable'; +var map1: Map; +map1 = Map({ a: 1, b: 2, c: 3 }); +var map2 = map1.set('b', 50); +map1.get('b'); // 2 +map2.get('b'); // 50 +``` + +## The case for Immutability Much of what makes application development difficult is tracking mutation and maintaining state. Developing with immutable data encourages you to think differently about how data flows through your application. -Subscribing to data events throughout your application, by using -`Object.observe`, or any other mechanism, creates a huge overhead of +Subscribing to data events throughout your application creates a huge overhead of book-keeping which can hurt performance, sometimes dramatically, and creates opportunities for areas of your application to get out of sync with each other -due to simple programmer error. Since immutable data never changes, subscribing -to changes throughout the model is a dead-end and new data can only ever be -passed from above. +due to easy to make programmer error. Since immutable data never changes, +subscribing to changes throughout the model is a dead-end and new data can only +ever be passed from above. -This model of data flow aligns well with the architecture of [React](http://facebook.github.io/react/) -and especially well with an application designed using the ideas of [Flux](http://facebook.github.io/react/docs/flux-overview.html). +This model of data flow aligns well with the architecture of [React][] +and especially well with an application designed using the ideas of [Flux][]. When data is passed from above rather than being subscribed to, and you're only interested in doing work when something has changed, you can use equality. -`immutable` always returns itself when a mutation results in an identical -collection, allowing for using `===` equality to determine if something -has changed. - -```javascript -var map1 = Immutable.Map({a:1, b:2, c:3}); -var map2 = map1.set('b', 2); -assert(map1 === map2); + +Immutable collections should be treated as _values_ rather than _objects_. While +objects represent some thing which could change over time, a value represents +the state of that thing at a particular instance of time. This principle is most +important to understanding the appropriate use of immutable data. In order to +treat Immutable.js collections as values, it's important to use the +`Immutable.is()` function or `.equals()` method to determine _value equality_ +instead of the `===` operator which determines object _reference identity_. + + + +```js +const { Map } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3 }); +const map2 = Map({ a: 1, b: 2, c: 3 }); +map1.equals(map2); // true +map1 === map2; // false +``` + +Note: As a performance optimization Immutable.js attempts to return the existing +collection when an operation would result in an identical collection, allowing +for using `===` reference equality to determine if something definitely has not +changed. This can be extremely useful when used within a memoization function +which would prefer to re-run the function if a deeper equality check could +potentially be more costly. The `===` equality check is also used internally by +`Immutable.is` and `.equals()` as a performance optimization. + + + +```js +const { Map } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3 }); +const map2 = map1.set('b', 2); // Set to same value +map1 === map2; // true ``` -If an object is immutable, it can be "cloned" simply by making another reference +If an object is immutable, it can be "copied" simply by making another reference to it instead of copying the entire object. Because a reference is much smaller than the object itself, this results in memory savings and a potential boost in execution speed for programs which rely on copies (such as an undo-stack). -```javascript -var map1 = Immutable.Map({a:1, b:2, c:3}); -var clone = map1; + + +```js +const { Map } = require('immutable'); +const map = Map({ a: 1, b: 2, c: 3 }); +const mapCopy = map; // Look, "copies" are free! ``` +[React]: https://reactjs.org/ +[Flux]: https://facebook.github.io/flux/docs/in-depth-overview/ + -JavaScript-first API --------------------- +## JavaScript-first API -While `immutable` is inspired by Clojure, Haskell and other functional +While Immutable.js is inspired by Clojure, Scala, Haskell and other functional programming environments, it's designed to bring these powerful concepts to JavaScript, and therefore has an Object-Oriented API that closely mirrors that -of [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array), -[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and -[Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set). +of [ES2015][] [Array][], [Map][], and [Set][]. + +[es2015]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla +[array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array +[map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map +[set]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set The difference for the immutable collections is that methods which would mutate -the collection, like `push`, `set`, `unshift` or `splice` instead return a new -immutable collection. Methods which return new arrays like `slice` or `concat` +the collection, like `push`, `set`, `unshift` or `splice`, instead return a new +immutable collection. Methods which return new arrays, like `slice` or `concat`, instead return new immutable collections. -```javascript -var vect1 = Immutable.Vector(1, 2); -var vect2 = vect1.push(3, 4, 5); -var vect3 = vect2.unshift(0); -var vect4 = vect1.concat(vect2, vect3); -assert(vect1.length === 2); -assert(vect2.length === 5); -assert(vect3.length === 6); -assert(vect4.length === 13); -assert(vect4.get(0) === 1); + + +```js +const { List } = require('immutable'); +const list1 = List([1, 2]); +const list2 = list1.push(3, 4, 5); +const list3 = list2.unshift(0); +const list4 = list1.concat(list2, list3); +assert.equal(list1.size, 2); +assert.equal(list2.size, 5); +assert.equal(list3.size, 6); +assert.equal(list4.size, 13); +assert.equal(list4.get(0), 1); ``` -Almost all of the methods on `Array` will be found in similar form on -`Immutable.Vector`, those of `Map` found on `Immutable.Map`, and those of `Set` -found on `Immutable.Set`, including sequence operations like `forEach` and `map`. +Almost all of the methods on [Array][] will be found in similar form on +`Immutable.List`, those of [Map][] found on `Immutable.Map`, and those of [Set][] +found on `Immutable.Set`, including collection operations like `forEach()` +and `map()`. + + -```javascript -var alpha = Immutable.Map({a:1, b:2, c:3, d:4}); +```js +const { Map } = require('immutable'); +const alpha = Map({ a: 1, b: 2, c: 3, d: 4 }); alpha.map((v, k) => k.toUpperCase()).join(); // 'A,B,C,D' ``` -### Accepts raw JavaScript objects. +### Convert from raw JavaScript objects and arrays. -Designed to inter-operate with your existing JavaScript, `immutable` +Designed to inter-operate with your existing JavaScript, Immutable.js accepts plain JavaScript Arrays and Objects anywhere a method expects a -`Sequence` with no performance penalty. +`Collection`. -```javascript -var map1 = Immutable.Map({a:1, b:2, c:3, d:4}); -var map2 = Immutable.Map({c:10, a:20, t:30}); -var obj = {d:100, o:200, g:300}; -var map3 = map1.merge(map2, obj); + + +```js +const { Map, List } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3, d: 4 }); +const map2 = Map({ c: 10, a: 20, t: 30 }); +const obj = { d: 100, o: 200, g: 300 }; +const map3 = map1.merge(map2, obj); // Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 } +const list1 = List([1, 2, 3]); +const list2 = List([4, 5, 6]); +const array = [7, 8, 9]; +const list3 = list1.concat(list2, array); +// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ``` -This is possible because `immutable` can treat any JavaScript Array or Object -as a Sequence. You can take advantage of this in order to get sophisticated -sequence methods on JavaScript Objects, which otherwise have a very sparse -native API. Because Sequences evaluate lazily and do not cache intermediate -results, these operations are extremely efficient. +This is possible because Immutable.js can treat any JavaScript Array or Object +as a Collection. You can take advantage of this in order to get sophisticated +collection methods on JavaScript Objects, which otherwise have a very sparse +native API. Because Seq evaluates lazily and does not cache intermediate +results, these operations can be extremely efficient. + + -```javascript -var myObject = {a:1,b:2,c:3}; -Sequence(myObject).map(x => x * x).toObject(); +```js +const { Seq } = require('immutable'); +const myObject = { a: 1, b: 2, c: 3 }; +Seq(myObject) + .map(x => x * x) + .toObject(); // { a: 1, b: 4, c: 9 } ``` +Keep in mind, when using JS objects to construct Immutable Maps, that +JavaScript Object properties are always strings, even if written in a quote-less +shorthand, while Immutable Maps accept keys of any type. + + + +```js +const { fromJS } = require('immutable'); + +const obj = { 1: 'one' }; +console.log(Object.keys(obj)); // [ "1" ] +console.log(obj['1'], obj[1]); // "one", "one" + +const map = fromJS(obj); +console.log(map.get('1'), map.get(1)); // "one", undefined +``` + +Property access for JavaScript Objects first converts the key to a string, but +since Immutable Map keys can be of any type the argument to `get()` is +not altered. + ### Converts back to raw JavaScript objects. -All `immutable` Sequences can be converted to plain JavaScript Arrays and +All Immutable.js Collections can be converted to plain JavaScript Arrays and Objects shallowly with `toArray()` and `toObject()` or deeply with `toJS()`. -All sequences also implement `toJSON()` allowing them to be passed to -`JSON.stringify` directly. - -```javascript -var deep = Immutable.Map({a:1, b:2, c:Immutable.Vector(3,4,5)}); -deep.toObject() // { a: 1, b: 2, c: Vector [ 3, 4, 5 ] } -deep.toArray() // [ 1, 2, Vector [ 3, 4, 5 ] ] -deep.toJS() // { a: 1, b: 2, c: [ 3, 4, 5 ] } -JSON.stringify(deep) // '{"a":1,"b":2,"c":[3,4,5]}' +All Immutable Collections also implement `toJSON()` allowing them to be passed +to `JSON.stringify` directly. They also respect the custom `toJSON()` methods of +nested objects. + + + +```js +const { Map, List } = require('immutable'); +const deep = Map({ a: 1, b: 2, c: List([3, 4, 5]) }); +console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] } +console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ] +console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] } +JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}' ``` +### Embraces ES2015 -Nested Structures ------------------ +Immutable.js supports all JavaScript environments, including legacy +browsers (even IE11). However it also takes advantage of features added to +JavaScript in [ES2015][], the latest standard version of JavaScript, including +[Iterators][], [Arrow Functions][], [Classes][], and [Modules][]. It's inspired +by the native [Map][] and [Set][] collections added to ES2015. -The collections in `immutable` are intended to be nested, allowing for deep -trees of data, similar to JSON. +All examples in the Documentation are presented in ES2015. To run in all +browsers, they need to be translated to ES5. -```javascript -var nested = Immutable.fromJS({a:{b:{c:[3,4,5]}}}); -// Map { a: Map { b: Map { c: Vector [ 3, 4, 5 ] } } } +```js +// ES2015 +const mapped = foo.map(x => x * x); +// ES5 +var mapped = foo.map(function (x) { + return x * x; +}); ``` -A few power-tools allow for reading and operating on nested data. The -most useful are `mergeDeep`, `getIn` and `updateIn`, found on `Vector`, `Map` -and `OrderedMap`. +All Immutable.js collections are [Iterable][iterators], which allows them to be +used anywhere an Iterable is expected, such as when spreading into an Array. + + -```javascript -var nested2 = nested.mergeDeep({a:{b:{d:6}}}); -// Map { a: Map { b: Map { c: Vector [ 3, 4, 5 ], d: 6 } } } +```js +const { List } = require('immutable'); +const aList = List([1, 2, 3]); +const anArray = [0, ...aList, 4, 5]; // [ 0, 1, 2, 3, 4, 5 ] ``` -```javascript -nested2.getIn(['a', 'b', 'd']); // 6 +Note: A Collection is always iterated in the same order, however that order may +not always be well defined, as is the case for the `Map` and `Set`. -var nested3 = nested2.updateIn(['a', 'b', 'd'], value => value + 1); -// Map { a: Map { b: Map { c: Vector [ 3, 4, 5 ], d: 7 } } } +[Iterators]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol +[Arrow Functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions +[Classes]: https://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes +[Modules]: https://www.2ality.com/2014/09/es6-modules-final.html -var nested4 = nested3.updateIn(['a', 'b', 'c'], vect => vect.push(6)); -// Map { a: Map { b: Map { c: Vector [ 3, 4, 5, 6 ], d: 7 } } } -``` +## Nested Structures -Lazy Sequences --------------- +The collections in Immutable.js are intended to be nested, allowing for deep +trees of data, similar to JSON. -The `Sequence` is a set of (key, value) entries which can be iterated, and -is the base class for all collections in `immutable`, allowing them to make -use of all the Sequence methods (such as `map` and `filter`). + -**Sequences are immutable** — Once a sequence is created, it cannot be -changed, appended to, rearranged or otherwise modified. Instead, any mutative -method called on a sequence will return a new immutable sequence. - -**Sequences are lazy** — Sequences do as little work as necessary to respond -to any method call. +```js +const { fromJS } = require('immutable'); +const nested = fromJS({ a: { b: { c: [3, 4, 5] } } }); +// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } } +``` -For example, the following does not perform any work, because the resulting sequence is -never used: +A few power-tools allow for reading and operating on nested data. The +most useful are `mergeDeep`, `getIn`, `setIn`, and `updateIn`, found on `List`, +`Map` and `OrderedMap`. - var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8) - .filter(x => x % 2).map(x => x * x); + -Once the sequence is used, it performs only the work necessary. In this -example, no intermediate arrays are ever created, filter is only called -twice, and map is only called once: +```js +const { fromJS } = require('immutable'); +const nested = fromJS({ a: { b: { c: [3, 4, 5] } } }); - console.log(oddSquares.last()); // 49 +const nested2 = nested.mergeDeep({ a: { b: { d: 6 } } }); +// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } } -Lazy Sequences allow for the efficient chaining of sequence operations, allowing -for the expression of logic that can otherwise be very tedious: +console.log(nested2.getIn(['a', 'b', 'd'])); // 6 - Immutable.Sequence({a:1, b:1, c:1}) - .flip().map(key => key.toUpperCase()).flip().toObject(); - // Map { A: 1, B: 1, C: 1 } +const nested3 = nested2.updateIn(['a', 'b', 'd'], value => value + 1); +console.log(nested3); +// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } } -As well as expressing logic that would otherwise seem memory-limited: +const nested4 = nested3.updateIn(['a', 'b', 'c'], list => list.push(6)); +// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } } +``` - Immutable.Range(1, Infinity) - .skip(1000) - .map(n => -n) - .filter(n => n % 2 === 0) - .take(2) - .reduce((r, n) => r * n, 1); - // 1006008 +## Equality treats Collections as Values -Note: A sequence is always iterated in the same order, however that order may -not always be well defined, as is the case for the `Map`. +Immutable.js collections are treated as pure data _values_. Two immutable +collections are considered _value equal_ (via `.equals()` or `is()`) if they +represent the same collection of values. This differs from JavaScript's typical +_reference equal_ (via `===` or `==`) for Objects and Arrays which only +determines if two variables represent references to the same object instance. +Consider the example below where two identical `Map` instances are not +_reference equal_ but are _value equal_. -Equality treats Collections as Data ------------------------------------ + -`immutable` provides equality which treats immutable data structures as -pure data, performing a deep equality check if necessary. +```js +// First consider: +const obj1 = { a: 1, b: 2, c: 3 }; +const obj2 = { a: 1, b: 2, c: 3 }; +obj1 !== obj2; // two different instances are always not equal with === -```javascript -var map1 = Immutable.Map({a:1, b:1, c:1}); -var map2 = Immutable.Map({a:1, b:1, c:1}); -assert(map1 !== map2); -assert(Immutable.is(map1, map2) === true); +const { Map, is } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3 }); +const map2 = Map({ a: 1, b: 2, c: 3 }); +map1 !== map2; // two different instances are not reference-equal +map1.equals(map2); // but are value-equal if they have the same values +is(map1, map2); // alternatively can use the is() function ``` -`Immutable.is` uses the same measure of equality as [Object.is](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) -including if both are immutable sequences and all keys and values are equal -using the same measure of equality. +Value equality allows Immutable.js collections to be used as keys in Maps or +values in Sets, and retrieved with different but equivalent collections: + -Cursors -------- +```js +const { Map, Set } = require('immutable'); +const map1 = Map({ a: 1, b: 2, c: 3 }); +const map2 = Map({ a: 1, b: 2, c: 3 }); +const set = Set().add(map1); +set.has(map2); // true because these are value-equal +``` -Cursors allow you to hold a reference to a path in a nested immutable data -structure, allowing you to pass smaller sections of a larger nested -collection to portions of your application while maintaining a central point -aware of changes to the entire data structure: an `onChange` function which is -called whenever a cursor or sub-cursor calls `update`. +Note: `is()` uses the same measure of equality as [Object.is][] for scalar +strings and numbers, but uses value equality for Immutable collections, +determining if both are immutable and all keys and values are equal +using the same measure of equality. -This is particularly useful when used in conjuction with component-based UI -libraries like [React](http://facebook.github.io/react/) or to simulate -"state" throughout an application while maintaining a single flow of logic. +[object.is]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is +#### Performance tradeoffs -```javascript -var data = Immutable.fromJS({ a: { b: { c: 1 } } }); -var cursor = data.cursor(['a', 'b', 'c'], newData => { - data = newData; -}); +While value equality is useful in many circumstances, it has different +performance characteristics than reference equality. Understanding these +tradeoffs may help you decide which to use in each case, especially when used +to memoize some operation. -// ... elsewhere ... +When comparing two collections, value equality may require considering every +item in each collection, on an `O(N)` time complexity. For large collections of +values, this could become a costly operation. Though if the two are not equal +and hardly similar, the inequality is determined very quickly. In contrast, when +comparing two collections with reference equality, only the initial references +to memory need to be compared which is not based on the size of the collections, +which has an `O(1)` time complexity. Checking reference equality is always very +fast, however just because two collections are not reference-equal does not rule +out the possibility that they may be value-equal. -cursor.deref(); // 1 -cursor = cursor.update(x => x + 1); -cursor.deref(); // 2 +#### Return self on no-op optimization -// ... back to data ... +When possible, Immutable.js avoids creating new objects for updates where no +change in _value_ occurred, to allow for efficient _reference equality_ checking +to quickly determine if no change occurred. -data.getIn(['a', 'b', 'c']); // 2 + + +```js +const { Map } = require('immutable'); +const originalMap = Map({ a: 1, b: 2, c: 3 }); +const updatedMap = originalMap.set('b', 2); +updatedMap === originalMap; // No-op .set() returned the original reference. ``` +However updates which do result in a change will return a new reference. Each +of these operations occur independently, so two similar updates will not return +the same reference: + + + +```js +const { Map } = require('immutable'); +const originalMap = Map({ a: 1, b: 2, c: 3 }); +const updatedMap = originalMap.set('b', 1000); +// New instance, leaving the original immutable. +updatedMap !== originalMap; +const anotherUpdatedMap = originalMap.set('b', 1000); +// Despite both the results of the same operation, each created a new reference. +anotherUpdatedMap !== updatedMap; +// However the two are value equal. +anotherUpdatedMap.equals(updatedMap); +``` -Batching Mutations ------------------- +## Batching Mutations > If a tree falls in the woods, does it make a sound? > @@ -330,49 +539,223 @@ Batching Mutations > > — Rich Hickey, Clojure -Applying a mutation to create a new immutable object will result in a performance penalty. -If you need to apply a series of mutations, `immutable` gives you the ability to create a -temporary mutable copy of a collection and apply a batch of mutations in a highly -performant manner by using `withMutations`. In fact, this is exactly how `immutable` -applies complex mutations itself. +Applying a mutation to create a new immutable object results in some overhead, +which can add up to a minor performance penalty. If you need to apply a series +of mutations locally before returning, Immutable.js gives you the ability to +create a temporary mutable (transient) copy of a collection and apply a batch of +mutations in a performant manner by using `withMutations`. In fact, this is +exactly how Immutable.js applies complex mutations itself. -As an example, this results in the creation of 2, not 4, new immutable Vectors. +As an example, building `list2` results in the creation of 1, not 3, new +immutable Lists. -```javascript -var vect1 = Immutable.Vector(1,2,3); -var vect2 = vect1.withMutations(function (vect) { - vect.push(4).push(5).push(6); + + +```js +const { List } = require('immutable'); +const list1 = List([1, 2, 3]); +const list2 = list1.withMutations(function (list) { + list.push(4).push(5).push(6); }); -assert(vect1.length === 3); -assert(vect2.length === 6); +assert.equal(list1.size, 3); +assert.equal(list2.size, 6); ``` -Note: `immutable` also provides `asMutable` and `asImmutable`, but only -encourages their use when `withMutations` will not suffice. +Note: Immutable.js also provides `asMutable` and `asImmutable`, but only +encourages their use when `withMutations` will not suffice. Use caution to not +return a mutable copy, which could result in undesired behavior. +_Important!_: Only a select few methods can be used in `withMutations` including +`set`, `push` and `pop`. These methods can be applied directly against a +persistent data-structure where other methods like `map`, `filter`, `sort`, +and `splice` will always return new immutable data-structures and never mutate +a mutable collection. -API Documentation ------------------ +## Lazy Seq -All documentation is contained within the type definition file, [Immutable.d.ts](./type-definitions/Immutable.d.ts). +`Seq` describes a lazy operation, allowing them to efficiently chain +use of all the higher-order collection methods (such as `map` and `filter`) +by not creating intermediate collections. +**Seq is immutable** — Once a Seq is created, it cannot be +changed, appended to, rearranged or otherwise modified. Instead, any mutative +method called on a `Seq` will return a new `Seq`. -Contribution ------------- +**Seq is lazy** — `Seq` does as little work as necessary to respond to any +method call. Values are often created during iteration, including implicit +iteration when reducing or converting to a concrete data structure such as +a `List` or JavaScript `Array`. -Use [Github issues](https://github.com/facebook/immutable-js/issues) for requests. +For example, the following performs no work, because the resulting +`Seq`'s values are never iterated: -We actively welcome pull requests, learn how to [contribute](./CONTRIBUTING.md). +```js +const { Seq } = require('immutable'); +const oddSquares = Seq([1, 2, 3, 4, 5, 6, 7, 8]) + .filter(x => x % 2 !== 0) + .map(x => x * x); +``` +Once the `Seq` is used, it performs only the work necessary. In this +example, no intermediate arrays are ever created, filter is called three +times, and map is only called once: -Thanks ------- +```js +oddSquares.get(1); // 9 +``` -[Hugh Jackson](https://github.com/hughfdjackson/), for providing the npm package -name. If you're looking for his unsupported package, see [v1.4.1](https://www.npmjs.org/package/immutable/1.4.1). +Any collection can be converted to a lazy Seq with `Seq()`. + + + +```js +const { Map, Seq } = require('immutable'); +const map = Map({ a: 1, b: 2, c: 3 }); +const lazySeq = Seq(map); +``` + +`Seq` allows for the efficient chaining of operations, allowing for the +expression of logic that can otherwise be very tedious: + +```js +lazySeq + .flip() + .map(key => key.toUpperCase()) + .flip(); +// Seq { A: 1, B: 2, C: 3 } +``` + +As well as expressing logic that would otherwise seem memory or time +limited, for example `Range` is a special kind of Lazy sequence. + + + +```js +const { Range } = require('immutable'); +Range(1, Infinity) + .skip(1000) + .map(n => -n) + .filter(n => n % 2 === 0) + .take(2) + .reduce((r, n) => r * n, 1); +// 1006008 +``` + +## Comparison of filter(), groupBy(), and partition() + +The `filter()`, `groupBy()`, and `partition()` methods are similar in that they +all divide a collection into parts based on applying a function to each element. +All three call the predicate or grouping function once for each item in the +input collection. All three return zero or more collections of the same type as +their input. The returned collections are always distinct from the input +(according to `===`), even if the contents are identical. + +Of these methods, `filter()` is the only one that is lazy and the only one which +discards items from the input collection. It is the simplest to use, and the +fact that it returns exactly one collection makes it easy to combine with other +methods to form a pipeline of operations. + +The `partition()` method is similar to an eager version of `filter()`, but it +returns two collections; the first contains the items that would have been +discarded by `filter()`, and the second contains the items that would have been +kept. It always returns an array of exactly two collections, which can make it +easier to use than `groupBy()`. Compared to making two separate calls to +`filter()`, `partition()` makes half as many calls it the predicate passed to +it. + +The `groupBy()` method is a more generalized version of `partition()` that can +group by an arbitrary function rather than just a predicate. It returns a map +with zero or more entries, where the keys are the values returned by the +grouping function, and the values are nonempty collections of the corresponding +arguments. Although `groupBy()` is more powerful than `partition()`, it can be +harder to use because it is not always possible predict in advance how many +entries the returned map will have and what their keys will be. + +| Summary | `filter` | `partition` | `groupBy` | +|:------------------------------|:---------|:------------|:---------------| +| ease of use | easiest | moderate | hardest | +| generality | least | moderate | most | +| laziness | lazy | eager | eager | +| # of returned sub-collections | 1 | 2 | 0 or more | +| sub-collections may be empty | yes | yes | no | +| can discard items | yes | no | no | +| wrapping container | none | array | Map/OrderedMap | + +## Additional Tools and Resources +- [Atom-store](https://github.com/jameshopkins/atom-store/) + - A Clojure-inspired atom implementation in Javascript with configurability + for external persistance. -License -------- +- [Chai Immutable](https://github.com/astorije/chai-immutable) + - If you are using the [Chai Assertion Library](https://chaijs.com/), this + provides a set of assertions to use against Immutable.js collections. -`immutable` is [BSD-licensed](./LICENSE). We also provide an additional [patent grant](./PATENTS). +- [Fantasy-land](https://github.com/fantasyland/fantasy-land) + - Specification for interoperability of common algebraic structures in JavaScript. + +- [Immutagen](https://github.com/pelotom/immutagen) + - A library for simulating immutable generators in JavaScript. + +- [Immutable-cursor](https://github.com/redbadger/immutable-cursor) + - Immutable cursors incorporating the Immutable.js interface over + Clojure-inspired atom. + +- [Immutable-ext](https://github.com/DrBoolean/immutable-ext) + - Fantasyland extensions for immutablejs + +- [Immutable-js-tools](https://github.com/madeinfree/immutable-js-tools) + - Util tools for immutable.js + +- [Immutable-Redux](https://github.com/gajus/redux-immutable) + - redux-immutable is used to create an equivalent function of Redux + combineReducers that works with Immutable.js state. + +- [Immutable-Treeutils](https://github.com/lukasbuenger/immutable-treeutils) + - Functional tree traversal helpers for ImmutableJS data structures. + +- [Irecord](https://github.com/ericelliott/irecord) + - An immutable store that exposes an RxJS observable. Great for React. + +- [Mudash](https://github.com/brianneisler/mudash) + - Lodash wrapper providing Immutable.JS support. + +- [React-Immutable-PropTypes](https://github.com/HurricaneJames/react-immutable-proptypes) + - PropType validators that work with Immutable.js. + +- [Redux-Immutablejs](https://github.com/indexiatech/redux-immutablejs) + - Redux Immutable facilities. + +- [Rxstate](https://github.com/yamalight/rxstate) + - Simple opinionated state management library based on RxJS and Immutable.js. + +- [Transit-Immutable-js](https://github.com/glenjamin/transit-immutable-js) + - Transit serialisation for Immutable.js. + - See also: [Transit-js](https://github.com/cognitect/transit-js) + +Have an additional tool designed to work with Immutable.js? +Submit a PR to add it to this list in alphabetical order. + +## Contributing + +Use [Github issues](https://github.com/immutable-js/immutable-js/issues) for requests. + +We actively welcome pull requests, learn how to [contribute](https://github.com/immutable-js/immutable-js/blob/main/.github/CONTRIBUTING.md). + +Immutable.js is maintained within the [Contributor Covenant's Code of Conduct](https://www.contributor-covenant.org/version/2/0/code_of_conduct/). + +### Changelog + +Changes are tracked as [Github releases](https://github.com/immutable-js/immutable-js/releases). + +### License + +Immutable.js is [MIT-licensed](./LICENSE). + +### Thanks + +[Phil Bagwell](https://www.youtube.com/watch?v=K2NYwP90bNs), for his inspiration +and research in persistent data structures. + +[Hugh Jackson](https://github.com/hughfdjackson/), for providing the npm package +name. If you're looking for his unsupported package, see [this repository](https://github.com/hughfdjackson/immutable). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..a1fdc82e73 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 5.1.x | :white_check_mark: | +| 5.0.x | :x: | +| 4.0.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +You can send an email to julien@deniau.me to report a security vulnerability. +Please be as specific as possible on how to reproduce and understand the issue. This way, we can fix the issue as fast as possible. + +I will try to reply to you in the following days (it might be sometime longer depending on my personal life). diff --git a/__tests__/ArraySeq.ts b/__tests__/ArraySeq.ts new file mode 100644 index 0000000000..1068acb93e --- /dev/null +++ b/__tests__/ArraySeq.ts @@ -0,0 +1,91 @@ +import { describe, expect, it } from '@jest/globals'; +import { Seq } from 'immutable'; + +describe('ArraySequence', () => { + it('every is true when predicate is true for all entries', () => { + expect(Seq([]).every(() => false)).toBe(true); + expect(Seq([1, 2, 3]).every((v) => v > 0)).toBe(true); + expect(Seq([1, 2, 3]).every((v) => v < 3)).toBe(false); + }); + + it('some is true when predicate is true for any entry', () => { + expect(Seq([]).some(() => true)).toBe(false); + expect(Seq([1, 2, 3]).some((v) => v > 0)).toBe(true); + expect(Seq([1, 2, 3]).some((v) => v < 3)).toBe(true); + expect(Seq([1, 2, 3]).some((v) => v > 1)).toBe(true); + expect(Seq([1, 2, 3]).some((v) => v < 0)).toBe(false); + }); + + it('maps', () => { + const i = Seq([1, 2, 3]); + const m = i.map((x) => x + x).toArray(); + expect(m).toEqual([2, 4, 6]); + }); + + it('reduces', () => { + const i = Seq([1, 2, 3]); + const r = i.reduce((acc, x) => acc + x); + expect(r).toEqual(6); + }); + + it('efficiently chains iteration methods', () => { + const i = Seq('abcdefghijklmnopqrstuvwxyz'.split('')); + function studly(letter, index) { + return index % 2 === 0 ? letter : letter.toUpperCase(); + } + const result = i + .reverse() + .take(10) + .reverse() + .take(5) + .map(studly) + .toArray() + .join(''); + expect(result).toBe('qRsTu'); + }); + + it('counts from the end of the sequence on negative index', () => { + const i = Seq([1, 2, 3, 4, 5, 6, 7]); + expect(i.get(-1)).toBe(7); + expect(i.get(-5)).toBe(3); + expect(i.get(-9)).toBe(undefined); + expect(i.get(-999, 1000)).toBe(1000); + }); + + it('handles trailing holes', () => { + const a = [1, 2, 3]; + a.length = 10; + const seq = Seq(a); + expect(seq.size).toBe(10); + expect(seq.toArray().length).toBe(10); + expect(seq.map((x) => x * x).size).toBe(10); + expect(seq.map((x) => x * x).toArray().length).toBe(10); + expect(seq.skip(2).toArray().length).toBe(8); + expect(seq.take(2).toArray().length).toBe(2); + expect(seq.take(5).toArray().length).toBe(5); + expect(seq.filter((x) => x % 2 === 1).toArray().length).toBe(2); + expect(seq.toKeyedSeq().flip().size).toBe(10); + expect(seq.toKeyedSeq().flip().flip().size).toBe(10); + expect(seq.toKeyedSeq().flip().flip().toArray().length).toBe(10); + }); + + it('can be iterated', () => { + const a = [1, 2, 3]; + const seq = Seq(a); + const entries = seq.entries(); + expect(entries.next()).toEqual({ value: [0, 1], done: false }); + expect(entries.next()).toEqual({ value: [1, 2], done: false }); + expect(entries.next()).toEqual({ value: [2, 3], done: false }); + expect(entries.next()).toEqual({ value: undefined, done: true }); + }); + + it('cannot be mutated after calling toArray', () => { + const seq = Seq(['A', 'B', 'C']); + + const firstReverse = Seq(seq.toArray().reverse()); + const secondReverse = Seq(seq.toArray().reverse()); + + expect(firstReverse.get(0)).toEqual('C'); + expect(secondReverse.get(0)).toEqual('C'); + }); +}); diff --git a/__tests__/ArraySequence.ts b/__tests__/ArraySequence.ts deleted file mode 100644 index 949cdc086c..0000000000 --- a/__tests__/ArraySequence.ts +++ /dev/null @@ -1,79 +0,0 @@ -/// -/// -jest.autoMockOff(); - -import Immutable = require('immutable'); - -describe('ArraySequence', () => { - - it('every is true when predicate is true for all entries', () => { - expect(Immutable.Sequence([]).every(() => false)).toBe(true); - expect(Immutable.Sequence([1,2,3]).every(v => v > 0)).toBe(true); - expect(Immutable.Sequence([1,2,3]).every(v => v < 3)).toBe(false); - }); - - it('some is true when predicate is true for any entry', () => { - expect(Immutable.Sequence([]).some(() => true)).toBe(false); - expect(Immutable.Sequence([1,2,3]).some(v => v > 0)).toBe(true); - expect(Immutable.Sequence([1,2,3]).some(v => v < 3)).toBe(true); - expect(Immutable.Sequence([1,2,3]).some(v => v > 1)).toBe(true); - expect(Immutable.Sequence([1,2,3]).some(v => v < 0)).toBe(false); - }); - - it('maps', () => { - var i = Immutable.Sequence([1,2,3]); - var m = i.map(x => x + x).toObject(); - expect(m).toEqual([2,4,6]); - }); - - it('reduces', () => { - var i = Immutable.Sequence([1,2,3]); - var r = i.reduce((r, x) => r + x); - expect(r).toEqual(6); - }); - - it('efficiently chains iteration methods', () => { - var i = Immutable.Sequence('abcdefghijklmnopqrstuvwxyz'.split('')); - function studly(letter, index) { - return index % 2 === 0 ? letter : letter.toUpperCase(); - } - var result = i.reverse().take(10).reverse().take(5).map(studly).toArray().join(''); - expect(result).toBe('qRsTu'); - }); - - it('counts from the end of the sequence on negative index', () => { - var i = Immutable.Sequence(1, 2, 3, 4, 5, 6, 7); - expect(i.get(-1)).toBe(7); - expect(i.get(-5)).toBe(3); - expect(i.get(-9)).toBe(undefined); - expect(i.get(-999, 1000)).toBe(1000); - }); - - it('handles trailing holes', () => { - var a = [1,2,3]; - a.length = 10; - var seq = Immutable.Sequence(a); - expect(seq.length).toBe(10); - expect(seq.toArray().length).toBe(10); - expect(seq.map(x => x*x).length).toBe(10); - expect(seq.map(x => x*x).toArray().length).toBe(10); - expect(seq.skip(2).toArray().length).toBe(8); - expect(seq.take(2).toArray().length).toBe(2); - expect(seq.take(5).toArray().length).toBe(5); - expect(seq.filter(x => x%2==1).toArray().length).toBe(2); - expect(seq.flip().length).toBe(10); - expect(seq.flip().flip().length).toBe(10); - expect(seq.flip().flip().toArray().length).toBe(10); - }); - - it('can be iterated', () => { - var a = [1,2,3]; - var seq = Immutable.Sequence(a); - var entries = seq.entries(); - expect(entries.next()).toEqual({ value: [0, 1], done: false }); - expect(entries.next()).toEqual({ value: [1, 2], done: false }); - expect(entries.next()).toEqual({ value: [2, 3], done: false }); - expect(entries.next()).toEqual({ value: undefined, done: true }); - }); - -}); diff --git a/__tests__/Comparator.ts b/__tests__/Comparator.ts new file mode 100644 index 0000000000..39ab3679fb --- /dev/null +++ b/__tests__/Comparator.ts @@ -0,0 +1,67 @@ +import { describe, expect, it } from '@jest/globals'; +import { List, OrderedSet, Seq, type Comparator, PairSorting } from 'immutable'; + +const sourceNumbers: readonly number[] = [3, 4, 5, 6, 7, 9, 10, 12, 90, 92, 95]; + +const expectedSortedNumbers: readonly number[] = [ + 7, 95, 90, 92, 3, 5, 9, 4, 6, 10, 12, +]; + +const testComparator: Comparator = (left, right) => { + //The number 7 always goes first... + if (left === 7) { + return PairSorting.LeftThenRight; + } else if (right === 7) { + return PairSorting.RightThenLeft; + } + + //...followed by numbers >= 90, then by all the others. + if (left >= 90 && right < 90) { + return PairSorting.LeftThenRight; + } else if (left < 90 && right >= 90) { + return PairSorting.RightThenLeft; + } + + //Within each group, even numbers go first... + if (left % 2 && !(right % 2)) { + return PairSorting.LeftThenRight; + } else if (!(left % 2) && right % 2) { + return PairSorting.RightThenLeft; + } + + //...and, finally, sort the numbers of each subgroup in ascending order. + return left - right; +}; + +describe.each([ + ['List', List], + ['OrderedSet', OrderedSet], + ['Seq.Indexed', Seq.Indexed], +])('Comparator applied to %s', (_collectionName, testCollectionConstructor) => { + const sourceCollection = testCollectionConstructor(sourceNumbers); + + const expectedSortedCollection = testCollectionConstructor( + expectedSortedNumbers + ); + + describe('when sorting', () => { + it('should support the enum as well as numeric return values', () => { + const actualCollection = sourceCollection.sort(testComparator); + expect(actualCollection).toEqual(expectedSortedCollection); + }); + }); + + describe('when retrieving the max value', () => { + it('should support the enum as well as numeric return values', () => { + const actualMax = sourceCollection.max(testComparator); + expect(actualMax).toBe(12); + }); + }); + + describe('when retrieving the min value', () => { + it('should support the enum as well as numeric return values', () => { + const actualMin = sourceCollection.min(testComparator); + expect(actualMin).toBe(7); + }); + }); +}); diff --git a/__tests__/Conversion.ts b/__tests__/Conversion.ts index 20e8dec2c8..5a008e7e55 100644 --- a/__tests__/Conversion.ts +++ b/__tests__/Conversion.ts @@ -1,140 +1,218 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); -import Map = Immutable.Map; -import OrderedMap = Immutable.OrderedMap; -import Vector = Immutable.Vector; - -declare function expect(val: any): ExpectWithIs; - -interface ExpectWithIs extends Expect { - is(expected: any): void; - not: ExpectWithIs; -} +import { describe, expect, it } from '@jest/globals'; +import { fromJS, is, List, Map, OrderedMap, Record } from 'immutable'; +import fc, { type JsonValue } from 'fast-check'; describe('Conversion', () => { - - beforeEach(function () { - this.addMatchers({ - is: function(expected) { - return Immutable.is(this.actual, expected); - } - }); - }); - // Note: order of keys based on Map's hashing order - var js = { + const js = { deepList: [ { - position: "first" + position: 'first', }, { - position: "second" + position: 'second', }, { - position: "third" + position: 'third', }, ], deepMap: { - a: "A", - b: "B" + a: 'A', + b: 'B', }, - point: {x: 10, y: 20}, - string: "Hello", - list: [1, 2, 3] + emptyMap: Object.create(null), + point: { x: 10, y: 20 }, + string: 'Hello', + list: [1, 2, 3], }; - var Point = Immutable.Record({x:0, y:0}, 'Point'); + const Point = Record({ x: 0, y: 0 }, 'Point'); - var immutableData = Map({ - deepList: Vector( + const immutableData = Map({ + deepList: List.of( Map({ - position: "first" + position: 'first', }), Map({ - position: "second" + position: 'second', }), Map({ - position: "third" + position: 'third', }) ), deepMap: Map({ - a: "A", - b: "B" + a: 'A', + b: 'B', }), - point: Map({x: 10, y: 20}), - string: "Hello", - list: Vector(1, 2, 3) + emptyMap: Map(), + point: Map({ x: 10, y: 20 }), + string: 'Hello', + list: List.of(1, 2, 3), }); - var immutableOrderedData = OrderedMap({ - deepList: Vector( + const immutableOrderedData = OrderedMap({ + deepList: List.of( OrderedMap({ - position: "first" + position: 'first', }), OrderedMap({ - position: "second" + position: 'second', }), OrderedMap({ - position: "third" + position: 'third', }) ), deepMap: OrderedMap({ - a: "A", - b: "B" + a: 'A', + b: 'B', }), - point: new Point({x: 10, y: 20}), - string: "Hello", - list: Vector(1, 2, 3) + emptyMap: OrderedMap(), + point: new Point({ x: 10, y: 20 }), + string: 'Hello', + list: List.of(1, 2, 3), }); - var immutableOrderedDataString = 'OrderedMap { ' + - 'deepList: Vector [ '+ - 'OrderedMap { '+ - 'position: "first"'+ - ' }, ' + - 'OrderedMap { '+ - 'position: "second"'+ - ' }, '+ - 'OrderedMap { '+ - 'position: "third"'+ - ' }' + - ' ], '+ - 'deepMap: OrderedMap { '+ - 'a: "A", '+ - 'b: "B"'+ - ' }, '+ - 'point: Point { x: 10, y: 20 }, '+ - 'string: "Hello", '+ - 'list: Vector [ 1, 2, 3 ]'+ - ' }'; + const immutableOrderedDataString = + 'OrderedMap { ' + + '"deepList": List [ ' + + 'OrderedMap { ' + + '"position": "first"' + + ' }, ' + + 'OrderedMap { ' + + '"position": "second"' + + ' }, ' + + 'OrderedMap { ' + + '"position": "third"' + + ' }' + + ' ], ' + + '"deepMap": OrderedMap { ' + + '"a": "A", ' + + '"b": "B"' + + ' }, ' + + '"emptyMap": OrderedMap {}, ' + + '"point": Point { x: 10, y: 20 }, ' + + '"string": "Hello", ' + + '"list": List [ 1, 2, 3 ]' + + ' }'; + + const nonStringKeyMap = OrderedMap().set(1, true).set(false, 'foo'); + const nonStringKeyMapString = 'OrderedMap { 1: true, false: "foo" }'; it('Converts deep JS to deep immutable sequences', () => { - expect(Immutable.fromJS(js)).is(immutableData); + expect(fromJS(js)).toEqual(immutableData); + }); + + it('Throws when provided circular reference', () => { + type OType = { a: { b: { c: OType | null } } }; + + const o: OType = { a: { b: { c: null } } }; + o.a.b.c = o; + expect(() => fromJS(o)).toThrow( + 'Cannot convert circular structure to Immutable' + ); }); it('Converts deep JSON with custom conversion', () => { - var seq = Immutable.fromJS(js, function (key, sequence) { + const seq = fromJS(js, function (key, sequence) { if (key === 'point') { + // @ts-expect-error -- to convert to real typing return new Point(sequence); } - return Array.isArray(this[key]) ? sequence.toVector() : sequence.toOrderedMap(); + return Array.isArray(this[key]) + ? sequence.toList() + : sequence.toOrderedMap(); + }); + expect(seq).toEqual(immutableOrderedData); + expect(seq.toString()).toEqual(immutableOrderedDataString); + }); + + it('Converts deep JSON with custom conversion including keypath if requested', () => { + const paths: Array | undefined> = []; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const seq1 = fromJS(js, function (key, sequence, keypath) { + expect(arguments.length).toBe(3); + paths.push(keypath); + return Array.isArray(this[key]) + ? sequence.toList() + : sequence.toOrderedMap(); }); - expect(seq).is(immutableOrderedData); - expect(seq.toString()).is(immutableOrderedDataString); + expect(paths).toEqual([ + [], + ['deepList'], + ['deepList', 0], + ['deepList', 1], + ['deepList', 2], + ['deepMap'], + ['emptyMap'], + ['point'], + ['list'], + ]); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const seq2 = fromJS(js, function (key, sequence) { + // eslint-disable-next-line prefer-rest-params + expect(arguments[2]).toBe(undefined); + }); + }); + + it('Prints keys as JS values', () => { + expect(nonStringKeyMap.toString()).toEqual(nonStringKeyMapString); + }); + + it('Converts deep sequences to JS', () => { + const js2 = immutableData.toJS(); + expect(is(js2, js)).toBe(false); // raw JS is not immutable. + expect(js2).toEqual(js); // but should be deep equal. }); - it('Converts deep sequences to JSON', () => { - var json = immutableData.toJS(); - expect(json).not.is(js); // raw JS is not immutable. - expect(json).toEqual(js); // but should be deep equal. + it('Converts shallowly to JS', () => { + const js2 = immutableData.toJSON(); + expect(js2).not.toEqual(js); + expect(js2.deepList).toBe(immutableData.get('deepList')); }); it('JSON.stringify() works equivalently on immutable sequences', () => { expect(JSON.stringify(js)).toBe(JSON.stringify(immutableData)); }); + it('JSON.stringify() respects toJSON methods on values', () => { + const Model = Record({}); + Model.prototype.toJSON = function () { + return 'model'; + }; + expect(Map({ a: new Model() }).toJS()).toEqual({ a: {} }); + expect(JSON.stringify(Map({ a: new Model() }))).toEqual('{"a":"model"}'); + }); + + it('is conservative with array-likes, only accepting true Arrays.', () => { + expect(fromJS({ 1: 2, length: 3 })).toEqual( + Map().set('1', 2).set('length', 3) + ); + expect(fromJS('string')).toEqual('string'); + }); + + it('toJS isomorphic value', () => { + fc.assert( + fc.property(fc.jsonValue(), (v: JsonValue) => { + const imm = fromJS(v); + expect( + // @ts-expect-error Property 'toJS' does not exist on type '{}'.ts(2339) + imm && imm.toJS ? imm.toJS() : imm + ).toEqual(v); + }), + { numRuns: 30 } + ); + }); + + it('Explicitly convert values to string using String constructor', () => { + expect(() => fromJS({ foo: Symbol('bar') }) + '').not.toThrow(); + expect(() => Map().set('foo', Symbol('bar')) + '').not.toThrow(); + expect(() => Map().set(Symbol('bar'), 'foo') + '').not.toThrow(); + }); + + it('Converts an immutable value of an entry correctly', () => { + const arr = [{ key: 'a' }]; + const result = fromJS(arr).entrySeq().toJS(); + expect(result).toEqual([[0, { key: 'a' }]]); + }); }); diff --git a/__tests__/Cursor.ts b/__tests__/Cursor.ts deleted file mode 100644 index ee91237e67..0000000000 --- a/__tests__/Cursor.ts +++ /dev/null @@ -1,175 +0,0 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); - -jasmine.getEnv().addEqualityTester((a, b) => - a instanceof Immutable.Sequence && b instanceof Immutable.Sequence ? - Immutable.is(a, b) : - jasmine.undefined -); - -describe('Cursor', () => { - - var json = { a: { b: { c: 1 } } }; - - it('gets from its path', () => { - var data = Immutable.fromJS(json); - var cursor = data.cursor(); - - expect(cursor.deref()).toBe(data); - - var deepCursor = cursor.cursor(['a', 'b']); - expect(deepCursor.deref().toJS()).toEqual(json.a.b); - expect(deepCursor.deref()).toBe(data.getIn(['a', 'b'])); - expect(deepCursor.get('c')).toBe(1); - - var leafCursor = deepCursor.cursor('c'); - expect(leafCursor.deref()).toBe(1); - - var missCursor = leafCursor.cursor('d'); - expect(missCursor.deref()).toBe(undefined); - }); - - it('gets return new cursors', () => { - var data = Immutable.fromJS(json); - var cursor = data.cursor(); - var deepCursor = cursor.getIn(['a', 'b']); - expect(deepCursor.deref()).toBe(data.getIn(['a', 'b'])); - }); - - it('can be treated as a value', () => { - var data = Immutable.fromJS(json); - var cursor = data.cursor(['a', 'b']); - expect(cursor.toJS()).toEqual(json.a.b); - expect(cursor).toEqual(data.getIn(['a', 'b'])); - expect(cursor.length).toBe(1); - expect(cursor.get('c')).toBe(1); - }); - - it('can be value compared to a primitive', () => { - var data = Immutable.Map({ a: 'A' }); - var aCursor = data.cursor('a'); - expect(aCursor.length).toBe(null); - expect(aCursor.deref()).toBe('A'); - expect(Immutable.is(aCursor, 'A')).toBe(true); - }); - - it('updates at its path', () => { - var onChange = jest.genMockFunction(); - - var data = Immutable.fromJS(json); - var aCursor = data.cursor('a', onChange); - - var deepCursor = aCursor.cursor(['b', 'c']); - expect(deepCursor.deref()).toBe(1); - - // cursor edits return new cursors: - var newDeepCursor = deepCursor.update(x => x + 1); - expect(newDeepCursor.deref()).toBe(2); - expect(onChange).lastCalledWith( - Immutable.fromJS({a:{b:{c:2}}}), - data, - ['a', 'b', 'c'] - ); - - var newestDeepCursor = newDeepCursor.update(x => x + 1); - expect(newestDeepCursor.deref()).toBe(3); - expect(onChange).lastCalledWith( - Immutable.fromJS({a:{b:{c:3}}}), - Immutable.fromJS({a:{b:{c:2}}}), - ['a', 'b', 'c'] - ); - - // meanwhile, data is still immutable: - expect(data.toJS()).toEqual(json); - - // as is the original cursor. - expect(deepCursor.deref()).toBe(1); - var otherNewDeepCursor = deepCursor.update(x => x + 10); - expect(otherNewDeepCursor.deref()).toBe(11); - expect(onChange).lastCalledWith( - Immutable.fromJS({a:{b:{c:11}}}), - data, - ['a', 'b', 'c'] - ); - - // and update has been called exactly thrice. - expect(onChange.mock.calls.length).toBe(3); - }); - - it('has map API for update shorthand', () => { - var onChange = jest.genMockFunction(); - - var data = Immutable.fromJS(json); - var aCursor = data.cursor('a', onChange); - var bCursor = aCursor.cursor('b'); - var cCursor = bCursor.cursor('c'); - - expect(bCursor.set('c', 10).deref()).toEqual( - Immutable.fromJS({ c: 10 }) - ); - expect(onChange).lastCalledWith( - Immutable.fromJS({ a: { b: { c: 10 } } }), - data, - ['a', 'b', 'c'] - ); - }); - - it('creates maps as necessary', () => { - var data = Immutable.Map(); - var cursor = data.cursor(['a', 'b', 'c']); - expect(cursor.deref()).toBe(undefined); - cursor = cursor.set('d', 3); - expect(cursor.deref()).toEqual(Immutable.Map({d: 3})); - }); - - it('has the sequence API', () => { - var data = Immutable.Map({a: 1, b: 2, c: 3}); - var cursor = data.cursor(); - expect(cursor.map(x => x * x)).toEqual(Immutable.Map({a: 1, b: 4, c: 9})); - }); - - it('returns wrapped values for sequence API', () => { - var data = Immutable.fromJS({a: {v: 1}, b: {v: 2}, c: {v: 3}}); - var onChange = jest.genMockFunction(); - var cursor = data.cursor(onChange); - var found = cursor.find(map => map.get('v') === 2); - expect(typeof found.deref).toBe('function'); // is a cursor! - found = found.set('v', 20); - expect(onChange).lastCalledWith( - Immutable.fromJS({a: {v: 1}, b: {v: 20}, c: {v: 3}}), - data, - ['b', 'v'] - ); - }); - - it('can have mutations apply with a single callback', () => { - var onChange = jest.genMockFunction(); - var data = Immutable.fromJS({'a': 1}); - - var c1 = data.cursor(onChange); - var c2 = c1.withMutations(m => m.set('b', 2).set('c', 3).set('d', 4)); - - expect(c1.deref().toObject()).toEqual({'a': 1}); - expect(c2.deref().toObject()).toEqual({'a': 1, 'b': 2, 'c': 3, 'd': 4}); - expect(onChange.mock.calls.length).toBe(1); - }); - - it('can use withMutations on an unfulfilled cursor', () => { - var onChange = jest.genMockFunction(); - var data = Immutable.fromJS({}); - - var c1 = data.cursor(['a', 'b', 'c'], onChange); - var c2 = c1.withMutations(m => m.set('x', 1).set('y', 2).set('z', 3)); - - expect(c1.deref()).toEqual(undefined); - expect(c2.deref()).toEqual(Immutable.fromJS( - { x: 1, y: 2, z: 3 } - )); - expect(onChange.mock.calls.length).toBe(1); - }); - -}); diff --git a/__tests__/Equality.ts b/__tests__/Equality.ts index 118304613d..ae95ef4a12 100644 --- a/__tests__/Equality.ts +++ b/__tests__/Equality.ts @@ -1,22 +1,20 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); +import { describe, expect, it } from '@jest/globals'; +import { is, List, Map, Seq, Set } from 'immutable'; +import fc from 'fast-check'; describe('Equality', () => { - function expectIs(left, right) { - var comparison = Immutable.is(left, right); - var commutative = Immutable.is(right, left); - return comparison && commutative && comparison === commutative; + const comparison = is(left, right); + expect(comparison).toBe(true); + const commutative = is(right, left); + expect(commutative).toBe(true); } function expectIsNot(left, right) { - var comparison = Immutable.is(left, right); - var commutative = Immutable.is(right, left); - return !comparison && !commutative && comparison === commutative; + const comparison = is(left, right); + expect(comparison).toBe(false); + const commutative = is(right, left); + expect(commutative).toBe(false); } it('uses Object.is semantics', () => { @@ -33,53 +31,130 @@ describe('Equality', () => { expectIs(NaN, NaN); expectIs(0, 0); expectIs(-0, -0); - expectIsNot(0, -0); - expectIs(NaN, 0/0); - - var string = "hello"; - expectIs(string, string); - expectIs(string, "hello"); - expectIsNot("hello", "HELLO"); - expectIsNot("hello", "goodbye"); - - var array = [1,2,3]; + // Note: Unlike Object.is, is assumes 0 and -0 are the same value, + // matching the behavior of ES6 Map key equality. + expectIs(0, -0); + expectIs(NaN, 0 / 0); + + const str = 'hello'; + expectIs(str, str); + expectIs(str, 'hello'); + expectIsNot('hello', 'HELLO'); + expectIsNot('hello', 'goodbye'); + + const array = [1, 2, 3]; expectIs(array, array); - expectIsNot(array, [1,2,3]); + expectIsNot(array, [1, 2, 3]); - var object = {key:'value'}; + const object = { key: 'value' }; expectIs(object, object); - expectIsNot(object, {key:'value'}); + expectIsNot(object, { key: 'value' }); + }); + + it('dereferences things', () => { + const ptrA = { foo: 1 }; + const ptrB = { foo: 2 }; + expectIsNot(ptrA, ptrB); + ptrA.valueOf = ptrB.valueOf = function () { + return 5; + }; + expectIs(ptrA, ptrB); + const object = { key: 'value' }; + ptrA.valueOf = ptrB.valueOf = function () { + return object; + }; + expectIs(ptrA, ptrB); + ptrA.valueOf = ptrB.valueOf = function () { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return null as any; + }; + expectIs(ptrA, ptrB); + ptrA.valueOf = ptrB.valueOf = function () { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return undefined as any; + }; + expectIs(ptrA, ptrB); + ptrA.valueOf = function () { + return 4; + }; + ptrB.valueOf = function () { + return 5; + }; + expectIsNot(ptrA, ptrB); }); it('compares sequences', () => { - var arraySeq = Immutable.Sequence(1,2,3); - var arraySeq2 = Immutable.Sequence([1,2,3]); + const arraySeq = Seq([1, 2, 3]); + const arraySeq2 = Seq([1, 2, 3]); expectIs(arraySeq, arraySeq); - expectIs(arraySeq, Immutable.Sequence(1,2,3)); + expectIs(arraySeq, Seq([1, 2, 3])); expectIs(arraySeq2, arraySeq2); - expectIs(arraySeq2, Immutable.Sequence([1,2,3])); - expectIsNot(arraySeq, [1,2,3]); - expectIsNot(arraySeq2, [1,2,3]); + expectIs(arraySeq2, Seq([1, 2, 3])); + expectIsNot(arraySeq, [1, 2, 3]); + expectIsNot(arraySeq2, [1, 2, 3]); expectIs(arraySeq, arraySeq2); - expectIs(arraySeq, arraySeq.map(x => x)); - expectIs(arraySeq2, arraySeq2.map(x => x)); + expectIs( + arraySeq, + arraySeq.map((x) => x) + ); + expectIs( + arraySeq2, + arraySeq2.map((x) => x) + ); }); - it('compares vectors', () => { - var vector = Immutable.Vector(1,2,3); - expectIs(vector, vector); - expectIsNot(vector, [1,2,3]); + it('compares lists', () => { + const list = List([1, 2, 3]); + expectIs(list, list); + expectIsNot(list, [1, 2, 3]); - expectIs(vector, Immutable.Sequence(1,2,3)); - expectIs(vector, Immutable.Vector(1,2,3)); + expectIs(list, Seq([1, 2, 3])); + expectIs(list, List([1, 2, 3])); - var vectorLonger = vector.push(4); - expectIsNot(vector, vectorLonger); - var vectorShorter = vectorLonger.pop(); - expect(vector === vectorShorter).toBe(false); - expectIs(vector, vectorShorter); + const listLonger = list.push(4); + expectIsNot(list, listLonger); + const listShorter = listLonger.pop(); + expect(list === listShorter).toBe(false); + expectIs(list, listShorter); }); - // TODO: more tests + const genSimpleVal = fc.oneof(fc.constant('A'), fc.constant(1)); + + const genVal = fc.oneof( + fc.array(genSimpleVal, { minLength: 0, maxLength: 4 }).map(List), + fc.array(genSimpleVal, { minLength: 0, maxLength: 4 }).map(Set), + fc + .array(fc.array(genSimpleVal, { minLength: 2, maxLength: 2 }), { + minLength: 0, + maxLength: 4, + }) + .map(Map) + ); + + it('has symmetric equality', () => { + fc.assert( + fc.property(genVal, genVal, (a, b) => { + expect(is(a, b)).toBe(is(b, a)); + }), + { numRuns: 1000 } + ); + }); + it('has hash symmetry', () => { + fc.assert( + fc.property(genVal, genVal, (a, b) => { + if (is(a, b)) { + // eslint-disable-next-line jest/no-conditional-expect + expect(a.hashCode()).toBe(b.hashCode()); + } + }), + { numRuns: 1000 } + ); + }); + + describe('hash', () => { + it('differentiates decimals', () => { + expect(Seq([1.5]).hashCode()).not.toBe(Seq([1.6]).hashCode()); + }); + }); }); diff --git a/__tests__/IndexedSeq.ts b/__tests__/IndexedSeq.ts new file mode 100644 index 0000000000..9d33c234e0 --- /dev/null +++ b/__tests__/IndexedSeq.ts @@ -0,0 +1,49 @@ +import { describe, expect, it } from '@jest/globals'; +import { Seq } from 'immutable'; + +describe('IndexedSequence', () => { + it('maintains skipped offset', () => { + const seq = Seq(['A', 'B', 'C', 'D', 'E']); + + // This is what we expect for IndexedSequences + const operated = seq.skip(1); + expect(operated.entrySeq().toArray()).toEqual([ + [0, 'B'], + [1, 'C'], + [2, 'D'], + [3, 'E'], + ]); + + expect(operated.first()).toEqual('B'); + }); + + it('reverses correctly', () => { + const seq = Seq(['A', 'B', 'C', 'D', 'E']); + + // This is what we expect for IndexedSequences + const operated = seq.reverse(); + expect(operated.get(0)).toEqual('E'); + expect(operated.get(1)).toEqual('D'); + expect(operated.get(4)).toEqual('A'); + + expect(operated.first()).toEqual('E'); + expect(operated.last()).toEqual('A'); + }); + + it('negative indexes correctly', () => { + const seq = Seq(['A', 'B', 'C', 'D', 'E']); + + expect(seq.first()).toEqual('A'); + expect(seq.last()).toEqual('E'); + expect(seq.get(-0)).toEqual('A'); + expect(seq.get(2)).toEqual('C'); + expect(seq.get(-2)).toEqual('D'); + + const indexes = seq.keySeq(); + expect(indexes.first()).toEqual(0); + expect(indexes.last()).toEqual(4); + expect(indexes.get(-0)).toEqual(0); + expect(indexes.get(2)).toEqual(2); + expect(indexes.get(-2)).toEqual(3); + }); +}); diff --git a/__tests__/IterableSequence.ts b/__tests__/IterableSequence.ts deleted file mode 100644 index 22881f5595..0000000000 --- a/__tests__/IterableSequence.ts +++ /dev/null @@ -1,164 +0,0 @@ -/// -/// -jest.autoMockOff(); - -import Immutable = require('immutable'); - - -describe('IterableSequence', () => { - - it('creates a sequence from an iterable', () => { - var i = new SimpleIterable(); - var s = Immutable.Sequence(i); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - }) - - it('is stable', () => { - var i = new SimpleIterable(); - var s = Immutable.Sequence(i); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - }) - - it('counts iterations', () => { - var i = new SimpleIterable(10); - var s = Immutable.Sequence(i); - expect(s.forEach(x => x)).toEqual(10); - expect(s.take(5).forEach(x => x)).toEqual(5); - expect(s.forEach(x => x < 3)).toEqual(4); - }) - - it('creates a new iterator on every operations', () => { - var mockFn = jest.genMockFunction(); - var i = new SimpleIterable(3, mockFn); - var s = Immutable.Sequence(i); - expect(s.toArray()).toEqual([ 0,1,2 ]); - expect(mockFn.mock.calls).toEqual([[0],[1],[2]]); - // The iterator is recreated for the second time. - expect(s.toArray()).toEqual([ 0,1,2 ]); - expect(mockFn.mock.calls).toEqual([[0],[1],[2],[0],[1],[2]]); - }) - - it('can be iterated', () => { - var mockFn = jest.genMockFunction(); - var i = new SimpleIterable(3, mockFn); - var seq = Immutable.Sequence(i); - var entries = seq.entries(); - expect(entries.next()).toEqual({ value: [0, 0], done: false }); - // The iteration is lazy - expect(mockFn.mock.calls).toEqual([[0]]); - expect(entries.next()).toEqual({ value: [1, 1], done: false }); - expect(entries.next()).toEqual({ value: [2, 2], done: false }); - expect(entries.next()).toEqual({ value: undefined, done: true }); - expect(mockFn.mock.calls).toEqual([[0],[1],[2]]); - // The iterator is recreated for the second time. - entries = seq.entries(); - expect(entries.next()).toEqual({ value: [0, 0], done: false }); - expect(entries.next()).toEqual({ value: [1, 1], done: false }); - expect(entries.next()).toEqual({ value: [2, 2], done: false }); - expect(entries.next()).toEqual({ value: undefined, done: true }); - expect(mockFn.mock.calls).toEqual([[0],[1],[2],[0],[1],[2]]); - }) - - it('can be mapped and filtered', () => { - var mockFn = jest.genMockFunction(); - var i = new SimpleIterable(undefined, mockFn); // infinite - var seq = Immutable.Sequence(i).filter(x => x % 2 === 1).map(x => x * x); - var entries = seq.entries(); - expect(entries.next()).toEqual({ value: [0, 1], done: false }); - expect(entries.next()).toEqual({ value: [1, 9], done: false }); - expect(entries.next()).toEqual({ value: [2, 25], done: false }); - expect(mockFn.mock.calls).toEqual([[0],[1],[2],[3],[4],[5]]); - }) - - describe('IteratorSequence', () => { - - it('creates a sequence from a raw iterable', () => { - var i = new SimpleIterable(10); - var s = Immutable.Sequence(i['@@iterator']()); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - }) - - it('is stable', () => { - var i = new SimpleIterable(10); - var s = Immutable.Sequence(i['@@iterator']()); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - }) - - it('counts iterations', () => { - var i = new SimpleIterable(10); - var s = Immutable.Sequence(i['@@iterator']()); - expect(s.forEach(x => x)).toEqual(10); - expect(s.take(5).forEach(x => x)).toEqual(5); - expect(s.forEach(x => x < 3)).toEqual(4); - }) - - it('memoizes the iterator', () => { - var mockFn = jest.genMockFunction(); - var i = new SimpleIterable(10, mockFn); - var s = Immutable.Sequence(i['@@iterator']()); - expect(s.take(3).toArray()).toEqual([ 0,1,2 ]); - expect(mockFn.mock.calls).toEqual([[0],[1],[2]]); - - // Second call uses memoized values - expect(s.take(3).toArray()).toEqual([ 0,1,2 ]); - expect(mockFn.mock.calls).toEqual([[0],[1],[2]]); - - // Further ahead in the iterator yields more results. - expect(s.take(5).toArray()).toEqual([ 0,1,2,3,4 ]); - expect(mockFn.mock.calls).toEqual([[0],[1],[2],[3],[4]]); - }) - - it('can be iterated', () => { - var mockFn = jest.genMockFunction(); - var i = new SimpleIterable(3, mockFn); - var seq = Immutable.Sequence(i['@@iterator']()); - var entries = seq.entries(); - expect(entries.next()).toEqual({ value: [0, 0], done: false }); - // The iteration is lazy - expect(mockFn.mock.calls).toEqual([[0]]); - expect(entries.next()).toEqual({ value: [1, 1], done: false }); - expect(entries.next()).toEqual({ value: [2, 2], done: false }); - expect(entries.next()).toEqual({ value: undefined, done: true }); - expect(mockFn.mock.calls).toEqual([[0],[1],[2]]); - // The iterator has been memoized for the second time. - entries = seq.entries(); - expect(entries.next()).toEqual({ value: [0, 0], done: false }); - expect(entries.next()).toEqual({ value: [1, 1], done: false }); - expect(entries.next()).toEqual({ value: [2, 2], done: false }); - expect(entries.next()).toEqual({ value: undefined, done: true }); - expect(mockFn.mock.calls).toEqual([[0],[1],[2]]); - }) - - }) - -}) - - -// Helper for this test - -function SimpleIterable(max?: number, watcher?: any) { - this.max = max; - this.watcher = watcher; -} -SimpleIterable.prototype['@@iterator'] = function() { - return new SimpleIterator(this); -} - -function SimpleIterator(iterable) { - this.iterable = iterable; - this.value = 0; -} -SimpleIterator.prototype.next = function() { - if (this.value >= this.iterable.max) { - return { value: undefined, done: true }; - } - this.iterable.watcher && this.iterable.watcher(this.value); - return { value: this.value++, done: false }; -} -SimpleIterator.prototype['@@iterator'] = function() { - return this; -} diff --git a/__tests__/KeyedIndexedSequence.ts b/__tests__/KeyedIndexedSequence.ts deleted file mode 100644 index ed5f70af9f..0000000000 --- a/__tests__/KeyedIndexedSequence.ts +++ /dev/null @@ -1,88 +0,0 @@ -/// -/// -jest.autoMockOff(); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); - -import Immutable = require('immutable'); - -describe('KeyedIndexedSequence', () => { - - check.it('is equivalent', [gen.array(gen.int)], (ints) => { - var seq = Immutable.Sequence(ints); - var keyed = seq.toKeyedSeq(); - expect(seq.equals(keyed)).toBe(true); - }); - - it('maintains keys', () => { - var isEven = x => x % 2 === 0; - var seq = Immutable.Range(0, 100); - - // This is what we expect for IndexedSequences - var operated = seq.filter(isEven).skip(10).take(5); - expect(operated.entrySeq().toArray()).toEqual([ - [0, 20], - [1, 22], - [2, 24], - [3, 26], - [4, 28], - ]); - - // Where Keyed Sequences maintain keys. - var keyed = seq.toKeyedSeq(); - var keyedOperated = keyed.filter(isEven).skip(10).take(5); - expect(keyedOperated.entrySeq().toArray()).toEqual([ - [20, 20], - [22, 22], - [24, 24], - [26, 26], - [28, 28], - ]); - }); - - it('works with reverse', () => { - var seq = Immutable.Range(0, 100); - - // This is what we expect for IndexedSequences - expect(seq.reverse().take(5).entrySeq().toArray()).toEqual([ - [0, 99], - [1, 98], - [2, 97], - [3, 96], - [4, 95], - ]); - - // Where Keyed Sequences maintain keys. - expect(seq.toKeyedSeq().reverse().take(5).entrySeq().toArray()).toEqual([ - [99, 99], - [98, 98], - [97, 97], - [96, 96], - [95, 95], - ]); - }); - - it('works with double reverse', () => { - var seq = Immutable.Range(0, 100); - - // This is what we expect for IndexedSequences - expect(seq.reverse().skip(10).take(5).reverse().entrySeq().toArray()).toEqual([ - [0, 85], - [1, 86], - [2, 87], - [3, 88], - [4, 89], - ]); - - // Where Keyed Sequences maintain keys. - expect(seq.reverse().toKeyedSeq().skip(10).take(5).reverse().entrySeq().toArray()).toEqual([ - [14, 85], - [13, 86], - [12, 87], - [11, 88], - [10, 89], - ]); - }); - -}); diff --git a/__tests__/KeyedSeq.ts b/__tests__/KeyedSeq.ts new file mode 100644 index 0000000000..528c28f523 --- /dev/null +++ b/__tests__/KeyedSeq.ts @@ -0,0 +1,133 @@ +import { describe, expect, it } from '@jest/globals'; +import { Range, Seq } from 'immutable'; +import fc from 'fast-check'; + +describe('KeyedSeq', () => { + it('iterates equivalently', () => { + fc.assert( + fc.property(fc.array(fc.integer()), (ints) => { + const seq = Seq(ints); + const keyed = seq.toKeyedSeq(); + + const seqEntries = seq.entries(); + const keyedEntries = keyed.entries(); + + let seqStep; + let keyedStep; + do { + seqStep = seqEntries.next(); + keyedStep = keyedEntries.next(); + expect(keyedStep).toEqual(seqStep); + } while (!seqStep.done); + }) + ); + }); + + it('maintains keys', () => { + const isEven = (x) => x % 2 === 0; + const seq = Range(0, 100); + + // This is what we expect for IndexedSequences + const operated = seq.filter(isEven).skip(10).take(5); + expect(operated.entrySeq().toArray()).toEqual([ + [0, 20], + [1, 22], + [2, 24], + [3, 26], + [4, 28], + ]); + const [indexed0, indexed1] = seq + .partition(isEven) + .map((part) => part.skip(10).take(5)); + expect(indexed0.entrySeq().toArray()).toEqual([ + [0, 21], + [1, 23], + [2, 25], + [3, 27], + [4, 29], + ]); + expect(indexed1.entrySeq().toArray()).toEqual([ + [0, 20], + [1, 22], + [2, 24], + [3, 26], + [4, 28], + ]); + + // Where Keyed Sequences maintain keys. + const keyed = seq.toKeyedSeq(); + const keyedOperated = keyed.filter(isEven).skip(10).take(5); + expect(keyedOperated.entrySeq().toArray()).toEqual([ + [20, 20], + [22, 22], + [24, 24], + [26, 26], + [28, 28], + ]); + const [keyed0, keyed1] = keyed + .partition(isEven) + .map((part) => part.skip(10).take(5)); + expect(keyed0.entrySeq().toArray()).toEqual([ + [21, 21], + [23, 23], + [25, 25], + [27, 27], + [29, 29], + ]); + expect(keyed1.entrySeq().toArray()).toEqual([ + [20, 20], + [22, 22], + [24, 24], + [26, 26], + [28, 28], + ]); + }); + + it('works with reverse', () => { + const seq = Range(0, 100); + + // This is what we expect for IndexedSequences + expect(seq.reverse().take(5).entrySeq().toArray()).toEqual([ + [0, 99], + [1, 98], + [2, 97], + [3, 96], + [4, 95], + ]); + + // Where Keyed Sequences maintain keys. + expect(seq.toKeyedSeq().reverse().take(5).entrySeq().toArray()).toEqual([ + [99, 99], + [98, 98], + [97, 97], + [96, 96], + [95, 95], + ]); + }); + + it('works with double reverse', () => { + const seq = Range(0, 100); + + // This is what we expect for IndexedSequences + expect( + seq.reverse().skip(10).take(5).reverse().entrySeq().toArray() + ).toEqual([ + [0, 85], + [1, 86], + [2, 87], + [3, 88], + [4, 89], + ]); + + // Where Keyed Sequences maintain keys. + expect( + seq.reverse().toKeyedSeq().skip(10).take(5).reverse().entrySeq().toArray() + ).toEqual([ + [14, 85], + [13, 86], + [12, 87], + [11, 88], + [10, 89], + ]); + }); +}); diff --git a/__tests__/List.ts b/__tests__/List.ts new file mode 100644 index 0000000000..da2e9d996b --- /dev/null +++ b/__tests__/List.ts @@ -0,0 +1,1076 @@ +import { describe, expect, it } from '@jest/globals'; +import { fromJS, List, Map, Range, Seq, Set } from 'immutable'; +import fc from 'fast-check'; +import { create as createSeed } from 'random-seed'; + +function arrayOfSize(s: number) { + const a = new Array(s); + for (let ii = 0; ii < s; ii++) { + a[ii] = ii; + } + return a; +} + +describe('List', () => { + it('determines assignment of unspecified value types', () => { + interface Test { + list: List; + } + + const t: Test = { + list: List(), + }; + + expect(t.list.size).toBe(0); + }); + + it('of provides initial values', () => { + const v = List.of('a', 'b', 'c'); + expect(v.get(0)).toBe('a'); + expect(v.get(1)).toBe('b'); + expect(v.get(2)).toBe('c'); + }); + + it('toArray provides a JS array', () => { + const v = List.of('a', 'b', 'c'); + expect(v.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('does not accept a scalar', () => { + expect(() => { + // @ts-expect-error -- test that runtime does throw + List(3); + }).toThrow('Expected Array or collection object of values: 3'); + }); + + it('accepts an array', () => { + const v = List(['a', 'b', 'c']); + expect(v.get(1)).toBe('b'); + expect(v.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts an array-like', () => { + const v = List({ length: 3, 2: 'c' }); + expect(v.get(2)).toBe('c'); + expect(v.toArray()).toEqual([undefined, undefined, 'c']); + }); + + it('accepts any array-like collection, including strings', () => { + const v = List('abc'); + expect(v.get(1)).toBe('b'); + expect(v.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts an indexed Seq', () => { + const seq = Seq(['a', 'b', 'c']); + const v = List(seq); + expect(v.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts a keyed Seq as a list of entries', () => { + const seq = Seq({ a: null, b: null, c: null }).flip(); + const v = List(seq); + expect(v.toArray()).toEqual([ + [null, 'a'], + [null, 'b'], + [null, 'c'], + ]); + // Explicitly getting the values sequence + const v2 = List(seq.valueSeq()); + expect(v2.toArray()).toEqual(['a', 'b', 'c']); + // toList() does this for you. + const v3 = seq.toList(); + expect(v3.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('can set and get a value', () => { + let v = List(); + expect(v.get(0)).toBe(undefined); + v = v.set(0, 'value'); + expect(v.get(0)).toBe('value'); + }); + + it('can setIn and getIn a deep value', () => { + let v = List([ + Map({ + aKey: List(['bad', 'good']), + }), + ]); + expect(v.getIn([0, 'aKey', 1])).toBe('good'); + v = v.setIn([0, 'aKey', 1], 'great'); + expect(v.getIn([0, 'aKey', 1])).toBe('great'); + }); + + it('can setIn on an inexistant index', () => { + const myMap = Map<{ a: Array; b: Array; c?: List }>( + { a: [], b: [] } + ); + const out = myMap.setIn(['a', 0], 'v').setIn(['c', 0], 'v'); + + expect(out.getIn(['a', 0])).toEqual('v'); + expect(out.getIn(['c', 0])).toEqual('v'); + expect(out.get('a')).toBeInstanceOf(Array); + expect(out.get('b')).toBeInstanceOf(Array); + expect(out.get('c')).toBeInstanceOf(Map); + expect(out.get('c')?.keySeq().first()).toBe(0); + }); + + it('throw when calling setIn on a non data structure', () => { + const avengers = [ + 'ironMan', // index [0] + [ + 'captainAmerica', // index [1][0] + [ + 'blackWidow', // index [1][1][0] + ['theHulk'], // index [1][1][1][0] + ], + ], + ]; + + const avengersList = fromJS(avengers) as List; + + // change theHulk to scarletWitch + const out1 = avengersList.setIn([1, 1, 1, 0], 'scarletWitch'); + expect(out1.getIn([1, 1, 1, 0])).toEqual('scarletWitch'); + + const out2 = avengersList.setIn([1, 1, 1, 3], 'scarletWitch'); + expect(out2.getIn([1, 1, 1, 3])).toEqual('scarletWitch'); + + expect(() => { + avengersList.setIn([0, 1], 'scarletWitch'); + }).toThrow( + 'Cannot update within non-data-structure value in path [0]: ironMan' + ); + }); + + it('can update a value', () => { + const l = List.of(5); + // @ts-expect-error -- Type definition limitation + expect(l.update(0, (v) => v * v).toArray()).toEqual([25]); + }); + + it('can updateIn a deep value', () => { + let l = List([ + Map({ + aKey: List(['bad', 'good']), + }), + ]); + // @ts-expect-error -- Type definition limitation + l = l.updateIn([0, 'aKey', 1], (v) => v + v); + expect(l.toJS()).toEqual([ + { + aKey: ['bad', 'goodgood'], + }, + ]); + }); + + it('returns undefined when getting a null value', () => { + const v = List([1, 2, 3]); + // @ts-expect-error -- test runtime + expect(v.get(null)).toBe(undefined); + + const o = List([{ a: 1 }, { b: 2 }, { c: 3 }]); + // @ts-expect-error -- test runtime + expect(o.get(null)).toBe(undefined); + }); + + it('counts from the end of the list on negative index', () => { + const i = List.of(1, 2, 3, 4, 5, 6, 7); + expect(i.get(-1)).toBe(7); + expect(i.get(-5)).toBe(3); + expect(i.get(-9)).toBe(undefined); + expect(i.get(-999, 1000)).toBe(1000); + }); + + it('coerces numeric-string keys', () => { + // Of course, TypeScript protects us from this, so cast to "any" to test. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const i: any = List.of(1, 2, 3, 4, 5, 6); + expect(i.get('1')).toBe(2); + expect(i.set('3', 10).get('3')).toBe(10); + // Like array, string negative numbers do not qualify + expect(i.get('-1')).toBe(undefined); + // Like array, string floating point numbers do not qualify + expect(i.get('1.0')).toBe(undefined); + }); + + it('uses not set value for string index', () => { + const list = List(); + // @ts-expect-error -- test runtime + expect(list.get('stringKey', 'NOT-SET')).toBe('NOT-SET'); + }); + + it('uses not set value for index {}', () => { + const list = List.of(1, 2, 3, 4, 5); + // @ts-expect-error -- test runtime + expect(list.get({}, 'NOT-SET')).toBe('NOT-SET'); + }); + + it('uses not set value for index void 0', () => { + const list = List.of(1, 2, 3, 4, 5); + // @ts-expect-error -- test runtime + + expect(list.get(void 0, 'NOT-SET')).toBe('NOT-SET'); + }); + + it('uses not set value for index undefined', () => { + const list = List.of(1, 2, 3, 4, 5); + // @ts-expect-error -- test runtime + expect(list.get(undefined, 'NOT-SET')).toBe('NOT-SET'); + }); + + it('doesnt coerce empty strings to index 0', () => { + const list = List.of(1, 2, 3); + // @ts-expect-error -- test runtime + expect(list.has('')).toBe(false); + }); + + it('doesnt contain elements at non-empty string keys', () => { + const list = List.of(1, 2, 3, 4, 5); + // @ts-expect-error -- test runtime + expect(list.has('str')).toBe(false); + }); + + it('hasIn doesnt contain elements at non-empty string keys', () => { + const list = List.of(1, 2, 3, 4, 5); + expect(list.hasIn(['str'])).toBe(false); + }); + + it('hasIn doesnt throw for bad key-path', () => { + const list = List.of(1, 2, 3, 4, 5); + expect(list.hasIn([1, 2, 3])).toBe(false); + + const list2 = List([{}]); + expect(list2.hasIn([0, 'bad'])).toBe(false); + }); + + it('setting creates a new instance', () => { + const v0 = List.of('a'); + const v1 = v0.set(0, 'A'); + expect(v0.get(0)).toBe('a'); + expect(v1.get(0)).toBe('A'); + }); + + it('size includes the highest index', () => { + const v0 = List(); + const v1 = v0.set(0, 'a'); + const v2 = v1.set(1, 'b'); + const v3 = v2.set(2, 'c'); + expect(v0.size).toBe(0); + expect(v1.size).toBe(1); + expect(v2.size).toBe(2); + expect(v3.size).toBe(3); + }); + + it('get helpers make for easier to read code', () => { + const v = List.of('a', 'b', 'c'); + expect(v.first()).toBe('a'); + expect(v.get(1)).toBe('b'); + expect(v.last()).toBe('c'); + }); + + it('slice helpers make for easier to read code', () => { + const v0 = List.of('a', 'b', 'c'); + const v1 = List.of('a', 'b'); + const v2 = List.of('a'); + const v3 = List(); + + expect(v0.rest().toArray()).toEqual(['b', 'c']); + expect(v0.butLast().toArray()).toEqual(['a', 'b']); + + expect(v1.rest().toArray()).toEqual(['b']); + expect(v1.butLast().toArray()).toEqual(['a']); + + expect(v2.rest().toArray()).toEqual([]); + expect(v2.butLast().toArray()).toEqual([]); + + expect(v3.rest().toArray()).toEqual([]); + expect(v3.butLast().toArray()).toEqual([]); + }); + + it('can set at arbitrary indices', () => { + const v0 = List.of('a', 'b', 'c'); + const v1 = v0.set(1, 'B'); // within existing tail + const v2 = v1.set(3, 'd'); // at last position + const v3 = v2.set(31, 'e'); // (testing internal guts) + const v4 = v3.set(32, 'f'); // (testing internal guts) + const v5 = v4.set(1023, 'g'); // (testing internal guts) + const v6 = v5.set(1024, 'h'); // (testing internal guts) + const v7 = v6.set(32, 'F'); // set within existing tree + expect(v7.size).toBe(1025); + const expectedArray = ['a', 'B', 'c', 'd']; + expectedArray[31] = 'e'; + expectedArray[32] = 'F'; + expectedArray[1023] = 'g'; + expectedArray[1024] = 'h'; + expect(v7.toArray()).toEqual(expectedArray); + }); + + it('can contain a large number of indices', () => { + const r = Range(0, 20000).toList(); + let iterations = 0; + r.forEach((v) => { + expect(v).toBe(iterations); + iterations++; + }); + }); + + it('describes a dense list', () => { + const v = List.of('a', 'b', 'c') + .push('d') + .set(14, 'o') + .set(6, undefined) + .remove(1); + expect(v.size).toBe(14); + // eslint-disable-next-line no-sparse-arrays + expect(v.toJS()).toEqual(['a', 'c', 'd', , , , , , , , , , , 'o']); + }); + + it('iterates a dense list', () => { + const v = List() + .setSize(11) + .set(1, 1) + .set(3, 3) + .set(5, 5) + .set(7, 7) + .set(9, 9); + expect(v.size).toBe(11); + + const forEachResults: Array<[number, undefined | number]> = []; + v.forEach((val, i) => forEachResults.push([i, val])); + expect(forEachResults).toEqual([ + [0, undefined], + [1, 1], + [2, undefined], + [3, 3], + [4, undefined], + [5, 5], + [6, undefined], + [7, 7], + [8, undefined], + [9, 9], + [10, undefined], + ]); + + const arrayResults = v.toArray(); + expect(arrayResults).toEqual([ + undefined, + 1, + undefined, + 3, + undefined, + 5, + undefined, + 7, + undefined, + 9, + undefined, + ]); + + const iteratorResults: Array<[number, undefined | number]> = []; + const iterator = v.entries(); + let step; + while (!(step = iterator.next()).done) { + iteratorResults.push(step.value); + } + expect(iteratorResults).toEqual([ + [0, undefined], + [1, 1], + [2, undefined], + [3, 3], + [4, undefined], + [5, 5], + [6, undefined], + [7, 7], + [8, undefined], + [9, 9], + [10, undefined], + ]); + }); + + it('has the same iterator function for values', () => { + const l = List(['a', 'b', 'c']); + expect(l[Symbol.iterator]).toBe(l.values); + }); + + it('push inserts at highest index', () => { + const v0 = List.of('a', 'b', 'c'); + const v1 = v0.push('d', 'e', 'f'); + expect(v0.size).toBe(3); + expect(v1.size).toBe(6); + expect(v1.toArray()).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); + }); + + it('pushes multiple values to the end', () => { + fc.assert( + fc.property(fc.nat(100), fc.nat(100), (s1, s2) => { + const a1 = arrayOfSize(s1); + const a2 = arrayOfSize(s2); + + const v1 = List(a1); + const v3 = v1.push.apply(v1, a2); + + const a3 = a1.slice(); + a3.push.apply(a3, a2); + + expect(v3.size).toEqual(a3.length); + expect(v3.toArray()).toEqual(a3); + }) + ); + }); + + it('pop removes the highest index, decrementing size', () => { + let v = List.of('a', 'b', 'c').pop(); + expect(v.last()).toBe('b'); + expect(v.toArray()).toEqual(['a', 'b']); + v = v.set(1230, 'x'); + expect(v.size).toBe(1231); + expect(v.last()).toBe('x'); + v = v.pop(); + expect(v.size).toBe(1230); + expect(v.last()).toBe(undefined); + v = v.push('X'); + expect(v.size).toBe(1231); + expect(v.last()).toBe('X'); + }); + + it('pop removes the highest index, just like array', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const a = arrayOfSize(len); + let v = List(a); + + while (a.length) { + expect(v.size).toBe(a.length); + expect(v.toArray()).toEqual(a); + v = v.pop(); + a.pop(); + } + expect(v.size).toBe(a.length); + expect(v.toArray()).toEqual(a); + }) + ); + }); + + it('push adds the next highest index, just like array', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const a: Array = []; + let v = List(); + + for (let ii = 0; ii < len; ii++) { + expect(v.size).toBe(a.length); + expect(v.toArray()).toEqual(a); + v = v.push(ii); + a.push(ii); + } + expect(v.size).toBe(a.length); + expect(v.toArray()).toEqual(a); + }) + ); + }); + + it('allows popping an empty list', () => { + let v = List.of('a').pop(); + expect(v.size).toBe(0); + expect(v.toArray()).toEqual([]); + v = v.pop().pop().pop().pop().pop(); + expect(v.size).toBe(0); + expect(v.toArray()).toEqual([]); + }); + + it.each(['remove', 'delete'])('remove removes any index', (fn) => { + let v = List.of('a', 'b', 'c')[fn](2)[fn](0); + expect(v.size).toBe(1); + expect(v.get(0)).toBe('b'); + expect(v.get(1)).toBe(undefined); + expect(v.get(2)).toBe(undefined); + expect(v.toArray()).toEqual(['b']); + v = v.push('d'); + expect(v.size).toBe(2); + expect(v.get(1)).toBe('d'); + expect(v.toArray()).toEqual(['b', 'd']); + }); + + it('shifts values from the front', () => { + const v = List.of('a', 'b', 'c').shift(); + expect(v.first()).toBe('b'); + expect(v.size).toBe(2); + }); + + it('unshifts values to the front', () => { + const v = List.of('a', 'b', 'c').unshift('x', 'y', 'z'); + expect(v.first()).toBe('x'); + expect(v.size).toBe(6); + expect(v.toArray()).toEqual(['x', 'y', 'z', 'a', 'b', 'c']); + }); + + it('unshifts multiple values to the front', () => { + fc.assert( + fc.property(fc.nat(100), fc.nat(100), (s1, s2) => { + const a1 = arrayOfSize(s1); + const a2 = arrayOfSize(s2); + + const v1 = List(a1); + const v3 = v1.unshift.apply(v1, a2); + + const a3 = a1.slice(); + a3.unshift.apply(a3, a2); + + expect(v3.size).toEqual(a3.length); + expect(v3.toArray()).toEqual(a3); + }) + ); + }); + + it('finds values using indexOf', () => { + const v = List.of('a', 'b', 'c', 'b', 'a'); + expect(v.indexOf('b')).toBe(1); + expect(v.indexOf('c')).toBe(2); + expect(v.indexOf('d')).toBe(-1); + }); + + it('finds values using lastIndexOf', () => { + const v = List.of('a', 'b', 'c', 'b', 'a'); + expect(v.lastIndexOf('b')).toBe(3); + expect(v.lastIndexOf('c')).toBe(2); + expect(v.lastIndexOf('d')).toBe(-1); + }); + + it('finds values using findIndex', () => { + const v = List.of('a', 'b', 'c', 'B', 'a'); + expect(v.findIndex((value) => value.toUpperCase() === value)).toBe(3); + expect(v.findIndex((value) => value.length > 1)).toBe(-1); + }); + + it('finds values using findEntry', () => { + const v = List.of('a', 'b', 'c', 'B', 'a'); + expect(v.findEntry((value) => value.toUpperCase() === value)).toEqual([ + 3, + 'B', + ]); + expect(v.findEntry((value) => value.length > 1)).toBe(undefined); + }); + + it('maps values', () => { + const v = List.of('a', 'b', 'c'); + const r = v.map((value) => value.toUpperCase()); + expect(r.toArray()).toEqual(['A', 'B', 'C']); + }); + + it('map no-ops return the same reference', () => { + const v = List.of('a', 'b', 'c'); + const r = v.map((value) => value); + expect(r).toBe(v); + }); + + it('ensures iter is unmodified', () => { + const v = List.of(1, 2, 3); + const r = v.map((value, index, iter) => iter.get(index - 1)); + expect(r.toArray()).toEqual([3, 1, 2]); + }); + + it('filters values', () => { + const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); + const r = v.filter((value, index) => index % 2 === 1); + expect(r.toArray()).toEqual(['b', 'd', 'f']); + }); + + it('partitions values', () => { + const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); + const r = v + .partition((value, index) => index % 2 === 1) + .map((part) => part.toArray()); + expect(r).toEqual([ + ['a', 'c', 'e'], + ['b', 'd', 'f'], + ]); + }); + + it('filters values based on type', () => { + class A {} + class B extends A { + b(): void {} + } + class C extends A { + c(): void {} + } + const l1 = List([new B(), new C(), new B(), new C()]); + const l2: List = l1.filter((v): v is C => v instanceof C); + expect(l2.size).toEqual(2); + expect(l2.every((v) => v instanceof C)).toBe(true); + }); + + it('partitions values based on type', () => { + class A {} + class B extends A { + b(): void {} + } + class C extends A { + c(): void {} + } + const l1 = List([new B(), new C(), new B(), new C()]); + const [la, lc]: [List, List] = l1.partition( + (v): v is C => v instanceof C + ); + expect(la.size).toEqual(2); + expect(la.some((v) => v instanceof C)).toBe(false); + expect(lc.size).toEqual(2); + expect(lc.every((v) => v instanceof C)).toBe(true); + }); + + it('reduces values', () => { + const v = List.of(1, 10, 100); + const r = v.reduce((reduction, value) => reduction + value); + expect(r).toEqual(111); + const r2 = v.reduce((reduction, value) => reduction + value, 1000); + expect(r2).toEqual(1111); + }); + + it('reduces from the right', () => { + const v = List.of('a', 'b', 'c'); + const r = v.reduceRight((reduction, value) => reduction + value); + expect(r).toEqual('cba'); + const r2 = v.reduceRight((reduction, value) => reduction + value, 'x'); + expect(r2).toEqual('xcba'); + }); + + it('takes maximum number', () => { + const v = List.of('a', 'b', 'c'); + const r = v.take(Number.MAX_SAFE_INTEGER); + expect(r).toBe(v); + }); + + it('takes and skips values', () => { + const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); + const r = v.skip(2).take(2); + expect(r.toArray()).toEqual(['c', 'd']); + }); + + it('takes and skips no-ops return same reference', () => { + const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); + const r = v.skip(0).take(6); + expect(r).toBe(v); + }); + + it('takeLast and skipLast values', () => { + const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); + const r = v.skipLast(1).takeLast(2); + expect(r.toArray()).toEqual(['d', 'e']); + }); + + it('takeLast and skipLast no-ops return same reference', () => { + const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); + const r = v.skipLast(0).takeLast(6); + expect(r).toBe(v); + }); + + it('efficiently chains array methods', () => { + const v = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); + + const r = v + .filter((x) => x % 2 === 0) + .skip(2) + .map((x) => x * x) + .take(3) + .reduce((a: number, b: number) => a + b, 0); + + expect(r).toEqual(200); + }); + + it('can convert to a map', () => { + const v = List.of('a', 'b', 'c'); + const m = v.toMap(); + expect(m.size).toBe(3); + expect(m.get(1)).toBe('b'); + }); + + it('reverses', () => { + const v = List.of('a', 'b', 'c'); + expect(v.reverse().toArray()).toEqual(['c', 'b', 'a']); + }); + + it('ensures equality', () => { + // Make a sufficiently long list. + const a = Array(100).join('abcdefghijklmnopqrstuvwxyz').split(''); + const v1 = List(a); + const v2 = List(a); + + // eslint-disable-next-line eqeqeq + expect(v1 == v2).not.toBe(true); + expect(v1 === v2).not.toBe(true); + expect(v1.equals(v2)).toBe(true); + }); + + it('works with insert', () => { + const v = List.of('a', 'b', 'c'); + const m = v.insert(1, 'd'); + expect(m.size).toBe(4); + expect(m.get(1)).toBe('d'); + + // Works when index is greater than size of array. + const n = v.insert(10, 'e'); + expect(n.size).toBe(4); + expect(n.get(3)).toBe('e'); + + // Works when index is negative. + const o = v.insert(-4, 'f'); + expect(o.size).toBe(4); + expect(o.get(0)).toBe('f'); + }); + + it('works with push, set and insert without phantom values', () => { + const v = List.of().set(287, 287).push(42).insert(33, 33); + expect(v.toJS().filter((item) => item === 287)).toHaveLength(1); + const v2 = List.of().push(0).unshift(-1).unshift(-2).pop().pop().set(2, 2); + expect(v2.toJS()).toEqual([-2, undefined, 2]); + const v3 = List.of().set(447, 447).push(0).insert(65, 65); + expect(v3.toJS().filter((item) => item === 447)).toHaveLength(1); + const v4 = List.of().set(-28, -28).push(0).shift().set(-30, -30); + expect(v4.toJS().filter((item) => item === -28)).toHaveLength(0); + const v5 = List.of().unshift(0).set(33, 33).shift().set(-35, -35); + expect(v5.toJS().filter((item) => item === 0)).toHaveLength(0); + + // execute the same test as `v` but for the 2000 first integers + const isOkV1 = (v) => + List.of() + .set(v, v) + .push('pushed-value') + .insert(33, 'inserted-value') + .filter((item) => item === v).size === 1; + + const arr = new Array(2000).fill(null).map((_, v) => v); + + const notOkArray = arr.filter((v) => !isOkV1(v)); + + expect(notOkArray).toHaveLength(0); + }); + + // TODO: assert that findIndex only calls the function as much as it needs to. + + it('forEach iterates in the correct order', () => { + let n = 0; + const a: Array = []; + const v = List.of(0, 1, 2, 3, 4); + v.forEach((x) => { + a.push(x); + n++; + }); + expect(n).toBe(5); + expect(a.length).toBe(5); + expect(a).toEqual([0, 1, 2, 3, 4]); + }); + + it('forEach iteration terminates when callback returns false', () => { + const a: Array = []; + function count(x) { + if (x > 2) { + return false; + } + a.push(x); + } + const v = List.of(0, 1, 2, 3, 4); + v.forEach(count); + expect(a).toEqual([0, 1, 2]); + }); + + it('concat works like Array.prototype.concat', () => { + const v1 = List([1, 2, 3]); + const v2 = v1.concat( + 4, + List([5, 6]), + [7, 8], + Seq([9, 10]), + Set.of(11, 12), + null + ); + expect(v1.toArray()).toEqual([1, 2, 3]); + expect(v2.toArray()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, null]); + }); + + it('concat works like Array.prototype.concat even for IE11', () => { + const v1 = List([1, 2, 3]); + const a = [4]; + + // remove Symbol.iterator as IE11 does not handle it. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator#browser_compatibility + // @ts-expect-error -- simulate IE11 + a[Symbol.iterator] = undefined; + + const v2 = v1.concat(a); + expect(v1.toArray()).toEqual([1, 2, 3]); + expect(v2.toArray()).toEqual([1, 2, 3, 4]); + }); + + it('concat returns self when no changes', () => { + const v1 = List([1, 2, 3]); + expect(v1.concat([])).toBe(v1); + }); + + it('concat returns arg when concat to empty', () => { + const v1 = List([1, 2, 3]); + expect(List().concat(v1)).toBe(v1); + }); + + it('concats a single value', () => { + const v1 = List([1, 2, 3]); + expect(v1.concat(4)).toEqual(List([1, 2, 3, 4])); + }); + + it('concat returns List-coerced arg when concat to empty', () => { + expect(List().concat([1, 2, 3])).toEqual(List([1, 2, 3])); + }); + + it('concat does not spread in string characters', () => { + const v1 = List([1, 2, 3]); + expect(v1.concat('abcdef')).toEqual(List([1, 2, 3, 'abcdef'])); + }); + + it('allows chained mutations', () => { + const v1 = List(); + const v2 = v1.push(1); + const v3 = v2.withMutations((v) => v.push(2).push(3).push(4)); + const v4 = v3.push(5); + + expect(v1.toArray()).toEqual([]); + expect(v2.toArray()).toEqual([1]); + expect(v3.toArray()).toEqual([1, 2, 3, 4]); + expect(v4.toArray()).toEqual([1, 2, 3, 4, 5]); + }); + + it('allows chained mutations using alternative API', () => { + const v1 = List(); + const v2 = v1.push(1); + const v3 = v2.asMutable().push(2).push(3).push(4).asImmutable(); + const v4 = v3.push(5); + + expect(v1.toArray()).toEqual([]); + expect(v2.toArray()).toEqual([1]); + expect(v3.toArray()).toEqual([1, 2, 3, 4]); + expect(v4.toArray()).toEqual([1, 2, 3, 4, 5]); + }); + + it('chained mutations does not result in new empty list instance', () => { + const v1 = List(['x']); + const v2 = v1.withMutations((v) => v.push('y').pop().pop()); + expect(v2).toEqual(List()); + }); + + it('calling `clear` and `setSize` should set all items to undefined', () => { + const l = List(['a', 'b']); + const l2 = l.clear().setSize(3); + + expect(l2.get(0)).toBeUndefined(); + expect(l2.get(1)).toBeUndefined(); + expect(l2.get(2)).toBeUndefined(); + }); + + it('calling `clear` and `setSize` while mutating should set all items to undefined', () => { + const l = List(['a', 'b']); + const l2 = l.withMutations((innerList) => { + innerList.clear().setSize(3); + }); + expect(l2.get(0)).toBeUndefined(); + expect(l2.get(1)).toBeUndefined(); + expect(l2.get(2)).toBeUndefined(); + }); + + it('allows size to be set', () => { + const v1 = Range(0, 2000).toList(); + const v2 = v1.setSize(1000); + const v3 = v2.setSize(1500); + expect(v1.size).toBe(2000); + expect(v2.size).toBe(1000); + expect(v3.size).toBe(1500); + expect(v1.get(900)).toBe(900); + expect(v1.get(1300)).toBe(1300); + expect(v1.get(1800)).toBe(1800); + expect(v2.get(900)).toBe(900); + expect(v2.get(1300)).toBe(undefined); + expect(v2.get(1800)).toBe(undefined); + expect(v3.get(900)).toBe(900); + expect(v3.get(1300)).toBe(undefined); + expect(v3.get(1800)).toBe(undefined); + }); + + it('discards truncated elements when using slice', () => { + const list: Array = [1, 2, 3, 4, 5, 6]; + const v1 = fromJS(list) as List; + const v2 = v1.slice(0, 3); + const v3 = v2.setSize(6); + + expect(v2.toArray()).toEqual(list.slice(0, 3)); + expect(v3.toArray()).toEqual( + list.slice(0, 3).concat([undefined, undefined, undefined]) + ); + }); + + it('discards truncated elements when using setSize', () => { + const list: Array = [1, 2, 3, 4, 5, 6]; + const v1 = fromJS(list) as List; + const v2 = v1.setSize(3); + const v3 = v2.setSize(6); + + expect(v2.toArray()).toEqual(list.slice(0, 3)); + expect(v3.toArray()).toEqual( + list.slice(0, 3).concat([undefined, undefined, undefined]) + ); + }); + + it('can be efficiently sliced', () => { + const v1 = Range(0, 2000).toList(); + const v2 = v1.slice(100, -100).toList(); + const v3 = v2.slice(0, Infinity); + expect(v1.size).toBe(2000); + expect(v2.size).toBe(1800); + expect(v3.size).toBe(1800); + expect(v2.first()).toBe(100); + expect(v2.rest().size).toBe(1799); + expect(v2.last()).toBe(1899); + expect(v2.butLast().size).toBe(1799); + }); + + [NaN, Infinity, -Infinity].forEach((zeroishValue) => { + it(`treats ${zeroishValue} like zero when setting size`, () => { + const v1 = List.of('a', 'b', 'c'); + const v2 = v1.setSize(zeroishValue); + expect(v2.size).toBe(0); + }); + }); + + it('Does not infinite loop when sliced with NaN #459', () => { + const list = List([1, 2, 3, 4, 5]); + const newList = list.slice(0, NaN); + expect(newList.toJS()).toEqual([]); + }); + + it('Accepts NaN for slice and concat #602', () => { + const list = List().slice(0, NaN).concat(NaN); + // toEqual([ NaN ]) + expect(list.size).toBe(1); + expect(isNaNValue(list.get(0))).toBe(true); + }); + + it('return a new emptyList if the emptyList has been mutated #2003', () => { + const emptyList = List(); + + const nonEmptyList = emptyList.withMutations((l) => { + l.setSize(1); + l.set(0, 'a'); + }); + + expect(nonEmptyList.size).toBe(1); + expect(nonEmptyList).toEqual(List.of('a')); + expect(emptyList.size).toBe(0); + + const mutableList = emptyList.asMutable(); + + mutableList.setSize(1); + mutableList.set(0, 'b'); + + expect(mutableList.size).toBe(1); + expect(mutableList).toEqual(List.of('b')); + + expect(emptyList.size).toBe(0); + expect(List().size).toBe(0); + }); + + it('Mutating empty list with a JS API should not mutate new instances', () => { + Object.assign(List(), List([1, 2])); + + expect(List().size).toBe(0); + expect(List().toArray()).toEqual([]); + }); + + // Note: NaN is the only value not equal to itself. The isNaN() built-in + // function returns true for any non-numeric value, not just the NaN value. + function isNaNValue(value) { + return value !== value; + } + + describe('when slicing', () => { + [NaN, -Infinity].forEach((zeroishValue) => { + it(`considers a ${zeroishValue} begin argument to be zero`, () => { + const v1 = List.of('a', 'b', 'c'); + const v2 = v1.slice(zeroishValue, 3); + expect(v2.size).toBe(3); + }); + it(`considers a ${zeroishValue} end argument to be zero`, () => { + const v1 = List.of('a', 'b', 'c'); + const v2 = v1.slice(0, zeroishValue); + expect(v2.size).toBe(0); + }); + it(`considers ${zeroishValue} begin and end arguments to be zero`, () => { + const v1 = List.of('a', 'b', 'c'); + const v2 = v1.slice(zeroishValue, zeroishValue); + expect(v2.size).toBe(0); + }); + }); + }); + + describe('when shuffling', () => { + const list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + it('should work when empty', () => { + expect(List().shuffle()).toStrictEqual(List()); + }); + it('should work with Math.random', () => { + expect(list.shuffle().sort()).toStrictEqual(list); + }); + it('should work with a pseudo random number generator', () => { + const seed = createSeed('lorem ipsum'); + const random = () => seed.random(); + + expect(list.shuffle(random)).toStrictEqual( + List.of(5, 2, 4, 7, 6, 3, 10, 1, 9, 8) + ); + expect(list.shuffle(random)).toStrictEqual( + List.of(1, 6, 2, 3, 9, 7, 4, 10, 5, 8) + ); + expect(list.shuffle(random)).toStrictEqual( + List.of(6, 1, 8, 10, 9, 5, 4, 7, 3, 2) + ); + }); + }); + + describe('Iterator', () => { + const pInt = fc.nat(100); + + it('iterates through List', () => { + fc.assert( + fc.property(pInt, pInt, (start, len) => { + const l1 = Range(0, start + len).toList(); + const l2: List = l1.slice(start, start + len); + expect(l2.size).toBe(len); + const valueIter = l2.values(); + const keyIter = l2.keys(); + const entryIter = l2.entries(); + for (let ii = 0; ii < len; ii++) { + expect(valueIter.next().value).toBe(start + ii); + expect(keyIter.next().value).toBe(ii); + expect(entryIter.next().value).toEqual([ii, start + ii]); + } + }) + ); + }); + + it('iterates through List in reverse', () => { + fc.assert( + fc.property(pInt, pInt, (start, len) => { + const l1 = Range(0, start + len).toList(); + const l2: List = l1.slice(start, start + len); + const s = l2.toSeq().reverse(); // impl calls List.__iterator(REVERSE) + expect(s.size).toBe(len); + const valueIter = s.values(); + const keyIter = s.keys(); + const entryIter = s.entries(); + for (let ii = 0; ii < len; ii++) { + expect(valueIter.next().value).toBe(start + len - 1 - ii); + expect(keyIter.next().value).toBe(ii); + expect(entryIter.next().value).toEqual([ii, start + len - 1 - ii]); + } + }) + ); + }); + }); +}); diff --git a/__tests__/ListJS.js b/__tests__/ListJS.js new file mode 100644 index 0000000000..ae18d4881d --- /dev/null +++ b/__tests__/ListJS.js @@ -0,0 +1,47 @@ +import { describe, expect, it } from '@jest/globals'; +import { List } from 'immutable'; + +const NON_NUMBERS = { + array: ['not', 'a', 'number'], + NaN: NaN, + object: { not: 'a number' }, + string: 'not a number', +}; + +describe('List', () => { + describe('setSize()', () => { + Object.keys(NON_NUMBERS).forEach((type) => { + const nonNumber = NON_NUMBERS[type]; + it(`considers a size argument of type '${type}' to be zero`, () => { + const v1 = List.of(1, 2, 3); + const v2 = v1.setSize(nonNumber); + expect(v2.size).toBe(0); + }); + }); + }); + describe('slice()', () => { + // Mimic the behavior of Array::slice() + // http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.slice + Object.keys(NON_NUMBERS).forEach((type) => { + const nonNumber = NON_NUMBERS[type]; + it(`considers a begin argument of type '${type}' to be zero`, () => { + const v1 = List.of('a', 'b', 'c'); + const v2 = v1.slice(nonNumber, 2); + expect(v2.size).toBe(2); + expect(v2.first()).toBe('a'); + expect(v2.rest().size).toBe(1); + expect(v2.last()).toBe('b'); + expect(v2.butLast().size).toBe(1); + }); + it(`considers an end argument of type '${type}' to be zero`, () => { + const v1 = List.of('a', 'b', 'c'); + const v2 = v1.slice(0, nonNumber); + expect(v2.size).toBe(0); + expect(v2.first()).toBe(undefined); + expect(v2.rest().size).toBe(0); + expect(v2.last()).toBe(undefined); + expect(v2.butLast().size).toBe(0); + }); + }); + }); +}); diff --git a/__tests__/Map.ts b/__tests__/Map.ts index 6f8d30e8d8..d8ae8b16ca 100644 --- a/__tests__/Map.ts +++ b/__tests__/Map.ts @@ -1,115 +1,194 @@ -/// -/// - -jest.autoMockOff(); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); - -import Immutable = require('immutable'); -import Map = Immutable.Map; +import { describe, expect, it, jest } from '@jest/globals'; +import { fromJS, is, List, Map, Range, Record, Seq } from 'immutable'; +import fc from 'fast-check'; describe('Map', () => { - it('converts from object', () => { - var m = Map.from({'a': 'A', 'b': 'B', 'c': 'C'}); - expect(m.length).toBe(3); + const m = Map({ a: 'A', b: 'B', c: 'C' }); + expect(m.size).toBe(3); + expect(m.get('a')).toBe('A'); + expect(m.get('b')).toBe('B'); + expect(m.get('c')).toBe('C'); + }); + + it('converts from JS (global) Map', () => { + const m = Map( + new global.Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]) + ); + expect(Map.isMap(m)).toBe(true); + expect(m.size).toBe(3); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); }); it('constructor provides initial values', () => { - var m = Map({'a': 'A', 'b': 'B', 'c': 'C'}); - expect(m.length).toBe(3); + const m = Map({ a: 'A', b: 'B', c: 'C' }); + expect(m.size).toBe(3); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); }); it('constructor provides initial values as array of entries', () => { - var m = Map([['a','A'],['b','B'],['c','C']]); - expect(m.length).toBe(3); + const m = Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]); + expect(m.size).toBe(3); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); }); it('constructor provides initial values as sequence', () => { - var s = Immutable.Sequence({'a': 'A', 'b': 'B', 'c': 'C'}); - var m = Map(s); - expect(m.length).toBe(3); + const s = Seq({ a: 'A', b: 'B', c: 'C' }); + const m = Map(s); + expect(m.size).toBe(3); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); }); + it('constructor provides initial values as list of lists', () => { + const l = List([List(['a', 'A']), List(['b', 'B']), List(['c', 'C'])]); + const m = Map(l); + expect(m.size).toBe(3); + // @ts-expect-error -- Not supported by typescript since 4.0.0 https://github.com/immutable-js/immutable-js/pull/1626 + expect(m.get('a')).toBe('A'); + // @ts-expect-error -- Not supported by typescript since 4.0.0 https://github.com/immutable-js/immutable-js/pull/1626 + expect(m.get('b')).toBe('B'); + // @ts-expect-error -- Not supported by typescript since 4.0.0 https://github.com/immutable-js/immutable-js/pull/1626 + expect(m.get('c')).toBe('C'); + }); + it('constructor is identity when provided map', () => { - var m1 = Map({'a': 'A', 'b': 'B', 'c': 'C'}); - var m2 = Map(m1); + const m1 = Map({ a: 'A', b: 'B', c: 'C' }); + const m2 = Map(m1); expect(m2).toBe(m1); }); + it('does not accept a scalar', () => { + expect(() => { + // TODO: should expect error + Map(3); + }).toThrow( + 'Expected Array or collection object of [k, v] entries, or keyed object: 3' + ); + }); + + it('does not accept strings (collection, but scalar)', () => { + expect(() => { + // @ts-expect-error -- constructor does not accept strings, this is expected to throw + Map('abc'); + }).toThrow(); + }); + + it('does not accept non-entries array', () => { + expect(() => { + // @ts-expect-error -- not an array of entries, this is expected to throw + Map([1, 2, 3]); + }).toThrow('Expected [K, V] tuple: 1'); + }); + + it('accepts non-collection array-like objects as keyed collections', () => { + const m = Map({ length: 3, 1: 'one' }); + expect(m.get('length')).toBe(3); + // @ts-expect-error -- type error, but the API is tolerante + expect(m.get('1')).toBe('one'); + expect(m.toJS()).toEqual({ length: 3, 1: 'one' }); + }); + it('converts back to JS object', () => { - var m = Map({'a': 'A', 'b': 'B', 'c': 'C'}); - expect(m.toObject()).toEqual({'a': 'A', 'b': 'B', 'c': 'C'}); + const m = Map({ a: 'A', b: 'B', c: 'C' }); + expect(m.toObject()).toEqual({ a: 'A', b: 'B', c: 'C' }); }); it('iterates values', () => { - var m = Map({'a': 'A', 'b': 'B', 'c': 'C'}); - var iterator = jest.genMockFunction(); + const m = Map({ a: 'A', b: 'B', c: 'C' }); + const iterator = jest.fn(); m.forEach(iterator); expect(iterator.mock.calls).toEqual([ ['A', 'a', m], ['B', 'b', m], - ['C', 'c', m] + ['C', 'c', m], ]); }); + it('has the same iterator function for entries', () => { + const m = Map({ a: 'A', b: 'B', c: 'C' }); + expect(m[Symbol.iterator]).toBe(m.entries); + }); + it('merges two maps', () => { - var m1 = Map({'a': 'A', 'b': 'B', 'c': 'C'}); - var m2 = Map({'wow': 'OO', 'd': 'DD', 'b': 'BB'}); - expect(m2.toObject()).toEqual({'wow': 'OO', 'd': 'DD', 'b': 'BB'}); - var m3 = m1.merge(m2); - expect(m3.toObject()).toEqual({'a': 'A', 'b': 'BB', 'c': 'C', 'wow': 'OO', 'd': 'DD'}); + const m1 = Map({ a: 'A', b: 'B', c: 'C' }); + const m2 = Map({ wow: 'OO', d: 'DD', b: 'BB' }); + expect(m2.toObject()).toEqual({ wow: 'OO', d: 'DD', b: 'BB' }); + const m3 = m1.merge(m2); + expect(m3.toObject()).toEqual({ + a: 'A', + b: 'BB', + c: 'C', + wow: 'OO', + d: 'DD', + }); + }); + + it('concatenates two maps (alias for merge)', () => { + const m1 = Map({ a: 'A', b: 'B', c: 'C' }); + const m2 = Map({ wow: 'OO', d: 'DD', b: 'BB' }); + expect(m2.toObject()).toEqual({ wow: 'OO', d: 'DD', b: 'BB' }); + const m3 = m1.concat(m2); + expect(m3.toObject()).toEqual({ + a: 'A', + b: 'BB', + c: 'C', + wow: 'OO', + d: 'DD', + }); }); it('accepts null as a key', () => { - var m1 = Map(); - var m2 = m1.set(null, 'null'); - var m3 = m2.remove(null); - expect(m1.length).toBe(0); - expect(m2.length).toBe(1); - expect(m3.length).toBe(0); + const m1 = Map(); + const m2 = m1.set(null, 'null'); + const m3 = m2.remove(null); + expect(m1.size).toBe(0); + expect(m2.size).toBe(1); + expect(m3.size).toBe(0); expect(m2.get(null)).toBe('null'); }); it('is persistent to sets', () => { - var m1 = Map(); - var m2 = m1.set('a', 'Aardvark'); - var m3 = m2.set('b', 'Baboon'); - var m4 = m3.set('c', 'Canary'); - var m5 = m4.set('b', 'Bonobo'); - expect(m1.length).toBe(0); - expect(m2.length).toBe(1); - expect(m3.length).toBe(2); - expect(m4.length).toBe(3); - expect(m5.length).toBe(3); + const m1 = Map(); + const m2 = m1.set('a', 'Aardvark'); + const m3 = m2.set('b', 'Baboon'); + const m4 = m3.set('c', 'Canary'); + const m5 = m4.set('b', 'Bonobo'); + expect(m1.size).toBe(0); + expect(m2.size).toBe(1); + expect(m3.size).toBe(2); + expect(m4.size).toBe(3); + expect(m5.size).toBe(3); expect(m3.get('b')).toBe('Baboon'); expect(m5.get('b')).toBe('Bonobo'); }); it('is persistent to deletes', () => { - var m1 = Map(); - var m2 = m1.set('a', 'Aardvark'); - var m3 = m2.set('b', 'Baboon'); - var m4 = m3.set('c', 'Canary'); - var m5 = m4.remove('b'); - expect(m1.length).toBe(0); - expect(m2.length).toBe(1); - expect(m3.length).toBe(2); - expect(m4.length).toBe(3); - expect(m5.length).toBe(2); + const m1 = Map(); + const m2 = m1.set('a', 'Aardvark'); + const m3 = m2.set('b', 'Baboon'); + const m4 = m3.set('c', 'Canary'); + const m5 = m4.remove('b'); + expect(m1.size).toBe(0); + expect(m2.size).toBe(1); + expect(m3.size).toBe(2); + expect(m4.size).toBe(3); + expect(m5.size).toBe(2); expect(m3.has('b')).toBe(true); expect(m3.get('b')).toBe('Baboon'); expect(m5.has('b')).toBe(false); @@ -118,157 +197,397 @@ describe('Map', () => { }); it('deletes down to empty map', () => { - var m1 = Map({a:'A', b:'B', c:'C'}); - var m2 = m1.remove('a'); - var m3 = m2.remove('b'); - var m4 = m3.remove('c'); - expect(m1.length).toBe(3); - expect(m2.length).toBe(2); - expect(m3.length).toBe(1); - expect(m4.length).toBe(0); - expect(m4).toBe(Map.empty()); + fc.assert( + fc.property(fc.nat(100), (size) => { + let m = Range(0, size).toMap(); + expect(m.size).toBe(size); + for (let ii = size - 1; ii >= 0; ii--) { + m = m.remove(ii); + expect(m.size).toBe(ii); + } + expect(m).toBe(Map()); + }) + ); }); it('can map many items', () => { - var m = Map(); - for (var ii = 0; ii < 2000; ii++) { - m = m.set('thing:' + ii, ii); + let m = Map(); + for (let ii = 0; ii < 2000; ii++) { + m = m.set('thing:' + ii, ii); } - expect(m.length).toBe(2000); + expect(m.size).toBe(2000); expect(m.get('thing:1234')).toBe(1234); }); + it('can use weird keys', () => { + const symbol = Symbol('A'); + const m = Map() + .set(NaN, 1) + .set(Infinity, 2) + .set(symbol, 'A') + .set(-Infinity, 3); + + expect(m.get(symbol)).toBe('A'); + expect(m.get(NaN)).toBe(1); + expect(m.get(Infinity)).toBe(2); + expect(m.get(-Infinity)).toBe(3); + }); + it('can map items known to hash collide', () => { - var m = Map().set('AAA', 'letters').set(64545, 'numbers'); - expect(m.length).toBe(2); + // make a big map, so it hashmaps + let m: Map = Range(0, 32).toMap(); + m = m.set('AAA', 'letters').set(64545, 'numbers'); + expect(m.size).toBe(34); expect(m.get('AAA')).toEqual('letters'); expect(m.get(64545)).toEqual('numbers'); }); it('can progressively add items known to collide', () => { - var map = Map(); + // make a big map, so it hashmaps + let map: Map = Range(0, 32).toMap(); map = map.set('@', '@'); map = map.set(64, 64); map = map.set(96, 96); - expect(map.length).toBe(3); + expect(map.size).toBe(35); expect(map.get('@')).toBe('@'); expect(map.get(64)).toBe(64); expect(map.get(96)).toBe(96); }); it('maps values', () => { - var m = Map({a:'a', b:'b', c:'c'}); - var r = m.map(value => value.toUpperCase()); - expect(r.toObject()).toEqual({a:'A', b:'B', c:'C'}); + const m = Map({ a: 'a', b: 'b', c: 'c' }); + const r = m.map((value) => value.toUpperCase()); + expect(r.toObject()).toEqual({ a: 'A', b: 'B', c: 'C' }); }); it('maps keys', () => { - var m = Map({a:'a', b:'b', c:'c'}); - var r = m.mapKeys(value => value.toUpperCase()); - expect(r.toObject()).toEqual({A:'a', B:'b', C:'c'}); + const m = Map({ a: 'a', b: 'b', c: 'c' }); + const r = m.mapKeys((key) => key.toUpperCase()); + expect(r.toObject()).toEqual({ A: 'a', B: 'b', C: 'c' }); + }); + + it('maps no-ops return the same reference', () => { + const m = Map({ a: 'a', b: 'b', c: 'c' }); + const r = m.map((value) => value); + expect(r).toBe(m); + }); + + it('provides unmodified original collection as 3rd iter argument', () => { + const m = Map({ a: 1, b: 1 }); + const r = m.map((value, key, iter) => { + expect(iter).toEqual(m); + return 2 * (iter.get(key) as number); + }); + expect(r.toObject()).toEqual({ a: 2, b: 2 }); }); it('filters values', () => { - var m = Map({a:1, b:2, c:3, d:4, e:5, f:6}); - var r = m.filter(value => value % 2 === 1); - expect(r.toObject()).toEqual({a:1, c:3, e:5}); + const m = Map({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }); + const r = m.filter((value) => value % 2 === 1); + expect(r.toObject()).toEqual({ a: 1, c: 3, e: 5 }); + }); + + it('filterNots values', () => { + const m = Map({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }); + const r = m.filterNot((value) => value % 2 === 1); + expect(r.toObject()).toEqual({ b: 2, d: 4, f: 6 }); + }); + + it('partitions values', () => { + const m = Map({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }); + const r = m + .partition((value) => value % 2 === 1) + .map((part) => part.toObject()); + expect(r).toEqual([ + { b: 2, d: 4, f: 6 }, + { a: 1, c: 3, e: 5 }, + ]); }); it('derives keys', () => { - var v = Map({a:1, b:2, c:3, d:4, e:5, f:6}); + const v = Map({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }); expect(v.keySeq().toArray()).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); }); it('flips keys and values', () => { - var v = Map({a:1, b:2, c:3, d:4, e:5, f:6}); - expect(v.flip().toObject()).toEqual({1:'a', 2:'b', 3:'c', 4:'d', 5:'e', 6:'f'}); + const v = Map({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }); + expect(v.flip().toObject()).toEqual({ + 1: 'a', + 2: 'b', + 3: 'c', + 4: 'd', + 5: 'e', + 6: 'f', + }); }); - it('can convert to a vector', () => { - var m = Map({a:1, b:2, c:3}); - var v = m.toVector(); - var k = m.keySeq().toVector(); - expect(v.length).toBe(3); - expect(k.length).toBe(3); - // Note: Map has undefined ordering, this Vector may not be the same + it('can convert to a list', () => { + const m = Map({ a: 1, b: 2, c: 3 }); + const v = m.toList(); + const k = m.keySeq().toList(); + expect(v.size).toBe(3); + expect(k.size).toBe(3); + // Note: Map has undefined ordering, this List may not be the same // order as the order you set into the Map. expect(v.get(1)).toBe(2); expect(k.get(1)).toBe('b'); }); - check.it('works like an object', {maxSize: 50}, [gen.object(gen.JSONPrimitive)], obj => { - var map = Immutable.Map.from(obj); - Object.keys(obj).forEach(key => { - expect(map.get(key)).toBe(obj[key]); - expect(map.has(key)).toBe(true); - }); - Object.keys(obj).forEach(key => { - expect(map.get(key)).toBe(obj[key]); - expect(map.has(key)).toBe(true); - map = map.remove(key); - expect(map.get(key)).toBe(undefined); - expect(map.has(key)).toBe(false); - }); + it('works like an object', () => { + fc.assert( + fc.property(fc.object({ maxKeys: 50 }), (obj) => { + let map = Map(obj); + Object.keys(obj).forEach((key) => { + expect(map.get(key)).toBe(obj[key]); + expect(map.has(key)).toBe(true); + }); + Object.keys(obj).forEach((key) => { + expect(map.get(key)).toBe(obj[key]); + expect(map.has(key)).toBe(true); + map = map.remove(key); + expect(map.get(key)).toBe(undefined); + expect(map.has(key)).toBe(false); + }); + }) + ); }); - check.it('sets', {maxSize: 5000}, [gen.posInt], len => { - var map = Immutable.Map(); - for (var ii = 0; ii < len; ii++) { - expect(map.length).toBe(ii); - map = map.set(''+ii, ii); - } - expect(map.length).toBe(len); - expect(Immutable.is(map.toSet(), Immutable.Range(0, len).toSet())).toBe(true); + it('sets', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + let map = Map(); + for (let ii = 0; ii < len; ii++) { + expect(map.size).toBe(ii); + map = map.set('' + ii, ii); + } + expect(map.size).toBe(len); + expect(is(map.toSet(), Range(0, len).toSet())).toBe(true); + }) + ); }); - check.it('has and get', {maxSize: 5000}, [gen.posInt], len => { - var map = Immutable.Range(0, len).mapKeys(x => ''+x).toMap(); - for (var ii = 0; ii < len; ii++) { - expect(map.get(''+ii)).toBe(ii); - expect(map.has(''+ii)).toBe(true); - } + it('has and get', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const map = Range(0, len) + .toKeyedSeq() + .mapKeys((x) => '' + x) + .toMap(); + for (let ii = 0; ii < len; ii++) { + expect(map.get('' + ii)).toBe(ii); + expect(map.has('' + ii)).toBe(true); + } + }) + ); }); - check.it('deletes', {maxSize: 5000}, [gen.posInt], len => { - var map = Immutable.Range(0, len).toMap(); - for (var ii = 0; ii < len; ii++) { - expect(map.length).toBe(len - ii); - map = map.remove(ii); - } - expect(map.length).toBe(0); - expect(map.toObject()).toEqual({}); + it('deletes', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + let map = Range(0, len).toMap(); + for (let ii = 0; ii < len; ii++) { + expect(map.size).toBe(len - ii); + map = map.remove(ii); + } + expect(map.size).toBe(0); + expect(map.toObject()).toEqual({}); + }) + ); }); - check.it('deletes from transient', {maxSize: 5000}, [gen.posInt], len => { - var map = Immutable.Range(0, len).toMap().asMutable(); - for (var ii = 0; ii < len; ii++) { - expect(map.length).toBe(len - ii); - map.remove(ii); - } - expect(map.length).toBe(0); - expect(map.toObject()).toEqual({}); + it('deletes from transient', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const map = Range(0, len).toMap().asMutable(); + for (let ii = 0; ii < len; ii++) { + expect(map.size).toBe(len - ii); + map.remove(ii); + } + expect(map.size).toBe(0); + expect(map.toObject()).toEqual({}); + }) + ); }); - check.it('iterates through all entries', [gen.posInt], len => { - var v = Immutable.Range(0, len).toMap(); - var a = v.toArray(); - var iter = v.entries(); - for (var ii = 0; ii < len; ii++) { - delete a[ iter.next().value[0] ]; - } - expect(a).toEqual(new Array(len)); + it('iterates through all entries', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const v = Range(0, len).toMap(); + const a = v.toArray(); + const iter = v.entries(); + for (let ii = 0; ii < len; ii++) { + delete a[iter.next().value[0]]; + } + expect(a).toEqual(new Array(len)); + }) + ); }); it('allows chained mutations', () => { - var m1 = Map(); - var m2 = m1.set('a', 1); - var m3 = m2.withMutations(m => m.set('b', 2).set('c', 3)); - var m4 = m3.set('d', 4); + const m1 = Map(); + const m2 = m1.set('a', 1); + const m3 = m2.withMutations((m) => m.set('b', 2).set('c', 3)); + const m4 = m3.set('d', 4); expect(m1.toObject()).toEqual({}); - expect(m2.toObject()).toEqual({'a':1}); - expect(m3.toObject()).toEqual({'a': 1, 'b': 2, 'c': 3}); - expect(m4.toObject()).toEqual({'a': 1, 'b': 2, 'c': 3, 'd': 4}); + expect(m2.toObject()).toEqual({ a: 1 }); + expect(m3.toObject()).toEqual({ a: 1, b: 2, c: 3 }); + expect(m4.toObject()).toEqual({ a: 1, b: 2, c: 3, d: 4 }); + }); + + it('chained mutations does not result in new empty map instance', () => { + const v1 = Map<{ x?: number; y?: number }>({ x: 1 }); + const v2 = v1.withMutations((v) => v.set('y', 2).delete('x').delete('y')); + expect(v2).toBe(Map()); + }); + + it('expresses value equality with unordered sequences', () => { + const m1 = Map({ A: 1, B: 2, C: 3 }); + const m2 = Map({ C: 3, B: 2, A: 1 }); + expect(is(m1, m2)).toBe(true); + }); + + it('does not equal Record with same values', () => { + const m1 = Map({ A: 1, B: 2, C: 3 }); + const m2 = Record({ A: 1, B: 2, C: 3 }); + expect(is(m1, m2)).toBe(false); + }); + + it('deletes all the provided keys', () => { + const NOT_SET = undefined; + const m1 = Map({ A: 1, B: 2, C: 3 }); + const m2 = m1.deleteAll(['A', 'B']); + expect(m2.get('A')).toBe(NOT_SET); + expect(m2.get('B')).toBe(NOT_SET); + expect(m2.get('C')).toBe(3); + expect(m2.size).toBe(1); }); + it('remains unchanged when no keys are provided', () => { + const m1 = Map({ A: 1, B: 2, C: 3 }); + const m2 = m1.deleteAll([]); + expect(m1).toBe(m2); + }); + + it('uses toString on keys and values', () => { + class A extends Record({ x: null as number | null }) { + toString() { + return this.x; + } + } + + const r = new A({ x: 2 }); + const map = Map([[r, r]]); + expect(map.toString()).toEqual('Map { 2: 2 }'); + }); + + it('supports Symbols as tuple keys', () => { + const a = Symbol('a'); + const b = Symbol('b'); + const c = Symbol('c'); + const m = Map([ + [a, 'a'], + [b, 'b'], + [c, 'c'], + ]); + expect(m.size).toBe(3); + expect(m.get(a)).toBe('a'); + expect(m.get(b)).toBe('b'); + expect(m.get(c)).toBe('c'); + }); + + it('supports Symbols as object constructor keys', () => { + const a = Symbol.for('a'); + const b = Symbol('b'); + const c = Symbol('c'); + const m = Map({ + [a]: 'a', + [b]: 'b', + [c]: 'c', + }); + expect(m.size).toBe(3); + expect(m.get(a)).toBe('a'); + expect(m.get(b)).toBe('b'); + expect(m.get(c)).toBe('c'); + + const m2 = fromJS({ [a]: 'a' }) as Map; + expect(m2.size).toBe(1); + expect(m2.get(a)).toBe('a'); + }); + + it('Symbol keys are unique', () => { + const a = Symbol('FooBar'); + const b = Symbol('FooBar'); + const m = Map([ + [a, 'FizBuz'], + [b, 'FooBar'], + ]); + expect(m.size).toBe(2); + expect(m.get(a)).toBe('FizBuz'); + expect(m.get(b)).toBe('FooBar'); + }); + + it('mergeDeep with tuple Symbol keys', () => { + const a = Symbol('a'); + const b = Symbol('b'); + const c = Symbol('c'); + const d = Symbol('d'); + const e = Symbol('e'); + const f = Symbol('f'); + const g = Symbol('g'); + + // Note the use of nested Map constructors, Map() does not do a + // deep conversion! + const m1 = Map([ + [ + a, + Map([ + [ + b, + Map([ + [c, 1], + [d, 2], + ]), + ], + ]), + ], + ]); + const m2 = Map([ + [ + a, + Map([ + [ + b, + Map([ + [c, 10], + [e, 20], + [f, 30], + [g, 40], + ]), + ], + ]), + ], + ]); + const merged = m1.mergeDeep(m2); + + expect(merged).toEqual( + Map([ + [ + a, + Map([ + [ + b, + Map([ + [c, 10], + [d, 2], + [e, 20], + [f, 30], + [g, 40], + ]), + ], + ]), + ], + ]) + ); + }); }); diff --git a/__tests__/MultiRequire.js b/__tests__/MultiRequire.js new file mode 100644 index 0000000000..17c3de9472 --- /dev/null +++ b/__tests__/MultiRequire.js @@ -0,0 +1,92 @@ +import { describe, expect, it, jest } from '@jest/globals'; +import * as Immutable1 from '../src/Immutable'; + +jest.resetModules(); + +const Immutable2 = jest.requireActual('../src/Immutable'); + +describe('MultiRequire', () => { + it('might require two different instances of Immutable', () => { + expect(Immutable1).not.toBe(Immutable2); + expect(Immutable1.Map({ a: 1 }).toJS()).toEqual({ a: 1 }); + expect(Immutable2.Map({ a: 1 }).toJS()).toEqual({ a: 1 }); + }); + + it('detects sequences', () => { + const x = Immutable1.Map({ a: 1 }); + const y = Immutable2.Map({ a: 1 }); + expect(Immutable1.isCollection(y)).toBe(true); + expect(Immutable2.isCollection(x)).toBe(true); + }); + + it('detects records', () => { + const R1 = Immutable1.Record({ a: 1 }); + const R2 = Immutable2.Record({ a: 1 }); + expect(Immutable1.Record.isRecord(R2())).toBe(true); + expect(Immutable2.Record.isRecord(R1())).toBe(true); + }); + + it('converts to JS when inter-nested', () => { + const deep = Immutable1.Map({ + a: 1, + b: 2, + c: Immutable2.Map({ + x: 3, + y: 4, + z: Immutable1.Map(), + }), + }); + + expect(deep.toJS()).toEqual({ + a: 1, + b: 2, + c: { + x: 3, + y: 4, + z: {}, + }, + }); + }); + + it('compares for equality', () => { + const x = Immutable1.Map({ a: 1 }); + const y = Immutable2.Map({ a: 1 }); + expect(Immutable1.is(x, y)).toBe(true); + expect(Immutable2.is(x, y)).toBe(true); + }); + + it('flattens nested values', () => { + const nested = Immutable1.List( + Immutable2.List(Immutable1.List(Immutable2.List.of(1, 2))) + ); + + expect(nested.flatten().toJS()).toEqual([1, 2]); + }); + + it('detects types', () => { + let c1 = Immutable1.Map(); + let c2 = Immutable2.Map(); + expect(Immutable1.Map.isMap(c2)).toBe(true); + expect(Immutable2.Map.isMap(c1)).toBe(true); + + c1 = Immutable1.OrderedMap(); + c2 = Immutable2.OrderedMap(); + expect(Immutable1.OrderedMap.isOrderedMap(c2)).toBe(true); + expect(Immutable2.OrderedMap.isOrderedMap(c1)).toBe(true); + + c1 = Immutable1.List(); + c2 = Immutable2.List(); + expect(Immutable1.List.isList(c2)).toBe(true); + expect(Immutable2.List.isList(c1)).toBe(true); + + c1 = Immutable1.Stack(); + c2 = Immutable2.Stack(); + expect(Immutable1.Stack.isStack(c2)).toBe(true); + expect(Immutable2.Stack.isStack(c1)).toBe(true); + + c1 = Immutable1.Set(); + c2 = Immutable2.Set(); + expect(Immutable1.Set.isSet(c2)).toBe(true); + expect(Immutable2.Set.isSet(c1)).toBe(true); + }); +}); diff --git a/__tests__/ObjectSeq.ts b/__tests__/ObjectSeq.ts new file mode 100644 index 0000000000..2b10807cb5 --- /dev/null +++ b/__tests__/ObjectSeq.ts @@ -0,0 +1,63 @@ +import { describe, expect, it } from '@jest/globals'; +import { Seq } from 'immutable'; + +describe('ObjectSequence', () => { + it('maps', () => { + const i = Seq({ a: 'A', b: 'B', c: 'C' }); + const m = i.map((x) => x + x).toObject(); + expect(m).toEqual({ a: 'AA', b: 'BB', c: 'CC' }); + }); + + it('reduces', () => { + const i = Seq({ a: 'A', b: 'B', c: 'C' }); + const r = i.reduce((acc, x) => acc + x, ''); + expect(r).toEqual('ABC'); + }); + + it('extracts keys', () => { + const i = Seq({ a: 'A', b: 'B', c: 'C' }); + const k = i.keySeq().toArray(); + expect(k).toEqual(['a', 'b', 'c']); + }); + + it('is reversable', () => { + const i = Seq({ a: 'A', b: 'B', c: 'C' }); + const k = i.reverse().toArray(); + expect(k).toEqual([ + ['c', 'C'], + ['b', 'B'], + ['a', 'A'], + ]); + }); + + it('is double reversable', () => { + const i = Seq({ a: 'A', b: 'B', c: 'C' }); + const k = i.reverse().reverse().toArray(); + expect(k).toEqual([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]); + }); + + it('can be iterated', () => { + const obj = { a: 1, b: 2, c: 3 }; + const seq = Seq(obj); + const entries = seq.entries(); + expect(entries.next()).toEqual({ value: ['a', 1], done: false }); + expect(entries.next()).toEqual({ value: ['b', 2], done: false }); + expect(entries.next()).toEqual({ value: ['c', 3], done: false }); + expect(entries.next()).toEqual({ value: undefined, done: true }); + }); + + it('cannot be mutated after calling toObject', () => { + const seq = Seq({ a: 1, b: 2, c: 3 }); + + const obj = seq.toObject(); + obj.c = 10; + const seq2 = Seq(obj); + + expect(seq.get('c')).toEqual(3); + expect(seq2.get('c')).toEqual(10); + }); +}); diff --git a/__tests__/ObjectSequence.ts b/__tests__/ObjectSequence.ts deleted file mode 100644 index f8008d1082..0000000000 --- a/__tests__/ObjectSequence.ts +++ /dev/null @@ -1,50 +0,0 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); - -describe('ObjectSequence', () => { - - it('maps', () => { - var i = Immutable.Sequence({'a': 'A', 'b': 'B', 'c': 'C'}); - var m = i.map(x => x + x).toObject(); - expect(m).toEqual({'a': 'AA', 'b': 'BB', 'c': 'CC'}); - }); - - it('reduces', () => { - var i = Immutable.Sequence({'a': 'A', 'b': 'B', 'c': 'C'}); - var r = i.reduce((r, x) => r + x, ''); - expect(r).toEqual('ABC'); - }); - - it('extracts keys', () => { - var i = Immutable.Sequence({'a': 'A', 'b': 'B', 'c': 'C'}); - var k = i.keySeq().toArray(); - expect(k).toEqual(['a', 'b', 'c']); - }); - - it('is reversable', () => { - var i = Immutable.Sequence({'a': 'A', 'b': 'B', 'c': 'C'}); - var k = i.reverse().toArray(); - expect(k).toEqual(['C', 'B', 'A']); - }); - - it('can double reversable', () => { - var i = Immutable.Sequence({'a': 'A', 'b': 'B', 'c': 'C'}); - var k = i.reverse().reverse().toArray(); - expect(k).toEqual(['A', 'B', 'C']); - }); - - it('can be iterated', () => { - var obj = { a: 1, b: 2, c: 3 }; - var seq = Immutable.Sequence(obj); - var entries = seq.entries(); - expect(entries.next()).toEqual({ value: ['a', 1], done: false }); - expect(entries.next()).toEqual({ value: ['b', 2], done: false }); - expect(entries.next()).toEqual({ value: ['c', 3], done: false }); - expect(entries.next()).toEqual({ value: undefined, done: true }); - }); - -}); diff --git a/__tests__/OrderedMap.ts b/__tests__/OrderedMap.ts index f42a4840e3..9c06a6582e 100644 --- a/__tests__/OrderedMap.ts +++ b/__tests__/OrderedMap.ts @@ -1,84 +1,142 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); -import OrderedMap = Immutable.OrderedMap; +import { describe, expect, it } from '@jest/globals'; +import { OrderedMap, Range, Seq } from 'immutable'; describe('OrderedMap', () => { - it('converts from object', () => { - var m = OrderedMap.from({'c': 'C', 'b': 'B', 'a': 'A'}); + const m = OrderedMap({ c: 'C', b: 'B', a: 'A' }); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); - expect(m.toArray()).toEqual(['C','B','A']); + expect(m.toArray()).toEqual([ + ['c', 'C'], + ['b', 'B'], + ['a', 'A'], + ]); }); it('constructor provides initial values', () => { - var m = OrderedMap({'a': 'A', 'b': 'B', 'c': 'C'}); + const m = OrderedMap({ a: 'A', b: 'B', c: 'C' }); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); - expect(m.length).toBe(3); - expect(m.toArray()).toEqual(['A','B','C']); + expect(m.size).toBe(3); + expect(m.toArray()).toEqual([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]); }); it('provides initial values in a mixed order', () => { - var m = OrderedMap({'c': 'C', 'b': 'B', 'a': 'A'}); + const m = OrderedMap({ c: 'C', b: 'B', a: 'A' }); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); - expect(m.length).toBe(3); - expect(m.toArray()).toEqual(['C','B','A']); + expect(m.size).toBe(3); + expect(m.toArray()).toEqual([ + ['c', 'C'], + ['b', 'B'], + ['a', 'A'], + ]); }); it('constructor accepts sequences', () => { - var s = Immutable.Sequence({'c': 'C', 'b': 'B', 'a': 'A'}); - var m = OrderedMap(s); + const s = Seq({ c: 'C', b: 'B', a: 'A' }); + const m = OrderedMap(s); expect(m.get('a')).toBe('A'); expect(m.get('b')).toBe('B'); expect(m.get('c')).toBe('C'); - expect(m.length).toBe(3); - expect(m.toArray()).toEqual(['C','B','A']); + expect(m.size).toBe(3); + expect(m.toArray()).toEqual([ + ['c', 'C'], + ['b', 'B'], + ['a', 'A'], + ]); }); it('maintains order when new keys are set', () => { - var m = OrderedMap() + const m = OrderedMap() .set('A', 'aardvark') .set('Z', 'zebra') .set('A', 'antelope'); - expect(m.length).toBe(2); - expect(m.toArray()).toEqual(['antelope', 'zebra']); + expect(m.size).toBe(2); + expect(m.toArray()).toEqual([ + ['A', 'antelope'], + ['Z', 'zebra'], + ]); }); it('resets order when a keys is deleted', () => { - var m = OrderedMap() + const m = OrderedMap() .set('A', 'aardvark') .set('Z', 'zebra') .remove('A') .set('A', 'antelope'); - expect(m.length).toBe(2); - expect(m.toArray()).toEqual(['zebra', 'antelope']); + expect(m.size).toBe(2); + expect(m.toArray()).toEqual([ + ['Z', 'zebra'], + ['A', 'antelope'], + ]); + }); + + it('removes correctly', () => { + const m = OrderedMap({ + A: 'aardvark', + Z: 'zebra', + }).remove('A'); + expect(m.size).toBe(1); + expect(m.get('A')).toBe(undefined); + expect(m.get('Z')).toBe('zebra'); }); it('respects order for equality', () => { - var m1 = OrderedMap().set('A', 'aardvark').set('Z', 'zebra'); - var m2 = OrderedMap().set('Z', 'zebra').set('A', 'aardvark'); + const m1 = OrderedMap().set('A', 'aardvark').set('Z', 'zebra'); + const m2 = OrderedMap().set('Z', 'zebra').set('A', 'aardvark'); expect(m1.equals(m2)).toBe(false); expect(m1.equals(m2.reverse())).toBe(true); }); it('respects order when merging', () => { - var m1 = OrderedMap({A: 'apple', B: 'banana', C: 'coconut'}); - var m2 = OrderedMap({C: 'chocolate', B: 'butter', D: 'donut'}); - expect(m1.merge(m2).entrySeq().toArray()).toEqual( - [['A','apple'],['B','butter'],['C','chocolate'],['D','donut']] - ); - expect(m2.merge(m1).entrySeq().toArray()).toEqual( - [['C','coconut'],['B','banana'],['D','donut'],['A','apple']] - ); + const m1 = OrderedMap({ A: 'apple', B: 'banana', C: 'coconut' }); + const m2 = OrderedMap({ C: 'chocolate', B: 'butter', D: 'donut' }); + expect(m1.merge(m2).entrySeq().toArray()).toEqual([ + ['A', 'apple'], + ['B', 'butter'], + ['C', 'chocolate'], + ['D', 'donut'], + ]); + expect(m2.merge(m1).entrySeq().toArray()).toEqual([ + ['C', 'coconut'], + ['B', 'banana'], + ['D', 'donut'], + ['A', 'apple'], + ]); }); + it('performs deleteAll correctly after resizing internal list', () => { + // See condition for resizing internal list here: + // https://github.com/immutable-js/immutable-js/blob/91c7c1e82ec616804768f968cc585565e855c8fd/src/OrderedMap.js#L138 + + // Create OrderedMap greater than or equal to SIZE (currently 32) + const SIZE = 32; + let map = OrderedMap(Range(0, SIZE).map((key) => [key, 0])); + + // Delete half of the keys so that internal list is twice the size of internal map + const keysToDelete = Range(0, SIZE / 2); + map = map.deleteAll(keysToDelete); + + // Delete one more key to trigger resizing + map = map.deleteAll([SIZE / 2]); + + expect(map.size).toBe(SIZE / 2 - 1); + }); + + it('hashCode should return the same value if the values are the same', () => { + const m1 = OrderedMap({ b: 'b' }); + const m2 = OrderedMap({ a: 'a', b: 'b' }).remove('a'); + const m3 = OrderedMap({ b: 'b' }).remove('b').set('b', 'b'); + + expect(m1.hashCode()).toEqual(m2.hashCode()); + expect(m1.hashCode()).toEqual(m3.hashCode()); + }); }); diff --git a/__tests__/OrderedSet.ts b/__tests__/OrderedSet.ts new file mode 100644 index 0000000000..12c958072d --- /dev/null +++ b/__tests__/OrderedSet.ts @@ -0,0 +1,153 @@ +import { describe, expect, it } from '@jest/globals'; +import { OrderedSet, Map } from 'immutable'; + +describe('OrderedSet', () => { + it('provides initial values in a mixed order', () => { + const s = OrderedSet.of('C', 'B', 'A'); + expect(s.has('A')).toBe(true); + expect(s.has('B')).toBe(true); + expect(s.has('C')).toBe(true); + expect(s.size).toBe(3); + expect(s.toArray()).toEqual(['C', 'B', 'A']); + }); + + it('maintains order when new values are added', () => { + const s = OrderedSet().add('A').add('Z').add('A'); + expect(s.size).toBe(2); + expect(s.toArray()).toEqual(['A', 'Z']); + }); + + it('resets order when a value is deleted', () => { + const s = OrderedSet().add('A').add('Z').remove('A').add('A'); + expect(s.size).toBe(2); + expect(s.toArray()).toEqual(['Z', 'A']); + }); + + it('removes correctly', () => { + const s = OrderedSet(['A', 'Z']).remove('A'); + expect(s.size).toBe(1); + expect(s.has('A')).toBe(false); + expect(s.has('Z')).toBe(true); + }); + + it('respects order for equality', () => { + const s1 = OrderedSet.of('A', 'Z'); + const s2 = OrderedSet.of('Z', 'A'); + expect(s1.equals(s2)).toBe(false); + expect(s1.equals(s2.reverse())).toBe(true); + }); + + it('respects order when unioning', () => { + const s1 = OrderedSet.of('A', 'B', 'C'); + const s2 = OrderedSet.of('C', 'B', 'D'); + expect(s1.union(s2).toArray()).toEqual(['A', 'B', 'C', 'D']); + expect(s2.union(s1).toArray()).toEqual(['C', 'B', 'D', 'A']); + }); + + it('can be zipped', () => { + const s1 = OrderedSet.of('A', 'B', 'C'); + const s2 = OrderedSet.of('C', 'B', 'D'); + expect(s1.zip(s2).toArray()).toEqual([ + ['A', 'C'], + ['B', 'B'], + ['C', 'D'], + ]); + expect(s1.zipWith((c1, c2) => c1 + c2, s2).toArray()).toEqual([ + 'AC', + 'BB', + 'CD', + ]); + }); + + /** + * @see https://github.com/immutable-js/immutable-js/issues/1716 + */ + it('handles `subtract` when Set contains >=32 elements', () => { + const fillArray = (nb) => + Array(nb) + .fill(1) + .map((el, i) => i + 1); + + const capacity = 32; + // items from keys 0 to 31 and values 1 to 32 + const defaultItems = fillArray(capacity); + + const allItems = OrderedSet(defaultItems); + + const partialCapacity = Math.ceil(capacity / 2) + 1; + const someOfThem = fillArray(partialCapacity); + expect(someOfThem.length).toBe(17); + + const existingItems = OrderedSet(someOfThem).intersect(allItems); + + expect(allItems.subtract(existingItems).size).toBe(15); + expect(allItems.subtract(existingItems).size + someOfThem.length).toBe(32); + }); + + /** + * @see https://github.com/immutable-js/immutable-js/issues/1603 + */ + it('handles consecutive `subtract` invocations', () => { + let a = OrderedSet(); + let b = OrderedSet(); + let c; + let d; + // Set a to 0-45 + for (let i = 0; i < 46; i++) { + a = a.add(i); + } + // Set b to 0-24 + for (let i = 0; i < 25; i++) { + b = b.add(i); + } + // Set c to 0-23 + // eslint-disable-next-line prefer-const + c = b.butLast(); + + // Set d to 0-22 + // eslint-disable-next-line prefer-const + d = c.butLast(); + + // Internal list resizing happens on the final `subtract` when subtracting d from a + const aNotB = a.subtract(b); + const aNotC = a.subtract(c); + const aNotD = a.subtract(d); + + expect(aNotB.size).toBe(21); + expect(aNotC.size).toBe(22); + expect(aNotD.size).toBe(23); + }); + + it('keeps the Set ordered when updating a value with .map()', () => { + const first = Map({ id: 1, valid: true }); + const second = Map({ id: 2, valid: true }); + const third = Map({ id: 3, valid: true }); + const initial = OrderedSet([first, second, third]); + + const out = initial.map((t) => { + if (t.get('id') === 2) { + return t.set('valid', false); + } + return t; + }); + + const expected = OrderedSet([ + Map({ id: 1, valid: true }), + Map({ id: 2, valid: false }), + Map({ id: 3, valid: true }), + ]); + + expect(out).toEqual(expected); + + expect(out.has(first)).toBe(true); + expect(out.has(second)).toBe(false); + expect(out.has(third)).toBe(true); + }); + + it('hashCode should return the same value if the values are the same', () => { + const set1 = OrderedSet(['hello']); + const set2 = OrderedSet(['goodbye', 'hello']).remove('goodbye'); + + expect(set1.hashCode()).toBe(set2.hashCode()); + }); +}); diff --git a/__tests__/Predicates.ts b/__tests__/Predicates.ts new file mode 100644 index 0000000000..0ab282205b --- /dev/null +++ b/__tests__/Predicates.ts @@ -0,0 +1,61 @@ +import { describe, expect, it } from '@jest/globals'; +import { + is, + isImmutable, + isValueObject, + List, + Map, + Set, + Stack, +} from 'immutable'; + +describe('isImmutable', () => { + it('behaves as advertised', () => { + expect(isImmutable([])).toBe(false); + expect(isImmutable({})).toBe(false); + expect(isImmutable(Map())).toBe(true); + expect(isImmutable(List())).toBe(true); + expect(isImmutable(Set())).toBe(true); + expect(isImmutable(Stack())).toBe(true); + expect(isImmutable(Map().asMutable())).toBe(true); + }); +}); + +describe('isValueObject', () => { + it('behaves as advertised', () => { + expect(isValueObject(null)).toBe(false); + expect(isValueObject(123)).toBe(false); + expect(isValueObject('abc')).toBe(false); + expect(isValueObject([])).toBe(false); + expect(isValueObject({})).toBe(false); + expect(isValueObject(Map())).toBe(true); + expect(isValueObject(List())).toBe(true); + expect(isValueObject(Set())).toBe(true); + expect(isValueObject(Stack())).toBe(true); + expect(isValueObject(Map().asMutable())).toBe(true); + }); + + it('works on custom types', () => { + class MyValueType { + v: number; + + constructor(val: number) { + this.v = val; + } + + equals(other) { + return Boolean(other && this.v === other.v); + } + + hashCode() { + return this.v; + } + } + + expect(isValueObject(new MyValueType(123))).toBe(true); + expect(is(new MyValueType(123), new MyValueType(123))).toBe(true); + expect(Set().add(new MyValueType(123)).add(new MyValueType(123)).size).toBe( + 1 + ); + }); +}); diff --git a/__tests__/Range.ts b/__tests__/Range.ts index 76fe59b1e6..94c096d1a8 100644 --- a/__tests__/Range.ts +++ b/__tests__/Range.ts @@ -1,60 +1,69 @@ -/// -/// - -jest.autoMockOff(); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); - -import Immutable = require('immutable'); -import Range = Immutable.Range; +import { describe, expect, it } from '@jest/globals'; +import { Range } from 'immutable'; +import fc from 'fast-check'; describe('Range', () => { - it('fixed range', () => { - var v = Range(0, 3); - expect(v.length).toBe(3); + const v = Range(0, 3); + expect(v.size).toBe(3); expect(v.first()).toBe(0); - expect(v.rest().toArray()).toEqual([1,2]); + expect(v.rest().toArray()).toEqual([1, 2]); expect(v.last()).toBe(2); - expect(v.butLast().toArray()).toEqual([0,1]); - expect(v.toArray()).toEqual([0,1,2]); + expect(v.butLast().toArray()).toEqual([0, 1]); + expect(v.toArray()).toEqual([0, 1, 2]); }); it('stepped range', () => { - var v = Range(1, 10, 3); - expect(v.length).toBe(3); + const v = Range(1, 10, 3); + expect(v.size).toBe(3); expect(v.first()).toBe(1); - expect(v.rest().toArray()).toEqual([4,7]); + expect(v.rest().toArray()).toEqual([4, 7]); expect(v.last()).toBe(7); - expect(v.butLast().toArray()).toEqual([1,4]); - expect(v.toArray()).toEqual([1,4,7]); + expect(v.butLast().toArray()).toEqual([1, 4]); + expect(v.toArray()).toEqual([1, 4, 7]); + }); + + it('range should contain start and end values', () => { + // @ts-expect-error -- test that runtime error is thrown + expect(() => Range()).toThrow( + 'You must define a start value when using Range' + ); + // @ts-expect-error -- test that runtime error is thrown + expect(() => Range(1)).toThrow( + 'You must define an end value when using Range' + ); }); it('open range', () => { - var v = Range(10); - expect(v.length).toBe(Infinity); + const v = Range(10, Infinity); + expect(v.size).toBe(Infinity); expect(v.first()).toBe(10); expect(v.rest().first()).toBe(11); expect(v.last()).toBe(Infinity); expect(v.butLast().first()).toBe(10); expect(v.butLast().last()).toBe(Infinity); - expect(() => v.rest().toArray()).toThrow('Cannot perform this action with an infinite sequence.'); - expect(() => v.butLast().toArray()).toThrow('Cannot perform this action with an infinite sequence.'); - expect(() => v.toArray()).toThrow('Cannot perform this action with an infinite sequence.'); + expect(() => v.rest().toArray()).toThrow( + 'Cannot perform this action with an infinite size.' + ); + expect(() => v.butLast().toArray()).toThrow( + 'Cannot perform this action with an infinite size.' + ); + expect(() => v.toArray()).toThrow( + 'Cannot perform this action with an infinite size.' + ); }); it('backwards range', () => { - var v = Range(10, 1, 3); - expect(v.length).toBe(3); + const v = Range(10, 1, 3); + expect(v.size).toBe(3); expect(v.first()).toBe(10); expect(v.last()).toBe(4); - expect(v.toArray()).toEqual([10,7,4]); + expect(v.toArray()).toEqual([10, 7, 4]); }); it('empty range', () => { - var v = Range(10, 10); - expect(v.length).toBe(0); + const v = Range(10, 10); + expect(v.size).toBe(0); expect(v.first()).toBe(undefined); expect(v.rest().toArray()).toEqual([]); expect(v.last()).toBe(undefined); @@ -62,119 +71,162 @@ describe('Range', () => { expect(v.toArray()).toEqual([]); }); - check.it('includes first, excludes last', [gen.int, gen.int], function (from, to) { - var isIncreasing = to >= from; - var length = isIncreasing ? to - from : from - to; - var r = Range(from, to); - var a = r.toArray(); - expect(r.length).toBe(length); - expect(a.length).toBe(length); - expect(r.get(0)).toBe(length ? from : undefined); - expect(a[0]).toBe(length ? from : undefined); - var last = to + (isIncreasing ? -1 : 1); - expect(r.last()).toBe(length ? last : undefined); - if (length) { - expect(a[a.length - 1]).toBe(last); - } - }); - - var shrinkInt = gen.shrink(gen.int); - - check.it('slices the same as array slices', - [shrinkInt, shrinkInt, shrinkInt, shrinkInt], - function (from, to, begin, end) { - var r = Range(from, to); - var a = r.toArray(); - expect(r.slice(begin, end).toArray()).toEqual(a.slice(begin, end)); - } - ); + const shrinkInt = fc.integer({ min: -1000, max: 1000 }); + + it('includes first, excludes last', () => { + fc.assert( + fc.property(shrinkInt, shrinkInt, (from, to) => { + const isIncreasing = to >= from; + const size = isIncreasing ? to - from : from - to; + const r = Range(from, to); + const a = r.toArray(); + expect(r.size).toBe(size); + expect(a.length).toBe(size); + expect(r.get(0)).toBe(size ? from : undefined); + expect(a[0]).toBe(size ? from : undefined); + const last = to + (isIncreasing ? -1 : 1); + expect(r.last()).toBe(size ? last : undefined); + if (size) { + // eslint-disable-next-line jest/no-conditional-expect + expect(a[a.length - 1]).toBe(last); + } + }) + ); + }); + + it('slices the same as array slices', () => { + fc.assert( + fc.property( + shrinkInt, + shrinkInt, + shrinkInt, + shrinkInt, + (from, to, begin, end) => { + const r = Range(from, to); + const a = r.toArray(); + expect(r.slice(begin, end).toArray()).toEqual(a.slice(begin, end)); + } + ) + ); + }); it('slices range', () => { - var v = Range(1, 11, 2); - var s = v.slice(1, -2); - expect(s.length).toBe(2); - expect(s.toArray()).toEqual([3,5]); + const v = Range(1, 11, 2); + const s = v.slice(1, -2); + expect(s.size).toBe(2); + expect(s.toArray()).toEqual([3, 5]); }); it('empty slice of range', () => { - var v = Range(1, 11, 2); - var s = v.slice(100, 200); - expect(s.length).toBe(0); + const v = Range(1, 11, 2); + const s = v.slice(100, 200); + expect(s.size).toBe(0); expect(s.toArray()).toEqual([]); }); it('slices empty range', () => { - var v = Range(10, 10); - var s = v.slice(1, -2); - expect(s.length).toBe(0); + const v = Range(10, 10); + const s = v.slice(1, -2); + expect(s.size).toBe(0); expect(s.toArray()).toEqual([]); }); it('stepped range does not land on end', () => { - var v = Range(0, 7, 2); - expect(v.length).toBe(4); - expect(v.toArray()).toEqual([0,2,4,6]); + const v = Range(0, 7, 2); + expect(v.size).toBe(4); + expect(v.toArray()).toEqual([0, 2, 4, 6]); }); it('can be float', () => { - var v = Range(0.5, 2.5, 0.5); - expect(v.length).toBe(4); + const v = Range(0.5, 2.5, 0.5); + expect(v.size).toBe(4); expect(v.toArray()).toEqual([0.5, 1, 1.5, 2]); }); it('can be negative', () => { - var v = Range(10, -10, 5); - expect(v.length).toBe(4); - expect(v.toArray()).toEqual([10,5,0,-5]); + const v = Range(10, -10, 5); + expect(v.size).toBe(4); + expect(v.toArray()).toEqual([10, 5, 0, -5]); }); it('can get from any index in O(1)', () => { - var v = Range(0, Infinity, 8); + const v = Range(0, Infinity, 8); expect(v.get(111)).toBe(888); }); it('can find an index in O(1)', () => { - var v = Range(0, Infinity, 8); + const v = Range(0, Infinity, 8); expect(v.indexOf(888)).toBe(111); }); it('maps values', () => { - var r = Range(0, 4).map(v => v * v); - expect(r.toArray()).toEqual([0,1,4,9]); + const r = Range(0, 4).map((v) => v * v); + expect(r.toArray()).toEqual([0, 1, 4, 9]); }); it('filters values', () => { - var r = Range(0, 10).filter(v => v % 2 == 0); - expect(r.toArray()).toEqual([0,2,4,6,8]); + const r = Range(0, 10).filter((v) => v % 2 === 0); + expect(r.toArray()).toEqual([0, 2, 4, 6, 8]); }); - it('reduces values', () => { - var v = Range(0, 10, 2); - - var r = v.reduce((a, b) => a + b, 0); + it('partitions values', () => { + const r = Range(0, 10) + .partition((v) => v % 2 === 0) + .map((part) => part.toArray()); + expect(r).toEqual([ + [1, 3, 5, 7, 9], + [0, 2, 4, 6, 8], + ]); + }); + it('reduces values', () => { + const v = Range(0, 10, 2); + const r = v.reduce((a, b) => a + b, 0); expect(r).toEqual(20); }); it('takes and skips values', () => { - var v = Range(0, 100, 3) - - var r = v.skip(2).take(2); - + const v = Range(0, 100, 3); + const r = v.skip(2).take(2); expect(r.toArray()).toEqual([6, 9]); }); - it('efficiently chains array methods', () => { - var v = Range(1, Infinity); + it('can describe lazy operations', () => { + expect( + Range(1, Infinity) + .map((n) => -n) + .take(5) + .toArray() + ).toEqual([-1, -2, -3, -4, -5]); + }); - var r = v - .filter(x => x % 2 == 0) + it('efficiently chains array methods', () => { + const v = Range(1, Infinity); + const r = v + .filter((x) => x % 2 === 0) .skip(2) - .map(x => x * x) + .map((x) => x * x) .take(3) .reduce((a, b) => a + b, 0); expect(r).toEqual(200); }); + it('sliced sequence works even on filtered sequence', () => { + expect(Range(0, 3).slice(-2).toArray()).toEqual([1, 2]); + + expect( + Range(0, 3) + .filter(() => true) + .slice(-2) + .toArray() + ).toEqual([1, 2]); + }); + + it('toString', () => { + expect(Range(0, 0).toString()).toBe('Range []'); + expect(Range(0, 3).toString()).toBe('Range [ 0...3 ]'); + expect(Range(0, 10, 2).toString()).toBe('Range [ 0...10 by 2 ]'); + expect(Range(10, 0, -2).toString()).toBe('Range [ 10...0 by -2 ]'); + }); }); diff --git a/__tests__/Record.ts b/__tests__/Record.ts index 94c71af226..3839b6c46b 100644 --- a/__tests__/Record.ts +++ b/__tests__/Record.ts @@ -1,64 +1,319 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); -import Record = Immutable.Record; +import { describe, expect, it } from '@jest/globals'; +import { isKeyed, List, Map, Record, Seq } from 'immutable'; describe('Record', () => { - it('defines a constructor', () => { - var MyType = Record({a:1, b:2, c:3}); + const MyType = Record({ a: 1, b: 2, c: 3 }); - var t1 = new MyType(); - var t2 = t1.set('a', 10); - var t3 = t2.clear(); + const t1 = MyType(); + const t2 = t1.set('a', 10); - expect(t1 instanceof Record); - expect(t1 instanceof MyType); + expect(t1 instanceof Record).toBe(true); + expect(t1 instanceof MyType).toBe(true); - expect(t3 instanceof Record); - expect(t3 instanceof MyType); + expect(t2 instanceof Record).toBe(true); + expect(t2 instanceof MyType).toBe(true); expect(t1.get('a')).toBe(1); expect(t2.get('a')).toBe(10); + }); + + it('allows for a descriptive name', () => { + const Person = Record({ name: null as string | null }, 'Person'); + + const me = Person({ name: 'My Name' }); + expect(me.toString()).toEqual('Person { name: "My Name" }'); + expect(Record.getDescriptiveName(me)).toEqual('Person'); + expect(Person.displayName).toBe('Person'); + }); + + it('passes through records of the same type', () => { + const P2 = Record({ x: 0, y: 0 }); + const P3 = Record({ x: 0, y: 0, z: 0 }); + const p2 = P2(); + const p3 = P3(); + expect(P3(p2) instanceof P3).toBe(true); + expect(P2(p3) instanceof P2).toBe(true); + expect(P2(p2)).toBe(p2); + expect(P3(p3)).toBe(p3); + }); - expect(t1.length).toBe(3); - expect(t2.length).toBe(3); - }) + it('setting an unknown key is a no-op', () => { + const MyType = Record({ a: 1, b: 2, c: 3 }); - it('only persists values it knows about', () => { - var MyType = Record({a:1, b:2, c:3}); + const t1 = MyType({ a: 10, b: 20 }); + // @ts-expect-error -- try to force an unknown value + const t2 = t1.set('d', 4); - var t1 = new MyType({a: 10, b:20}); - var t2 = t1.set('d', 4); - var t3 = t2.remove('a'); - var t4 = t3.clear(); + expect(t2).toBe(t1); + }); - expect(t1.length).toBe(3); - expect(t2.length).toBe(3); - expect(t3.length).toBe(3); - expect(t4.length).toBe(3); + it('falls back to default values when deleted or cleared', () => { + const MyType = Record({ a: 1, b: 2, c: 3 }); + const t1 = MyType({ a: 10, b: 20 }); + const t2 = MyType({ b: 20 }); + const t3 = t1.delete('a'); + const t4 = t3.clear(); expect(t1.get('a')).toBe(10); - expect(t2.get('d')).toBe(undefined); + expect(t2.get('a')).toBe(1); expect(t3.get('a')).toBe(1); expect(t4.get('b')).toBe(2); - }) + + expect(t2.equals(t3)).toBe(true); + expect(t2.equals(t4)).toBe(false); + expect(t4.equals(MyType())).toBe(true); + }); + + it('allows deletion of values deep within a tree', () => { + const AType = Record({ a: 1 }); + const BType = Record({ b: AType({ a: 2 }) }); + const t1 = BType(); + const t2 = t1.deleteIn(['b', 'a']); + + expect(t1.get('b').get('a')).toBe(2); + expect(t2.get('b').get('a')).toBe(1); + }); + + it('is a value type and equals other similar Records', () => { + const MyType = Record({ a: 1, b: 2, c: 3 }); + const t1 = MyType({ a: 10 }); + const t2 = MyType({ a: 10, b: 2 }); + expect(t1.equals(t2)).toBe(true); + }); + + it('if compared against undefined or null should return false', () => { + const MyType = Record({ a: 1, b: 2 }); + const t1 = MyType(); + expect(t1.equals(undefined)).toBeFalsy(); + expect(t1.equals(null)).toBeFalsy(); + }); + + it('if compared against Map should return false', () => { + const MyType = Record({ a: 1, b: 2 }); + const t1 = MyType(); + expect(t1.equals(Map({ a: 1, b: 2 }))).toBeFalsy(); + }); + + it('merges in Objects and other Records', () => { + const Point2 = Record({ x: 0, y: 0 }); + const Point3 = Record({ x: 0, y: 0, z: 0 }); + + const p2 = Point2({ x: 20, y: 20 }); + const p3 = Point3({ x: 10, y: 10, z: 10 }); + + expect(p3.merge(p2).toObject()).toEqual({ x: 20, y: 20, z: 10 }); + + expect(p2.merge({ y: 30 }).toObject()).toEqual({ x: 20, y: 30 }); + expect(p3.merge({ y: 30, z: 30 }).toObject()).toEqual({ + x: 10, + y: 30, + z: 30, + }); + }); it('converts sequences to records', () => { - var MyType = Record({a:1, b:2, c:3}); - var seq = Immutable.Sequence({a: 10, b:20}); - var t = new MyType(seq); - expect(t.toObject()).toEqual({a:10, b:20, c:3}) - }) + const MyType = Record({ a: 1, b: 2, c: 3 }); + const seq = Seq({ a: 10, b: 20 }); + const t = MyType(seq); + expect(t.toObject()).toEqual({ a: 10, b: 20, c: 3 }); + }); it('allows for functional construction', () => { - var MyType = Record({a:1, b:2, c:3}); - var seq = Immutable.Sequence({a: 10, b:20}); - var t = MyType(seq); - expect(t.toObject()).toEqual({a:10, b:20, c:3}) - }) + const MyType = Record({ a: 1, b: 2, c: 3 }); + const seq = Seq({ a: 10, b: 20 }); + const t = MyType(seq); + expect(t.toObject()).toEqual({ a: 10, b: 20, c: 3 }); + }); + + it('skips unknown keys', () => { + const MyType = Record({ a: 1, b: 2 }); + const seq = Seq({ b: 20, c: 30 }); + const t = MyType(seq); + + expect(t.get('a')).toEqual(1); + expect(t.get('b')).toEqual(20); + // @ts-expect-error -- unknown key should not return anything + expect(t.get('c')).toBeUndefined(); + }); + + it('returns itself when setting identical values', () => { + const MyType = Record({ a: 1, b: 2 }); + const t1 = MyType(); + const t2 = MyType({ a: 1 }); + const t3 = t1.set('a', 1); + const t4 = t2.set('a', 1); + expect(t3).toBe(t1); + expect(t4).toBe(t2); + }); + + it('returns record when setting values', () => { + const MyType = Record({ a: 1, b: 2 }); + const t1 = MyType(); + const t2 = MyType({ a: 1 }); + const t3 = t1.set('a', 3); + const t4 = t2.set('a', 3); + expect(t3).not.toBe(t1); + expect(t4).not.toBe(t2); + }); + + it('allows for readonly property access', () => { + const MyType = Record({ a: 1, b: 'foo' }); + const t1 = MyType(); + const a: number = t1.a; + const b: string = t1.b; + expect(a).toEqual(1); + expect(b).toEqual('foo'); + // @ts-expect-error -- test that runtime does throw + expect(() => (t1.a = 2)).toThrow('Cannot set on an immutable record.'); + }); + + it('allows for class extension', () => { + class ABClass extends Record({ a: 1, b: 2 }) { + setA(aVal: number) { + return this.set('a', aVal); + } + + setB(bVal: number) { + return this.set('b', bVal); + } + } + + // Note: `new` is only used because of `class` + const t1 = new ABClass({ a: 1 }); + const t2 = t1.setA(3); + const t3 = t2.setB(10); + + const a: number = t3.a; + expect(a).toEqual(3); + expect(t3.toObject()).toEqual({ a: 3, b: 10 }); + }); + + it('does not allow overwriting property names', () => { + const realWarn = console.warn; + + try { + const warnings: Array = []; + + console.warn = (w) => warnings.push(w); + + // size is a safe key to use + const MyType1 = Record({ size: 123 }); + const t1 = MyType1(); + expect(warnings.length).toBe(0); + expect(t1.size).toBe(123); + + // get() is not safe to use + const MyType2 = Record({ get: 0 }); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const t2 = MyType2(); + expect(warnings.length).toBe(1); + expect(warnings[0]).toBe( + 'Cannot define Record with property "get" since that property name is part of the Record API.' + ); + } finally { + console.warn = realWarn; + } + }); + + it('can be converted to a keyed sequence', () => { + const MyType = Record({ a: 0, b: 0 }); + const t1 = MyType({ a: 10, b: 20 }); + + const seq1 = t1.toSeq(); + expect(isKeyed(seq1)).toBe(true); + expect(seq1.toJS()).toEqual({ a: 10, b: 20 }); + + const seq2 = Seq(t1); + expect(isKeyed(seq2)).toBe(true); + expect(seq2.toJS()).toEqual({ a: 10, b: 20 }); + + const seq3 = Seq.Keyed(t1); + expect(isKeyed(seq3)).toBe(true); + expect(seq3.toJS()).toEqual({ a: 10, b: 20 }); + + const seq4 = Seq.Indexed(t1); + expect(isKeyed(seq4)).toBe(false); + expect(seq4.toJS()).toEqual([ + ['a', 10], + ['b', 20], + ]); + }); + + it('can be iterated over', () => { + const MyType = Record({ a: 0, b: 0 }); + const t1 = MyType({ a: 10, b: 20 }); + + const entries: Array<[string, number]> = []; + for (const entry of t1) { + entries.push(entry); + } + + expect(entries).toEqual([ + ['a', 10], + ['b', 20], + ]); + }); + + it('calling `equals` between two instance of factories with same properties and same value should return true', () => { + const factoryA = Record({ id: '' }); + const factoryB = Record({ id: '' }); + + expect(factoryA().equals(factoryA())).toBe(true); + expect(factoryA().equals(factoryB())).toBe(true); + }); + + /** + * @see https://github.com/immutable-js/immutable-js/issues/1565 + */ + it('check that reset does reset the record.', () => { + type UserType = { + name: string; + roles: List | Array; + }; + + const User = Record({ + name: 'default name', + roles: List(), + }); + + const user0 = new User({ + name: 'John', + roles: ['superuser', 'admin'], + }); + const user1 = user0.clear(); + + expect(user1.name).toBe('default name'); + expect(user1.roles).toEqual(List()); + + const user2 = user0.withMutations((mutable: Record) => { + mutable.clear(); + }); + + expect(user2.name).toBe('default name'); + expect(user2.roles).toEqual(List()); + }); + + it('does not accept a Record as constructor', () => { + const Foo = Record({ foo: 'bar' }); + const fooInstance = Foo(); + expect(() => { + Record(fooInstance); + }).toThrowErrorMatchingSnapshot(); + }); + + it('does not accept a non object as constructor', () => { + const defaultValues = null; + expect(() => { + // @ts-expect-error -- test that runtime does throw + Record(defaultValues); + }).toThrowErrorMatchingSnapshot(); + }); + it('does not accept an immutable object that is not a Record as constructor', () => { + const defaultValues = Map({ foo: 'bar' }); + expect(() => { + Record(defaultValues); + }).toThrowErrorMatchingSnapshot(); + }); }); diff --git a/__tests__/RecordJS.js b/__tests__/RecordJS.js index a3ecdec8e8..3ae53fb878 100644 --- a/__tests__/RecordJS.js +++ b/__tests__/RecordJS.js @@ -1,28 +1,27 @@ -jest.autoMockOff(); - -var Immutable = require('immutable'); -var Record = Immutable.Record; +import { describe, expect, it } from '@jest/globals'; +import { Record } from 'immutable'; describe('Record', () => { + it('defines a record factory', () => { + const MyType = Record({ a: 1, b: 2, c: 3 }); - it('defines a constructor', () => { - var MyType = Record({a:1, b:2, c:3}); - - var t = new MyType(); - var t2 = t.set('a', 10); + const t = MyType(); + const t2 = t.set('a', 10); expect(t.a).toBe(1); expect(t2.a).toBe(10); }); it('can have mutations apply', () => { - var MyType = Record({a:1, b:2, c:3}); + const MyType = Record({ a: 1, b: 2, c: 3 }); - var t = new MyType(); + const t = MyType(); - expect(() => { t.a = 10; }).toThrow(); + expect(() => { + t.a = 10; + }).toThrow(); - var t2 = t.withMutations(mt => { + const t2 = t.withMutations((mt) => { mt.a = 10; mt.b = 20; mt.c = 30; @@ -33,20 +32,43 @@ describe('Record', () => { }); it('can be subclassed', () => { - - class Alphabet extends Record({a:1, b:2, c:3}) { + class Alphabet extends Record({ a: 1, b: 2, c: 3 }) { soup() { return this.a + this.b + this.c; } } - var t = new Alphabet(); - var t2 = t.set('b', 200); + // Note: `new` is only used because of `class` + const t = new Alphabet(); + const t2 = t.set('b', 200); - expect(t instanceof Record); - expect(t instanceof Alphabet); + expect(t instanceof Record).toBe(true); + expect(t instanceof Alphabet).toBe(true); expect(t.soup()).toBe(6); expect(t2.soup()).toBe(204); + + // Uses class name as descriptive name + expect(Record.getDescriptiveName(t)).toBe('Alphabet'); + + // Uses display name over class name + class NotADisplayName extends Record({ x: 1 }, 'DisplayName') {} + const t3 = new NotADisplayName(); + expect(Record.getDescriptiveName(t3)).toBe('DisplayName'); }); + it('can be cleared', () => { + const MyType = Record({ a: 1, b: 2, c: 3 }); + let t = MyType({ c: 'cats' }); + + expect(t.c).toBe('cats'); + t = t.clear(); + expect(t.c).toBe(3); + + const MyType2 = Record({ d: 4, e: 5, f: 6 }); + let t2 = MyType2({ d: 'dogs' }); + + expect(t2.d).toBe('dogs'); + t2 = t2.clear(); + expect(t2.d).toBe(4); + }); }); diff --git a/__tests__/Repeat.ts b/__tests__/Repeat.ts index 913ec54c41..1553232ba5 100644 --- a/__tests__/Repeat.ts +++ b/__tests__/Repeat.ts @@ -1,22 +1,19 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); -import Repeat = Immutable.Repeat; +import { describe, expect, it } from '@jest/globals'; +import { Repeat } from 'immutable'; describe('Repeat', () => { - it('fixed repeat', () => { - var v = Repeat('wtf', 3); - expect(v.length).toBe(3); + const v = Repeat('wtf', 3); + expect(v.size).toBe(3); expect(v.first()).toBe('wtf'); - expect(v.rest().toArray()).toEqual(['wtf','wtf']); + expect(v.rest().toArray()).toEqual(['wtf', 'wtf']); expect(v.last()).toBe('wtf'); - expect(v.butLast().toArray()).toEqual(['wtf','wtf']); - expect(v.toArray()).toEqual(['wtf','wtf','wtf']); + expect(v.butLast().toArray()).toEqual(['wtf', 'wtf']); + expect(v.toArray()).toEqual(['wtf', 'wtf', 'wtf']); expect(v.join()).toEqual('wtf,wtf,wtf'); }); + it('does not claim to be equal to undefined', () => { + expect(Repeat(1).equals(undefined)).toEqual(false); + }); }); diff --git a/__tests__/Seq.ts b/__tests__/Seq.ts new file mode 100644 index 0000000000..cbb048eb8b --- /dev/null +++ b/__tests__/Seq.ts @@ -0,0 +1,142 @@ +import { describe, expect, it } from '@jest/globals'; +import { isCollection, isIndexed, isKeyed, Seq } from 'immutable'; + +describe('Seq', () => { + it('returns undefined if empty and first is called without default argument', () => { + expect(Seq().first()).toBeUndefined(); + }); + + it('returns undefined if empty and last is called without default argument', () => { + expect(Seq().last()).toBeUndefined(); + }); + + it('returns default value if empty and first is called with default argument', () => { + expect(Seq().first({})).toEqual({}); + }); + + it('returns default value if empty and last is called with default argument', () => { + expect(Seq().last({})).toEqual({}); + }); + + it('can be empty', () => { + expect(Seq().size).toBe(0); + }); + + it('accepts an array', () => { + expect(Seq([1, 2, 3]).size).toBe(3); + }); + + it('accepts an object', () => { + expect(Seq({ a: 1, b: 2, c: 3 }).size).toBe(3); + }); + + it('accepts an object with a next property', () => { + expect(Seq({ a: 1, b: 2, next: (_) => _ }).size).toBe(3); + }); + + it('accepts a collection string', () => { + expect(Seq('foo').size).toBe(3); + }); + + it('accepts arbitrary objects', () => { + function Foo() { + this.bar = 'bar'; + this.baz = 'baz'; + } + expect(Seq(new Foo()).size).toBe(2); + }); + + it('accepts another sequence', () => { + const seq = Seq([1, 2, 3]); + expect(Seq(seq).size).toBe(3); + }); + + it('accepts a string', () => { + const seq = Seq('abc'); + expect(seq.size).toBe(3); + expect(seq.get(1)).toBe('b'); + expect(seq.join('')).toBe('abc'); + }); + + it('accepts an array-like', () => { + const seq = Seq({ length: 2, 0: 'a', 1: 'b' }); + expect(isIndexed(seq)).toBe(true); + expect(seq.size).toBe(2); + expect(seq.get(1)).toBe('b'); + + const map = Seq({ length: 1, foo: 'bar' }); + expect(isIndexed(map)).toBe(false); + expect(map.size).toBe(2); + expect(map.get('foo')).toBe('bar'); + + const empty = Seq({ length: 0 }); + expect(isIndexed(empty)).toBe(true); + expect(empty.size).toEqual(0); + }); + + it('accepts a JS (global) Map', () => { + const seq = Seq( + new global.Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]) + ); + expect(isKeyed(seq)).toBe(true); + expect(seq.size).toBe(3); + }); + + it('accepts a JS (global) Set', () => { + const seq = Seq(new global.Set(['a', 'b', 'c'])); + expect(isIndexed(seq)).toBe(false); + expect(isKeyed(seq)).toBe(false); + expect(seq.size).toBe(3); + }); + + it('does not accept a scalar', () => { + expect(() => { + // @ts-expect-error -- test that runtime does throw + Seq(3); + }).toThrow( + 'Expected Array or collection object of values, or keyed object: 3' + ); + }); + + it('detects sequences', () => { + const seq = Seq([1, 2, 3]); + expect(Seq.isSeq(seq)).toBe(true); + expect(isCollection(seq)).toBe(true); + }); + + it('Does not infinite loop when sliced with NaN', () => { + const list = Seq([1, 2, 3, 4, 5]); + expect(list.slice(0, NaN).toJS()).toEqual([]); + expect(list.slice(NaN).toJS()).toEqual([1, 2, 3, 4, 5]); + }); + + it('Does not infinite loop when spliced with negative number #559', () => { + const dog = Seq(['d', 'o', 'g']); + const dg = dog.filter((c) => c !== 'o'); + const dig = dg.splice(-1, 0, 'i'); + expect(dig.toJS()).toEqual(['d', 'i', 'g']); + }); + + it('Does not infinite loop when an undefined number is passed to take', () => { + const list = Seq([1, 2, 3, 4, 5]); + expect(list.take(NaN).toJS()).toEqual([]); + }); + + it('Converts deeply toJS after converting to entries', () => { + const list = Seq([Seq([1, 2]), Seq({ a: 'z' })]); + expect(list.entrySeq().toJS()).toEqual([ + [0, [1, 2]], + [1, { a: 'z' }], + ]); + + const map = Seq({ x: Seq([1, 2]), y: Seq({ a: 'z' }) }); + expect(map.entrySeq().toJS()).toEqual([ + ['x', [1, 2]], + ['y', { a: 'z' }], + ]); + }); +}); diff --git a/__tests__/Sequence.ts b/__tests__/Sequence.ts deleted file mode 100644 index d82094ab28..0000000000 --- a/__tests__/Sequence.ts +++ /dev/null @@ -1,27 +0,0 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); - -describe('Sequence', () => { - - it('can be empty', () => { - expect(Immutable.Sequence().length).toBe(0); - }); - - it('accepts an array', () => { - expect(Immutable.Sequence([1,2,3]).length).toBe(3); - }); - - it('accepts varargs', () => { - expect(Immutable.Sequence(1,2,3).length).toBe(3); - }); - - it('accepts another sequence', () => { - var seq = Immutable.Sequence(1,2,3); - expect(Immutable.Sequence(seq).length).toBe(3); - }); - -}); diff --git a/__tests__/Set.ts b/__tests__/Set.ts index 10fdfcc8a5..5e8f1fe5d7 100644 --- a/__tests__/Set.ts +++ b/__tests__/Set.ts @@ -1,64 +1,86 @@ -/// -/// - -jest.autoMockOff(); - -import Immutable = require('immutable'); -import Set = Immutable.Set; - -declare function expect(val: any): ExpectWithIs; - -interface ExpectWithIs extends Expect { - is(expected: any): void; - not: ExpectWithIs; -} +import { describe, expect, it, jest } from '@jest/globals'; +import { fromJS, is, List, Map, OrderedSet, Seq, Set } from 'immutable'; describe('Set', () => { + it('accepts array of values', () => { + const s = Set([1, 2, 3]); + expect(s.has(1)).toBe(true); + expect(s.has(2)).toBe(true); + expect(s.has(3)).toBe(true); + expect(s.has(4)).toBe(false); + }); - beforeEach(function () { - this.addMatchers({ - is: function(expected) { - return Immutable.is(this.actual, expected); - } - }) - }) + it('accepts array-like of values', () => { + const s = Set({ length: 3, 2: 3 }); + expect(s.size).toBe(2); + expect(s.has(undefined)).toBe(true); + expect(s.has(3)).toBe(true); + expect(s.has(2)).toBe(false); + }); - it('converts from array of values', () => { - var s = Set.from([1,2,3]); + it('accepts a JS (global) Set', () => { + const s = Set(new global.Set([1, 2, 3])); + expect(Set.isSet(s)).toBe(true); + expect(s.size).toBe(3); expect(s.has(1)).toBe(true); expect(s.has(2)).toBe(true); expect(s.has(3)).toBe(true); expect(s.has(4)).toBe(false); }); - it('converts from sequence of values', () => { - var seq = Immutable.Sequence(1,2,3); - var s = Set.from(seq); + it('accepts string, an array-like collection', () => { + const s = Set('abc'); + expect(s.size).toBe(3); + expect(s.has('a')).toBe(true); + expect(s.has('b')).toBe(true); + expect(s.has('c')).toBe(true); + expect(s.has('abc')).toBe(false); + }); + + it('accepts sequence of values', () => { + const seq = Seq([1, 2, 3]); + const s = Set(seq); expect(s.has(1)).toBe(true); expect(s.has(2)).toBe(true); expect(s.has(3)).toBe(true); expect(s.has(4)).toBe(false); }); - it('converts from object keys', () => { - var s = Set.fromKeys({a:null, b:null, c:null}); + it('accepts a keyed Seq as a set of entries', () => { + const seq = Seq({ a: null, b: null, c: null }).flip(); + const s = Set(seq); + expect(s.toArray()).toEqual([ + [null, 'a'], + [null, 'b'], + [null, 'c'], + ]); + // Explicitly getting the values sequence + const s2 = Set(seq.valueSeq()); + expect(s2.toArray()).toEqual(['a', 'b', 'c']); + // toSet() does this for you. + const v3 = seq.toSet(); + expect(v3.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts object keys', () => { + const s = Set.fromKeys({ a: null, b: null, c: null }); expect(s.has('a')).toBe(true); expect(s.has('b')).toBe(true); expect(s.has('c')).toBe(true); expect(s.has('d')).toBe(false); }); - it('converts from sequence keys', () => { - var seq = Immutable.Sequence({a:null, b:null, c:null}); - var s = Set.fromKeys(seq); + it('accepts sequence keys', () => { + const seq = Seq({ a: null, b: null, c: null }); + const s = Set.fromKeys(seq); expect(s.has('a')).toBe(true); expect(s.has('b')).toBe(true); expect(s.has('c')).toBe(true); expect(s.has('d')).toBe(false); }); - it('constructor provides initial values', () => { - var s = Set(1,2,3); + it('accepts explicit values', () => { + const s = Set([1, 2, 3]); expect(s.has(1)).toBe(true); expect(s.has(2)).toBe(true); expect(s.has(3)).toBe(true); @@ -66,101 +88,290 @@ describe('Set', () => { }); it('converts back to JS array', () => { - var s = Set(1,2,3); - expect(s.toArray()).toEqual([1,2,3]); + const s = Set([1, 2, 3]); + expect(s.toArray()).toEqual([1, 2, 3]); }); it('converts back to JS object', () => { - var s = Set('a','b','c'); - expect(s.toObject()).toEqual({a:'a',b:'b',c:'c'}); + const s = Set.of('a', 'b', 'c'); + expect(s.toObject()).toEqual({ a: 'a', b: 'b', c: 'c' }); + }); + + it('maps no-ops return the same reference', () => { + const s = Set([1, 2, 3]); + const r = s.map((value) => value); + expect(r).toBe(s); + }); + + it('maps should produce new set if values changed', () => { + const s = Set([1, 2, 3]); + expect(s.has(4)).toBe(false); + expect(s.size).toBe(3); + + const m = s.map((v) => v + 1); + expect(m.has(1)).toBe(false); + expect(m.has(2)).toBe(true); + expect(m.has(3)).toBe(true); + expect(m.has(4)).toBe(true); + expect(m.size).toBe(3); + }); + + it('unions an unknown collection of Sets', () => { + const abc = Set(['a', 'b', 'c']); + const cat = Set(['c', 'a', 't']); + expect(Set.union([abc, cat]).toArray()).toEqual(['c', 'a', 't', 'b']); + expect(Set.union([abc])).toBe(abc); + expect(Set.union([])).toBe(Set()); + }); + + it('intersects an unknown collection of Sets', () => { + const abc = Set(['a', 'b', 'c']); + const cat = Set(['c', 'a', 't']); + expect(Set.intersect([abc, cat]).toArray()).toEqual(['c', 'a']); + expect(Set.intersect([abc])).toBe(abc); + expect(Set.intersect([])).toBe(Set()); + }); + + it('concatenates strings using union', () => { + const s = Set(['one', 'two']); + expect(s.union('three').toArray()).toEqual(['one', 'two', 'three']); }); it('iterates values', () => { - var s = Set(1,2,3); - var iterator = jest.genMockFunction(); + const s = Set([1, 2, 3]); + const iterator = jest.fn(); s.forEach(iterator); expect(iterator.mock.calls).toEqual([ [1, 1, s], [2, 2, s], - [3, 3, s] + [3, 3, s], ]); }); + it('has the same iterator function for keys and values', () => { + const s = Set([1, 2, 3]); + expect(s[Symbol.iterator]).toBe(s.keys); + expect(s[Symbol.iterator]).toBe(s.values); + }); + it('unions two sets', () => { - var s1 = Set('a', 'b', 'c'); - var s2 = Set('wow', 'd', 'b'); - var s3 = s1.union(s2); + const s1 = Set.of('a', 'b', 'c'); + const s2 = Set.of('d', 'b', 'wow'); + const s3 = s1.union(s2); expect(s3.toArray()).toEqual(['a', 'b', 'c', 'd', 'wow']); }); it('returns self when union results in no-op', () => { - var s1 = Set('a', 'b', 'c'); - var s2 = Set('c', 'a'); - var s3 = s1.union(s2); + const s1 = Set.of('a', 'b', 'c'); + const s2 = Set.of('c', 'a'); + const s3 = s1.union(s2); expect(s3).toBe(s1); }); + it('returns arg when union results in no-op', () => { + const s1 = Set(); + const s2 = Set.of('a', 'b', 'c'); + const s3 = s1.union(s2); + expect(s3).toBe(s2); + }); + + it('unions a set and another collection and returns a set', () => { + const s1 = Set([1, 2, 3]); + const emptySet = Set(); + const l = List([1, 2, 3]); + const s2 = s1.union(l); + const s3 = emptySet.union(l); + const o = OrderedSet([1, 2, 3]); + const s4 = s1.union(o); + const s5 = emptySet.union(o); + expect(Set.isSet(s2)).toBe(true); + expect(Set.isSet(s3)).toBe(true); + expect(Set.isSet(s4) && !OrderedSet.isOrderedSet(s4)).toBe(true); + expect(Set.isSet(s5) && !OrderedSet.isOrderedSet(s5)).toBe(true); + }); + it('is persistent to adds', () => { - var s1 = Set(); - var s2 = s1.add('a'); - var s3 = s2.add('b'); - var s4 = s3.add('c'); - var s5 = s4.add('b'); - expect(s1.length).toBe(0); - expect(s2.length).toBe(1); - expect(s3.length).toBe(2); - expect(s4.length).toBe(3); - expect(s5.length).toBe(3); + const s1 = Set(); + const s2 = s1.add('a'); + const s3 = s2.add('b'); + const s4 = s3.add('c'); + const s5 = s4.add('b'); + expect(s1.size).toBe(0); + expect(s2.size).toBe(1); + expect(s3.size).toBe(2); + expect(s4.size).toBe(3); + expect(s5.size).toBe(3); }); it('is persistent to deletes', () => { - var s1 = Set(); - var s2 = s1.add('a'); - var s3 = s2.add('b'); - var s4 = s3.add('c'); - var s5 = s4.remove('b'); - expect(s1.length).toBe(0); - expect(s2.length).toBe(1); - expect(s3.length).toBe(2); - expect(s4.length).toBe(3); - expect(s5.length).toBe(2); + const s1 = Set(); + const s2 = s1.add('a'); + const s3 = s2.add('b'); + const s4 = s3.add('c'); + const s5 = s4.remove('b'); + expect(s1.size).toBe(0); + expect(s2.size).toBe(1); + expect(s3.size).toBe(2); + expect(s4.size).toBe(3); + expect(s5.size).toBe(2); expect(s3.has('b')).toBe(true); expect(s5.has('b')).toBe(false); }); it('deletes down to empty set', () => { - var s = Set('A').remove('A'); - expect(s).toBe(Set.empty()); + const s = Set.of('A').remove('A'); + expect(s).toBe(Set()); }); it('unions multiple sets', () => { - var s = Set('A', 'B', 'C').union(Set('C', 'D', 'E'), Set('D', 'B', 'F')); - expect(s).is(Set('A','B','C','D','E','F')); + const s = Set.of('A', 'B', 'C').union( + Set.of('C', 'D', 'E'), + Set.of('D', 'B', 'F') + ); + expect(s).toEqual(Set.of('A', 'B', 'C', 'D', 'E', 'F')); }); it('intersects multiple sets', () => { - var s = Set('A', 'B', 'C').intersect(Set('B', 'C', 'D'), Set('A', 'C', 'E')); - expect(s).is(Set('C')); + const s = Set.of('A', 'B', 'C').intersect( + Set.of('B', 'C', 'D'), + Set.of('A', 'C', 'E') + ); + expect(s).toEqual(Set.of('C')); }); it('diffs multiple sets', () => { - var s = Set('A', 'B', 'C').subtract(Set('C', 'D', 'E'), Set('D', 'B', 'F')); - expect(s).is(Set('A')); + const s = Set.of('A', 'B', 'C').subtract( + Set.of('C', 'D', 'E'), + Set.of('D', 'B', 'F') + ); + expect(s).toEqual(Set.of('A')); }); - it('expresses value equality with set-ish sequences', () => { - var s1 = Set('A', 'B', 'C'); + it('expresses value equality with set sequences', () => { + const s1 = Set.of('A', 'B', 'C'); expect(s1.equals(null)).toBe(false); - var s2 = Set('C', 'B', 'A'); + const s2 = Set.of('C', 'B', 'A'); expect(s1 === s2).toBe(false); - expect(Immutable.is(s1, s2)).toBe(true); + expect(is(s1, s2)).toBe(true); expect(s1.equals(s2)).toBe(true); - var v1 = Immutable.Vector('A', 'B', 'C'); - expect(Immutable.is(s1, v1)).toBe(true); + // Map and Set are not the same (keyed vs unkeyed) + const v1 = Map({ A: 'A', C: 'C', B: 'B' }); + expect(is(s1, v1)).toBe(false); + }); + + it('can use union in a withMutation', () => { + const js = Set() + .withMutations((set) => { + set.union(['a']); + set.add('b'); + }) + .toJS(); + expect(js).toEqual(['a', 'b']); }); - // TODO: more tests + it('can determine if an array is a subset', () => { + const s = Set.of('A', 'B', 'C'); + expect(s.isSuperset(['B', 'C'])).toBe(true); + expect(s.isSuperset(['B', 'C', 'D'])).toBe(false); + }); + + describe('accepts Symbol as entry #579', () => { + it('operates on small number of symbols, preserving set uniqueness', () => { + const a = Symbol(); + + const b = Symbol(); + + const c = Symbol(); + const symbolSet = Set([a, b, c, a, b, c, a, b, c, a, b, c]); + expect(symbolSet.size).toBe(3); + expect(symbolSet.has(b)).toBe(true); + expect(symbolSet.get(c)).toEqual(c); + }); + + it('operates on a large number of symbols, maintaining obj uniqueness', () => { + const manySymbols = [ + Symbol('a'), + Symbol('b'), + Symbol('c'), + Symbol('a'), + Symbol('b'), + Symbol('c'), + Symbol('a'), + Symbol('b'), + Symbol('c'), + Symbol('a'), + Symbol('b'), + Symbol('c'), + ]; + + const symbolSet = Set(manySymbols); + expect(symbolSet.size).toBe(12); + expect(symbolSet.has(manySymbols[10])).toBe(true); + expect(symbolSet.get(manySymbols[10])).toEqual(manySymbols[10]); + }); + }); + + it('can use intersect after add or union in a withMutation', () => { + const set = Set(['a', 'd']).withMutations((s) => { + s.add('b'); + s.union(['c']); + s.intersect(['b', 'c', 'd']); + }); + expect(set.toArray()).toEqual(['c', 'd', 'b']); + }); + + it('can count entries that satisfy a predicate', () => { + const set = Set([1, 2, 3, 4, 5]); + expect(set.size).toEqual(5); + expect(set.count()).toEqual(5); + expect(set.count((x) => x % 2 === 0)).toEqual(2); + expect(set.count(() => true)).toEqual(5); + }); + + describe('"size" should correctly reflect the number of elements in a Set', () => { + describe('deduplicating custom classes that invoke fromJS() as part of equality check', () => { + class Entity { + entityId: string; + + entityKey: string; + + constructor(entityId: string, entityKey: string) { + this.entityId = entityId; + this.entityKey = entityKey; + } + + asImmutable() { + return fromJS({ + entityId: this.entityId, + entityKey: this.entityKey, + }); + } + + valueOf() { + return this.asImmutable().toString(); + } + } + it('with mutations', () => { + const testSet = Set().withMutations((mutableSet) => { + mutableSet.add(new Entity('hello', 'world')); + mutableSet.add(new Entity('testing', 'immutable')); + mutableSet.add(new Entity('hello', 'world')); + }); + expect(testSet.size).toEqual(2); + }); + it('without mutations', () => { + const testSet0 = Set(); + const testSet1 = testSet0.add(new Entity('hello', 'world')); + const testSet2 = testSet1.add(new Entity('testing', 'immutable')); + const testSet3 = testSet2.add(new Entity('hello', 'world')); + expect(testSet0.size).toEqual(0); + expect(testSet1.size).toEqual(1); + expect(testSet2.size).toEqual(2); + expect(testSet3.size).toEqual(2); + }); + }); + }); }); diff --git a/__tests__/Stack.ts b/__tests__/Stack.ts new file mode 100644 index 0000000000..f3fc3d9326 --- /dev/null +++ b/__tests__/Stack.ts @@ -0,0 +1,222 @@ +import { describe, expect, it } from '@jest/globals'; +import { Seq, Stack } from 'immutable'; +import fc from 'fast-check'; + +function arrayOfSize(s) { + const a = new Array(s); + for (let ii = 0; ii < s; ii++) { + a[ii] = ii; + } + return a; +} + +describe('Stack', () => { + it('constructor provides initial values', () => { + const s = Stack.of('a', 'b', 'c'); + expect(s.get(0)).toBe('a'); + expect(s.get(1)).toBe('b'); + expect(s.get(2)).toBe('c'); + }); + + it('toArray provides a JS array', () => { + const s = Stack.of('a', 'b', 'c'); + expect(s.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts a JS array', () => { + const s = Stack(['a', 'b', 'c']); + expect(s.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts a Seq', () => { + const seq = Seq(['a', 'b', 'c']); + const s = Stack(seq); + expect(s.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('accepts a keyed Seq', () => { + const seq = Seq({ a: null, b: null, c: null }).flip(); + const s = Stack(seq); + expect(s.toArray()).toEqual([ + [null, 'a'], + [null, 'b'], + [null, 'c'], + ]); + // Explicit values + const s2 = Stack(seq.valueSeq()); + expect(s2.toArray()).toEqual(['a', 'b', 'c']); + // toStack() does this for you. + const s3 = seq.toStack(); + expect(s3.toArray()).toEqual(['a', 'b', 'c']); + }); + + it('pushing creates a new instance', () => { + const s0 = Stack.of('a'); + const s1 = s0.push('A'); + expect(s0.get(0)).toBe('a'); + expect(s1.get(0)).toBe('A'); + }); + + it('get helpers make for easier to read code', () => { + const s = Stack.of('a', 'b', 'c'); + expect(s.first()).toBe('a'); + expect(s.last()).toBe('c'); + expect(s.peek()).toBe('a'); + }); + + it('slice helpers make for easier to read code', () => { + const s = Stack.of('a', 'b', 'c'); + expect(s.rest().toArray()).toEqual(['b', 'c']); + }); + + it('iterable in reverse order', () => { + const s = Stack.of('a', 'b', 'c'); + expect(s.size).toBe(3); + + const forEachResults: Array<[number, string, string | undefined]> = []; + s.forEach((val, i) => forEachResults.push([i, val, s.get(i)])); + expect(forEachResults).toEqual([ + [0, 'a', 'a'], + [1, 'b', 'b'], + [2, 'c', 'c'], + ]); + + // map will cause reverse iterate + expect(s.map((val) => val + val).toArray()).toEqual(['aa', 'bb', 'cc']); + + let iteratorResults: Array<[number, string]> = []; + let iterator = s.entries(); + let step: IteratorResult<[number, string]>; + while (!(step = iterator.next()).done) { + iteratorResults.push(step.value); + } + expect(iteratorResults).toEqual([ + [0, 'a'], + [1, 'b'], + [2, 'c'], + ]); + + iteratorResults = []; + iterator = s.toSeq().reverse().entries(); + while (!(step = iterator.next()).done) { + iteratorResults.push(step.value); + } + expect(iteratorResults).toEqual([ + [0, 'c'], + [1, 'b'], + [2, 'a'], + ]); + }); + + it('map is called in reverse order but with correct indices', () => { + const s = Stack(['a', 'b', 'c']); + const s2 = s.map((v, i, c) => v + i + c.get(i)); + expect(s2.toArray()).toEqual(['a0a', 'b1b', 'c2c']); + + const mappedSeq = s.toSeq().map((v, i, c) => v + i + c.get(i)); + const s3 = Stack(mappedSeq); + expect(s3.toArray()).toEqual(['a0a', 'b1b', 'c2c']); + }); + + it('push inserts at lowest index', () => { + const s0 = Stack.of('a', 'b', 'c'); + const s1 = s0.push('d', 'e', 'f'); + expect(s0.size).toBe(3); + expect(s1.size).toBe(6); + expect(s1.toArray()).toEqual(['d', 'e', 'f', 'a', 'b', 'c']); + }); + + it('pop removes the lowest index, decrementing size', () => { + const s = Stack.of('a', 'b', 'c').pop(); + expect(s.peek()).toBe('b'); + expect(s.toArray()).toEqual(['b', 'c']); + }); + + it('shift removes the lowest index, just like array', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const a = arrayOfSize(len); + let s = Stack(a); + + while (a.length) { + expect(s.size).toBe(a.length); + expect(s.toArray()).toEqual(a); + s = s.shift(); + a.shift(); + } + expect(s.size).toBe(a.length); + expect(s.toArray()).toEqual(a); + }) + ); + }); + + it('unshift adds the next lowest index, just like array', () => { + fc.assert( + fc.property(fc.nat(100), (len) => { + const a: Array = []; + let s = Stack(); + + for (let ii = 0; ii < len; ii++) { + expect(s.size).toBe(a.length); + expect(s.toArray()).toEqual(a); + s = s.unshift(ii); + a.unshift(ii); + } + expect(s.size).toBe(a.length); + expect(s.toArray()).toEqual(a); + }) + ); + }); + + it('unshifts multiple values to the front', () => { + fc.assert( + fc.property(fc.nat(100), fc.nat(100), (size1: number, size2: number) => { + const a1 = arrayOfSize(size1); + const a2 = arrayOfSize(size2); + + const s1 = Stack(a1); + const s3 = s1.unshift.apply(s1, a2); + + const a3 = a1.slice(); + a3.unshift.apply(a3, a2); + + expect(s3.size).toEqual(a3.length); + expect(s3.toArray()).toEqual(a3); + }) + ); + }); + + it('finds values using indexOf', () => { + const s = Stack.of('a', 'b', 'c', 'b', 'a'); + expect(s.indexOf('b')).toBe(1); + expect(s.indexOf('c')).toBe(2); + expect(s.indexOf('d')).toBe(-1); + }); + + it('pushes on all items in an iter', () => { + const abc = Stack(['a', 'b', 'c']); + const xyz = Stack(['x', 'y', 'z']); + const xyzSeq = Seq(['x', 'y', 'z']); + + // Push all to the front of the Stack so first item ends up first. + expect(abc.pushAll(xyz).toArray()).toEqual(['x', 'y', 'z', 'a', 'b', 'c']); + expect(abc.pushAll(xyzSeq).toArray()).toEqual([ + 'x', + 'y', + 'z', + 'a', + 'b', + 'c', + ]); + + // Pushes Seq contents into Stack + expect(Stack().pushAll(xyzSeq)).not.toBe(xyzSeq); + expect(Stack().pushAll(xyzSeq).toArray()).toEqual(['x', 'y', 'z']); + + // Pushing a Stack onto an empty Stack returns === Stack + expect(Stack().pushAll(xyz)).toBe(xyz); + + // Pushing an empty Stack onto a Stack return === Stack + expect(abc.pushAll(Stack())).toBe(abc); + }); +}); diff --git a/__tests__/Vector.ts b/__tests__/Vector.ts deleted file mode 100644 index 6e58d2617b..0000000000 --- a/__tests__/Vector.ts +++ /dev/null @@ -1,480 +0,0 @@ -/// -/// - -jest.autoMockOff(); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); - -import Immutable = require('immutable'); -import Vector = Immutable.Vector; - -function arrayOfSize(s) { - var a = new Array(s); - for (var ii = 0; ii < s; ii++) { - a[ii] = ii; - } - return a; -} - -describe('Vector', () => { - - it('constructor provides initial values', () => { - var v = Vector('a', 'b', 'c'); - expect(v.get(0)).toBe('a'); - expect(v.get(1)).toBe('b'); - expect(v.get(2)).toBe('c'); - }); - - it('toArray provides a JS array', () => { - var v = Vector('a', 'b', 'c'); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('from consumes a JS array', () => { - var v = Vector.from(['a', 'b', 'c']); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('from consumes a Sequence', () => { - var seq = Immutable.Sequence(['a', 'b', 'c']); - var v = Vector.from(seq); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('from consumes a non-indexed Sequence', () => { - var seq = Immutable.Sequence({a:null, b:null, c:null}).flip(); - var v = Vector.from(seq); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('can set and get a value', () => { - var v = Vector(); - expect(v.get(0)).toBe(undefined); - v = v.set(0, 'value'); - expect(v.get(0)).toBe('value'); - }); - - it('counts from the end of the vector on negative index', () => { - var i = Immutable.Vector(1, 2, 3, 4, 5, 6, 7); - expect(i.get(-1)).toBe(7); - expect(i.get(-5)).toBe(3); - expect(i.get(-9)).toBe(undefined); - expect(i.get(-999, 1000)).toBe(1000); - }); - - it('setting creates a new instance', () => { - var v0 = Vector('a'); - var v1 = v0.set(0, 'A'); - expect(v0.get(0)).toBe('a'); - expect(v1.get(0)).toBe('A'); - }); - - it('length includes the highest index', () => { - var v0 = Vector(); - var v1 = v0.set(0, 'a'); - var v2 = v1.set(1, 'b'); - var v3 = v2.set(2, 'c'); - expect(v0.length).toBe(0); - expect(v1.length).toBe(1); - expect(v2.length).toBe(2); - expect(v3.length).toBe(3); - }); - - it('get helpers make for easier to read code', () => { - var v = Vector('a', 'b', 'c'); - expect(v.first()).toBe('a'); - expect(v.get(1)).toBe('b'); - expect(v.last()).toBe('c'); - }); - - it('slice helpers make for easier to read code', () => { - var v0 = Vector('a', 'b', 'c'); - var v1 = Vector('a', 'b'); - var v2 = Vector('a'); - var v3 = Vector.empty(); - - expect(v0.rest().toArray()).toEqual(['b', 'c']); - expect(v0.butLast().toArray()).toEqual(['a', 'b']); - - expect(v1.rest().toArray()).toEqual(['b']); - expect(v1.butLast().toArray()).toEqual(['a']); - - expect(v2.rest().toArray()).toEqual([]); - expect(v2.butLast().toArray()).toEqual([]); - - expect(v3.rest().toArray()).toEqual([]); - expect(v3.butLast().toArray()).toEqual([]); - }); - - it('can set at arbitrary indices', () => { - var v0 = Vector('a', 'b', 'c'); - var v1 = v0.set(1, 'B'); // within existing tail - var v2 = v1.set(3, 'd'); // at last position - var v3 = v2.set(31, 'e'); // (testing internal guts) - var v4 = v3.set(32, 'f'); // (testing internal guts) - var v5 = v4.set(1023, 'g'); // (testing internal guts) - var v6 = v5.set(1024, 'h'); // (testing internal guts) - var v7 = v6.set(32, 'F'); // set within existing tree - expect(v7.length).toBe(1025); - var expectedArray = ['a', 'B', 'c', 'd']; - expectedArray[31] = 'e'; - expectedArray[32] = 'F'; - expectedArray[1023] = 'g'; - expectedArray[1024] = 'h'; - expect(v7.toArray()).toEqual(expectedArray); - }); - - it('can contain a large number of indices', () => { - var v = Immutable.Range(0,20000).toVector(); - var iterations = 0; - v.forEach(v => { - expect(v).toBe(iterations); - iterations++; - }); - }) - - it('describes a dense vector', () => { - var v = Vector('a', 'b', 'c').push('d').set(14, 'o').set(6, undefined).remove(1); - expect(v.length).toBe(15); - expect(v.has(2)).toBe(true); // original end - expect(v.has(3)).toBe(true); // end after push - expect(v.has(14)).toBe(true); // end after set - expect(v.has(6)).toBe(true); // set as undefined, still has index - expect(v.has(1)).toBe(true); // was removed, but still in bounds - expect(v.has(15)).toBe(false); // out of bounds - expect(v.has(13)).toBe(true); // never set, but still in bounds - }); - - it('iterates a dense vector', () => { - var v = Vector.empty().setLength(11).set(1,1).set(3,3).set(5,5).set(7,7).set(9,9); - expect(v.length).toBe(11); - - var forEachResults = []; - v.forEach((val, i) => forEachResults.push([i, val])); - expect(forEachResults).toEqual([ - [0,undefined], - [1,1], - [2,undefined], - [3,3], - [4,undefined], - [5,5], - [6,undefined], - [7,7], - [8,undefined], - [9,9], - [10,undefined], - ]); - - var arrayResults = v.toArray(); - expect(arrayResults).toEqual([ - undefined, - 1, - undefined, - 3, - undefined, - 5, - undefined, - 7, - undefined, - 9, - undefined, - ]); - - var iteratorResults = []; - var iterator = v.entries(); - var step; - while (!(step = iterator.next()).done) { - iteratorResults.push(step.value); - } - expect(iteratorResults).toEqual([ - [0,undefined], - [1,1], - [2,undefined], - [3,3], - [4,undefined], - [5,5], - [6,undefined], - [7,7], - [8,undefined], - [9,9], - [10,undefined], - ]); - }); - - it('push inserts at highest index', () => { - var v0 = Vector('a', 'b', 'c'); - var v1 = v0.push('d', 'e', 'f'); - expect(v0.length).toBe(3); - expect(v1.length).toBe(6); - expect(v1.toArray()).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); - }); - - check.it('pushes multiple values to the end', {maxSize: 2000}, - [gen.posInt, gen.posInt], (s1, s2) => { - var a1 = arrayOfSize(s1); - var a2 = arrayOfSize(s2); - - var v1 = Vector.from(a1); - var v3 = v1.push.apply(v1, a2); - - var a3 = a1.slice(); - a3.push.apply(a3, a2); - - expect(v3.length).toEqual(a3.length); - expect(v3.toArray()).toEqual(a3); - } - ); - - it('pop removes the highest index, decrementing length', () => { - var v = Vector('a', 'b', 'c').pop(); - expect(v.last()).toBe('b'); - expect(v.toArray()).toEqual(['a','b']); - v = v.set(1230, 'x'); - expect(v.length).toBe(1231); - expect(v.last()).toBe('x'); - v = v.pop(); - expect(v.length).toBe(1230); - expect(v.last()).toBe(undefined); - v = v.push('X'); - expect(v.length).toBe(1231); - expect(v.last()).toBe('X'); - }); - - check.it('pop removes the highest index, just like array', {maxSize: 2000}, - [gen.posInt], len => { - var a = arrayOfSize(len); - var v = Vector.from(a); - - while (a.length) { - expect(v.length).toBe(a.length); - expect(v.toArray()).toEqual(a); - v = v.pop(); - a.pop(); - } - expect(v.length).toBe(a.length); - expect(v.toArray()).toEqual(a); - } - ); - - check.it('push adds the next highest index, just like array', {maxSize: 2000}, - [gen.posInt], len => { - var a = []; - var v = Vector(); - - for (var ii = 0; ii < len; ii++) { - expect(v.length).toBe(a.length); - expect(v.toArray()).toEqual(a); - v = v.push(ii); - a.push(ii); - } - expect(v.length).toBe(a.length); - expect(v.toArray()).toEqual(a); - } - ); - - it('allows popping an empty vector', () => { - var v = Vector('a').pop(); - expect(v.length).toBe(0); - expect(v.toArray()).toEqual([]); - v = v.pop().pop().pop().pop().pop(); - expect(v.length).toBe(0); - expect(v.toArray()).toEqual([]); - }); - - it('remove removes an index, but does not affect length', () => { - var v = Vector('a', 'b', 'c').remove(2).remove(0); - expect(v.length).toBe(3); - expect(v.get(0)).toBe(undefined); - expect(v.get(1)).toBe('b'); - expect(v.get(2)).toBe(undefined); - // explicit triplicate trailing comma. - // Typescript consumes the first. - // Node consumes the second. - // JS interprets the third as a hole. - expect(v.toArray()).toEqual([,'b',,,]); - v = v.push('d'); - expect(v.length).toBe(4); - expect(v.get(3)).toBe('d'); - expect(v.toArray()).toEqual([,'b',,'d']); - }); - - it('shifts values from the front', () => { - var v = Vector('a', 'b', 'c').shift(); - expect(v.first()).toBe('b'); - expect(v.length).toBe(2); - }); - - it('unshifts values to the front', () => { - var v = Vector('a', 'b', 'c').unshift('x', 'y', 'z'); - expect(v.first()).toBe('x'); - expect(v.length).toBe(6); - expect(v.toArray()).toEqual(['x', 'y', 'z', 'a', 'b', 'c']); - }); - - check.it('unshifts multiple values to the front', {maxSize: 2000}, - [gen.posInt, gen.posInt], (s1, s2) => { - var a1 = arrayOfSize(s1); - var a2 = arrayOfSize(s2); - - var v1 = Vector.from(a1); - var v3 = v1.unshift.apply(v1, a2); - - var a3 = a1.slice(); - a3.unshift.apply(a3, a2); - - expect(v3.length).toEqual(a3.length); - expect(v3.toArray()).toEqual(a3); - } - ); - - it('finds values using indexOf', () => { - var v = Vector('a', 'b', 'c', 'b', 'a'); - expect(v.indexOf('b')).toBe(1); - expect(v.indexOf('c')).toBe(2); - expect(v.indexOf('d')).toBe(-1); - }); - - it('finds values using findIndex', () => { - var v = Vector('a', 'b', 'c', 'B', 'a'); - expect(v.findIndex(value => value.toUpperCase() === value)).toBe(3); - }); - - it('maps values', () => { - var v = Vector('a', 'b', 'c'); - var r = v.map(value => value.toUpperCase()); - expect(r.toArray()).toEqual(['A', 'B', 'C']); - }); - - it('filters values', () => { - var v = Vector('a', 'b', 'c', 'd', 'e', 'f'); - var r = v.filter((value, index) => index % 2 === 1); - expect(r.toArray()).toEqual(['b', 'd', 'f']); - }); - - it('reduces values', () => { - var v = Vector(1,10,100); - var r = v.reduce((reduction, value) => reduction + value); - expect(r).toEqual(111); - }); - - it('reduces from the right', () => { - var v = Vector('a','b','c'); - var r = v.reduceRight((reduction, value) => reduction + value); - expect(r).toEqual('cba'); - }); - - it('takes and skips values', () => { - var v = Vector('a', 'b', 'c', 'd', 'e', 'f'); - var r = v.skip(2).take(2); - expect(r.toArray()).toEqual(['c', 'd']); - }); - - it('efficiently chains array methods', () => { - var v = Vector(1,2,3,4,5,6,7,8,9,10,11,12,13,14); - - var r = v - .filter(x => x % 2 == 0) - .skip(2) - .map(x => x * x) - .take(3) - .reduce((a: number, b: number) => a + b, 0); - - expect(r).toEqual(200); - }); - - it('can convert to a map', () => { - var v = Vector('a', 'b', 'c'); - var m = v.toMap(); - expect(m.length).toBe(3); - expect(m.get(1)).toBe('b'); - }); - - it('reverses', () => { - var v = Vector('a', 'b', 'c'); - expect(v.reverse().toArray()).toEqual(['c', 'b', 'a']); - }); - - it('ensures equality', () => { - // Make a sufficiently long vector. - var a = Array(100).join('abcdefghijklmnopqrstuvwxyz').split(''); - var v1 = Vector.from(a); - var v2 = Vector.from(a); - expect(v1 == v2).not.toBe(true); - expect(v1 === v2).not.toBe(true); - expect(v1.equals(v2)).toBe(true); - }); - - // TODO: assert that findIndex only calls the function as much as it needs to. - - // TODO: assert that forEach iterates in the correct order and is only called as much as it needs to be. - - it('concat works like Array.prototype.concat', () => { - var v1 = Vector(1, 2, 3); - var v2 = v1.concat(4, Vector(5, 6), [7, 8], Immutable.Sequence({a:9,b:10}), Immutable.Set(11,12), null); - expect(v1.toArray()).toEqual([1, 2, 3]); - expect(v2.toArray()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, null]); - }); - - it('allows chained mutations', () => { - var v1 = Vector(); - var v2 = v1.push(1); - var v3 = v2.withMutations(v => v.push(2).push(3).push(4)); - var v4 = v3.push(5); - - expect(v1.toArray()).toEqual([]); - expect(v2.toArray()).toEqual([1]); - expect(v3.toArray()).toEqual([1,2,3,4]); - expect(v4.toArray()).toEqual([1,2,3,4,5]); - }); - - it('allows chained mutations using alternative API', () => { - var v1 = Vector(); - var v2 = v1.push(1); - var v3 = v2.asMutable().push(2).push(3).push(4).asImmutable(); - var v4 = v3.push(5); - - expect(v1.toArray()).toEqual([]); - expect(v2.toArray()).toEqual([1]); - expect(v3.toArray()).toEqual([1,2,3,4]); - expect(v4.toArray()).toEqual([1,2,3,4,5]); - }); - - it('allows length to be set', () => { - var v1 = Immutable.Range(0,2000).toVector(); - var v2 = v1.setLength(1000); - var v3 = v2.setLength(1500); - expect(v1.length).toBe(2000); - expect(v2.length).toBe(1000); - expect(v3.length).toBe(1500); - expect(v1.get(900)).toBe(900); - expect(v1.get(1300)).toBe(1300); - expect(v1.get(1800)).toBe(1800); - expect(v2.get(900)).toBe(900); - expect(v2.get(1300)).toBe(undefined); - expect(v2.get(1800)).toBe(undefined); - expect(v3.get(900)).toBe(900); - expect(v3.get(1300)).toBe(undefined); - expect(v3.get(1800)).toBe(undefined); - }); - - it('can be efficiently sliced', () => { - var v1 = Immutable.Range(0,2000).toVector(); - var v2 = v1.slice(100,-100).toVector(); - expect(v1.length).toBe(2000) - expect(v2.length).toBe(1800); - expect(v2.first()).toBe(100); - expect(v2.rest().length).toBe(1799); - expect(v2.last()).toBe(1899); - expect(v2.butLast().length).toBe(1799); - }); - - check.it('iterates through all values', [gen.posInt], len => { - var v = Immutable.Range(0, len).toVector(); - var valueIter = v.values(); - for (var ii = 0; ii < len; ii++) { - expect(valueIter.next().value).toBe(ii); - } - }); - -}); diff --git a/__tests__/__snapshots__/Record.ts.snap b/__tests__/__snapshots__/Record.ts.snap new file mode 100644 index 0000000000..46daf60171 --- /dev/null +++ b/__tests__/__snapshots__/Record.ts.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Record does not accept a Record as constructor 1`] = `"Can not call \`Record\` with an immutable Record as default values. Use a plain javascript object instead."`; + +exports[`Record does not accept a non object as constructor 1`] = `"Can not call \`Record\` with a non-object as default values. Use a plain javascript object instead."`; + +exports[`Record does not accept an immutable object that is not a Record as constructor 1`] = `"Can not call \`Record\` with an immutable Collection as default values. Use a plain javascript object instead."`; diff --git a/__tests__/concat.ts b/__tests__/concat.ts index e65fed7f1d..35710a7c49 100644 --- a/__tests__/concat.ts +++ b/__tests__/concat.ts @@ -1,110 +1,222 @@ -/// -/// - -jest.autoMockOff(); - -import I = require('immutable'); -import Sequence = I.Sequence; - -declare function expect(val: any): ExpectWithIs; - -interface ExpectWithIs extends Expect { - is(expected: any): void; - not: ExpectWithIs; -} +import { describe, expect, it } from '@jest/globals'; +import { List, Seq, Set } from 'immutable'; describe('concat', () => { - - beforeEach(function () { - this.addMatchers({ - is: function(expected) { - return I.is(this.actual, expected); - } - }) - }) - it('concats two sequences', () => { - var a = Sequence(1,2,3); - var b = Sequence(4,5,6); - expect(a.concat(b)).is(Sequence(1,2,3,4,5,6)) - expect(a.concat(b).length).toBe(6); - expect(a.concat(b).toArray()).toEqual([1,2,3,4,5,6]); - }) + const a = Seq([1, 2, 3]); + const b = Seq([4, 5, 6]); + expect(a.concat(b).size).toBe(6); + expect(a.concat(b).toArray()).toEqual([1, 2, 3, 4, 5, 6]); + }); it('concats two object sequences', () => { - var a = Sequence({a:1,b:2,c:3}); - var b = Sequence({d:4,e:5,f:6}); - expect(a.length).toBe(3); - expect(a.concat(b).length).toBe(6); - expect(a.concat(b).toObject()).toEqual({a:1,b:2,c:3,d:4,e:5,f:6}); - }) - - it('concats objects', () => { - var a = Sequence({a:1,b:2,c:3}); - var b = {d:4,e:5,f:6}; - expect(a.concat(b).toObject()).toEqual({a:1,b:2,c:3,d:4,e:5,f:6}); - }) - - it('concats arrays', () => { - var a = Sequence(1,2,3); - var b = [4,5,6]; - expect(a.concat(b).length).toBe(6); - expect(a.concat(b).toObject()).toEqual([1,2,3,4,5,6]); - }) + const a = Seq({ a: 1, b: 2, c: 3 }); + const b = Seq({ d: 4, e: 5, f: 6 }); + expect(a.size).toBe(3); + expect(a.concat(b).size).toBe(6); + expect(a.concat(b).toObject()).toEqual({ + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6, + }); + }); + + it('concats objects to keyed seq', () => { + const a = Seq({ a: 1, b: 2, c: 3 }); + const b = { d: 4, e: 5, f: 6 }; + expect(a.concat(b).toObject()).toEqual({ + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6, + }); + }); + + it('doesnt concat raw arrays to keyed seq', () => { + const a = Seq({ a: 1, b: 2, c: 3 }); + const b = [4, 5, 6]; + expect(() => { + // @ts-expect-error -- test that runtime does throw + a.concat(b).toJS(); + }).toThrow('Expected [K, V] tuple: 4'); + }); + + it('concats arrays to indexed seq', () => { + const a = Seq([1, 2, 3]); + const b = [4, 5, 6]; + expect(a.concat(b).size).toBe(6); + expect(a.concat(b).toArray()).toEqual([1, 2, 3, 4, 5, 6]); + }); it('concats values', () => { - var a = Sequence(1,2,3); - expect(a.concat(4,5,6).length).toBe(6); - expect(a.concat(4,5,6).toObject()).toEqual([1,2,3,4,5,6]); - }) + const a = Seq([1, 2, 3]); + expect(a.concat(4, 5, 6).size).toBe(6); + expect(a.concat(4, 5, 6).toArray()).toEqual([1, 2, 3, 4, 5, 6]); + }); + + it('doesnt concat objects to indexed seq', () => { + const a = Seq([0, 1, 2, 3]); + const b = { 4: 4 }; + const i = a.concat(b); + expect(i.size).toBe(5); + expect(i.get(4)).toBe(b); + expect(i.toArray()).toEqual([0, 1, 2, 3, { 4: 4 }]); + }); it('concats multiple arguments', () => { - var a = Sequence(1,2,3); - var b = [4,5,6]; - var c = [7,8,9]; - expect(a.concat(b, c).length).toBe(9); - expect(a.concat(b, c).toObject()).toEqual([1,2,3,4,5,6,7,8,9]); - }) + const a = Seq([1, 2, 3]); + const b = [4, 5, 6]; + const c = [7, 8, 9]; + expect(a.concat(b, c).size).toBe(9); + expect(a.concat(b, c).toArray()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); + }); it('can concat itself!', () => { - var a = Sequence(1,2,3); - expect(a.concat(a, a).length).toBe(9); - expect(a.concat(a, a).toObject()).toEqual([1,2,3,1,2,3,1,2,3]); - }) + const a = Seq([1, 2, 3]); + expect(a.concat(a, a).size).toBe(9); + expect(a.concat(a, a).toArray()).toEqual([1, 2, 3, 1, 2, 3, 1, 2, 3]); + }); + + it('returns itself when concat does nothing', () => { + const a = Seq([1, 2, 3]); + const b = Seq(); + expect(a.concat()).toBe(a); + expect(a.concat(b)).toBe(a); + expect(b.concat(b)).toBe(b); + }); + + it('returns non-empty item when concat does nothing', () => { + const a = Seq([1, 2, 3]); + const b = Seq(); + expect(a.concat(b)).toBe(a); + expect(b.concat(a)).toBe(a); + expect(b.concat(b, b, b, a, b, b)).toBe(a); + }); + + it('always returns the same type', () => { + const a = Set([1, 2, 3]); + const b = List(); + expect(b.concat(a)).not.toBe(a); + expect(List.isList(b.concat(a))).toBe(true); + expect(b.concat(a)).toEqual(List([1, 2, 3])); + }); it('iterates repeated keys', () => { - var a = Sequence({a:1,b:2,c:3}); - expect(a.concat(a, a).toObject()).toEqual({a:1,b:2,c:3}); - expect(a.concat(a, a).toArray()).toEqual([1,2,3,1,2,3,1,2,3]); - expect(a.concat(a, a).keySeq().toArray()).toEqual(['a','b','c','a','b','c','a','b','c']); - }) + const a = Seq({ a: 1, b: 2, c: 3 }); + expect(a.concat(a, a).toObject()).toEqual({ a: 1, b: 2, c: 3 }); + expect(a.concat(a, a).valueSeq().toArray()).toEqual([ + 1, 2, 3, 1, 2, 3, 1, 2, 3, + ]); + expect(a.concat(a, a).keySeq().toArray()).toEqual([ + 'a', + 'b', + 'c', + 'a', + 'b', + 'c', + 'a', + 'b', + 'c', + ]); + expect(a.concat(a, a).toArray()).toEqual([ + ['a', 1], + ['b', 2], + ['c', 3], + ['a', 1], + ['b', 2], + ['c', 3], + ['a', 1], + ['b', 2], + ['c', 3], + ]); + }); it('lazily reverses un-indexed sequences', () => { - var a = Sequence({a:1,b:2,c:3}); - var b = Sequence({d:4,e:5,f:6}); - expect(a.concat(b).reverse().keySeq().toArray()).toEqual(['f','e','d','c','b','a']); - }) + const a = Seq({ a: 1, b: 2, c: 3 }); + const b = Seq({ d: 4, e: 5, f: 6 }); + expect(a.concat(b).reverse().keySeq().toArray()).toEqual([ + 'f', + 'e', + 'd', + 'c', + 'b', + 'a', + ]); + }); it('lazily reverses indexed sequences', () => { - var a = Sequence([1,2,3]); - expect(a.concat(a, a).reverse().length).toBe(9); - expect(a.concat(a, a).reverse().toArray()).toEqual([3,2,1,3,2,1,3,2,1]); - }) - - it('lazily reverses indexed sequences with unknown length, maintaining indicies', () => { - var a = Sequence([1,2,3]).filter(x=>true); - expect(a.concat(a, a).toKeyedSeq().reverse().length).toBe(undefined); - expect(a.concat(a, a).toKeyedSeq().reverse().entrySeq().toArray()).toEqual( - [[8,3],[7,2],[6,1],[5,3],[4,2],[3,1],[2,3],[1,2],[0,1]] - ); - }) + const a = Seq([1, 2, 3]); + expect(a.concat(a, a).reverse().size).toBe(9); + expect(a.concat(a, a).reverse().toArray()).toEqual([ + 3, 2, 1, 3, 2, 1, 3, 2, 1, + ]); + }); + + it('lazily reverses indexed sequences with unknown size, maintaining indicies', () => { + const a = Seq([1, 2, 3]).filter(() => true); + expect(a.size).toBe(undefined); // Note: lazy filter does not know what size in O(1). + expect(a.concat(a, a).toKeyedSeq().reverse().size).toBe(undefined); + expect(a.concat(a, a).toKeyedSeq().reverse().toArray()).toEqual([ + [8, 3], + [7, 2], + [6, 1], + [5, 3], + [4, 2], + [3, 1], + [2, 3], + [1, 2], + [0, 1], + ]); + }); it('counts from the end of the indexed sequence on negative index', () => { - var i = I.Vector(9, 5, 3, 1).map(x => - x); + const i = List.of(9, 5, 3, 1).map((x) => -x); expect(i.get(0)).toBe(-9); expect(i.get(-1)).toBe(-1); expect(i.get(-4)).toBe(-9); expect(i.get(-5, 888)).toBe(888); - }) - -}) + }); + + it('should iterate on many concatenated sequences', () => { + let meta = Seq(); + + for (let i = 0; i < 10000; ++i) { + meta = meta.concat(i) as Seq; // TODO fix typing + } + + expect(meta.toList().size).toBe(10000); + }); + + it('should handle iterator on many concatenated sequences', () => { + const nbLoops = 10000; + let meta = Seq(); + for (let i = 1; i < nbLoops; i++) { + meta = meta.concat(i) as Seq; // TODO fix typing + } + const it = meta[Symbol.iterator](); + let done = false; + let i = 0; + while (!done) { + const result = it.next(); + i++; + done = !!result.done; + } + expect(i).toBe(nbLoops); + }); + + it('should iterate on reverse order on concatenated sequences', () => { + let meta = Seq([1]); + meta = meta.concat(42); + const it = meta.reverse()[Symbol.iterator](); + const result = it.next(); + expect(result).toEqual({ + done: false, + value: 42, + }); + }); +}); diff --git a/__tests__/count.ts b/__tests__/count.ts index 88b9238cc2..488e8d8b5d 100644 --- a/__tests__/count.ts +++ b/__tests__/count.ts @@ -1,50 +1,80 @@ -/// -/// - -jest.autoMockOff(); - -import I = require('immutable'); +import { describe, expect, it } from '@jest/globals'; +import { Range, Seq } from 'immutable'; describe('count', () => { - it('counts sequences with known lengths', () => { - expect(I.Sequence(1,2,3,4,5).length).toBe(5); - expect(I.Sequence(1,2,3,4,5).count()).toBe(5); - }) + expect(Seq([1, 2, 3, 4, 5]).size).toBe(5); + expect(Seq([1, 2, 3, 4, 5]).count()).toBe(5); + }); - it('counts sequences with unknown lengths, resulting in a cached length', () => { - var seq = I.Sequence(1,2,3,4,5,6).filter(x => x % 2 === 0); - expect(seq.length).toBe(undefined); + it('counts sequences with unknown lengths, resulting in a cached size', () => { + const seq = Seq([1, 2, 3, 4, 5, 6]).filter((x) => x % 2 === 0); + expect(seq.size).toBe(undefined); expect(seq.count()).toBe(3); - expect(seq.length).toBe(3); - }) + expect(seq.size).toBe(3); + }); it('counts sequences with a specific predicate', () => { - var seq = I.Sequence(1,2,3,4,5,6); - expect(seq.length).toBe(6); - expect(seq.count(x => x > 3)).toBe(3); - }) - - it('counts by keyed sequence', () => { - var grouped = I.Sequence({a:1,b:2,c:3,d:4}).countBy(x => x % 2); - expect(grouped.toJS()).toEqual({1:2, 0:2}); - expect(grouped.get(1)).toEqual(2); - }) - - it('counts by indexed sequence', () => { - expect( - I.Sequence(1,2,3,4,5,6).countBy(x => x % 2).toJS() - ).toEqual( - {1:3, 0:3} - ); - }) - - it('counts by specific keys', () => { - expect( - I.Sequence(1,2,3,4,5,6).countBy(x => x % 2 ? 'odd' : 'even').toJS() - ).toEqual( - {odd:3, even:3} - ); - }) - -}) + const seq = Seq([1, 2, 3, 4, 5, 6]); + expect(seq.size).toBe(6); + expect(seq.count((x) => x > 3)).toBe(3); + }); + + describe('countBy', () => { + it('counts by keyed sequence', () => { + const grouped = Seq({ a: 1, b: 2, c: 3, d: 4 }).countBy((x) => x % 2); + expect(grouped.toJS()).toEqual({ 1: 2, 0: 2 }); + expect(grouped.get(1)).toEqual(2); + }); + + it('counts by indexed sequence', () => { + expect( + Seq([1, 2, 3, 4, 5, 6]) + .countBy((x) => x % 2) + .toJS() + ).toEqual({ 1: 3, 0: 3 }); + }); + + it('counts by specific keys', () => { + expect( + Seq([1, 2, 3, 4, 5, 6]) + .countBy((x) => (x % 2 ? 'odd' : 'even')) + .toJS() + ).toEqual({ odd: 3, even: 3 }); + }); + }); + + describe('isEmpty', () => { + it('is O(1) on sequences with known lengths', () => { + expect(Seq([1, 2, 3, 4, 5]).size).toBe(5); + expect(Seq([1, 2, 3, 4, 5]).isEmpty()).toBe(false); + expect(Seq().size).toBe(0); + expect(Seq().isEmpty()).toBe(true); + }); + + it('lazily evaluates Seq with unknown length', () => { + let seq = Seq([1, 2, 3, 4, 5, 6]).filter((x) => x % 2 === 0); + expect(seq.size).toBe(undefined); + expect(seq.isEmpty()).toBe(false); + expect(seq.size).toBe(undefined); + + seq = Seq([1, 2, 3, 4, 5, 6]).filter((x) => x > 10); + expect(seq.size).toBe(undefined); + expect(seq.isEmpty()).toBe(true); + expect(seq.size).toBe(undefined); + }); + + it('with infinitely long sequences of known length', () => { + const seq = Range(0, Infinity); + expect(seq.size).toBe(Infinity); + expect(seq.isEmpty()).toBe(false); + }); + + it('with infinitely long sequences of unknown length', () => { + const seq = Range(0, Infinity).filter((x) => x % 2 === 0); + expect(seq.size).toBe(undefined); + expect(seq.isEmpty()).toBe(false); + expect(seq.size).toBe(undefined); + }); + }); +}); diff --git a/__tests__/find.ts b/__tests__/find.ts new file mode 100644 index 0000000000..2f6f186690 --- /dev/null +++ b/__tests__/find.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from '@jest/globals'; +import { Seq } from 'immutable'; + +describe('find', () => { + it('find returns notSetValue when match is not found', () => { + expect(Seq([1, 2, 3, 4, 5, 6]).find(() => false, null, 9)).toEqual(9); + }); + + it('findEntry returns notSetValue when match is not found', () => { + expect( + Seq([1, 2, 3, 4, 5, 6]).findEntry( + () => false, + + null, + 9 + ) + ).toEqual(9); + }); + + it('findLastEntry returns notSetValue when match is not found', () => { + expect(Seq([1, 2, 3, 4, 5, 6]).findLastEntry(() => false, null, 9)).toEqual( + 9 + ); + }); +}); diff --git a/__tests__/flatten.ts b/__tests__/flatten.ts index bdc5d07f4b..0d5cea91e8 100644 --- a/__tests__/flatten.ts +++ b/__tests__/flatten.ts @@ -1,60 +1,143 @@ -/// -/// - -jest.autoMockOff(); - -import I = require('immutable'); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); +import { describe, expect, it } from '@jest/globals'; +import { Collection, fromJS, List, Range, Seq } from 'immutable'; describe('flatten', () => { - it('flattens sequences one level deep', () => { - var nested = I.fromJS([[1,2],[3,4],[5,6]]); - var flat = nested.flatten(); - expect(flat.toJS()).toEqual([1,2,3,4,5,6]); - }) + const nested = fromJS([ + [1, 2], + [3, 4], + [5, 6], + ]); + const flat = nested.flatten(); + expect(flat.toJS()).toEqual([1, 2, 3, 4, 5, 6]); + }); - it('returns an indexed sequence', () => { - var nested = I.fromJS([[1],2,3,[4,5,6]]); - var flat = nested.flatten(); - expect(flat.toString()).toEqual("Seq [ 1, 2, 3, 4, 5, 6 ]"); - }) + it('flattening a List returns a List', () => { + const nested = fromJS([[1], 2, 3, [4, 5, 6]]); + const flat = nested.flatten(); + expect(flat.toString()).toEqual('List [ 1, 2, 3, 4, 5, 6 ]'); + }); it('gives the correct iteration count', () => { - var nested = I.fromJS([[1,2,3],[4,5,6]]); - var flat = nested.flatten(); - expect(flat.forEach(x => x < 4)).toEqual(4); - }) + const nested = fromJS([ + [1, 2, 3], + [4, 5, 6], + ]); + const flat = nested.flatten(); + // @ts-expect-error -- `flatten` return type should be improved + expect(flat.forEach((x: number) => x < 4)).toEqual(4); + }); + + type SeqType = number | Array | Collection; - it('flattens anything sequenceable', () => { - var nested = I.Sequence(I.Range(1,3),[3,4],I.Vector(5,6,7),8); - var flat = nested.flatten(); - expect(flat.toJS()).toEqual([1,2,3,4,5,6,7,8]); - }) + it('flattens only Sequences (not sequenceables)', () => { + const nested = Seq([Range(1, 3), [3, 4], List([5, 6, 7]), 8]); + const flat = nested.flatten(); + expect(flat.toJS()).toEqual([1, 2, [3, 4], 5, 6, 7, 8]); + }); it('can be reversed', () => { - var nested = I.Sequence(I.Range(1,3),[3,4],I.Vector(5,6,7),8); - var flat = nested.flatten(); - var reversed = flat.reverse(); - expect(reversed.toJS()).toEqual([8,7,6,5,4,3,2,1]); - }) + const nested = Seq([Range(1, 3), [3, 4], List([5, 6, 7]), 8]); + const flat = nested.flatten(); + const reversed = flat.reverse(); + expect(reversed.toJS()).toEqual([8, 7, 6, 5, [3, 4], 2, 1]); + }); + + it('can flatten at various levels of depth', () => { + const deeplyNested = fromJS([ + [ + [ + ['A', 'B'], + ['A', 'B'], + ], + [ + ['A', 'B'], + ['A', 'B'], + ], + ], + [ + [ + ['A', 'B'], + ['A', 'B'], + ], + [ + ['A', 'B'], + ['A', 'B'], + ], + ], + ]); + + // deeply flatten + expect(deeplyNested.flatten().toJS()).toEqual([ + 'A', + 'B', + 'A', + 'B', + 'A', + 'B', + 'A', + 'B', + 'A', + 'B', + 'A', + 'B', + 'A', + 'B', + 'A', + 'B', + ]); + + // shallow flatten + expect(deeplyNested.flatten(true).toJS()).toEqual([ + [ + ['A', 'B'], + ['A', 'B'], + ], + [ + ['A', 'B'], + ['A', 'B'], + ], + [ + ['A', 'B'], + ['A', 'B'], + ], + [ + ['A', 'B'], + ['A', 'B'], + ], + ]); + + // flatten two levels + expect(deeplyNested.flatten(2).toJS()).toEqual([ + ['A', 'B'], + ['A', 'B'], + ['A', 'B'], + ['A', 'B'], + ['A', 'B'], + ['A', 'B'], + ['A', 'B'], + ['A', 'B'], + ]); + }); describe('flatMap', () => { + it('first maps, then shallow flattens', () => { + const numbers = Range(97, 100); + const letters = numbers.flatMap((v) => + fromJS([String.fromCharCode(v), String.fromCharCode(v).toUpperCase()]) + ); + expect(letters.toJS()).toEqual(['a', 'A', 'b', 'B', 'c', 'C']); + }); - it('first maps, then flattens', () => { - var numbers = I.Range(97, 100); - var letters = numbers.flatMap(v => [ + it('maps to sequenceables, not only Sequences.', () => { + const numbers = Range(97, 100); + // the map function returns an Array, rather than a Collection. + // Array is iterable, so this works just fine. + const letters = numbers.flatMap((v) => [ String.fromCharCode(v), String.fromCharCode(v).toUpperCase(), ]); - expect(letters.toJS()).toEqual( - ['a','A','b','B','c','C'] - ) - }) - - }) - -}) - + expect(letters.toJS()).toEqual(['a', 'A', 'b', 'B', 'c', 'C']); + }); + }); +}); diff --git a/__tests__/fromJS.ts b/__tests__/fromJS.ts new file mode 100644 index 0000000000..90f70228e2 --- /dev/null +++ b/__tests__/fromJS.ts @@ -0,0 +1,81 @@ +import { describe, expect, it } from '@jest/globals'; +import { runInNewContext } from 'vm'; +import { List, Map, Set, isCollection, fromJS } from 'immutable'; + +describe('fromJS', () => { + it('convert Array to Immutable.List', () => { + const list = fromJS([1, 2, 3]); + expect(List.isList(list)).toBe(true); + expect(list.count()).toBe(3); + }); + + it('convert plain Object to Immutable.Map', () => { + const map = fromJS({ a: 'A', b: 'B', c: 'C' }); + expect(Map.isMap(map)).toBe(true); + expect(map.count()).toBe(3); + }); + + it('convert JS (global) Set to Immutable.Set', () => { + const set = fromJS(new global.Set([1, 2, 3])); + expect(Set.isSet(set)).toBe(true); + expect(set.count()).toBe(3); + }); + + it('convert JS (global) Map to Immutable.Map', () => { + const map = fromJS( + new global.Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]) + ); + expect(Map.isMap(map)).toBe(true); + expect(map.count()).toBe(3); + }); + + it('convert iterable to Immutable collection', () => { + function* values() { + yield 1; + yield 2; + yield 3; + } + const result = fromJS(values()); + expect(List.isList(result)).toBe(true); + expect(result.count()).toBe(3); + }); + + it('does not convert existing Immutable collections', () => { + const orderedSet = Set(['a', 'b', 'c']); + expect(fromJS(orderedSet)).toBe(orderedSet); + }); + + it('does not convert strings', () => { + expect(fromJS('abc')).toBe('abc'); + }); + + it('does not convert non-plain Objects', () => { + class Test {} + const result = fromJS(new Test()); + expect(isCollection(result)).toBe(false); + expect(result instanceof Test).toBe(true); + }); + + it('is iterable outside of a vm', () => { + expect(isCollection(fromJS({}))).toBe(true); + }); + + // eslint-disable-next-line jest/expect-expect + it('is iterable inside of a vm', () => { + runInNewContext( + ` + expect(isCollection(fromJS({}))).toBe(true); + `, + { + expect, + isCollection, + fromJS, + }, + {} + ); + }); +}); diff --git a/__tests__/functional/get.ts b/__tests__/functional/get.ts new file mode 100644 index 0000000000..901724f1c3 --- /dev/null +++ b/__tests__/functional/get.ts @@ -0,0 +1,37 @@ +import { describe, expect, it } from '@jest/globals'; +import { get, Map, List, Range } from 'immutable'; + +describe('get', () => { + it('for immutable structure', () => { + expect(get(Range(0, 100), 20)).toBe(20); + expect(get(List(['dog', 'frog', 'cat']), 1)).toBe('frog'); + expect(get(List(['dog', 'frog', 'cat']), 20)).toBeUndefined(); + expect(get(List(['dog', 'frog', 'cat']), 20, 'ifNotSet')).toBe('ifNotSet'); + + expect(get(Map({ x: 123, y: 456 }), 'x')).toBe(123); + }); + + it('for Array', () => { + expect(get(['dog', 'frog', 'cat'], 1)).toBe('frog'); + expect(get(['dog', 'frog', 'cat'], 20)).toBeUndefined(); + expect(get(['dog', 'frog', 'cat'], 20, 'ifNotSet')).toBe('ifNotSet'); + }); + + it('for plain objects', () => { + expect(get({ x: 123, y: 456 }, 'x')).toBe(123); + expect(get({ x: 123, y: 456 }, 'z', 'ifNotSet')).toBe('ifNotSet'); + + expect( + get( + { + x: 'xx', + y: 'yy', + get: function (key: string) { + return `${this[key].toUpperCase()}`; + }, + }, + 'x' + ) + ).toBe('XX'); + }); +}); diff --git a/__tests__/functional/has.ts b/__tests__/functional/has.ts new file mode 100644 index 0000000000..3d4f550dec --- /dev/null +++ b/__tests__/functional/has.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from '@jest/globals'; +import { has, Map, List, Range } from 'immutable'; + +describe('has', () => { + it('for immutable structure', () => { + expect(has(Range(0, 100), 20)).toBe(true); + expect(has(List(['dog', 'frog', 'cat']), 1)).toBe(true); + expect(has(List(['dog', 'frog', 'cat']), 20)).toBe(false); + + expect(has(Map({ x: 123, y: 456 }), 'x')).toBe(true); + }); + it('for Array', () => { + expect(has(['dog', 'frog', 'cat'], 1)).toBe(true); + expect(has(['dog', 'frog', 'cat'], 20)).toBe(false); + }); + + it('for plain objects', () => { + expect(has({ x: 123, y: 456 }, 'x')).toBe(true); + expect(has({ x: 123, y: 456 }, 'z')).toBe(false); + }); +}); diff --git a/__tests__/functional/remove.ts b/__tests__/functional/remove.ts new file mode 100644 index 0000000000..10674c695b --- /dev/null +++ b/__tests__/functional/remove.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from '@jest/globals'; +import { remove, List, Map } from 'immutable'; + +describe('remove', () => { + it('for immutable structure', () => { + expect(remove(List(['dog', 'frog', 'cat']), 1)).toEqual( + List(['dog', 'cat']) + ); + expect(remove(Map({ x: 123, y: 456 }), 'x')).toEqual(Map({ y: 456 })); + }); + + it('for Array', () => { + expect(remove(['dog', 'frog', 'cat'], 1)).toEqual(['dog', 'cat']); + }); + + it('for plain objects', () => { + expect(remove({ x: 123, y: 456 }, 'x')).toEqual({ y: 456 }); + }); +}); diff --git a/__tests__/functional/set.ts b/__tests__/functional/set.ts new file mode 100644 index 0000000000..154009880a --- /dev/null +++ b/__tests__/functional/set.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from '@jest/globals'; +import { set } from 'immutable'; + +describe('set', () => { + it('for immutable structure', () => { + const originalArray = ['dog', 'frog', 'cat']; + expect(set(originalArray, 1, 'cow')).toEqual(['dog', 'cow', 'cat']); + expect(set(originalArray, 4, 'cow')).toEqual([ + 'dog', + 'frog', + 'cat', + undefined, + 'cow', + ]); + expect(originalArray).toEqual(['dog', 'frog', 'cat']); + + const originalObject = { x: 123, y: 456 }; + expect(set(originalObject, 'x', 789)).toEqual({ x: 789, y: 456 }); + expect(set(originalObject, 'z', 789)).toEqual({ x: 123, y: 456, z: 789 }); + expect(originalObject).toEqual({ x: 123, y: 456 }); + }); + + it('for Array', () => { + const originalArray = ['dog', 'frog', 'cat']; + expect(set(originalArray, 1, 'cow')).toEqual(['dog', 'cow', 'cat']); + expect(set(originalArray, 4, 'cow')).toEqual([ + 'dog', + 'frog', + 'cat', + undefined, + 'cow', + ]); + expect(originalArray).toEqual(['dog', 'frog', 'cat']); + }); + + it('for plain objects', () => { + const originalObject = { x: 123, y: 456 }; + expect(set(originalObject, 'x', 789)).toEqual({ x: 789, y: 456 }); + expect(set(originalObject, 'z', 789)).toEqual({ x: 123, y: 456, z: 789 }); + expect(originalObject).toEqual({ x: 123, y: 456 }); + }); +}); diff --git a/__tests__/functional/update.ts b/__tests__/functional/update.ts new file mode 100644 index 0000000000..0ed9042e85 --- /dev/null +++ b/__tests__/functional/update.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from '@jest/globals'; +import { update } from 'immutable'; + +describe('update', () => { + it('for immutable structure', () => { + const originalArray = ['dog', 'frog', 'cat']; + expect(update(originalArray, 1, (val) => val?.toUpperCase())).toEqual([ + 'dog', + 'FROG', + 'cat', + ]); + expect(originalArray).toEqual(['dog', 'frog', 'cat']); + + const originalObject = { x: 123, y: 456 }; + expect(update(originalObject, 'x', (val) => val * 6)).toEqual({ + x: 738, + y: 456, + }); + expect(originalObject).toEqual({ x: 123, y: 456 }); + }); + + it('for Array', () => { + const originalArray = ['dog', 'frog', 'cat']; + expect(update(originalArray, 1, (val) => val?.toUpperCase())).toEqual([ + 'dog', + 'FROG', + 'cat', + ]); + expect(originalArray).toEqual(['dog', 'frog', 'cat']); + }); + + it('for plain objects', () => { + const originalObject = { x: 123, y: 456 }; + expect(update(originalObject, 'x', (val) => val * 6)).toEqual({ + x: 738, + y: 456, + }); + expect(originalObject).toEqual({ x: 123, y: 456 }); + }); +}); diff --git a/__tests__/get.ts b/__tests__/get.ts new file mode 100644 index 0000000000..7853ad30ca --- /dev/null +++ b/__tests__/get.ts @@ -0,0 +1,49 @@ +import { describe, expect, it } from '@jest/globals'; +import { Range } from 'immutable'; + +describe('get', () => { + it('gets any index', () => { + const seq = Range(0, 100); + expect(seq.get(20)).toBe(20); + }); + + it('gets first', () => { + const seq = Range(0, 100); + expect(seq.first()).toBe(0); + }); + + it('gets last', () => { + const seq = Range(0, 100); + expect(seq.last()).toBe(99); + }); + + it('gets any index after reversing', () => { + const seq = Range(0, 100).reverse(); + expect(seq.get(20)).toBe(79); + }); + + it('gets first after reversing', () => { + const seq = Range(0, 100).reverse(); + expect(seq.first()).toBe(99); + }); + + it('gets last after reversing', () => { + const seq = Range(0, 100).reverse(); + expect(seq.last()).toBe(0); + }); + + it('gets any index when size is unknown', () => { + const seq = Range(0, 100).filter((x) => x % 2 === 1); + expect(seq.get(20)).toBe(41); + }); + + it('gets first when size is unknown', () => { + const seq = Range(0, 100).filter((x) => x % 2 === 1); + expect(seq.first()).toBe(1); + }); + + it('gets last when size is unknown', () => { + const seq = Range(0, 100).filter((x) => x % 2 === 1); + expect(seq.last()).toBe(99); // Note: this is O(N) + }); +}); diff --git a/__tests__/getIn.ts b/__tests__/getIn.ts new file mode 100644 index 0000000000..57074034c6 --- /dev/null +++ b/__tests__/getIn.ts @@ -0,0 +1,97 @@ +import { describe, expect, it } from '@jest/globals'; +import { fromJS, getIn, List, Map } from 'immutable'; + +describe('getIn', () => { + it('deep get', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + expect(m.getIn(['a', 'b', 'c'])).toEqual(10); + expect(getIn(m, ['a', 'b', 'c'])).toEqual(10); + }); + + it('deep get with list as keyPath', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + expect(m.getIn(fromJS(['a', 'b', 'c']))).toEqual(10); + expect(getIn(m, fromJS(['a', 'b', 'c']))).toEqual(10); + }); + + it('deep get throws without list or array-like', () => { + // @ts-expect-error -- test that runtime does throw + expect(() => Map().getIn(undefined)).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: undefined' + ); + // @ts-expect-error -- test that runtime does throw + expect(() => Map().getIn({ a: 1, b: 2 })).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: [object Object]' + ); + // TODO: should expect error + expect(() => Map().getIn('abc')).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: abc' + ); + // TODO: should expect error + expect(() => getIn(Map(), 'abc')).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: abc' + ); + }); + + it('deep get returns not found if path does not match', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + expect(m.getIn(['a', 'b', 'z'])).toEqual(undefined); + expect(m.getIn(['a', 'b', 'z'], 123)).toEqual(123); + expect(m.getIn(['a', 'y', 'z'])).toEqual(undefined); + expect(m.getIn(['a', 'y', 'z'], 123)).toEqual(123); + expect(getIn(m, ['a', 'y', 'z'])).toEqual(undefined); + expect(getIn(m, ['a', 'y', 'z'], 123)).toEqual(123); + }); + + it('does not use notSetValue when path does exist but value is nullable', () => { + const m = fromJS({ a: { b: { c: null, d: undefined } } }); + expect(m.getIn(['a', 'b', 'c'])).toEqual(null); + expect(m.getIn(['a', 'b', 'd'])).toEqual(undefined); + expect(m.getIn(['a', 'b', 'c'], 123)).toEqual(null); + expect(m.getIn(['a', 'b', 'd'], 123)).toEqual(undefined); + expect(getIn(m, ['a', 'b', 'c'], 123)).toEqual(null); + expect(getIn(m, ['a', 'b', 'd'], 123)).toEqual(undefined); + }); + + it('deep get returns not found if path encounters non-data-structure', () => { + const m = fromJS({ a: { b: { c: null, d: undefined } } }); + expect(m.getIn(['a', 'b', 'c', 'x'])).toEqual(undefined); + expect(m.getIn(['a', 'b', 'c', 'x'], 123)).toEqual(123); + expect(m.getIn(['a', 'b', 'd', 'x'])).toEqual(undefined); + expect(m.getIn(['a', 'b', 'd', 'x'], 123)).toEqual(123); + expect(getIn(m, ['a', 'b', 'd', 'x'])).toEqual(undefined); + expect(getIn(m, ['a', 'b', 'd', 'x'], 123)).toEqual(123); + + expect(getIn('a', ['length'])).toEqual(undefined); + expect(getIn(new Date(), ['getDate'])).toEqual(undefined); + }); + + it('gets in nested plain Objects and Arrays', () => { + const m = List([{ key: ['item'] }]); + expect(m.getIn([0, 'key', 0])).toEqual('item'); + }); + + it('deep get returns not found if non-existing path in nested plain Object', () => { + const deep = Map({ + key: { regular: 'jsobj' }, + list: List([Map({ num: 10 })]), + }); + expect(deep.getIn(['key', 'foo', 'item'])).toBe(undefined); + expect(deep.getIn(['key', 'foo', 'item'], 'notSet')).toBe('notSet'); + expect(deep.getIn(['list', 0, 'num', 'badKey'])).toBe(undefined); + expect(deep.getIn(['list', 0, 'num', 'badKey'], 'notSet')).toBe('notSet'); + }); + + it('gets in plain Objects and Arrays', () => { + const m = [{ key: ['item'] }]; + expect(getIn(m, [0, 'key', 0])).toEqual('item'); + }); + + it('deep get returns not found if non-existing path in plain Object', () => { + const deep = { key: { regular: 'jsobj' }, list: [{ num: 10 }] }; + expect(getIn(deep, ['key', 'foo', 'item'])).toBe(undefined); + expect(getIn(deep, ['key', 'foo', 'item'], 'notSet')).toBe('notSet'); + expect(getIn(deep, ['list', 0, 'num', 'badKey'])).toBe(undefined); + expect(getIn(deep, ['list', 0, 'num', 'badKey'], 'notSet')).toBe('notSet'); + }); +}); diff --git a/__tests__/groupBy.ts b/__tests__/groupBy.ts index 1ae990d606..bfaba132df 100644 --- a/__tests__/groupBy.ts +++ b/__tests__/groupBy.ts @@ -1,50 +1,107 @@ -/// -/// +import { describe, expect, it } from '@jest/globals'; +import { + Collection, + Map, + Seq, + isOrdered, + OrderedMap, + List, + OrderedSet, + Set, + Stack, +} from 'immutable'; -jest.autoMockOff(); +describe('groupBy', () => { + it.each` + constructor | constructorIsOrdered | isObject + ${Collection} | ${true} | ${false} + ${List} | ${true} | ${false} + ${Seq} | ${true} | ${false} + ${Set} | ${false} | ${false} + ${Stack} | ${true} | ${false} + ${OrderedSet} | ${true} | ${false} + ${Map} | ${false} | ${true} + ${OrderedMap} | ${true} | ${true} + `( + 'groupBy returns ordered or unordered of the base type is ordered or not: $constructor.name', + ({ constructor, constructorIsOrdered, isObject }) => { + const iterableConstructor = ['a', 'b', 'a', 'c']; + const objectConstructor = { a: 1, b: 2, c: 3, d: 1 }; -import I = require('immutable'); + const col = constructor( + isObject ? objectConstructor : iterableConstructor + ); -describe('groupBy', () => { + const grouped = col.groupBy((v) => v); + + // all groupBy should be instance of Map + expect(grouped).toBeInstanceOf(Map); + + // ordered objects should be instance of OrderedMap + expect(isOrdered(col)).toBe(constructorIsOrdered); + expect(isOrdered(grouped)).toBe(constructorIsOrdered); + if (constructorIsOrdered) { + // eslint-disable-next-line jest/no-conditional-expect + expect(grouped).toBeInstanceOf(OrderedMap); + } else { + // eslint-disable-next-line jest/no-conditional-expect + expect(grouped).not.toBeInstanceOf(OrderedMap); + } + } + ); it('groups keyed sequence', () => { - var grouped = I.Sequence({a:1,b:2,c:3,d:4}).groupBy(x => x % 2); - expect(grouped.toJS()).toEqual({1:{a:1,c:3}, 0:{b:2,d:4}}); + const grouped = Seq({ a: 1, b: 2, c: 3, d: 4 }).groupBy((x) => x % 2); + expect(grouped.toJS()).toEqual({ 1: { a: 1, c: 3 }, 0: { b: 2, d: 4 } }); // Each group should be a keyed sequence, not an indexed sequence - expect(grouped.get(1).toArray()).toEqual([1, 3]); - }) + const firstGroup = grouped.get(1); + expect(firstGroup && firstGroup.toArray()).toEqual([ + ['a', 1], + ['c', 3], + ]); + }); it('groups indexed sequence', () => { - expect( - I.Sequence(1,2,3,4,5,6).groupBy(x => x % 2).toJS() - ).toEqual( - {1:[1,3,5], 0:[2,4,6]} - ); - }) + const group = Seq([1, 2, 3, 4, 5, 6]).groupBy((x) => x % 2); + + expect(group.toJS()).toEqual({ 1: [1, 3, 5], 0: [2, 4, 6] }); + }); it('groups to keys', () => { - expect( - I.Sequence(1,2,3,4,5,6).groupBy(x => x % 2 ? 'odd' : 'even').toJS() - ).toEqual( - {odd:[1,3,5], even:[2,4,6]} + const group = Seq([1, 2, 3, 4, 5, 6]).groupBy((x) => + x % 2 ? 'odd' : 'even' ); - }) + expect(group.toJS()).toEqual({ odd: [1, 3, 5], even: [2, 4, 6] }); + }); - it('groups indexed sequences, maintaining indicies', () => { - expect( - I.Sequence(1,2,3,4,5,6).toKeyedSeq().groupBy(x => x % 2).toJS() - ).toEqual( - {1:[1,,3,,5,,,], 0:[,2,,4,,6]} + it('allows `undefined` as a key', () => { + const group = Seq([1, 2, 3, 4, 5, 6]).groupBy((x) => + x % 2 ? undefined : 'even' ); - }) + expect(group.toJS()).toEqual({ undefined: [1, 3, 5], even: [2, 4, 6] }); + }); + + it('groups indexed sequences, maintaining indicies when keyed sequences', () => { + const group = Seq([1, 2, 3, 4, 5, 6]).groupBy((x) => x % 2); + + expect(group.toJS()).toEqual({ 1: [1, 3, 5], 0: [2, 4, 6] }); + + const keyedGroup = Seq([1, 2, 3, 4, 5, 6]) + .toKeyedSeq() + .groupBy((x) => x % 2); + + expect(keyedGroup.toJS()).toEqual({ + 1: { 0: 1, 2: 3, 4: 5 }, + 0: { 1: 2, 3: 4, 5: 6 }, + }); + }); it('has groups that can be mapped', () => { - expect( - I.Sequence(1,2,3,4,5,6).groupBy(x => x % 2).map(group => group.map(value => value * 10)).toJS() - ).toEqual( - {1:[10,30,50], 0:[20,40,60]} - ); - }) + const mappedGroup = Seq([1, 2, 3, 4, 5, 6]) + .groupBy((x) => x % 2) + .map((group) => group.map((value) => value * 10)); -}) + expect(mappedGroup.toJS()).toEqual({ 1: [10, 30, 50], 0: [20, 40, 60] }); + }); +}); diff --git a/__tests__/hasIn.ts b/__tests__/hasIn.ts new file mode 100644 index 0000000000..da2baa0a89 --- /dev/null +++ b/__tests__/hasIn.ts @@ -0,0 +1,63 @@ +import { describe, expect, it } from '@jest/globals'; +import { fromJS, hasIn, List, Map } from 'immutable'; + +describe('hasIn', () => { + it('deep has', () => { + const m = fromJS({ a: { b: { c: 10, d: undefined } } }); + expect(m.hasIn(['a', 'b', 'c'])).toEqual(true); + expect(m.hasIn(['a', 'b', 'd'])).toEqual(true); + expect(m.hasIn(['a', 'b', 'z'])).toEqual(false); + expect(m.hasIn(['a', 'y', 'z'])).toEqual(false); + expect(hasIn(m, ['a', 'b', 'c'])).toEqual(true); + expect(hasIn(m, ['a', 'b', 'z'])).toEqual(false); + }); + + it('deep has with list as keyPath', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + expect(m.hasIn(fromJS(['a', 'b', 'c']))).toEqual(true); + expect(m.hasIn(fromJS(['a', 'b', 'z']))).toEqual(false); + expect(m.hasIn(fromJS(['a', 'y', 'z']))).toEqual(false); + expect(hasIn(m, fromJS(['a', 'b', 'c']))).toEqual(true); + expect(hasIn(m, fromJS(['a', 'y', 'z']))).toEqual(false); + }); + + it('deep has throws without list or array-like', () => { + // @ts-expect-error -- test that runtime does throw + expect(() => Map().hasIn(undefined)).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: undefined' + ); + // @ts-expect-error -- test that runtime does throw + expect(() => Map().hasIn({ a: 1, b: 2 })).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: [object Object]' + ); + // TODO: should expect error + expect(() => Map().hasIn('abc')).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: abc' + ); + // TODO: should expect error + expect(() => hasIn(Map(), 'abc')).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: abc' + ); + }); + + it('deep has does not throw if non-readable path', () => { + const deep = Map({ + key: { regular: 'jsobj' }, + list: List([Map({ num: 10 })]), + }); + expect(deep.hasIn(['key', 'foo', 'item'])).toBe(false); + expect(deep.hasIn(['list', 0, 'num', 'badKey'])).toBe(false); + expect(hasIn(deep, ['key', 'foo', 'item'])).toBe(false); + expect(hasIn(deep, ['list', 0, 'num', 'badKey'])).toBe(false); + }); + + it('deep has in plain Object and Array', () => { + const m = { a: { b: { c: [10, undefined], d: undefined } } }; + expect(hasIn(m, ['a', 'b', 'c', 0])).toEqual(true); + expect(hasIn(m, ['a', 'b', 'c', 1])).toEqual(true); + expect(hasIn(m, ['a', 'b', 'c', 2])).toEqual(false); + expect(hasIn(m, ['a', 'b', 'd'])).toEqual(true); + expect(hasIn(m, ['a', 'b', 'z'])).toEqual(false); + expect(hasIn(m, ['a', 'b', 'z'])).toEqual(false); + }); +}); diff --git a/__tests__/hash.ts b/__tests__/hash.ts new file mode 100644 index 0000000000..168ded87f1 --- /dev/null +++ b/__tests__/hash.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from '@jest/globals'; +import { hash } from 'immutable'; +import fc from 'fast-check'; + +describe('hash', () => { + it('stable hash of well known values', () => { + expect(hash(true)).toBe(0x42108421); + expect(hash(false)).toBe(0x42108420); + expect(hash(0)).toBe(0); + expect(hash(null)).toBe(0x42108422); + expect(hash(undefined)).toBe(0x42108423); + expect(hash('a')).toBe(97); + expect(hash('immutable-js')).toBe(510203252); + expect(hash(123)).toBe(123); + }); + + it('generates different hashes for decimal values', () => { + expect(hash(123.456)).toBe(884763256); + expect(hash(123.4567)).toBe(887769707); + }); + + it('generates different hashes for different objects', () => { + const objA = {}; + const objB = {}; + expect(hash(objA)).toBe(hash(objA)); + expect(hash(objA)).not.toBe(hash(objB)); + }); + + it('generates different hashes for different symbols', () => { + const symA = Symbol(); + + const symB = Symbol(); + expect(hash(symA)).toBe(hash(symA)); + expect(hash(symA)).not.toBe(hash(symB)); + }); + + it('generates different hashes for different functions', () => { + const funA = () => {}; + const funB = () => {}; + expect(hash(funA)).toBe(hash(funA)); + expect(hash(funA)).not.toBe(hash(funB)); + }); + + const genValue = fc.oneof(fc.string(), fc.integer()); + + it('generates unsigned 31-bit integers', () => { + fc.assert( + fc.property(genValue, (value) => { + const hashVal = hash(value); + expect(Number.isInteger(hashVal)).toBe(true); + expect(hashVal).toBeGreaterThan(-(2 ** 31)); + expect(hashVal).toBeLessThan(2 ** 31); + }) + ); + }); +}); diff --git a/__tests__/interpose.ts b/__tests__/interpose.ts new file mode 100644 index 0000000000..a3698628af --- /dev/null +++ b/__tests__/interpose.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from '@jest/globals'; +import { Range } from 'immutable'; + +describe('interpose', () => { + it('separates with a value', () => { + const range = Range(10, 15); + const interposed = range.interpose(0); + expect(interposed.toArray()).toEqual([10, 0, 11, 0, 12, 0, 13, 0, 14]); + }); + + it('can be iterated', () => { + const range = Range(10, 15); + const interposed = range.interpose(0); + const values = interposed.values(); + expect(values.next()).toEqual({ value: 10, done: false }); + expect(values.next()).toEqual({ value: 0, done: false }); + expect(values.next()).toEqual({ value: 11, done: false }); + expect(values.next()).toEqual({ value: 0, done: false }); + expect(values.next()).toEqual({ value: 12, done: false }); + expect(values.next()).toEqual({ value: 0, done: false }); + expect(values.next()).toEqual({ value: 13, done: false }); + expect(values.next()).toEqual({ value: 0, done: false }); + expect(values.next()).toEqual({ value: 14, done: false }); + expect(values.next()).toEqual({ value: undefined, done: true }); + }); +}); diff --git a/__tests__/issues.ts b/__tests__/issues.ts new file mode 100644 index 0000000000..e283378cfc --- /dev/null +++ b/__tests__/issues.ts @@ -0,0 +1,185 @@ +import { describe, expect, it } from '@jest/globals'; +import { + fromJS, + List, + Map, + OrderedMap, + OrderedSet, + Record, + Seq, + Set, +} from 'immutable'; + +describe('Issue #1175', () => { + it('invalid hashCode() response should not infinitly recurse', () => { + class BadHash { + equals() { + return false; + } + + hashCode() { + return 2 ** 32; + } + } + + const set = Set([new BadHash()]); + expect(set.size).toEqual(1); + }); +}); + +describe('Issue #1188', () => { + it('Removing items from OrderedSet should return OrderedSet', () => { + const orderedSet = OrderedSet(['one', 'two', 'three']); + const emptyOrderedSet = orderedSet.subtract(['two', 'three', 'one']); + expect(OrderedSet.isOrderedSet(emptyOrderedSet)).toBe(true); + }); +}); + +describe('Issue #1220 : Seq.rest() throws an exception when invoked on a single item sequence', () => { + it('should be iterable', () => { + // Helper for this test + const ITERATOR_SYMBOL = + (typeof Symbol === 'function' && Symbol.iterator) || '@@iterator'; + + const r = Seq([1]).rest(); + const i = r[ITERATOR_SYMBOL](); + expect(i.next()).toEqual({ value: undefined, done: true }); + }); +}); + +describe('Issue #1245', () => { + it('should return empty collection after takeLast(0)', () => { + const size = List(['a', 'b', 'c']).takeLast(0).size; + expect(size).toEqual(0); + }); +}); + +describe('Issue #1262', () => { + it('Set.subtract should accept an array', () => { + const MyType = Record({ val: 1 }); + const set1 = Set([ + MyType({ val: 1 }), + MyType({ val: 2 }), + MyType({ val: 3 }), + ]); + const set2 = set1.subtract([MyType({ val: 2 })]); + const set3 = set1.subtract(List([MyType({ val: 2 })])); + expect(set2).toEqual(set3); + }); +}); + +describe('Issue #1287', () => { + it('should skip all items in OrderedMap when skipping Infinity', () => { + const size = OrderedMap([['a', 1]]).skip(Infinity).size; + expect(size).toEqual(0); + }); +}); + +describe('Issue #1247', () => { + it('Records should not be considered altered after creation', () => { + const R = Record({ a: 1 }); + const r = new R(); + expect(r.wasAltered()).toBe(false); + }); +}); + +describe('Issue #1252', () => { + it('should be toString-able even if it contains a value which is not', () => { + const prototypelessObj = Object.create(null); + const list = List([prototypelessObj]); + expect(list.toString()).toBe('List [ {} ]'); + }); +}); + +describe('Issue #1293', () => { + it('merge() should not deeply coerce values', () => { + type StateObject = { foo: string | { qux: string }; biz?: string }; + const State = Record({ foo: 'bar', biz: 'baz' }); + const deepObject = { qux: 'quux' }; + + const firstState = State({ foo: deepObject }); + const secondState = State().merge({ foo: deepObject }); + + expect(secondState).toEqual(firstState); + }); +}); + +describe('Issue #1643', () => { + [ + ['a string', 'test'], + ['a number', 5], + ['null', null], + ['undefined', undefined], + ['a boolean', true], + ['an object', {}], + ['an array', []], + ['a function', () => null], + ].forEach(([label, value]) => { + class MyClass { + valueOf() { + return value; + } + } + + it(`Collection#hashCode() should handle objects that return ${label} for valueOf`, () => { + const set = Set().add(new MyClass()); + expect(() => set.hashCode()).not.toThrow(); + }); + }); +}); + +describe('Issue #1785', () => { + it('merge() should not return undefined', () => { + const emptyRecord = Record({})(); + + expect(emptyRecord.merge({ id: 1 })).toBe(emptyRecord); + }); +}); + +describe('Issue #1475', () => { + it('complex case should return first value on mergeDeep when types are incompatible', () => { + const a = fromJS({ + ch: [ + { + code: 8, + }, + ], + }) as Map; + const b = fromJS({ + ch: { + code: 8, + }, + }); + expect(a.mergeDeep(b).equals(b)).toBe(true); + }); + + it('simple case should return first value on mergeDeep when types are incompatible', () => { + const a = fromJS({ + ch: [], + }) as Map; + const b = fromJS({ + ch: { code: 8 }, + }); + expect(a.merge(b).equals(b)).toBe(true); + }); +}); + +describe('Issue #1719', () => { + it('mergeDeep() should overwrite when types conflict', () => { + const objWithObj = fromJS({ + items: { + '1': { + id: '1', + }, + }, + }) as Map; + const objWithArray = fromJS({ + items: [ + { + id: '1', + }, + ], + }); + expect(objWithObj.mergeDeep(objWithArray).equals(objWithArray)).toBe(true); + }); +}); diff --git a/__tests__/join.ts b/__tests__/join.ts index cf73886521..4d6d472835 100644 --- a/__tests__/join.ts +++ b/__tests__/join.ts @@ -1,35 +1,52 @@ -/// -/// - -jest.autoMockOff(); - -import I = require('immutable'); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); +import { describe, expect, it } from '@jest/globals'; +import { Seq } from 'immutable'; +import fc from 'fast-check'; describe('join', () => { - it('string-joins sequences with commas by default', () => { - expect(I.Sequence(1,2,3,4,5).join()).toBe('1,2,3,4,5'); - }) + expect(Seq([1, 2, 3, 4, 5]).join()).toBe('1,2,3,4,5'); + }); it('string-joins sequences with any string', () => { - expect(I.Sequence(1,2,3,4,5).join('foo')).toBe('1foo2foo3foo4foo5'); - }) + expect(Seq([1, 2, 3, 4, 5]).join('foo')).toBe('1foo2foo3foo4foo5'); + }); it('string-joins sequences with empty string', () => { - expect(I.Sequence(1,2,3,4,5).join('')).toBe('12345'); - }) + expect(Seq([1, 2, 3, 4, 5]).join('')).toBe('12345'); + }); it('joins sparse-sequences like Array.join', () => { - var a = [1,,2,,3,,4,,5,,,]; - expect(I.Sequence(a).join()).toBe(a.join()); - }) - - check.it('behaves the same as Array.join', - [gen.array(gen.primitive), gen.primitive], (array, joiner) => { - expect(I.Sequence(array).join(joiner)).toBe(array.join(joiner)); - }) - -}) + const a = [ + 1, + undefined, + 2, + undefined, + 3, + undefined, + 4, + undefined, + 5, + undefined, + undefined, + ]; + expect(Seq(a).join()).toBe(a.join()); + }); + + const genPrimitive = fc.oneof( + fc.string(), + fc.integer(), + fc.boolean(), + fc.constant(null), + fc.constant(undefined), + fc.constant(NaN) + ); + + it('behaves the same as Array.join', () => { + fc.assert( + fc.property(fc.array(genPrimitive), genPrimitive, (array, joiner) => { + // @ts-expect-error unexpected values for typescript joiner, but valid at runtime despite the unexpected errors + expect(Seq(array).join(joiner)).toBe(array.join(joiner)); + }) + ); + }); +}); diff --git a/__tests__/merge.ts b/__tests__/merge.ts index fb7ae45c86..14e934b4c0 100644 --- a/__tests__/merge.ts +++ b/__tests__/merge.ts @@ -1,66 +1,349 @@ -/// -/// +import { describe, expect, it } from '@jest/globals'; +import { + fromJS, + List, + Map, + merge, + mergeDeep, + mergeDeepWith, + Record, + Set, +} from 'immutable'; -jest.autoMockOff(); - -import I = require('immutable'); +describe('merge', () => { + it('merges two maps', () => { + const m1 = Map({ a: 1, b: 2, c: 3 }); + const m2 = Map({ d: 10, b: 20, e: 30 }); + expect(m1.merge(m2)).toEqual(Map({ a: 1, b: 20, c: 3, d: 10, e: 30 })); + }); -declare function expect(val: any): ExpectWithIs; + it('can merge in an explicitly undefined value', () => { + const m1 = Map({ a: 1, b: 2 }); + const m2 = Map({ a: undefined }); + expect(m1.merge(m2)).toEqual(Map({ a: undefined, b: 2 })); + }); -interface ExpectWithIs extends Expect { - is(expected: any): void; - not: ExpectWithIs; -} + it('merges two maps with a merge function', () => { + const m1 = Map({ a: 1, b: 2, c: 3 }); + const m2 = Map({ d: 10, b: 20, e: 30 }); + expect(m1.mergeWith((a: number, b: number) => a + b, m2)).toEqual( + Map({ a: 1, b: 22, c: 3, d: 10, e: 30 }) + ); + }); -describe('merge', () => { + it('throws typeError without merge function', () => { + const m1 = Map({ a: 1, b: 2, c: 3 }); + const m2 = Map({ d: 10, b: 20, e: 30 }); + // @ts-expect-error -- test that runtime does throw + expect(() => m1.mergeWith(1, m2)).toThrow(TypeError); + }); - beforeEach(function () { - this.addMatchers({ - is: function(expected) { - return I.is(this.actual, expected); - } - }) - }) + it('provides key as the third argument of merge function', () => { + const m1 = Map({ id: 'temp', b: 2, c: 3 }); + const m2 = Map({ id: 10, b: 20, e: 30 }); + const add = (a: number, b: number) => a + b; + expect( + // @ts-expect-error -- it's difficult to type `a` not as `string | number` + m1.mergeWith((a, b, key) => (key !== 'id' ? add(a, b) : b), m2) + ).toEqual(Map({ id: 10, b: 22, c: 3, e: 30 })); + }); - it('merges two maps', () => { - var m1 = I.Map({a:1,b:2,c:3}); - var m2 = I.Map({d:10,b:20,e:30}); - expect(m1.merge(m2)).is(I.Map({a:1,b:20,c:3,d:10,e:30})); - }) + it('deep merges two maps', () => { + const m1 = fromJS({ a: { b: { c: 1, d: 2 } } }); + const m2 = fromJS({ a: { b: { c: 10, e: 20 }, f: 30 }, g: 40 }); + expect(m1.mergeDeep(m2)).toEqual( + fromJS({ a: { b: { c: 10, d: 2, e: 20 }, f: 30 }, g: 40 }) + ); + }); - it('merges two maps with a merge function', () => { - var m1 = I.Map({a:1,b:2,c:3}); - var m2 = I.Map({d:10,b:20,e:30}); - expect(m1.mergeWith((a, b) => a + b, m2)).is(I.Map({a:1,b:22,c:3,d:10,e:30})); - }) + it('merge uses === for return-self optimization', () => { + const date1 = new Date(1234567890000); + // Value equal, but different reference. + const date2 = new Date(1234567890000); + const m = Map().set('a', date1); + expect(m.merge({ a: date2 })).not.toBe(m); + expect(m.merge({ a: date1 })).toBe(m); + }); - it('deep merges two maps', () => { - var m1 = I.fromJS({a:{b:{c:1,d:2}}}); - var m2 = I.fromJS({a:{b:{c:10,e:20},f:30},g:40}); - expect(m1.mergeDeep(m2)).is(I.fromJS({a:{b:{c:10,d:2,e:20},f:30},g:40})); - }) + it('deep merge uses === for return-self optimization', () => { + const date1 = new Date(1234567890000); + // Value equal, but different reference. + const date2 = new Date(1234567890000); + const m = Map().setIn(['a', 'b', 'c'], date1); + expect(m.mergeDeep({ a: { b: { c: date2 } } })).not.toBe(m); + expect(m.mergeDeep({ a: { b: { c: date1 } } })).toBe(m); + }); it('deep merges raw JS', () => { - var m1 = I.fromJS({a:{b:{c:1,d:2}}}); - var js = {a:{b:{c:10,e:20},f:30},g:40}; - expect(m1.mergeDeep(js)).is(I.fromJS({a:{b:{c:10,d:2,e:20},f:30},g:40})); - }) + const m1 = fromJS({ a: { b: { c: 1, d: 2 } } }); + const js = { a: { b: { c: 10, e: 20 }, f: 30 }, g: 40 }; + expect(m1.mergeDeep(js)).toEqual( + fromJS({ a: { b: { c: 10, d: 2, e: 20 }, f: 30 }, g: 40 }) + ); + }); it('deep merges raw JS with a merge function', () => { - var m1 = I.fromJS({a:{b:{c:1,d:2}}}); - var js = {a:{b:{c:10,e:20},f:30},g:40}; - expect( - m1.mergeDeepWith((a, b) => a + b, js) - ).is(I.fromJS( - {a:{b:{c:11,d:2,e:20},f:30},g:40} - )); - }) + const m1 = fromJS({ a: { b: { c: 1, d: 2 } } }); + const js = { a: { b: { c: 10, e: 20 }, f: 30 }, g: 40 }; + // @ts-expect-error type of `mergeDeepWith` is too lazy for now + expect(m1.mergeDeepWith((a: number, b: number) => a + b, js)).toEqual( + fromJS({ a: { b: { c: 11, d: 2, e: 20 }, f: 30 }, g: 40 }) + ); + }); + + it('deep merges raw JS into raw JS with a merge function', () => { + const js1 = { a: { b: { c: 1, d: 2 } } }; + const js2 = { a: { b: { c: 10, e: 20 }, f: 30 }, g: 40 }; + // @ts-expect-error type of `mergeDeepWith` is too lazy for now + expect(mergeDeepWith((a: number, b: number) => a + b, js1, js2)).toEqual({ + a: { b: { c: 11, d: 2, e: 20 }, f: 30 }, + g: 40, + }); + }); + + it('deep merges collections into raw JS with a merge function', () => { + const js = { a: { b: { c: 1, d: 2 } } }; + const m = fromJS({ a: { b: { c: 10, e: 20 }, f: 30 }, g: 40 }); + // @ts-expect-error type of `mergeDeepWith` is too lazy for now + expect(mergeDeepWith((a: number, b: number) => a + b, js, m)).toEqual({ + a: { b: { c: 11, d: 2, e: 20 }, f: 30 }, + g: 40, + }); + }); it('returns self when a deep merges is a no-op', () => { - var m1 = I.fromJS({a:{b:{c:1,d:2}}}); + const m1 = fromJS({ a: { b: { c: 1, d: 2 } } }); + expect(m1.mergeDeep({ a: { b: { c: 1 } } })).toBe(m1); + }); + + it('returns arg when a deep merges is a no-op', () => { + const m1 = fromJS({ a: { b: { c: 1, d: 2 } } }); + expect(Map().mergeDeep(m1)).toBe(m1); + }); + + it('returns self when a deep merges is a no-op on raw JS', () => { + const m1 = { a: { b: { c: 1, d: 2 } } }; + expect(mergeDeep(m1, { a: { b: { c: 1 } } })).toBe(m1); + }); + + it('can overwrite existing maps', () => { + expect( + fromJS({ a: { x: 1, y: 1 }, b: { x: 2, y: 2 } }).merge({ + a: null, + b: Map({ x: 10 }), + }) + ).toEqual(fromJS({ a: null, b: { x: 10 } })); + expect( + fromJS({ a: { x: 1, y: 1 }, b: { x: 2, y: 2 } }).mergeDeep({ + a: null, + b: { x: 10 }, + }) + ).toEqual(fromJS({ a: null, b: { x: 10, y: 2 } })); + }); + + it('can overwrite existing maps with objects', () => { + const m1 = fromJS({ a: { x: 1, y: 1 } }); // deep conversion. + const m2 = Map({ a: { z: 10 } }); // shallow conversion to Map. + + // Raw object simply replaces map. + expect(m1.merge(m2).get('a')).toEqual({ z: 10 }); // raw object. + // However, mergeDeep will merge that value into the inner Map. + expect(m1.mergeDeep(m2).get('a')).toEqual(Map({ x: 1, y: 1, z: 10 })); + }); + + it('merges map entries with List and Set values', () => { + const initial = Map({ + a: Map({ x: 10, y: 20 }), + b: List([1, 2, 3]), + c: Set([1, 2, 3]), + }); + const additions = Map({ + a: Map({ y: 50, z: 100 }), + b: List([4, 5, 6]), + c: Set([4, 5, 6]), + }); + expect(initial.mergeDeep(additions)).toEqual( + Map({ + a: Map({ x: 10, y: 50, z: 100 }), + b: List([1, 2, 3, 4, 5, 6]), + c: Set([1, 2, 3, 4, 5, 6]), + }) + ); + }); + + it('merges map entries with new values', () => { + const initial = Map({ a: List([1]) }); + + // Note: merge and mergeDeep do not deeply coerce values, they only merge + // with what's there prior. + expect(initial.merge({ b: [2] })).toEqual(Map({ a: List([1]), b: [2] })); + expect(initial.mergeDeep({ b: [2] })).toEqual( + fromJS(Map({ a: List([1]), b: [2] })) + ); + }); + + it('maintains JS values inside immutable collections', () => { + const m1 = fromJS({ a: { b: { imm: 'map' } } }); + const m2 = m1.mergeDeep(Map({ a: Map({ b: { plain: 'obj' } }) })); + + expect(m1.getIn(['a', 'b'])).toEqual(Map([['imm', 'map']])); + // However mergeDeep will merge that value into the inner Map + expect(m2.getIn(['a', 'b'])).toEqual(Map({ imm: 'map', plain: 'obj' })); + }); + + it('merges plain Objects', () => { + expect(merge({ x: 1, y: 1 }, { y: 2, z: 2 }, Map({ z: 3, q: 3 }))).toEqual({ + x: 1, + y: 2, + z: 3, + q: 3, + }); + }); + + it('merges plain Arrays', () => { + expect(merge([1, 2], [3, 4], List([5, 6]))).toEqual([1, 2, 3, 4, 5, 6]); + }); + + it('merging plain Array returns self after no-op', () => { + const a = [1, 2, 3]; + expect(merge(a, [], [])).toBe(a); + }); + + it('merges records with a size property set to 0', () => { + const Sizable = Record({ size: 0 }); + expect(Sizable().merge({ size: 123 }).size).toBe(123); + }); + + it('mergeDeep merges partial conflicts', () => { + const a = fromJS({ + ch: [ + { + code: 8, + }, + ], + banana: 'good', + }) as Map; + const b = fromJS({ + ch: { + code: 8, + }, + apple: 'anti-doctor', + }); expect( - m1.mergeDeep({a:{b:{c:1}}}) - ).toBe(m1); - }) + a.mergeDeep(b).equals( + fromJS({ + ch: { + code: 8, + }, + apple: 'anti-doctor', + banana: 'good', + }) + ) + ).toBe(true); + }); + + const map = { type: 'Map', value: Map({ b: 5, c: 9 }) }; + const object = { type: 'object', value: { b: 7, d: 12 } }; + const RecordFactory = Record({ a: 1, b: 2 }); + const record = { type: 'Record', value: RecordFactory({ b: 3 }) }; + const list = { type: 'List', value: List(['5']) }; + const array = { type: 'array', value: ['9'] }; + const set = { type: 'Set', value: Set('3') }; + + const incompatibleTypes = [ + [map, list], + [map, array], + [map, set], + [object, list], + [object, array], + [object, set], + [record, list], + [record, array], + [record, set], + [list, set], + ]; + + for (const [ + { type: type1, value: value1 }, + { type: type2, value: value2 }, + ] of incompatibleTypes) { + it(`mergeDeep and Map#mergeDeep replaces ${type1} and ${type2} with each other`, () => { + const aObject = { a: value1 }; + const bObject = { a: value2 }; + expect(mergeDeep(aObject, bObject)).toEqual(bObject); + expect(mergeDeep(bObject, aObject)).toEqual(aObject); + + const aMap = Map({ a: value1 }); + const bMap = Map({ a: value2 }); + expect(aMap.mergeDeep(bMap).equals(bMap)).toBe(true); + expect(bMap.mergeDeep(aMap).equals(aMap)).toBe(true); + }); + } + + const compatibleTypesAndResult = [ + [map, object, Map({ b: 7, c: 9, d: 12 })], + [map, record, Map({ a: 1, b: 3, c: 9 })], + [object, map, { b: 5, c: 9, d: 12 }], + [object, record, { a: 1, b: 3, d: 12 }], + [record, map, RecordFactory({ b: 5 })], + [record, object, RecordFactory({ b: 7 })], + [list, array, List(['5', '9'])], + [array, list, ['9', '5']], + [map, { type: 'Map', value: Map({ b: 7 }) }, Map({ b: 7, c: 9 })], + [object, { type: 'object', value: { d: 3 } }, { b: 7, d: 3 }], + [ + record, + { type: 'Record', value: RecordFactory({ a: 3 }) }, + RecordFactory({ a: 3, b: 2 }), + ], + [list, { type: 'List', value: List(['12']) }, List(['5', '12'])], + [array, { type: 'array', value: ['3'] }, ['9', '3']], + [set, { type: 'Set', value: Set(['3', '5']) }, Set(['3', '5'])], + ] as const; + + for (const [ + { type: type1, value: value1 }, + { type: type2, value: value2 }, + result, + ] of compatibleTypesAndResult) { + it(`mergeDeep and Map#mergeDeep merges ${type1} and ${type2}`, () => { + const aObject = { a: value1 }; + const bObject = { a: value2 }; + expect(mergeDeep(aObject, bObject)).toEqual({ a: result }); + + const aMap = Map({ a: value1 }); + const bMap = Map({ a: value2 }); + expect(aMap.mergeDeep(bMap)).toEqual(Map({ a: result })); + }); + } + + it('Map#mergeDeep replaces nested List with Map and Map with List', () => { + const a = Map({ a: List([Map({ x: 1 })]) }); + const b = Map({ a: Map([[0, Map({ y: 2 })]]) }); + expect(a.mergeDeep(b).equals(b)).toBe(true); + expect(b.mergeDeep(a).equals(a)).toBe(true); + }); + + it('functional mergeDeep replaces nested array with Map', () => { + const a = { a: [{ x: 1 }] }; + const b = Map({ a: Map([[0, Map({ y: 2 })]]) }); + expect(mergeDeep(a, b)).toEqual({ a: Map([[0, Map({ y: 2 })]]) }); + }); + + it('works with an empty Record', () => { + class MyRecord extends Record({ a: 1 }) {} + + const myRecord = new MyRecord(); + expect(merge(myRecord, { a: 4 })).toEqual( + new MyRecord({ + a: 4, + }) + ); + + class MyEmptyRecord extends Record({}) {} -}) + const myEmptyRecord = new MyEmptyRecord(); + // merging with an empty record should return the same empty record instance + expect(merge(myEmptyRecord, { a: 4 })).toBe(myEmptyRecord); + }); +}); diff --git a/__tests__/minmax.ts b/__tests__/minmax.ts new file mode 100644 index 0000000000..9a4c7a3c59 --- /dev/null +++ b/__tests__/minmax.ts @@ -0,0 +1,134 @@ +import { describe, expect, it } from '@jest/globals'; +import { is, Seq } from 'immutable'; +import fc from 'fast-check'; + +const genHeterogeneousishArray = fc.oneof( + fc.sparseArray(fc.string()), + fc.array(fc.oneof(fc.integer(), fc.constant(NaN))) +); + +describe('max', () => { + it('returns max in a sequence', () => { + expect(Seq([1, 9, 2, 8, 3, 7, 4, 6, 5]).max()).toBe(9); + }); + + it('accepts a comparator', () => { + expect(Seq([1, 9, 2, 8, 3, 7, 4, 6, 5]).max((a, b) => b - a)).toBe(1); + }); + + it('by a mapper', () => { + const family = Seq([ + { name: 'Oakley', age: 7 }, + { name: 'Dakota', age: 7 }, + { name: 'Casey', age: 34 }, + { name: 'Avery', age: 34 }, + ]); + expect(family.maxBy((p) => p.age)).toBe(family.get(2)); + }); + + it('by a mapper and a comparator', () => { + const family = Seq([ + { name: 'Oakley', age: 7 }, + { name: 'Dakota', age: 7 }, + { name: 'Casey', age: 34 }, + { name: 'Avery', age: 34 }, + ]); + expect( + family.maxBy( + (p) => p.age, + (a, b) => b - a + ) + ).toBe(family.get(0)); + }); + + it('surfaces NaN, null, and undefined', () => { + expect(is(NaN, Seq([1, 2, 3, 4, 5, NaN]).max())).toBe(true); + expect(is(NaN, Seq([NaN, 1, 2, 3, 4, 5]).max())).toBe(true); + expect(is(null, Seq(['A', 'B', 'C', 'D', null]).max())).toBe(true); + expect(is(null, Seq([null, 'A', 'B', 'C', 'D']).max())).toBe(true); + }); + + it('null treated as 0 in default iterator', () => { + expect(is(2, Seq([-1, -2, null, 1, 2]).max())).toBe(true); + }); + + it('is not dependent on order', () => { + fc.assert( + fc.property(genHeterogeneousishArray, (vals) => { + expect( + is( + Seq(shuffle(vals.slice())).max(), + Seq(vals).max() + ) + ).toEqual(true); + }) + ); + }); +}); + +describe('min', () => { + it('returns min in a sequence', () => { + expect(Seq([1, 9, 2, 8, 3, 7, 4, 6, 5]).min()).toBe(1); + }); + + it('accepts a comparator', () => { + expect(Seq([1, 9, 2, 8, 3, 7, 4, 6, 5]).min((a, b) => b - a)).toBe(9); + }); + + it('by a mapper', () => { + const family = Seq([ + { name: 'Oakley', age: 7 }, + { name: 'Dakota', age: 7 }, + { name: 'Casey', age: 34 }, + { name: 'Avery', age: 34 }, + ]); + expect(family.minBy((p) => p.age)).toBe(family.get(0)); + }); + + it('by a mapper and a comparator', () => { + const family = Seq([ + { name: 'Oakley', age: 7 }, + { name: 'Dakota', age: 7 }, + { name: 'Casey', age: 34 }, + { name: 'Avery', age: 34 }, + ]); + expect( + family.minBy( + (p) => p.age, + (a, b) => b - a + ) + ).toBe(family.get(2)); + }); + + it('is not dependent on order', () => { + fc.assert( + fc.property(genHeterogeneousishArray, (vals) => { + expect( + is( + Seq(shuffle(vals.slice())).min(), + Seq(vals).min() + ) + ).toEqual(true); + }) + ); + }); +}); + +function shuffle>(array: A): A { + let m = array.length; + let t; + let i; + + // While there remain elements to shuffleâ€Ĥ + while (m) { + // Pick a remaining elementâ€Ĥ + i = Math.floor(Math.random() * m--); + + // And swap it with the current element. + t = array[m]; + array[m] = array[i]; + array[i] = t; + } + + return array; +} diff --git a/__tests__/partition.ts b/__tests__/partition.ts new file mode 100644 index 0000000000..0a59b3d8ec --- /dev/null +++ b/__tests__/partition.ts @@ -0,0 +1,102 @@ +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; +import { + isAssociative, + isIndexed, + isKeyed, + isList, + isMap, + isSeq, + isSet, + List, + Map as IMap, + Seq, + Set as ISet, +} from 'immutable'; + +describe('partition', () => { + let isOdd: jest.Mock<(x: number) => number>; + + beforeEach(() => { + isOdd = jest.fn((x) => x % 2); + }); + + it('partitions keyed sequence', () => { + const parts = Seq({ a: 1, b: 2, c: 3, d: 4 }).partition(isOdd); + expect(isKeyed(parts[0])).toBe(true); + expect(isSeq(parts[0])).toBe(true); + expect(parts.map((part) => part.toJS())).toEqual([ + { b: 2, d: 4 }, + { a: 1, c: 3 }, + ]); + expect(isOdd.mock.calls.length).toBe(4); + + // Each group should be a keyed sequence, not an indexed sequence + const trueGroup = parts[1]; + expect(trueGroup && trueGroup.toArray()).toEqual([ + ['a', 1], + ['c', 3], + ]); + }); + + it('partitions indexed sequence', () => { + const parts = Seq([1, 2, 3, 4, 5, 6]).partition(isOdd); + expect(isIndexed(parts[0])).toBe(true); + expect(isSeq(parts[0])).toBe(true); + expect(parts.map((part) => part.toJS())).toEqual([ + [2, 4, 6], + [1, 3, 5], + ]); + expect(isOdd.mock.calls.length).toBe(6); + }); + + it('partitions set sequence', () => { + const parts = Seq.Set([1, 2, 3, 4, 5, 6]).partition(isOdd); + expect(isAssociative(parts[0])).toBe(false); + expect(isSeq(parts[0])).toBe(true); + expect(parts.map((part) => part.toJS())).toEqual([ + [2, 4, 6], + [1, 3, 5], + ]); + expect(isOdd.mock.calls.length).toBe(6); + }); + + it('partitions keyed collection', () => { + const parts = IMap({ a: 1, b: 2, c: 3, d: 4 }).partition(isOdd); + expect(isMap(parts[0])).toBe(true); + expect(isSeq(parts[0])).toBe(false); + expect(parts.map((part) => part.toJS())).toEqual([ + { b: 2, d: 4 }, + { a: 1, c: 3 }, + ]); + expect(isOdd.mock.calls.length).toBe(4); + + // Each group should be a keyed collection, not an indexed collection + const trueGroup = parts[1]; + expect(trueGroup && trueGroup.toArray()).toEqual([ + ['a', 1], + ['c', 3], + ]); + }); + + it('partitions indexed collection', () => { + const parts = List([1, 2, 3, 4, 5, 6]).partition(isOdd); + expect(isList(parts[0])).toBe(true); + expect(isSeq(parts[0])).toBe(false); + expect(parts.map((part) => part.toJS())).toEqual([ + [2, 4, 6], + [1, 3, 5], + ]); + expect(isOdd.mock.calls.length).toBe(6); + }); + + it('partitions set collection', () => { + const parts = ISet([1, 2, 3, 4, 5, 6]).partition(isOdd); + expect(isSet(parts[0])).toBe(true); + expect(isSeq(parts[0])).toBe(false); + expect(parts.map((part) => part.toJS().sort())).toEqual([ + [2, 4, 6], + [1, 3, 5], + ]); + expect(isOdd.mock.calls.length).toBe(6); + }); +}); diff --git a/__tests__/slice.ts b/__tests__/slice.ts index 550a4a761c..07b763ff58 100644 --- a/__tests__/slice.ts +++ b/__tests__/slice.ts @@ -1,134 +1,299 @@ -/// -/// - -jest.autoMockOff(); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); - -import I = require('immutable'); -import Sequence = I.Sequence; -import Vector = I.Vector; +import { describe, expect, it } from '@jest/globals'; +import { List, Range, Seq } from 'immutable'; +import fc from 'fast-check'; describe('slice', () => { - it('slices a sequence', () => { - expect(Sequence(1,2,3,4,5,6).slice(2).toArray()).toEqual([3,4,5,6]); - expect(Sequence(1,2,3,4,5,6).slice(2, 4).toArray()).toEqual([3,4]); - expect(Sequence(1,2,3,4,5,6).slice(-3, -1).toArray()).toEqual([4,5]); - expect(Sequence(1,2,3,4,5,6).slice(-1).toArray()).toEqual([6]); - expect(Sequence(1,2,3,4,5,6).slice(0, -1).toArray()).toEqual([1,2,3,4,5]); - }) + expect(Seq([1, 2, 3, 4, 5, 6]).slice(2).toArray()).toEqual([3, 4, 5, 6]); + expect(Seq([1, 2, 3, 4, 5, 6]).slice(2, 4).toArray()).toEqual([3, 4]); + expect(Seq([1, 2, 3, 4, 5, 6]).slice(-3, -1).toArray()).toEqual([4, 5]); + expect(Seq([1, 2, 3, 4, 5, 6]).slice(-1).toArray()).toEqual([6]); + expect(Seq([1, 2, 3, 4, 5, 6]).slice(0, -1).toArray()).toEqual([ + 1, 2, 3, 4, 5, + ]); + }); it('creates an immutable stable sequence', () => { - var seq = Sequence(1,2,3,4,5,6); - var sliced = seq.slice(2, -2); + const seq = Seq([1, 2, 3, 4, 5, 6]); + const sliced = seq.slice(2, -2); expect(sliced.toArray()).toEqual([3, 4]); expect(sliced.toArray()).toEqual([3, 4]); expect(sliced.toArray()).toEqual([3, 4]); - }) + }); it('slices a sparse indexed sequence', () => { - expect(Sequence([1,,2,,3,,4,,5,,6]).slice(1).toArray()).toEqual([,2,,3,,4,,5,,6]); - expect(Sequence([1,,2,,3,,4,,5,,6]).slice(2).toArray()).toEqual([2,,3,,4,,5,,6]); - expect(Sequence([1,,2,,3,,4,,5,,6]).slice(3, -3).toArray()).toEqual([,3,,4,,,]); // one trailing hole. - }) + expect( + Seq([ + 1, + undefined, + 2, + undefined, + 3, + undefined, + 4, + undefined, + 5, + undefined, + 6, + ]) + .slice(1) + .toArray() + ).toEqual([ + undefined, + 2, + undefined, + 3, + undefined, + 4, + undefined, + 5, + undefined, + 6, + ]); + expect( + Seq([ + 1, + undefined, + 2, + undefined, + 3, + undefined, + 4, + undefined, + 5, + undefined, + 6, + ]) + .slice(2) + .toArray() + ).toEqual([2, undefined, 3, undefined, 4, undefined, 5, undefined, 6]); + expect( + Seq([ + 1, + undefined, + 2, + undefined, + 3, + undefined, + 4, + undefined, + 5, + undefined, + 6, + ]) + .slice(3, -3) + .toArray() + ).toEqual([undefined, 3, undefined, 4, undefined]); // one trailing hole. + }); it('can maintain indices for an keyed indexed sequence', () => { - expect(Sequence(1,2,3,4,5,6).toKeyedSeq().slice(2).entrySeq().toArray()).toEqual([ - [2,3], - [3,4], - [4,5], - [5,6], + expect( + Seq([1, 2, 3, 4, 5, 6]).toKeyedSeq().slice(2).entrySeq().toArray() + ).toEqual([ + [2, 3], + [3, 4], + [4, 5], + [5, 6], ]); - expect(Sequence(1,2,3,4,5,6).toKeyedSeq().slice(2, 4).entrySeq().toArray()).toEqual([ - [2,3], - [3,4], + expect( + Seq([1, 2, 3, 4, 5, 6]).toKeyedSeq().slice(2, 4).entrySeq().toArray() + ).toEqual([ + [2, 3], + [3, 4], ]); - }) + }); it('slices an unindexed sequence', () => { - expect(Sequence({a:1,b:2,c:3}).slice(1).toObject()).toEqual({b:2,c:3}); - expect(Sequence({a:1,b:2,c:3}).slice(1, 2).toObject()).toEqual({b:2}); - expect(Sequence({a:1,b:2,c:3}).slice(0, 2).toObject()).toEqual({a:1,b:2}); - expect(Sequence({a:1,b:2,c:3}).slice(-1).toObject()).toEqual({c:3}); - expect(Sequence({a:1,b:2,c:3}).slice(1, -1).toObject()).toEqual({b:2}); - }) + expect(Seq({ a: 1, b: 2, c: 3 }).slice(1).toObject()).toEqual({ + b: 2, + c: 3, + }); + expect(Seq({ a: 1, b: 2, c: 3 }).slice(1, 2).toObject()).toEqual({ b: 2 }); + expect(Seq({ a: 1, b: 2, c: 3 }).slice(0, 2).toObject()).toEqual({ + a: 1, + b: 2, + }); + expect(Seq({ a: 1, b: 2, c: 3 }).slice(-1).toObject()).toEqual({ c: 3 }); + expect(Seq({ a: 1, b: 2, c: 3 }).slice(1, -1).toObject()).toEqual({ b: 2 }); + }); it('is reversable', () => { - expect(Sequence(1,2,3,4,5,6).slice(2).reverse().toArray()).toEqual([6,5,4,3]); - expect(Sequence(1,2,3,4,5,6).slice(2, 4).reverse().toArray()).toEqual([4,3]); - expect(Sequence(1,2,3,4,5,6).toKeyedSeq().slice(2).reverse().entrySeq().toArray()).toEqual([ - [5,6], - [4,5], - [3,4], - [2,3], + expect(Seq([1, 2, 3, 4, 5, 6]).slice(2).reverse().toArray()).toEqual([ + 6, 5, 4, 3, ]); - expect(Sequence(1,2,3,4,5,6).toKeyedSeq().slice(2, 4).reverse().entrySeq().toArray()).toEqual([ - [3,4], - [2,3], + expect(Seq([1, 2, 3, 4, 5, 6]).slice(2, 4).reverse().toArray()).toEqual([ + 4, 3, ]); - }) + expect( + Seq([1, 2, 3, 4, 5, 6]) + .toKeyedSeq() + .slice(2) + .reverse() + .entrySeq() + .toArray() + ).toEqual([ + [5, 6], + [4, 5], + [3, 4], + [2, 3], + ]); + expect( + Seq([1, 2, 3, 4, 5, 6]) + .toKeyedSeq() + .slice(2, 4) + .reverse() + .entrySeq() + .toArray() + ).toEqual([ + [3, 4], + [2, 3], + ]); + }); - it('slices a vector', () => { - expect(Vector(1,2,3,4,5,6).slice(2).toArray()).toEqual([3,4,5,6]); - expect(Vector(1,2,3,4,5,6).slice(2, 4).toArray()).toEqual([3,4]); - }) + it('slices a list', () => { + expect(List([1, 2, 3, 4, 5, 6]).slice(2).toArray()).toEqual([3, 4, 5, 6]); + expect(List([1, 2, 3, 4, 5, 6]).slice(2, 4).toArray()).toEqual([3, 4]); + }); it('returns self for whole slices', () => { - var s = Sequence(1,2,3); + const s = Seq([1, 2, 3]); expect(s.slice(0)).toBe(s); expect(s.slice(0, 3)).toBe(s); expect(s.slice(-4, 4)).toBe(s); - var v = Vector(1,2,3); + const v = List([1, 2, 3]); expect(v.slice(-4, 4)).toBe(v); expect(v.slice(-3)).toBe(v); - expect(v.slice(-4, 4).toVector()).toBe(v); - }) - - it('creates a sliced vector in O(log32(n))', () => { - expect(Vector(1,2,3,4,5).slice(-3, -1).toVector().toArray()).toEqual([3,4]); - }) - - check.it('works like Array.prototype.slice', - [gen.int, gen.array(gen.oneOf([gen.int, gen.undefined]), 0, 3)], - (valuesLen, args) => { - var a = I.Range(0, valuesLen).toArray(); - var v = Vector.from(a); - var slicedV = v.slice.apply(v, args); - var slicedA = a.slice.apply(a, args); - expect(slicedV.toArray()).toEqual(slicedA); - }) - - check.it('works like Array.prototype.slice on sparse array input', - [gen.array(gen.array([gen.posInt, gen.int])), - gen.array(gen.oneOf([gen.int, gen.undefined]), 0, 3)], - (entries, args) => { - var a = []; - entries.forEach(entry => a[entry[0]] = entry[1]); - var s = Sequence(a); - var slicedS = s.slice.apply(s, args); - var slicedA = a.slice.apply(a, args); - expect(slicedS.toArray()).toEqual(slicedA); - }) + expect(v.slice(-4, 4).toList()).toBe(v); + }); - describe('take', () => { + it('creates a sliced list in O(log32(n))', () => { + expect(List([1, 2, 3, 4, 5]).slice(-3, -1).toList().toArray()).toEqual([ + 3, 4, + ]); + }); + + it('has the same behavior as array slice in known edge cases', () => { + const a = Range(0, 33).toArray(); + const v = List(a); + expect(v.slice(31).toList().toArray()).toEqual(a.slice(31)); + }); + + it('does not slice by floating-point numbers', () => { + const seq = Seq([0, 1, 2, 3, 4, 5]); + const sliced = seq.slice(0, 2.6); + expect(sliced.size).toEqual(2); + expect(sliced.toArray()).toEqual([0, 1]); + }); - check.it('takes the first n from a list', [gen.int, gen.posInt], (len, num) => { - var a = I.Range(0, len).toArray(); - var v = Vector.from(a); - expect(v.take(num).toArray()).toEqual(a.slice(0, num)); - }) + it('can create an iterator', () => { + const seq = Seq([0, 1, 2, 3, 4, 5]); + const iterFront = seq.slice(0, 2).values(); + expect(iterFront.next()).toEqual({ value: 0, done: false }); + expect(iterFront.next()).toEqual({ value: 1, done: false }); + expect(iterFront.next()).toEqual({ value: undefined, done: true }); + + const iterMiddle = seq.slice(2, 4).values(); + expect(iterMiddle.next()).toEqual({ value: 2, done: false }); + expect(iterMiddle.next()).toEqual({ value: 3, done: false }); + expect(iterMiddle.next()).toEqual({ value: undefined, done: true }); + + const iterTail = seq.slice(4, 123456).values(); + expect(iterTail.next()).toEqual({ value: 4, done: false }); + expect(iterTail.next()).toEqual({ value: 5, done: false }); + expect(iterTail.next()).toEqual({ value: undefined, done: true }); + }); + + it('stops the entries iterator when the sequence has an undefined end', () => { + let seq = Seq([0, 1, 2, 3, 4, 5]); + // flatMap is lazy and thus the resulting sequence has no size. + seq = seq.flatMap((a) => [a]); + expect(seq.size).toEqual(undefined); + + const iterFront = seq.slice(0, 2).entries(); + expect(iterFront.next()).toEqual({ value: [0, 0], done: false }); + expect(iterFront.next()).toEqual({ value: [1, 1], done: false }); + expect(iterFront.next()).toEqual({ value: undefined, done: true }); + + const iterMiddle = seq.slice(2, 4).entries(); + expect(iterMiddle.next()).toEqual({ value: [0, 2], done: false }); + expect(iterMiddle.next()).toEqual({ value: [1, 3], done: false }); + expect(iterMiddle.next()).toEqual({ value: undefined, done: true }); + + const iterTail = seq.slice(4, 123456).entries(); + expect(iterTail.next()).toEqual({ value: [0, 4], done: false }); + expect(iterTail.next()).toEqual({ value: [1, 5], done: false }); + expect(iterTail.next()).toEqual({ value: undefined, done: true }); + }); + + it('works like Array.prototype.slice', () => { + fc.assert( + fc.property( + fc.integer({ min: -1000, max: 1000 }), + fc.sparseArray(fc.integer({ min: -1000, max: 1000 }), { maxLength: 3 }), + (valuesLen, args) => { + const a = Range(0, valuesLen).toArray(); + const v = List(a); + const slicedV = v.slice.apply(v, args); + const slicedA = a.slice.apply(a, args); + expect(slicedV.toArray()).toEqual(slicedA); + } + ) + ); + }); + + it('works like Array.prototype.slice on sparse array input', () => { + fc.assert( + fc.property( + fc.array(fc.tuple(fc.nat(1000), fc.integer({ min: -1000, max: 1000 }))), + fc.sparseArray(fc.integer({ min: -1000, max: 1000 }), { maxLength: 3 }), + (entries, args) => { + const a: Array = []; + entries.forEach((entry) => (a[entry[0]] = entry[1])); + const s = Seq(a); + const slicedS = s.slice.apply(s, args); + const slicedA = a.slice.apply(a, args); + expect(slicedS.toArray()).toEqual(slicedA); + } + ) + ); + }); + + describe('take', () => { + it('takes the first n from a list', () => { + fc.assert( + fc.property( + fc.integer({ min: -1000, max: 1000 }), + fc.nat(1000), + (len, num) => { + const a = Range(0, len).toArray(); + const v = List(a); + expect(v.take(num).toArray()).toEqual(a.slice(0, num)); + } + ) + ); + }); it('creates an immutable stable sequence', () => { - var seq = Sequence(1,2,3,4,5,6); - var sliced = seq.take(3); + const seq = Seq([1, 2, 3, 4, 5, 6]); + const sliced = seq.take(3); expect(sliced.toArray()).toEqual([1, 2, 3]); expect(sliced.toArray()).toEqual([1, 2, 3]); expect(sliced.toArray()).toEqual([1, 2, 3]); - }) - - }) + }); -}) + it('converts to array with correct length', () => { + const seq = Seq([1, 2, 3, 4, 5, 6]); + const s1 = seq.take(3); + const s2 = seq.take(10); + const sn = seq.take(Infinity); + const s3 = seq.filter((v) => v < 4).take(10); + const s4 = seq.filter((v) => v < 4).take(2); + expect(s1.toArray().length).toEqual(3); + expect(s2.toArray().length).toEqual(6); + expect(sn.toArray().length).toEqual(6); + expect(s3.toArray().length).toEqual(3); + expect(s4.toArray().length).toEqual(2); + }); + }); +}); diff --git a/__tests__/sort.ts b/__tests__/sort.ts index 6ca2e8e3f3..0a5afbf9ad 100644 --- a/__tests__/sort.ts +++ b/__tests__/sort.ts @@ -1,46 +1,78 @@ -/// -/// - -jest.autoMockOff(); - -import I = require('immutable'); -import Sequence = I.Sequence; -import Vector = I.Vector; -import OrderedMap = I.OrderedMap; -import Range = I.Range; +import { describe, expect, it } from '@jest/globals'; +import { List, OrderedMap, Range, Seq } from 'immutable'; describe('sort', () => { - it('sorts a sequence', () => { - expect(Sequence(4,5,6,3,2,1).sort().toArray()).toEqual([1,2,3,4,5,6]); - }) + expect(Seq([4, 5, 6, 3, 2, 1]).sort().toArray()).toEqual([ + 1, 2, 3, 4, 5, 6, + ]); + }); - it('sorts a vector', () => { - expect(Vector(4,5,6,3,2,1).sort().toArray()).toEqual([1,2,3,4,5,6]); - }) + it('sorts a list', () => { + expect(List([4, 5, 6, 3, 2, 1]).sort().toArray()).toEqual([ + 1, 2, 3, 4, 5, 6, + ]); + }); + + it('sorts undefined values last', () => { + expect( + List([4, undefined, 5, 6, 3, undefined, 2, 1]).sort().toArray() + ).toEqual([1, 2, 3, 4, 5, 6, undefined, undefined]); + }); it('sorts a keyed sequence', () => { - expect(Sequence({z:1,y:2,x:3,c:3,b:2,a:1}).sort().entrySeq().toArray()) - .toEqual([['z', 1],['a', 1],['y', 2],['b', 2],['x', 3],['c', 3]]); - }) + expect( + Seq({ z: 1, y: 2, x: 3, c: 3, b: 2, a: 1 }).sort().entrySeq().toArray() + ).toEqual([ + ['z', 1], + ['a', 1], + ['y', 2], + ['b', 2], + ['x', 3], + ['c', 3], + ]); + }); it('sorts an OrderedMap', () => { - expect(OrderedMap({z:1,y:2,x:3,c:3,b:2,a:1}).sort().entrySeq().toArray()) - .toEqual([['z', 1],['a', 1],['y', 2],['b', 2],['x', 3],['c', 3]]); - }) + expect( + OrderedMap({ z: 1, y: 2, x: 3, c: 3, b: 2, a: 1 }) + .sort() + .entrySeq() + .toArray() + ).toEqual([ + ['z', 1], + ['a', 1], + ['y', 2], + ['b', 2], + ['x', 3], + ['c', 3], + ]); + }); it('accepts a sort function', () => { - expect(Sequence(4,5,6,3,2,1).sort((a, b) => b - a).toArray()).toEqual([6,5,4,3,2,1]); - }) + expect( + Seq([4, 5, 6, 3, 2, 1]) + .sort((a, b) => b - a) + .toArray() + ).toEqual([6, 5, 4, 3, 2, 1]); + }); it('sorts by using a mapper', () => { - expect(Range(1,10).sortBy(v => v % 3).toArray()) - .toEqual([3,6,9,1,4,7,2,5,8]); - }) + expect( + Range(1, 10) + .sortBy((v) => v % 3) + .toArray() + ).toEqual([3, 6, 9, 1, 4, 7, 2, 5, 8]); + }); it('sorts by using a mapper and a sort function', () => { - expect(Range(1,10).sortBy(v => v % 3, (a: number, b: number) => b - a).toArray()) - .toEqual([2,5,8,1,4,7,3,6,9]); - }) - -}) + expect( + Range(1, 10) + .sortBy( + (v) => v % 3, + (a: number, b: number) => b - a + ) + .toArray() + ).toEqual([2, 5, 8, 1, 4, 7, 3, 6, 9]); + }); +}); diff --git a/__tests__/splice.ts b/__tests__/splice.ts index 50fe4e7183..cb90281016 100644 --- a/__tests__/splice.ts +++ b/__tests__/splice.ts @@ -1,39 +1,65 @@ -/// -/// - -jest.autoMockOff(); - -import jasmineCheck = require('jasmine-check'); -jasmineCheck.install(); - -import I = require('immutable'); -import Sequence = I.Sequence; -import Vector = I.Vector; +import { describe, expect, it } from '@jest/globals'; +import { List, Range, Seq } from 'immutable'; +import fc from 'fast-check'; describe('splice', () => { - it('splices a sequence only removing elements', () => { - expect(Sequence(1,2,3).splice(0,1).toArray()).toEqual([2,3]); - expect(Sequence(1,2,3).splice(1,1).toArray()).toEqual([1,3]); - expect(Sequence(1,2,3).splice(2,1).toArray()).toEqual([1,2]); - expect(Sequence(1,2,3).splice(3,1).toArray()).toEqual([1,2,3]); - }) + expect(Seq([1, 2, 3]).splice(0, 1).toArray()).toEqual([2, 3]); + expect(Seq([1, 2, 3]).splice(1, 1).toArray()).toEqual([1, 3]); + expect(Seq([1, 2, 3]).splice(2, 1).toArray()).toEqual([1, 2]); + expect(Seq([1, 2, 3]).splice(3, 1).toArray()).toEqual([1, 2, 3]); + }); + + it('splices a list only removing elements', () => { + expect(List([1, 2, 3]).splice(0, 1).toArray()).toEqual([2, 3]); + expect(List([1, 2, 3]).splice(1, 1).toArray()).toEqual([1, 3]); + expect(List([1, 2, 3]).splice(2, 1).toArray()).toEqual([1, 2]); + expect(List([1, 2, 3]).splice(3, 1).toArray()).toEqual([1, 2, 3]); + }); + + it('splicing by infinity', () => { + const l = List(['a', 'b', 'c', 'd']); + expect(l.splice(2, Infinity, 'x').toArray()).toEqual(['a', 'b', 'x']); + expect(l.splice(Infinity, 2, 'x').toArray()).toEqual([ + 'a', + 'b', + 'c', + 'd', + 'x', + ]); - it('splices a vector only removing elements', () => { - expect(Vector(1,2,3).splice(0,1).toArray()).toEqual([2,3]); - expect(Vector(1,2,3).splice(1,1).toArray()).toEqual([1,3]); - expect(Vector(1,2,3).splice(2,1).toArray()).toEqual([1,2]); - expect(Vector(1,2,3).splice(3,1).toArray()).toEqual([1,2,3]); - }) + const s = List(['a', 'b', 'c', 'd']); + expect(s.splice(2, Infinity, 'x').toArray()).toEqual(['a', 'b', 'x']); + expect(s.splice(Infinity, 2, 'x').toArray()).toEqual([ + 'a', + 'b', + 'c', + 'd', + 'x', + ]); + }); - check.it('has the same behavior as array splice', - [gen.array(gen.int), gen.array(gen.oneOf([gen.int, gen.undefined]))], - (values, args) => { - var v = Vector.from(values); - var a = values.slice(); // clone - var splicedV = v.splice.apply(v, args); // persistent - a.splice.apply(a, args); // mutative - expect(splicedV.toArray()).toEqual(a); - }) + it('has the same behavior as array splice in known edge cases', () => { + // arbitrary numbers that sum to 31 + const a = Range(0, 49).toArray(); + const v = List(a); + a.splice(-18, 0, 0); + expect(v.splice(-18, 0, 0).toList().toArray()).toEqual(a); + }); -}) + it('has the same behavior as array splice', () => { + fc.assert( + fc.property( + fc.array(fc.integer()), + fc.array(fc.sparseArray(fc.integer())), + (values, args) => { + const v = List(values); + const a = values.slice(); // clone + const splicedV = v.splice.apply(v, args); // persistent + a.splice.apply(a, args); // mutative + expect(splicedV.toArray()).toEqual(a); + } + ) + ); + }); +}); diff --git a/__tests__/transformerProtocol.ts b/__tests__/transformerProtocol.ts new file mode 100644 index 0000000000..c3cedb3577 --- /dev/null +++ b/__tests__/transformerProtocol.ts @@ -0,0 +1,101 @@ +import { describe, expect, it } from '@jest/globals'; +import * as t from 'transducers-js'; +import { List, Map, Set, Stack } from 'immutable'; + +describe('Transformer Protocol', () => { + it('transduces Stack without initial values', () => { + const s = Stack.of(1, 2, 3, 4); + const xform = t.comp( + t.filter((x) => x % 2 === 0), + t.map((x) => x + 1) + ); + const s2 = t.transduce(xform, Stack(), s); + expect(s.toArray()).toEqual([1, 2, 3, 4]); + expect(s2.toArray()).toEqual([5, 3]); + }); + + it('transduces Stack with initial values', () => { + const v1 = Stack.of(1, 2, 3); + const v2 = Stack.of(4, 5, 6, 7); + const xform = t.comp( + t.filter((x) => x % 2 === 0), + t.map((x) => x + 1) + ); + const r = t.transduce(xform, Stack(), v1, v2); + expect(v1.toArray()).toEqual([1, 2, 3]); + expect(v2.toArray()).toEqual([4, 5, 6, 7]); + expect(r.toArray()).toEqual([7, 5, 1, 2, 3]); + }); + + it('transduces List without initial values', () => { + const v = List.of(1, 2, 3, 4); + const xform = t.comp( + t.filter((x) => x % 2 === 0), + t.map((x) => x + 1) + ); + const r = t.transduce(xform, List(), v); + expect(v.toArray()).toEqual([1, 2, 3, 4]); + expect(r.toArray()).toEqual([3, 5]); + }); + + it('transduces List with initial values', () => { + const v1 = List.of(1, 2, 3); + const v2 = List.of(4, 5, 6, 7); + const xform = t.comp( + t.filter((x) => x % 2 === 0), + t.map((x) => x + 1) + ); + const r = t.transduce(xform, List(), v1, v2); + expect(v1.toArray()).toEqual([1, 2, 3]); + expect(v2.toArray()).toEqual([4, 5, 6, 7]); + expect(r.toArray()).toEqual([1, 2, 3, 5, 7]); + }); + + it('transduces Map without initial values', () => { + const m1 = Map({ a: 1, b: 2, c: 3, d: 4 }); + const xform = t.comp( + t.filter(([_k, v]) => v % 2 === 0), + t.map(([k, v]) => [k, v * 2]) + ); + const m2 = t.transduce(xform, Map(), m1); + expect(m1.toObject()).toEqual({ a: 1, b: 2, c: 3, d: 4 }); + expect(m2.toObject()).toEqual({ b: 4, d: 8 }); + }); + + it('transduces Map with initial values', () => { + const m1 = Map({ a: 1, b: 2, c: 3 }); + const m2 = Map({ a: 4, b: 5 }); + const xform = t.comp( + t.filter(([_k, v]) => v % 2 === 0), + t.map(([k, v]) => [k, v * 2]) + ); + const m3 = t.transduce(xform, Map(), m1, m2); + expect(m1.toObject()).toEqual({ a: 1, b: 2, c: 3 }); + expect(m2.toObject()).toEqual({ a: 4, b: 5 }); + expect(m3.toObject()).toEqual({ a: 8, b: 2, c: 3 }); + }); + + it('transduces Set without initial values', () => { + const s1 = Set.of(1, 2, 3, 4); + const xform = t.comp( + t.filter((x) => x % 2 === 0), + t.map((x) => x + 1) + ); + const s2 = t.transduce(xform, Set(), s1); + expect(s1.toArray()).toEqual([1, 2, 3, 4]); + expect(s2.toArray()).toEqual([3, 5]); + }); + + it('transduces Set with initial values', () => { + const s1 = Set.of(1, 2, 3, 4); + const s2 = Set.of(2, 3, 4, 5, 6); + const xform = t.comp( + t.filter((x) => x % 2 === 0), + t.map((x) => x + 1) + ); + const s3 = t.transduce(xform, Set(), s1, s2); + expect(s1.toArray()).toEqual([1, 2, 3, 4]); + expect(s2.toArray()).toEqual([2, 3, 4, 5, 6]); + expect(s3.toArray()).toEqual([1, 2, 3, 4, 5, 7]); + }); +}); diff --git a/__tests__/ts-utils.ts b/__tests__/ts-utils.ts new file mode 100644 index 0000000000..d4cc759e68 --- /dev/null +++ b/__tests__/ts-utils.ts @@ -0,0 +1,7 @@ +import { expect } from '@jest/globals'; + +export function expectToBeDefined( + arg: T +): asserts arg is Exclude { + expect(arg).toBeDefined(); +} diff --git a/__tests__/tsconfig.json b/__tests__/tsconfig.json new file mode 100644 index 0000000000..78742cd9bd --- /dev/null +++ b/__tests__/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "noEmit": true, + // TODO: add additional strictness + "strictNullChecks": true, + "strictFunctionTypes": true, + "target": "esnext", + "moduleResolution": "node", + "skipLibCheck": true, + "paths": { + "immutable": ["../type-definitions/immutable.d.ts"] + } + } +} diff --git a/__tests__/updateIn.ts b/__tests__/updateIn.ts index 3dbbc02763..1ca054f979 100644 --- a/__tests__/updateIn.ts +++ b/__tests__/updateIn.ts @@ -1,91 +1,457 @@ -/// -/// +import { describe, expect, it } from '@jest/globals'; +import { + fromJS, + List, + Map, + MapOf, + removeIn, + Seq, + Set, + setIn, + updateIn, +} from 'immutable'; -jest.autoMockOff(); +describe('updateIn', () => { + it('deep edit', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + expect( + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + m.updateIn(['a', 'b', 'c'], (value: number) => value * 2).toJS() + ).toEqual({ + a: { b: { c: 20 } }, + }); + }); -import I = require('immutable'); + it('deep edit with list as keyPath', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + expect( + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + m.updateIn(fromJS(['a', 'b', 'c']), (value: number) => value * 2).toJS() + ).toEqual({ a: { b: { c: 20 } } }); + }); -describe('updateIn', () => { + it('deep edit in raw JS', () => { + const m = { a: { b: { c: [10] } } }; + expect( + updateIn(m, ['a', 'b', 'c', 0], (value: number) => value * 2) + ).toEqual({ + a: { b: { c: [20] } }, + }); + }); + + it('deep edit throws without list or array-like', () => { + // @ts-expect-error -- test that runtime does throw + expect(() => Map().updateIn(undefined, (x) => x)).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: undefined' + ); + // @ts-expect-error -- test that runtime does th + expect(() => Map().updateIn({ a: 1, b: 2 }, (x) => x)).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: [object Object]' + ); + expect(() => Map().updateIn('abc', (x) => x)).toThrow( + 'Invalid keyPath: expected Ordered Collection or Array: abc' + ); + }); - it('deep get', () => { - var m = I.fromJS({a: {b: {c: 10}}}); - expect(m.getIn(['a', 'b', 'c'])).toEqual(10); - }) + it('deep edit throws if non-editable path', () => { + const deep = Map({ key: Set([List(['item'])]) }); + expect(() => deep.updateIn(['key', 'foo', 'item'], () => 'newval')).toThrow( + 'Cannot update immutable value without .set() method: Set { List [ "item" ] }' + ); - it('deep get returns not found if path does not match', () => { - var m = I.fromJS({a: {b: {c: 10}}}); - expect(m.getIn(['a', 'b', 'z'])).toEqual(undefined); - expect(m.getIn(['a', 'b', 'c', 'd'])).toEqual(undefined); - }) + const deepSeq = Map({ key: Seq([List(['item'])]) }); + expect(() => + deepSeq.updateIn(['key', 'foo', 'item'], () => 'newval') + ).toThrow( + 'Cannot update immutable value without .set() method: Seq [ List [ "item" ] ]' + ); - it('deep edit', () => { - var m = I.fromJS({a: {b: {c: 10}}}); - expect( - m.updateIn(['a', 'b', 'c'], value => value * 2).toJS() - ).toEqual( - {a: {b: {c: 20}}} + const nonObj = Map({ key: 123 }); + expect(() => nonObj.updateIn(['key', 'foo'], () => 'newval')).toThrow( + 'Cannot update within non-data-structure value in path ["key"]: 123' ); - }) + }); + + it('handle ArrayLike objects that are nor Array not immutable Collection', () => { + class CustomArrayLike implements ArrayLike { + readonly length: number; + [n: number]: T; + + constructor(...values: Array) { + this.length = values.length; + + for (let i = 0; i < values.length; i++) { + this[i] = values[i]; + } + } + + // Define other methods if needed, but do not include the `slice` method + // For example, you can define a method to set values + set(index: number, value: T): void { + if (index < 0 || index >= this.length) { + throw new RangeError('Index out of bounds'); + } + + this[index] = value; + } + + // Define a method to get values + get(index: number): T { + if (index < 0 || index >= this.length) { + throw new RangeError('Index out of bounds'); + } + + return this[index]; + } + } + + // create an ArrayLike + const customArray = new CustomArrayLike(10, 20); + + // code that works perfectly + expect( + updateIn({ 10: { 20: 'a' } }, customArray, (v) => + // @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection | ArrayLike; + typeof v === 'string' ? v.toUpperCase() : v + ) + ).toEqual({ 10: { 20: 'A' } }); + + expect(() => + updateIn({ 10: 'a' }, customArray, (v) => + // @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection | ArrayLike; + typeof v === 'string' ? v.toUpperCase() : v + ) + ).toThrow('Cannot update within non-data-structure value in path [10]: a'); + }); + + it('identity with notSetValue is still identity', () => { + const m = Map({ a: { b: { c: 10 } } }); + expect(m.updateIn(['x'], 100, (id) => id)).toEqual(m); + }); + + it('shallow remove', () => { + const m = Map({ a: 123 }); + expect(m.updateIn([], () => undefined)).toEqual(undefined); + }); it('deep remove', () => { - var m = I.fromJS({a: {b: {c: 10}}}); + const m = fromJS({ a: { b: { c: 10 } } }); expect( - m.updateIn(['a', 'b'], map => map.remove('c')).toJS() - ).toEqual( - {a: {b: {}}} - ); - }) + m + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + .updateIn(['a', 'b'], (map: MapOf<{ c: number }>) => map.remove('c')) + .toJS() + ).toEqual({ + a: { b: {} }, + }); + }); it('deep set', () => { - var m = I.fromJS({a: {b: {c: 10}}}); + const m = fromJS({ a: { b: { c: 10 } } }); expect( - m.updateIn(['a', 'b'], map => map.set('d', 20)).toJS() - ).toEqual( - {a: {b: {c: 10, d: 20}}} - ); - }) + m + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + .updateIn(['a', 'b'], (map: MapOf<{ c: number }>) => map.set('d', 20)) + .toJS() + ).toEqual({ + a: { b: { c: 10, d: 20 } }, + }); + }); it('deep push', () => { - var m = I.fromJS({a: {b: [1,2,3]}}); + const m = fromJS({ a: { b: [1, 2, 3] } }); expect( - m.updateIn(['a', 'b'], vect => vect.push(4)).toJS() - ).toEqual( - {a: {b: [1,2,3,4]}} - ); - }) + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + m.updateIn(['a', 'b'], (list: List) => list.push(4)).toJS() + ).toEqual({ + a: { b: [1, 2, 3, 4] }, + }); + }); it('deep map', () => { - var m = I.fromJS({a: {b: [1,2,3]}}); + const m = fromJS({ a: { b: [1, 2, 3] } }); expect( - m.updateIn(['a', 'b'], vect => vect.map(value => value * 10)).toJS() - ).toEqual( - {a: {b: [10, 20, 30]}} - ); - }) + m + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + .updateIn(['a', 'b'], (list: List) => + list.map((value) => value * 10) + ) + .toJS() + ).toEqual({ a: { b: [10, 20, 30] } }); + }); it('creates new maps if path contains gaps', () => { - var m = I.fromJS({a: {b: {c: 10}}}); + const m = fromJS({ a: { b: { c: 10 } } }); expect( - m.updateIn(['a', 'z'], I.Map.empty(), map => map.set('d', 20)).toJS() - ).toEqual( - {a: {b: {c: 10}, z: {d: 20}}} - ); - }) + m + .updateIn( + ['a', 'q', 'z'], + Map(), + // @ts-expect-error -- updateIn should handle the `notSetValue` parameter + (map: Map) => map.set('d', 20) + ) + .toJS() + ).toEqual({ a: { b: { c: 10 }, q: { z: { d: 20 } } } }); + }); + + it('creates new objects if path contains gaps within raw JS', () => { + const m = { a: { b: { c: 10 } } }; + expect( + updateIn( + m, + ['a', 'b', 'z'], + Map(), + (map: Map) => map.set('d', 20) + ) + ).toEqual({ a: { b: { c: 10, z: Map({ d: 20 }) } } }); + }); it('throws if path cannot be set', () => { - var m = I.fromJS({a: {b: {c: 10}}}); + const m = fromJS({ a: { b: { c: 10 } } }); expect(() => { - m.updateIn(['a', 'b', 'c', 'd'], v => 20).toJS() - }).toThrow(); - }) + m.updateIn(['a', 'b', 'c', 'd'], () => 20).toJS(); + }).toThrow( + 'Cannot update within non-data-structure value in path ["a","b","c"]: 10' + ); + }); + + it('update with notSetValue when non-existing key', () => { + const m = Map({ a: { b: { c: 10 } } }); + // @ts-expect-error -- updateIn should handle the `notSetValue` parameter + expect(m.updateIn(['x'], 100, (map: number) => map + 1).toJS()).toEqual({ + a: { b: { c: 10 } }, + x: 101, + }); + }); + + it('update with notSetValue when non-existing key in raw JS', () => { + const m = { a: { b: { c: 10 } } }; + expect(updateIn(m, ['x'], 100, (map: number) => map + 1)).toEqual({ + a: { b: { c: 10 } }, + x: 101, + }); + }); it('updates self for empty path', () => { - var m = I.fromJS({a: 1, b: 2, c: 3}); - expect( - m.updateIn([], map => map.set('b', 20)).toJS() - ).toEqual( - {a: 1, b: 20, c: 3} - ) - }) + const m = fromJS({ a: 1, b: 2, c: 3 }); + // @ts-expect-error -- type of fromJS may return a MapOf in the future, to help `updateIn` to work, `updateIn` should copy the comportment of `getIn` + expect(m.updateIn([], (map: typeof m) => map.set('b', 20)).toJS()).toEqual({ + a: 1, + b: 20, + c: 3, + }); + }); + + it('does not perform edit when new value is the same as old value', () => { + const m = fromJS({ a: { b: { c: 10 } } }); + const m2 = m.updateIn(['a', 'b', 'c'], (id) => id); + expect(m2).toBe(m); + }); + + it('does not perform edit when new value is the same as old value in raw JS', () => { + const m = { a: { b: { c: 10 } } }; + const m2 = updateIn(m, ['a', 'b', 'c'], (id) => id); + expect(m2).toBe(m); + }); + + it('does not perform edit when notSetValue is what you return from updater', () => { + const m = Map(); + let spiedOnID; + const m2 = m.updateIn(['a', 'b', 'c'], Set(), (id) => (spiedOnID = id)); + expect(m2).toBe(m); + expect(spiedOnID).toBe(Set()); + }); + + it('provides default notSetValue of undefined', () => { + const m = Map(); + let spiedOnID; + const m2 = m.updateIn(['a', 'b', 'c'], (id) => (spiedOnID = id)); + expect(m2).toBe(m); + expect(spiedOnID).toBe(undefined); + }); + + describe('setIn', () => { + it('provides shorthand for updateIn to set a single value', () => { + const m = Map().setIn(['a', 'b', 'c'], 'X'); + expect(m).toEqual(fromJS({ a: { b: { c: 'X' } } })); + }); + + it('accepts a list as a keyPath', () => { + const m = Map().setIn(fromJS(['a', 'b', 'c']), 'X'); + expect(m).toEqual(fromJS({ a: { b: { c: 'X' } } })); + }); + + it('returns value when setting empty path', () => { + const m = Map(); + expect(m.setIn([], 'X')).toBe('X'); + }); + + it('can setIn undefined', () => { + const m = Map().setIn(['a', 'b', 'c'], undefined); + expect(m).toEqual(Map({ a: Map({ b: Map({ c: undefined }) }) })); + }); + + it('returns self for a no-op', () => { + const m = fromJS({ a: { b: { c: 123 } } }); + expect(m.setIn(['a', 'b', 'c'], 123)).toBe(m); + }); + + it('provides shorthand for updateIn to set a single value in raw JS', () => { + const m = setIn({}, ['a', 'b', 'c'], 'X'); + expect(m).toEqual({ a: { b: { c: 'X' } } }); + }); + + it('accepts a list as a keyPath in raw JS', () => { + const m = setIn({}, fromJS(['a', 'b', 'c']), 'X'); + expect(m).toEqual({ a: { b: { c: 'X' } } }); + }); + + it('returns value when setting empty path in raw JS', () => { + expect(setIn({}, [], 'X')).toBe('X'); + }); + + it('can setIn undefined in raw JS', () => { + const m = setIn({}, ['a', 'b', 'c'], undefined); + expect(m).toEqual({ a: { b: { c: undefined } } }); + }); + + it('returns self for a no-op in raw JS', () => { + const m = { a: { b: { c: 123 } } }; + expect(setIn(m, ['a', 'b', 'c'], 123)).toBe(m); + }); + }); + + describe('removeIn', () => { + it('provides shorthand for updateIn to remove a single value', () => { + const m = fromJS({ a: { b: { c: 'X', d: 'Y' } } }) as Map< + string, + unknown + >; + expect(m.removeIn(['a', 'b', 'c']).toJS()).toEqual({ + a: { b: { d: 'Y' } }, + }); + }); + + it('accepts a list as a keyPath', () => { + const m = fromJS({ a: { b: { c: 'X', d: 'Y' } } }) as Map< + string, + unknown + >; + expect(m.removeIn(fromJS(['a', 'b', 'c'])).toJS()).toEqual({ + a: { b: { d: 'Y' } }, + }); + }); + + it('does not create empty maps for an unset path', () => { + const m = Map(); + expect(m.removeIn(['a', 'b', 'c']).toJS()).toEqual({}); + }); + + it('removes itself when removing empty path', () => { + const m = Map(); + expect(m.removeIn([])).toBe(undefined); + }); + + it('removes values from a Set', () => { + const m = Map({ set: Set([1, 2, 3]) }); + const m2 = m.removeIn(['set', 2]); + expect(m2.toJS()).toEqual({ set: [1, 3] }); + }); + + it('returns undefined when removing an empty path in raw JS', () => { + expect(removeIn({}, [])).toBe(undefined); + }); + + it('can removeIn in raw JS', () => { + const m = removeIn({ a: { b: { c: 123 } } }, ['a', 'b', 'c']); + expect(m).toEqual({ a: { b: { c: undefined } } }); + }); + + it('returns self for a no-op in raw JS', () => { + const m = { a: { b: { c: 123 } } }; + expect(removeIn(m, ['a', 'b', 'd'])).toBe(m); + }); + }); + + describe('mergeIn', () => { + it('provides shorthand for updateIn to merge a nested value', () => { + const m1 = fromJS({ x: { a: 1, b: 2, c: 3 } }); + const m2 = fromJS({ d: 10, b: 20, e: 30 }); + expect(m1.mergeIn(['x'], m2).toJS()).toEqual({ + x: { a: 1, b: 20, c: 3, d: 10, e: 30 }, + }); + }); + + it('accepts a list as a keyPath', () => { + const m1 = fromJS({ x: { a: 1, b: 2, c: 3 } }); + const m2 = fromJS({ d: 10, b: 20, e: 30 }); + expect(m1.mergeIn(fromJS(['x']), m2).toJS()).toEqual({ + x: { a: 1, b: 20, c: 3, d: 10, e: 30 }, + }); + }); + + it('does not create empty maps for a no-op merge', () => { + const m = Map(); + expect(m.mergeIn(['a', 'b', 'c'], Map()).toJS()).toEqual({}); + }); + + it('merges into itself for empty path', () => { + const m = Map({ a: 1, b: 2, c: 3 }); + expect(m.mergeIn([], Map({ d: 10, b: 20, e: 30 })).toJS()).toEqual({ + a: 1, + b: 20, + c: 3, + d: 10, + e: 30, + }); + }); + + it('merges into plain JS Object and Array', () => { + const m = Map({ a: { x: [1, 2, 3] } }); + expect(m.mergeIn(['a', 'x'], [4, 5, 6])).toEqual( + Map({ a: { x: [1, 2, 3, 4, 5, 6] } }) + ); + }); + }); + + describe('mergeDeepIn', () => { + it('provides shorthand for updateIn to merge a nested value', () => { + const m1 = fromJS({ x: { a: 1, b: 2, c: 3 } }); + const m2 = fromJS({ d: 10, b: 20, e: 30 }); + expect(m1.mergeDeepIn(['x'], m2).toJS()).toEqual({ + x: { a: 1, b: 20, c: 3, d: 10, e: 30 }, + }); + }); + + it('accepts a list as a keyPath', () => { + const m1 = fromJS({ x: { a: 1, b: 2, c: 3 } }); + const m2 = fromJS({ d: 10, b: 20, e: 30 }); + expect(m1.mergeDeepIn(fromJS(['x']), m2).toJS()).toEqual({ + x: { a: 1, b: 20, c: 3, d: 10, e: 30 }, + }); + }); + + it('does not create empty maps for a no-op merge', () => { + const m = Map(); + expect(m.mergeDeepIn(['a', 'b', 'c'], Map()).toJS()).toEqual({}); + }); + + it('merges into itself for empty path', () => { + const m = Map({ a: 1, b: 2, c: 3 }); + expect(m.mergeDeepIn([], Map({ d: 10, b: 20, e: 30 })).toJS()).toEqual({ + a: 1, + b: 20, + c: 3, + d: 10, + e: 30, + }); + }); -}) + it('merges deep into plain JS Object and Array', () => { + const m = Map({ a: { x: [1, 2, 3] } }); + expect(m.mergeDeepIn(['a'], { x: [4, 5, 6] })).toEqual( + Map({ a: { x: [1, 2, 3, 4, 5, 6] } }) + ); + }); + }); +}); diff --git a/__tests__/utils.js b/__tests__/utils.js new file mode 100644 index 0000000000..1d1c6b0e44 --- /dev/null +++ b/__tests__/utils.js @@ -0,0 +1,62 @@ +/** + * @jest-environment jsdom + */ + +import { List, isPlainObject } from 'immutable'; + +describe('Utils', () => { + describe('isPlainObj()', function testFunc() { + const nonPlainCases = [ + ['Host object', document.createElement('div')], + ['bool primitive false', false], + ['bool primitive true', true], + ['falsy undefined', undefined], + ['falsy null', null], + ['Simple function', function () {}], + [ + 'Instance of other object', + (function () { + function Foo() {} + return new Foo(); + })(), + ], + ['Number primitive ', 5], + ['String primitive ', 'P'], + ['Number Object', Number(6)], + ['Immutable.List', new List()], + ['simple array', ['one']], + ['Error', Error], + ['Internal namespaces', Math], + ['Arguments', arguments], + ]; + const plainCases = [ + ['literal Object', {}], + // eslint-disable-next-line no-object-constructor + ['new Object', new Object()], + ['Object.create(null)', Object.create(null)], + ['nested object', { one: { prop: 'two' } }], + ['constructor prop', { constructor: 'prop' }], // shadows an object's constructor + ['constructor.name', { constructor: { name: 'two' } }], // shadows an object's constructor.name + [ + 'Fake toString', + { + toString: function () { + return '[object Object]'; + }, + }, + ], + ]; + + nonPlainCases.forEach(([name, value]) => { + it(`${name} returns false`, () => { + expect(isPlainObject(value)).toBe(false); + }); + }); + + plainCases.forEach(([name, value]) => { + it(`${name} returns true`, () => { + expect(isPlainObject(value)).toBe(true); + }); + }); + }); +}); diff --git a/__tests__/zip.ts b/__tests__/zip.ts new file mode 100644 index 0000000000..4487fa1b95 --- /dev/null +++ b/__tests__/zip.ts @@ -0,0 +1,147 @@ +import { describe, expect, it } from '@jest/globals'; +import { List, Range, Seq } from 'immutable'; +import fc from 'fast-check'; +import { expectToBeDefined } from './ts-utils'; + +describe('zip', () => { + it('zips lists into a list of tuples', () => { + expect( + Seq([1, 2, 3]) + .zip(Seq([4, 5, 6])) + .toArray() + ).toEqual([ + [1, 4], + [2, 5], + [3, 6], + ]); + }); + + it('zip results can be converted to JS', () => { + const l1 = List([List([1]), List([2]), List([3])]); + const l2 = List([List([4]), List([5]), List([6])]); + const zipped = l1.zip(l2); + expect(zipped).toEqual( + List([ + [List([1]), List([4])], + [List([2]), List([5])], + [List([3]), List([6])], + ]) + ); + expect(zipped.toJS()).toEqual([ + [[1], [4]], + [[2], [5]], + [[3], [6]], + ]); + }); + + it('zips with infinite lists', () => { + expect( + Range(0, Infinity) + .zip(Seq(['A', 'B', 'C'])) + .toArray() + ).toEqual([ + [0, 'A'], + [1, 'B'], + [2, 'C'], + ]); + }); + + it('has unknown size when zipped with unknown size', () => { + const seq = Range(0, 10); + const zipped = seq.zip(seq.filter((n) => n % 2 === 0)); + expect(zipped.size).toBe(undefined); + expect(zipped.count()).toBe(5); + }); + + it('is always the size of the smaller sequence', () => { + fc.assert( + fc.property(fc.array(fc.nat(), { minLength: 1 }), (lengths) => { + const ranges = lengths.map((l) => Range(0, l)); + const first = ranges.shift(); + expectToBeDefined(first); + const zipped = first.zip.apply(first, ranges); + const shortestLength = Math.min.apply(Math, lengths); + expect(zipped.size).toBe(shortestLength); + }) + ); + }); + + describe('zipWith', () => { + it('zips with a custom function', () => { + expect( + Seq([1, 2, 3]) + .zipWith((a, b) => a + b, Seq([4, 5, 6])) + .toArray() + ).toEqual([5, 7, 9]); + }); + + it('can zip to create immutable collections', () => { + expect( + Seq([1, 2, 3]) + .zipWith( + function () { + // eslint-disable-next-line prefer-rest-params + return List(arguments); + }, + Seq([4, 5, 6]), + Seq([7, 8, 9]) + ) + .toJS() + ).toEqual([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9], + ]); + }); + }); + + describe('zipAll', () => { + it('fills in the empty zipped values with undefined', () => { + expect( + Seq([1, 2, 3]) + .zipAll(Seq([4])) + .toArray() + ).toEqual([ + [1, 4], + [2, undefined], + [3, undefined], + ]); + }); + + it('is always the size of the longest sequence', () => { + fc.assert( + fc.property(fc.array(fc.nat(), { minLength: 1 }), (lengths) => { + const ranges = lengths.map((l) => Range(0, l)); + const first = ranges.shift(); + expectToBeDefined(first); + const zipped = first.zipAll.apply(first, ranges); + const longestLength = Math.max.apply(Math, lengths); + expect(zipped.size).toBe(longestLength); + }) + ); + }); + }); + + describe('interleave', () => { + it('interleaves multiple collections', () => { + expect( + Seq([1, 2, 3]) + .interleave(Seq([4, 5, 6]), Seq([7, 8, 9])) + .toArray() + ).toEqual([1, 4, 7, 2, 5, 8, 3, 6, 9]); + }); + + it('stops at the shortest collection', () => { + const i = Seq([1, 2, 3]).interleave(Seq([4, 5]), Seq([7, 8, 9])); + expect(i.size).toBe(6); + expect(i.toArray()).toEqual([1, 4, 7, 2, 5, 8]); + }); + + it('with infinite lists', () => { + const r: Seq.Indexed = Range(0, Infinity); + const i = r.interleave(Seq(['A', 'B', 'C'])); + expect(i.size).toBe(6); + expect(i.toArray()).toEqual([0, 'A', 1, 'B', 2, 'C']); + }); + }); +}); diff --git a/bower.json b/bower.json deleted file mode 100644 index b4a08a82dd..0000000000 --- a/bower.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "immutable", - "description": "Immutable Data Collections", - "homepage": "https://github.com/facebook/immutable-js", - "author": { - "name": "Lee Byron", - "homepage": "https://github.com/leebyron" - }, - "repository": { - "type": "git", - "url": "git://github.com/facebook/immutable-js.git" - }, - "main": "dist/Immutable.js", - "ignore": [ - "**/.*", - "__tests__", - "resources", - "src", - "type-definitions", - "package.json", - "Gruntfile.js" - ], - "keywords": [ - "immutable", - "persistent", - "lazy", - "data", - "datastructure", - "functional", - "collection", - "stateless", - "sequence", - "iteration" - ], - "license": "BSD" -} diff --git a/dist/Immutable.d.ts b/dist/Immutable.d.ts deleted file mode 100644 index 1d62f96114..0000000000 --- a/dist/Immutable.d.ts +++ /dev/null @@ -1,1864 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/** - * Immutable Data - * ============== - * - * Immutable data encourages pure functions (data-in, data-out) and lends itself - * to much simpler application development and enabling techniques from - * functional programming such as lazy evaluation. - * - * While designed to bring these powerful functional concepts to JavaScript, it - * presents an Object-Oriented API familiar to Javascript engineers and closely - * mirroring that of Array, Map, and Set. It is easy and efficient to convert to - * and from plain Javascript types. - */ - -declare module 'immutable' { - - /** - * `Immutable.is()` has the same semantics as Object.is(), but treats immutable - * sequences as data, equal if the second immutable sequences contains - * equivalent data. It's used throughout when checking for equality. - * - * var map1 = Immutable.Map({a:1, b:1, c:1}); - * var map2 = Immutable.Map({a:1, b:1, c:1}); - * assert(map1 !== map2); - * assert(Object.is(map1, map2) === false); - * assert(Immutable.is(map1, map2) === true); - * - */ - export function is(first: any, second: any): boolean; - - /** - * `Immutable.fromJS()` deeply converts plain JS objects and arrays to - * Immutable sequences. - * - * If a `converter` is optionally provided, it will be called with every - * sequence (beginning with the most nested sequences and proceeding to the - * original sequence itself), along with the key refering to this Sequence - * and the parent JS object provided as `this`. For the top level, object, - * the key will be "". This `converter` is expected to return a new Sequence, - * allowing for custom convertions from deep JS objects. - * - * This example converts JSON to Vector and OrderedMap: - * - * Immutable.fromJS({a: {b: [10, 20, 30]}, c: 40}, function (value, key) { - * var isIndexed = value instanceof IndexedSequence; - * console.log(isIndexed, key, this); - * return isIndexed ? value.toVector() : value.toOrderedMap(); - * }); - * - * // true, "b", {b: [10, 20, 30]} - * // false, "a", {a: {b: [10, 20, 30]}, c: 40} - * // false, "", {"": {a: {b: [10, 20, 30]}, c: 40}} - * - * If `converter` is not provided, the default behavior will convert Arrays into - * Vectors and Objects into Maps. - * - * Note: `converter` acts similarly to [`reviver`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter) - * in `JSON.parse`. - */ - export function fromJS( - json: any, - converter?: (k: any, v: Sequence) => any - ): any; - - - - /** - * Sequence - * -------- - * - * The `Sequence` is a set of (key, value) entries which can be iterated, and - * is the base class for all collections in `immutable`, allowing them to - * make use of all the Sequence methods (such as `map` and `filter`). - * - * **Sequences are immutable** — Once a sequence is created, it cannot be - * changed, appended to, rearranged or otherwise modified. Instead, any mutative - * method called on a sequence will return a new immutable sequence. - * - * **Sequences are lazy** — Sequences do as little work as necessary to respond - * to any method call. - * - * For example, the following does no work, because the resulting sequence is - * never used: - * - * var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8) - * .filter(x => x % 2).map(x => x * x); - * - * Once the sequence is used, it performs only the work necessary. In this - * example, no intermediate arrays are ever created, filter is only called - * twice, and map is only called once: - * - * console.log(evenSquares.last()); // 49 - * - * Lazy Sequences allow for the efficient chaining of sequence operations, - * allowing for the expression of logic that can otherwise be very tedious: - * - * Immutable.Sequence({a:1, b:1, c:1}) - * .flip().map(key => key.toUpperCase()).flip().toObject(); - * // Map { A: 1, B: 1, C: 1 } - * - * As well as expressing logic that would otherwise seem memory-limited: - * - * Immutable.Range(1, Infinity) - * .skip(1000) - * .map(n => -n) - * .filter(n => n % 2 === 0) - * .take(2) - * .reduce((r, n) => r * n, 1); - * // 1006008 - * - * Note: A sequence is always iterated in the same order, however that order may - * not always be well defined, as is the case for the `Map`. - */ - - /** - * `Immutable.Sequence()` returns a sequence of its parameters. - * - * * If provided a single argument: - * * If a Sequence, that same Sequence is returned. - * * If an Array, an `IndexedSequence` is returned. - * * If a plain Object, a `Sequence` is returned, iterated in the same order - * as the for-in would iterate through the Object itself. - * * An `IndexedSequence` of all arguments is returned. - * - * Note: if a Sequence is created from a JavaScript Array or Object, then it can - * still possibly mutated if the underlying Array or Object is ever mutated. - */ - export function Sequence(seq: IndexedSequence): IndexedSequence; - export function Sequence(array: Array): IndexedSequence; - export function Sequence(seq: Sequence): Sequence; - export function Sequence(obj: {[key: string]: V}): Sequence; - export function Sequence(iterable: Object/*Iterable*/): IndexedSequence; - export function Sequence(...values: T[]): IndexedSequence; - export function Sequence(): Sequence; - - /** - * Like `Immutable.Sequence()`, `Immutable.Sequence.from()` returns a sequence, - * but always expects a single argument. - */ - export module Sequence { - function from(seq: IndexedSequence): IndexedSequence; - function from(array: Array): IndexedSequence; - function from(seq: Sequence): Sequence; - function from(obj: {[key: string]: V}): Sequence; - } - - - export interface Sequence { - - // ### Conversion to other types - - /** - * Converts this sequence to an Array, discarding keys. - */ - toArray(): Array; - - /** - * Deeply converts this sequence to equivalent JS. - * - * IndexedSequences, Vectors, Ranges, Repeats and Sets become Arrays, while - * other Sequences become Objects. - */ - toJS(): any; - - /** - * Converts this sequence to a Map, Throws if keys are not hashable. - * - * Note: This is equivalent to `Map.from(this)`, but provided to allow for - * chained expressions. - */ - toMap(): Map; - - /** - * Converts this sequence to an Object. Throws if keys are not strings. - */ - toObject(): Object; - - /** - * Converts this sequence to a Map, maintaining the order of iteration. - * - * Note: This is equivalent to `OrderedMap.from(this)`, but provided to - * allow for chained expressions. - */ - toOrderedMap(): Map; - - /** - * Converts this sequence to a Set, discarding keys. Throws if values - * are not hashable. - * - * Note: This is equivalent to `Set.from(this)`, but provided to allow for - * chained expressions. - */ - toSet(): Set; - - /** - * Converts this sequence to a Vector, discarding keys. - * - * Note: This is equivalent to `Vector.from(this)`, but provided to allow - * for chained expressions. - */ - toVector(): Vector; - - - // ### Common JavaScript methods and properties - - /** - * Deeply converts this sequence to a string. - */ - toString(): string; - - /** - * Some sequences can describe their length lazily. When this is the case, - * length will be an integer. Otherwise it will be undefined. - * - * For example, the new Sequences returned from map() or reverse() - * preserve the length of the original sequence while filter() does not. - * - * Note: All original collections will have a length, including Maps, - * Vectors, Sets, Ranges, Repeats and Sequences made from - * Arrays and Objects. - */ - length: number; - - - // ### Sequential methods mirring those found on Array and Map (ES6) - - /** - * Returns a new sequence with other values and sequences concatenated to - * this one. All entries will be present in the resulting sequence, even if - * they have the same key. - */ - concat(...valuesOrSequences: any[]): Sequence; - - /** - * True if a value exists within this Sequence. - */ - contains(value: V): boolean; - - /** - * An iterator of this Map's entries as [key, value] tuples. - */ - entries(): Iterator>; - - /** - * True if `predicate` returns true for all entries in the sequence. - */ - every( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): boolean; - - /** - * Returns a new sequence with only the entries for which the `predicate` - * function returns true. - * - * Sequence({a:1,b:2,c:3,d:4}).filter(x => x % 2 === 0) // { b: 2, d: 4 } - * - */ - filter( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns the value for which the `predicate` returns true. - */ - find( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any, - notSetValue?: V - ): V; - - /** - * The `sideEffect` is executed for every entry in the sequence. - * - * Unlike `Array.prototype.forEach`, if any call of `sideEffect` returns - * `false`, the iteration will stop. Returns the length of the sequence which - * was iterated (including the last iteration which returned false). - */ - forEach( - sideEffect: (value?: V, key?: K, seq?: Sequence) => any, - context?: any - ): number; - - /** - * Joins values together as a string, inserting a separator between each. - * The default separator is ",". - */ - join(separator?: string): string; - - /** - * An iterator of this Map's keys. - */ - keys(): Iterator; - - /** - * Returns a new sequence with values passed through a `mapper` function. - * - * Sequence({ a: 1, b: 2 }).map(x => 10 * x) // { a: 10, b: 20 } - * - */ - map( - mapper: (value?: V, key?: K, seq?: Sequence) => M, - context?: any - ): Sequence; - - /** - * Reduces the sequence to a value by calling the `reducer` for every entry - * in the sequence and passing along the reduced value. - * - * If `initialReduction` is not provided, or is null, the first item in the - * sequence will be used. - * - * @see `Array.prototype.reduce`. - */ - reduce( - reducer: (reduction?: R, value?: V, key?: K, seq?: Sequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Reduces the sequence in reverse (from the right side). - * - * Note: Equivalent to this.reverse().reduce(), but provided for parity - * with `Array.prototype.reduceRight`. - */ - reduceRight( - reducer: (reduction?: R, value?: V, key?: K, seq?: Sequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Returns a new sequence which iterates in reverse order of this sequence. - */ - reverse(): Sequence; - - /** - * Returns a new sequence representing a portion of this sequence from start - * up to but not including end. - * - * If begin is negative, it is offset from the end of the sequence. e.g. - * `slice(-2)` returns a sequence of the last two entries. If it is not - * provided the new sequence will begin at the beginning of this sequence. - * - * If end is negative, it is offset from the end of the sequence. e.g. - * `slice(0, -1)` returns a sequence of everything but the last entry. If it - * is not provided, the new sequence will continue through the end of - * this sequence. - * - * If the requested slice is equivalent to the current Sequence, then it will - * return itself. - * - * Note: unlike `Array.prototype.slice`, this function is O(1) and copies - * no data. The resulting sequence is also lazy, and a copy is only made when - * it is converted such as via `toArray()` or `toVector()`. - */ - slice(begin?: number, end?: number): Sequence; - - /** - * True if `predicate` returns true for any entry in the sequence. - */ - some( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): boolean; - - /** - * Returns a new Sequence which contains the same [key, value] entries, - * (stable) sorted by using a comparator. - * - * If a comparator is not provided, a default comparator uses `a < b`. - * - * `comparator(valueA, valueB)`: - * - * * Returns `0` if the elements should not be swapped. - * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` - * * Returns `1` (or any positive number) if `valueA` comes after `valueB` - * * Is pure, i.e. it must always return the same value for the same pair - * of values. - */ - sort(comparator?: (valueA: V, valueB: V) => number): Sequence; - - /** - * An iterator of this Map's values. - */ - values(): Iterator; - - - // ### More sequential methods - - /** - * Returns a new Sequence containing all entries except the last. - */ - butLast(): Sequence; - - /** - * Regardless of if this sequence can describe its length lazily, this method - * will always return the correct length. E.g. it evaluates the full sequence - * if necessary. - * - * If `predicate` is provided, then this returns the count of entries in the - * sequence for which the `predicate` returns true. - */ - count(): number; - count( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): number; - - /** - * Returns a `Sequence` of counts, grouped by the return value of the - * `grouper` function. - * - * Note: This is not a lazy operation. - */ - countBy( - grouper: (value?: V, key?: K, seq?: Sequence) => G, - context?: any - ): Sequence; - - /** - * True if this and the other sequence have value equality, as defined - * by `Immutable.is()`. - * - * Note: This is equivalent to `Immutable.is(this, other)`, but provided to - * allow for chained expressions. - */ - equals(other: Sequence): boolean; - - /** - * Returns a new indexed sequence of [key, value] tuples. - */ - entrySeq(): IndexedSequence>; - - /** - * Returns the key for which the `predicate` returns true. - */ - findKey( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): K; - - /** - * Returns the last value for which the `predicate` returns true. - * - * Note: `predicate` will be called for each entry in reverse. - */ - findLast( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any, - notSetValue?: V - ): V; - - /** - * Returns the last key for which the `predicate` returns true. - * - * Note: `predicate` will be called for each entry in reverse. - */ - findLastKey( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): K; - - /** - * The first value in the sequence. - */ - first(): V; - - /** - * Flat-maps the Sequence. - */ - flatMap( - mapper: (value?: V, key?: K, seq?: Sequence) => Sequence, - context?: any - ): Sequence; - - /** - * Flattens nested Sequences by one level. - * - * Note: `flatten` operates on Sequence> and - * returns Sequence - */ - flatten(): Sequence; - - /** - * Returns a new sequence with this sequences's keys as it's values, and this - * sequences's values as it's keys. - * - * Sequence({ a: 'z', b: 'y' }).flip() // { z: 'a', y: 'b' } - * - */ - flip(): Sequence; - - /** - * Returns the value associated with the provided key, or notSetValue if - * the Sequence does not contain this key. - * - * Note: it is possible a key may be associated with an `undefined` value, so - * if `notSetValue` is not provided and this method returns `undefined`, - * that does not guarantee the key was not found. - */ - get(key: K, notSetValue?: V): V; - - /** - * Returns the value found by following a key path through nested sequences. - */ - getIn(searchKeyPath: Array, notSetValue?: V): V; - - /** - * Returns a `Sequence` of `Sequences`, grouped by the return value of the - * `grouper` function. - * - * Note: This is not a lazy operation. - */ - groupBy( - grouper: (value?: V, key?: K, seq?: Sequence) => G, - context?: any - ): Sequence>; - - /** - * True if a key exists within this Sequence. - */ - has(key: K): boolean; - - /** - * Returns a new indexed sequence of the keys of this sequence, - * discarding values. - */ - keySeq(): IndexedSequence; - - /** - * The last value in the sequence. - */ - last(): V; - - /** - * Returns a new sequence with entries ([key, value] tuples) passed through - * a `mapper` function. - * - * Sequence({ a: 1, b: 2 }) - * .mapEntries(([k, v]) => [k.toUpperCase(), v * 2]) - * // { A: 2, B: 4 } - * - */ - mapEntries( - mapper: (entry?: /*(K, V)*/Array, index?: number, seq?: Sequence) => /*(KM, VM)*/Array, - context?: any - ): Sequence; - - /** - * Returns a new sequence with keys passed through a `mapper` function. - * - * Sequence({ a: 1, b: 2 }).mapKeys(x => x.toUpperCase()) // { A: 1, B: 2 } - * - */ - mapKeys( - mapper: (key?: K, value?: V, seq?: Sequence) => M, - context?: any - ): Sequence; - - /** - * Returns a new Sequence containing all entries except the first. - */ - rest(): Sequence - - /** - * Returns a new sequence which excludes the first `amount` entries from - * this sequence. - */ - skip(amount: number): Sequence; - - /** - * Returns a new sequence which excludes the last `amount` entries from - * this sequence. - */ - skipLast(amount: number): Sequence; - - /** - * Returns a new sequence which contains entries starting from when - * `predicate` first returns false. - * - * Sequence('dog','frog','cat','hat','god').skipWhile(x => x.match(/g/)) - * // ['cat', 'hat', 'god'] - * - */ - skipWhile( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns a new sequence which contains entries starting from when - * `predicate` first returns true. - * - * Sequence('dog','frog','cat','hat','god').skipUntil(x => x.match(/hat/)) - * // ['hat', 'god'] - * - */ - skipUntil( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Like `sort`, but also accepts a `sortValueMapper` which allows for - * sorting by more sophisticated means: - * - * hitters.sortBy(hitter => hitter.avgHits); - * - */ - sortBy( - sortValueMapper: (value?: V, key?: K, seq?: Sequence) => S, - comparator?: (valueA: S, valueB: S) => number - ): Sequence; - - /** - * Returns a new sequence which contains the first `amount` entries from - * this sequence. - */ - take(amount: number): Sequence; - - /** - * Returns a new sequence which contains the last `amount` entries from - * this sequence. - */ - takeLast(amount: number): Sequence; - - /** - * Returns a new sequence which contains entries from this sequence as long - * as the `predicate` returns true. - * - * Sequence('dog','frog','cat','hat','god').takeWhile(x => x.match(/o/)) - * // ['dog', 'frog'] - * - */ - takeWhile( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns a new sequence which contains entries from this sequence as long - * as the `predicate` returns false. - * - * Sequence('dog','frog','cat','hat','god').takeUntil(x => x.match(/at/)) - * // ['dog', 'frog'] - * - */ - takeUntil( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns a new Sequence identical to this one, but does not behave as - * indexed. Instead the indices are treated as keys. This is useful if you - * want to operate on an IndexedSequence and preserve the index, value - * pairs. - * - * This is the generalized (and lazy) form of converting a Vector to Map. - * - * The returned Sequence will have identical iteration order as - * this Sequence. - * - * For already Keyed sequences, simply returns itself. - * - * Example: - * - * var indexedSeq = Immutable.Sequence('A', 'B', 'C'); - * indexedSeq.filter(v => v === 'B').toString() // Seq [ 'B' ] - * var keyedSeq = indexedSeq.toKeyedSeq(); - * keyedSeq.filter(v => v === 'B').toString() // Seq { 1: 'B' } - * - */ - toKeyedSeq(): Sequence; - - /** - * Returns a new indexed sequence of the values of this sequence, - * discarding keys. - */ - valueSeq(): IndexedSequence; - - - // ### Lazy Sequence methods - - /** - * Because Sequences are lazy and designed to be chained together, they do - * not cache their results. For example, this map function is called 6 times: - * - * var squares = Sequence(1,2,3).map(x => x * x); - * squares.join() + squares.join(); - * - * If you know a derived sequence will be used multiple times, it may be more - * efficient to first cache it. Here, map is called 3 times: - * - * var squares = Sequence(1,2,3).map(x => x * x).cacheResult(); - * squares.join() + squares.join(); - * - * Use this method judiciously, as it must fully evaluate a lazy Sequence. - * - * Note: after calling `cacheResult()`, a Sequence will always have a length. - */ - cacheResult(): Sequence; - } - - - /** - * Indexed Sequence - * ---------------- - * - * Indexed Sequences have incrementing numeric keys. They exhibit - * slightly different behavior than `Sequence` for some methods in order to - * better mirror the behavior of JavaScript's `Array`, and add others which do - * not make sense on non-indexed sequences such as `indexOf`. - * - * Unlike JavaScript arrays, `IndexedSequence`s are always dense. "Unset" - * indices and `undefined` indices are indistinguishable, and all indices from - * 0 to `length` are visited when iterated. - * - * All IndexedSequence methods return re-indexed Sequences. In other words, - * indices always start at 0 and increment until length. If you wish to - * preserve indices, using them as keys, use `toKeyedSeq()`. - * - */ - - export interface IndexedSequence extends Sequence { - - // ### Sequential methods mirring those found on Array (ES6) - - /** - * This new behavior will iterate through the values and sequences with - * increasing indices. - * @override - */ - concat(...valuesOrSequences: any[]): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - every( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): boolean; - - /** - * Returns IndexedSequence. - * @override - */ - filter( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - find( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any, - notSetValue?: T - ): T; - - /** - * Returns the first index in the sequence where a value satisfies the - * provided predicate function. Otherwise -1 is returned. - */ - findIndex( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Side effect takes IndexedSequence. - * @override - */ - forEach( - sideEffect: (value?: T, index?: number, seq?: IndexedSequence) => any, - context?: any - ): number; - - /** - * Returns the first index at which a given value can be found in the - * sequence, or -1 if it is not present. - */ - indexOf(searchValue: T): number; - - /** - * Returns the last index at which a given value can be found in the - * sequence, or -1 if it is not present. - */ - lastIndexOf(searchValue: T): number; - - /** - * Returns an IndexedSequence - * @override - */ - map( - mapper: (value?: T, index?: number, seq?: IndexedSequence) => M, - context?: any - ): IndexedSequence; - - /** - * Reducer takes IndexedSequence. - * @override - */ - reduce( - reducer: (reduction?: R, value?: T, index?: number, seq?: IndexedSequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Reducer takes IndexedSequence. - * @override - */ - reduceRight( - reducer: (reduction?: R, value?: T, index?: number, seq?: IndexedSequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Returns a new IndexedSequence with this sequences values in the - * reversed order. - * @override - */ - reverse(): IndexedSequence; - - /** - * Returns IndexedSequence. - * @override - */ - slice(begin?: number, end?: number): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - some( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): boolean; - - /** - * Returns an IndexedSequence - * @override - */ - sort( - comparator?: (valueA: T, valueB: T) => number - ): IndexedSequence; - - /** - * Splice returns a new indexed sequence by replacing a region of this sequence - * with new values. If values are not provided, it only skips the region to - * be removed. - * - * `index` may be a negative number, which indexes back from the end of the - * Sequence. `s.splice(-2)` splices after the second to last item. - * - * Sequence(['a','b','c','d']).splice(1, 2, 'q', 'r', 's') - * // ['a', 'q', 'r', 's', 'd'] - * - */ - splice(index: number, removeNum: number, ...values: any[]): IndexedSequence; - - - // ### More sequential methods - - /** - * Returns an IndexedSequence - * @override - */ - butLast(): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - count(): number; - count( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Predicate takes IndexedSequence. - * @override - */ - findKey( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Predicate takes IndexedSequence. - * @override - */ - findLast( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any, - notSetValue?: T - ): T; - - /** - * Returns the last index in the sequence where a value satisfies the - * provided predicate function. Otherwise -1 is returned. - */ - findLastIndex( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Predicate takes IndexedSequence. - * @override - */ - findLastKey( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Returns IndexedSequence - * @override - */ - flatMap( - mapper: (value?: T, index?: number, seq?: IndexedSequence) => IndexedSequence, - context?: any - ): IndexedSequence; - flatMap( - mapper: (value?: T, index?: number, seq?: IndexedSequence) => M[], - context?: any - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - flatten(): IndexedSequence; - - /** - * If this is a sequence of entries (key-value tuples), it will return a - * sequence of those entries. - */ - fromEntrySeq(): Sequence; - - /** - * Returns the value associated with the provided index, or notSetValue if - * the index is beyond the bounds of the sequence. - * - * `index` may be a negative number, which indexes back from the end of the - * Sequence. `s.get(-1)` gets the last item in the Sequence. - */ - get(index: number, notSetValue?: T): T; - - /** - * Returns Sequence> - * @override - */ - groupBy( - grouper: (value?: T, index?: number, seq?: IndexedSequence) => G, - context?: any - ): Sequence*/>; // Bug: exposing this causes the type checker to implode. - - /** - * Mapper takes IndexedSequence. - * @override - */ - mapEntries( - mapper: (entry?: /*(K, V)*/Array, index?: number, seq?: IndexedSequence) => /*(KM, VM)*/Array, - context?: any - ): Sequence; - - /** - * Mapper takes IndexedSequence. - * @override - */ - mapKeys( - mapper: (index?: number, value?: T, seq?: IndexedSequence) => M, - context?: any - ): Sequence; - - /** - * Returns IndexedSequence - * @override - */ - rest(): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skip(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skipLast(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skipWhile( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skipUntil( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Returns an IndexedSequence - * @override - */ - sortBy( - sortValueMapper: (value?: T, index?: number, seq?: IndexedSequence) => S, - comparator?: (valueA: S, valueB: S) => number - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - take(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - takeLast(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - takeWhile( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - takeUntil( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - - // ### Lazy Sequence methods - - /** - * Returns an IndexedSequence - * @override - */ - cacheResult(): IndexedSequence; - } - - - /** - * Range - * ----- - * - * Returns a lazy indexed sequence of numbers from `start` (inclusive) to `end` - * (exclusive), by `step`, where `start` defaults to 0, `step` to 1, and `end` to - * infinity. When `start` is equal to `end`, returns empty range. - * - * Range() // [0,1,2,3,...] - * Range(10) // [10,11,12,13,...] - * Range(10,15) // [10,11,12,13,14] - * Range(10,30,5) // [10,15,20,25] - * Range(30,10,5) // [30,25,20,15] - * Range(30,30,5) // [] - * - */ - export function Range(start?: number, end?: number, step?: number): IndexedSequence; - - - /** - * Repeat - * ------ - * - * Returns a lazy sequence of `value` repeated `times` times. When `times` is - * not defined, returns an infinite sequence of `value`. - * - * Repeat('foo') // ['foo','foo','foo',...] - * Repeat('bar',4) // ['bar','bar','bar','bar'] - * - */ - export function Repeat(value: T, times?: number): IndexedSequence; - - - /** - * Map - * --- - * - * A Map is a Sequence of (key, value) pairs with `O(log32 N)` gets and sets. - * - * Map is a hash map and requires keys that are hashable, either a primitive - * (string or number) or an object with a `hashCode(): number` method. - * - * Iteration order of a Map is undefined, however is stable. Multiple iterations - * of the same Map will iterate in the same order. - */ - - export module Map { - - /** - * `Map.empty()` creates a new immutable map of length 0. - */ - function empty(): Map; - - /** - * `Map.from()` creates a new immutable Map with the same key value pairs as - * the provided Sequence or JavaScript Object or Array. - * - * var newMap = Map.from({key: "value"}); - * var newMap = Map.from([["key", "value"]]); - * - */ - function from(sequence: Sequence): Map; - function from(object: {[key: string]: V}): Map; - function from(entries: Array>): Map; - } - - /** - * Alias for `Map.empty()`. - */ - export function Map(): Map; - - /** - * Alias for `Map.from()`. - */ - export function Map(sequence: Sequence): Map; - export function Map(object: {[key: string]: V}): Map; - export function Map(entries: Array>): Map; - - - export interface Map extends Sequence { - - /** - * Returns a new Map also containing the new key, value pair. If an equivalent - * key already exists in this Map, it will be replaced. - */ - set(key: K, value: V): Map; - - /** - * Returns a new Map which excludes this `key`. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(key: K): Map; - delete(key: K): Map; - - /** - * Returns a new Map containing no keys or values. - */ - clear(): Map; - - /** - * When this cursor's (or any of its sub-cursors') `update` method is called, - * the resulting new data structure will be provided to the `onChange` - * function. Use this callback to keep track of the most current value or - * update the rest of your application. - */ - cursor( - onChange?: (newValue: Map, oldValue?: Map, keyPath?: Array) => void - ): Cursor>; - cursor( - keyPath: Array, - onChange?: (newValue: Map, oldValue?: Map, keyPath?: Array) => void - ): Cursor; - cursor( - key: K, - onChange?: (newValue: Map, oldValue?: Map, keyPath?: Array) => void - ): Cursor; - - /** - * Returns a new Map having updated the value at this `key` with the return - * value of calling `updater` with the existing value, or `notSetValue` if - * the key was not set. If called with only a single argument, `updater` is - * called with the Map itself. - * - * Equivalent to: `map.set(key, updater(map.get(key, notSetValue)))`. - */ - update(updater: (value: Map) => Map): Map; - update(key: K, updater: (value: V) => V): Map; - update(key: K, notSetValue: V, updater: (value: V) => V): Map; - - /** - * Returns a new Map having applied the `updater` to the entry found at the - * keyPath. If any keys in `keyPath` do not exist, a new immutable Map will - * be created at that key. If the `keyPath` was not previously set, - * `updater` is called with `notSetValue` (if provided). - * - * var data = Immutable.fromJS({ a: { b: { c: 10 } } }); - * data.updateIn(['a', 'b'], map => map.set('d', 20)); - * // { a: { b: { c: 10, d: 20 } } } - * - */ - updateIn( - keyPath: Array, - updater: (value: any) => any - ): Map; - updateIn( - keyPath: Array, - notSetValue: any, - updater: (value: any) => any - ): Map; - - /** - * Returns a new Map resulting from merging the provided Sequences - * (or JS objects) into this Map. In other words, this takes each entry of - * each sequence and sets it on this Map. - * - * var x = Immutable.Map({a: 10, b: 20, c: 30}); - * var y = Immutable.Map({b: 40, a: 50, d: 60}); - * x.merge(y) // { a: 50, b: 40, c: 30, d: 60 } - * y.merge(x) // { b: 20, a: 10, d: 60, c: 30 } - * - */ - merge(...sequences: Sequence[]): Map; - merge(...sequences: {[key: string]: V}[]): Map; - - /** - * Like `merge()`, `mergeWith()` returns a new Map resulting from merging the - * provided Sequences (or JS objects) into this Map, but uses the `merger` - * function for dealing with conflicts. - * - * var x = Immutable.Map({a: 10, b: 20, c: 30}); - * var y = Immutable.Map({b: 40, a: 50, d: 60}); - * x.mergeWith((prev, next) => prev / next, y) // { a: 0.2, b: 0.5, c: 30, d: 60 } - * y.mergeWith((prev, next) => prev / next, x) // { b: 2, a: 5, d: 60, c: 30 } - * - */ - mergeWith( - merger: (previous?: V, next?: V) => V, - ...sequences: Sequence[] - ): Map; - mergeWith( - merger: (previous?: V, next?: V) => V, - ...sequences: {[key: string]: V}[] - ): Map; - - /** - * Like `merge()`, but when two Sequences conflict, it merges them as well, - * recursing deeply through the nested data. - * - * var x = Immutable.fromJS({a: { x: 10, y: 10 }, b: { x: 20, y: 50 } }); - * var y = Immutable.fromJS({a: { x: 2 }, b: { y: 5 }, c: { z: 3 } }); - * x.mergeDeep(y) // {a: { x: 2, y: 10 }, b: { x: 20, y: 5 }, c: { z: 3 } } - * - */ - mergeDeep(...sequences: Sequence[]): Map; - mergeDeep(...sequences: {[key: string]: V}[]): Map; - - /** - * Like `mergeDeep()`, but when two non-Sequences conflict, it uses the - * `merger` function to determine the resulting value. - * - * var x = Immutable.fromJS({a: { x: 10, y: 10 }, b: { x: 20, y: 50 } }); - * var y = Immutable.fromJS({a: { x: 2 }, b: { y: 5 }, c: { z: 3 } }); - * x.mergeDeepWith((prev, next) => prev / next, y) - * // {a: { x: 5, y: 10 }, b: { x: 20, y: 10 }, c: { z: 3 } } - * - */ - mergeDeepWith( - merger: (previous?: V, next?: V) => V, - ...sequences: Sequence[] - ): Map; - mergeDeepWith( - merger: (previous?: V, next?: V) => V, - ...sequences: {[key: string]: V}[] - ): Map; - - /** - * Every time you call one of the above functions, a new immutable Map is - * created. If a pure function calls a number of these to produce a final - * return value, then a penalty on performance and memory has been paid by - * creating all of the intermediate immutable Maps. - * - * If you need to apply a series of mutations to produce a new immutable - * Map, `withMutations()` creates a temporary mutable copy of the Map which - * can apply mutations in a highly performant manner. In fact, this is - * exactly how complex mutations like `merge` are done. - * - * As an example, this results in the creation of 2, not 4, new Maps: - * - * var map1 = Immutable.Map(); - * var map2 = map1.withMutations(map => { - * map.set('a', 1).set('b', 2).set('c', 3); - * }); - * assert(map1.length === 0); - * assert(map2.length === 3); - * - */ - withMutations(mutator: (mutable: Map) => any): Map; - - /** - * Another way to avoid creation of intermediate Immutable maps is to create - * a mutable copy of this collection. Mutable copies *always* return `this`, - * and thus shouldn't be used for equality. Your function should never return - * a mutable copy of a collection, only use it internally to create a new - * collection. If possible, use `withMutations` as it provides an easier to - * use API. - * - * Note: if the collection is already mutable, `asMutable` returns itself. - */ - asMutable(): Map; - - /** - * The yin to `asMutable`'s yang. Because it applies to mutable collections, - * this operation is *mutable* and returns itself. Once performed, the mutable - * copy has become immutable and can be safely returned from a function. - */ - asImmutable(): Map; - } - - - /** - * Ordered Map - * ----------- - * - * OrderedMap constructors return a Map which has the additional guarantee of - * the iteration order of entries to match the order in which they were set(). - * This makes OrderedMap behave similarly to native JS objects. - */ - - export module OrderedMap { - - /** - * `OrderedMap.empty()` creates a new immutable ordered Map of length 0. - */ - function empty(): Map; - - /** - * `OrderedMap.from()` creates a new immutable ordered Map with the same key - * value pairs as the provided Sequence or JavaScript Object or Array. - * - * var newMap = OrderedMap.from({key: "value"}); - * - */ - function from(sequence: Sequence): Map; - function from(object: {[key: string]: V}): Map; - function from(array: Array): Map; - } - - /** - * Alias for `OrderedMap.empty()`. - */ - export function OrderedMap(): Map; - - /** - * Alias for `OrderedMap.from()`. - */ - export function OrderedMap(sequence: Sequence): Map; - export function OrderedMap(object: {[key: string]: V}): Map; - export function OrderedMap(array: Array): Map; - - - /** - * Record - * ------ - * - * Creates a new Class which produces maps with a specific set of allowed string - * keys and have default values. - * - * var ABRecord = Record({a:1, b:2}) - * var myRecord = new ABRecord({b:3}) - * - * Records always have a value for the keys they define. `remove`ing a key - * from a record simply resets it to the default value for that key. - * - * myRecord.length // 2 - * myRecordWithoutB = myRecord.remove('b') - * myRecordWithoutB.get('b') // 2 - * myRecordWithoutB.length // 2 - * - * Because Records have a known set of string keys, property get access works as - * expected, however property sets will throw an Error. - * - * myRecord.b // 3 - * myRecord.b = 5 // throws Error - * - * Record Classes can be extended as well, allowing for custom methods on your - * Record. This isn't how things are done in functional environments, but is a - * common pattern in many JS programs. - * - * class ABRecord extends Record({a:1,b:2}) { - * getAB() { - * return this.a + this.b; - * } - * } - * - * var myRecord = new ABRecord(b:3) - * myRecord.getAB() // 4 - * - */ - export function Record(defaultValues: Sequence, name?: string): RecordClass; - export function Record(defaultValues: {[key: string]: any}, name?: string): RecordClass; - - export interface RecordClass { - new (): Map; - new (values: Sequence): Map; - new (values: {[key: string]: any}): Map; - } - - - /** - * Set - * --- - * - * A Set is a Sequence of unique values with `O(log32 N)` gets and sets. - * - * Sets, like Maps, require that their values are hashable, either a primitive - * (string or number) or an object with a `hashCode(): number` method. - * - * When iterating a Set, the entries will be (value, value) pairs. Iteration - * order of a Set is undefined, however is stable. Multiple iterations of the - * same Set will iterate in the same order. - */ - - export module Set { - - /** - * `Set.empty()` creates a new immutable set of length 0. - */ - function empty(): Set; - - /** - * `Set.from()` creates a new immutable Set containing the values from this - * Sequence or JavaScript Array. - */ - function from(sequence: Sequence): Set; - function from(array: Array): Set; - - /** - * `Set.fromkeySeq()` creates a new immutable Set containing the keys from - * this Sequence or JavaScript Object. - */ - function fromKeys(sequence: Sequence): Set; - function fromKeys(object: {[key: string]: any}): Set; - } - - /** - * Alias for `Set.empty()` - */ - export function Set(): Set; - - /** - * Like `Set.from()`, but accepts variable arguments instead of an Array. - */ - export function Set(...values: T[]): Set; - - - export interface Set extends Sequence { - - /** - * Returns a new Set which also includes this value. - */ - add(value: T): Set; - - /** - * Returns a new Set which excludes this value. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(value: T): Set; - delete(value: T): Set; - - /** - * Returns a new Set containing no values. - */ - clear(): Set; - - /** - * Alias for `union`. - * @see `Map.prototype.merge` - */ - merge(...sequences: Sequence[]): Set; - merge(...sequences: Array[]): Set; - - /** - * Returns a Set including any value from `sequences` that does not already - * exist in this Set. - */ - union(...sequences: Sequence[]): Set; - union(...sequences: Array[]): Set; - - /** - * Returns a Set which has removed any values not also contained - * within `sequences`. - */ - intersect(...sequences: Sequence[]): Set; - intersect(...sequences: Array[]): Set; - - /** - * Returns a Set excluding any values contained within `sequences`. - */ - subtract(...sequences: Sequence[]): Set; - subtract(...sequences: Array[]): Set; - - /** - * True if `sequence` contains every value in this Set. - */ - isSubset(sequence: Sequence): boolean; - isSubset(sequence: Array): boolean; - - /** - * True if this Set contains every value in `sequence`. - */ - isSuperset(sequence: Sequence): boolean; - isSuperset(sequence: Array): boolean; - - /** - * @see `Map.prototype.withMutations` - */ - withMutations(mutator: (mutable: Set) => any): Set; - - /** - * @see `Map.prototype.asMutable` - */ - asMutable(): Set; - - /** - * @see `Map.prototype.asImmutable` - */ - asImmutable(): Set; - } - - - /** - * Vector - * ------ - * - * Vectors are ordered indexed dense collections, much like a JavaScript - * Array. Unlike a JavaScript Array, there is no distinction between an - * "unset" index and an index set to `undefined`. `Vector#forEach` visits all - * indices from 0 to length, regardless of if they are defined. - */ - - export module Vector { - - /** - * `Vector.empty()` returns a Vector of length 0. - */ - function empty(): Vector; - - /** - * `Vector.from()` returns a Vector of the same length of the provided - * `values` JavaScript Array or Sequence, containing the values at the - * same indices. - * - * If a non-indexed Sequence is provided, its keys will be discarded and - * its values will be used to fill the returned Vector. - */ - function from(array: Array): Vector; - function from(sequence: Sequence): Vector; - } - - /** - * Alias for `Vector.empty()` - */ - export function Vector(): Vector; - - /** - * Like `Vector.from()`, but accepts variable arguments instead of an Array. - */ - export function Vector(...values: T[]): Vector; - - - export interface Vector extends IndexedSequence { - - /** - * Returns a new Vector which includes `value` at `index`. If `index` already - * exists in this Vector, it will be replaced. - * - * `index` may be a negative number, which indexes back from the end of the - * Vector. `v.set(-1, "value")` sets the last item in the Vector. - */ - set(index: number, value: T): Vector; - - /** - * Returns a new Vector which excludes this `index`. It will not affect the - * length of the Vector, instead leaving an undefined value. - * - * `index` may be a negative number, which indexes back from the end of the - * Vector. `v.delete(-1)` deletes the last item in the Vector. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(index: number): Vector; - delete(index: number): Vector; - - /** - * Returns a new Vector with 0 length and no values. - */ - clear(): Vector; - - /** - * Returns a new Vector with the provided `values` appended, starting at this - * Vector's `length`. - */ - push(...values: T[]): Vector; - - /** - * Returns a new Vector with a length ones less than this Vector, excluding - * the last index in this Vector. - * - * Note: this differs from `Array.prototype.pop` because it returns a new - * Vector rather than the removed value. Use `last()` to get the last value - * in this Vector. - */ - pop(): Vector; - - /** - * Returns a new Vector with the provided `values` prepended, pushing other - * values ahead to higher indices. - */ - unshift(...values: T[]): Vector; - - /** - * Returns a new Vector with a length ones less than this Vector, excluding - * the first index in this Vector, shifting all other values to a lower index. - * - * Note: this differs from `Array.prototype.shift` because it returns a new - * Vector rather than the removed value. Use `first()` to get the last value - * in this Vector. - */ - shift(): Vector; - - /** - * @see Map.cursor - */ - cursor( - onChange?: (newValue: Vector, oldValue?: Vector, keyPath?: Array) => void - ): Cursor>; - cursor( - keyPath: Array, - onChange?: (newValue: Vector, oldValue?: Vector, keyPath?: Array) => void - ): Cursor; - cursor( - key: number, - onChange?: (newValue: Vector, oldValue?: Vector, keyPath?: Array) => void - ): Cursor; - - - /** - * Returns a new Vector with an updated value at `index` with the return - * value of calling `updater` with the existing value, or `notSetValue` if - * `index` was not set. If called with a single argument, `updater` is - * called with the Vector itself. - * - * `index` may be a negative number, which indexes back from the end of the - * Vector. `v.update(-1)` updates the last item in the Vector. - * - * @see Map.update - */ - update(updater: (value: Vector) => Vector): Vector; - update(index: number, updater: (value: T) => T): Vector; - update(index: number, notSetValue: T, updater: (value: T) => T): Vector; - - /** - * @see `Map.prototype.updateIn` - */ - updateIn( - keyPath: Array, - updater: (value: any) => any - ): Vector; - updateIn( - keyPath: Array, - notSetValue: any, - updater: (value: any) => any - ): Vector; - - /** - * @see `Map.prototype.merge` - */ - merge(...sequences: IndexedSequence[]): Vector; - merge(...sequences: Array[]): Vector; - - /** - * @see `Map.prototype.mergeWith` - */ - mergeWith( - merger: (previous?: T, next?: T) => T, - ...sequences: IndexedSequence[] - ): Vector; - mergeWith( - merger: (previous?: T, next?: T) => T, - ...sequences: Array[] - ): Vector; - - /** - * @see `Map.prototype.mergeDeep` - */ - mergeDeep(...sequences: IndexedSequence[]): Vector; - mergeDeep(...sequences: Array[]): Vector; - - /** - * @see `Map.prototype.mergeDeepWith` - */ - mergeDeepWith( - merger: (previous?: T, next?: T) => T, - ...sequences: IndexedSequence[] - ): Vector; - mergeDeepWith( - merger: (previous?: T, next?: T) => T, - ...sequences: Array[] - ): Vector; - - /** - * Returns a new Vector with length `length`. If `length` is less than this - * Vector's length, the new Vector will exclude values at the higher indices. - * If `length` is greater than this Vector's length, the new Vector will have - * undefined values for the newly available indices. - */ - setLength(length: number): Vector; - - /** - * @see `Map.prototype.withMutations` - */ - withMutations(mutator: (mutable: Vector) => any): Vector; - - /** - * @see `Map.prototype.asMutable` - */ - asMutable(): Vector; - - /** - * @see `Map.prototype.asImmutable` - */ - asImmutable(): Vector; - } - - - /** - * Cursors - * ------- - * - * Cursors allow you to hold a reference to a path in a nested immutable data - * structure, allowing you to pass smaller sections of a larger nested - * collection to portions of your application while maintaining a central point - * aware of changes to the entire data structure. - * - * This is particularly useful when used in conjuction with component-based UI - * libraries like [React](http://facebook.github.io/react/) or to simulate - * "state" throughout an application while maintaining a single flow of logic. - * - * Cursors provide a simple API for getting the value at that path - * (the equivalent of `this.getIn(keyPath)`), updating the value at that path - * (the equivalent of `this.updateIn(keyPath)`), and getting a sub-cursor - * starting from that path. - * - * When updated, a new root collection is created and provided to the `onChange` - * function provided to the first call to `map.cursor(...)`. - * - * @see Map.cursor - */ - - export interface Cursor extends Sequence { - - /** - * Returns a sub-cursor following the key-path starting from this cursor. - */ - cursor(subKeyPath: Array): Cursor; - cursor(subKey: any): Cursor; - - /** - * Returns the value at the cursor, if the cursor path does not yet exist, - * returns `notSetValue`. - */ - deref(notSetValue?: T): T; - - /** - * Returns the value at the `key` in the cursor, or `notSetValue` if it - * does not exist. - * - * If the key would return a collection, a new Cursor is returned. - */ - get(key: any, notSetValue?: any): any; - - /** - * Returns the value at the `keyPath` in the cursor, or `notSetValue` if it - * does not exist. - * - * If the keyPath would return a collection, a new Cursor is returned. - */ - getIn(keyPath: Array, notSetValue?: any): any; - - /** - * Sets `value` at `key` in the cursor, returning a new cursor to the same - * point in the new data. - */ - set(key: any, value: any): Cursor; - - /** - * Deletes `key` from the cursor, returning a new cursor to the same - * point in the new data. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(key: any): Cursor; - delete(key: any): Cursor; - - /** - * Clears the value at this cursor, returning a new cursor to the same - * point in the new data. - */ - clear(): Cursor; - - /** - * Updates the value in the data this cursor points to, triggering the - * callback for the root cursor and returning a new cursor pointing to the - * new data. - */ - update(updater: (value: T) => T): Cursor; - update(key: any, updater: (value: any) => any): Cursor; - update(key: any, notSetValue: any, updater: (value: any) => any): Cursor; - - - /** - * Every time you call one of the above functions, a new immutable value is - * created and the callback is triggered. If you need to apply a series of - * mutations to a Cursor without triggering the callback repeatedly, - * `withMutations()` creates a temporary mutable copy of the value which - * can apply mutations in a highly performant manner. Afterwards the - * callback is triggered with the final value. - */ - withMutations(mutator: (mutable: T) => T): Cursor; - } - - // ES6 Iterator - export interface Iterator { - next(): { value: T; done: boolean; } - } - -} diff --git a/dist/Immutable.js b/dist/Immutable.js deleted file mode 100644 index 95a03d27ac..0000000000 --- a/dist/Immutable.js +++ /dev/null @@ -1,3070 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -function universalModule() { - var $Object = Object; - -function createClass(ctor, methods, staticMethods, superClass) { - var proto; - if (superClass) { - var superProto = superClass.prototype; - proto = $Object.create(superProto); - } else { - proto = ctor.prototype; - } - $Object.keys(methods).forEach(function (key) { - proto[key] = methods[key]; - }); - $Object.keys(staticMethods).forEach(function (key) { - ctor[key] = staticMethods[key]; - }); - proto.constructor = ctor; - ctor.prototype = proto; - return ctor; -} - -function superCall(self, proto, name, args) { - return $Object.getPrototypeOf(proto)[name].apply(self, args); -} - -function defaultSuperCall(self, proto, args) { - superCall(self, proto, 'constructor', args); -} - -var $traceurRuntime = {}; -$traceurRuntime.createClass = createClass; -$traceurRuntime.superCall = superCall; -$traceurRuntime.defaultSuperCall = defaultSuperCall; -"use strict"; -var DELETE = 'delete'; -var SHIFT = 5; -var SIZE = 1 << SHIFT; -var MASK = SIZE - 1; -var NOT_SET = {}; -var CHANGE_LENGTH = {value: false}; -var DID_ALTER = {value: false}; -function MakeRef(ref) { - ref.value = false; - return ref; -} -function SetRef(ref) { - ref && (ref.value = true); -} -function OwnerID() {} -function arrCopy(arr, offset) { - offset = offset || 0; - var len = Math.max(0, arr.length - offset); - var newArr = new Array(len); - for (var ii = 0; ii < len; ii++) { - newArr[ii] = arr[ii + offset]; - } - return newArr; -} -function invariant(condition, error) { - if (!condition) - throw new Error(error); -} -function hash(o) { - if (!o) { - return 0; - } - if (o === true) { - return 1; - } - var type = typeof o; - if (type === 'number') { - if ((o | 0) === o) { - return o & HASH_MAX_VAL; - } - o = '' + o; - type = 'string'; - } - if (type === 'string') { - return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); - } - if (o.hashCode) { - return hash(typeof o.hashCode === 'function' ? o.hashCode() : o.hashCode); - } - return hashJSObj(o); -} -function cachedHashString(string) { - var hash = stringHashCache[string]; - if (hash == null) { - hash = hashString(string); - if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { - STRING_HASH_CACHE_SIZE = 0; - stringHashCache = {}; - } - STRING_HASH_CACHE_SIZE++; - stringHashCache[string] = hash; - } - return hash; -} -function hashString(string) { - var hash = 0; - for (var ii = 0; ii < string.length; ii++) { - hash = (31 * hash + string.charCodeAt(ii)) & HASH_MAX_VAL; - } - return hash; -} -function hashJSObj(obj) { - var hash = obj[UID_HASH_KEY]; - if (hash) - return hash; - if (!canDefineProperty) { - hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; - if (hash) - return hash; - hash = getIENodeHash(obj); - if (hash) - return hash; - } - if (!canDefineProperty || Object.isExtensible(obj)) { - hash = ++objHashUID & HASH_MAX_VAL; - if (canDefineProperty) { - Object.defineProperty(obj, UID_HASH_KEY, { - 'enumerable': false, - 'configurable': false, - 'writable': false, - 'value': hash - }); - } else if (propertyIsEnumerable && obj.propertyIsEnumerable === propertyIsEnumerable) { - obj.propertyIsEnumerable = function() { - return propertyIsEnumerable.apply(this, arguments); - }; - obj.propertyIsEnumerable[UID_HASH_KEY] = hash; - } else if (obj.nodeType) { - obj[UID_HASH_KEY] = hash; - } else { - throw new Error('Unable to set a non-enumerable property on object.'); - } - return hash; - } else { - throw new Error('Non-extensible objects are not allowed as keys.'); - } -} -var propertyIsEnumerable = Object.prototype.propertyIsEnumerable; -var canDefineProperty = (function() { - try { - Object.defineProperty({}, 'x', {}); - return true; - } catch (e) { - return false; - } -}()); -function getIENodeHash(node) { - if (node && node.nodeType > 0) { - switch (node.nodeType) { - case 1: - return node.uniqueID; - case 9: - return node.documentElement && node.documentElement.uniqueID; - } - } -} -var HASH_MAX_VAL = 0x7FFFFFFF; -var objHashUID = 0; -var UID_HASH_KEY = '__immutablehash__'; -if (typeof Symbol !== 'undefined') { - UID_HASH_KEY = Symbol(UID_HASH_KEY); -} -var STRING_HASH_CACHE_MIN_STRLEN = 16; -var STRING_HASH_CACHE_MAX_SIZE = 255; -var STRING_HASH_CACHE_SIZE = 0; -var stringHashCache = {}; -var ITERATE_KEYS = 0; -var ITERATE_VALUES = 1; -var ITERATE_ENTRIES = 2; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; -var ITERATOR_SYMBOL = typeof Symbol !== 'undefined' ? Symbol.iterator : FAUX_ITERATOR_SYMBOL; -var Iterator = function Iterator(next) { - this.next = next; -}; -($traceurRuntime.createClass)(Iterator, {toString: function() { - return '[Iterator]'; - }}, {}); -var IteratorPrototype = Iterator.prototype; -IteratorPrototype.inspect = IteratorPrototype.toSource = function() { - return this.toString(); -}; -IteratorPrototype[ITERATOR_SYMBOL] = function() { - return this; -}; -var iteratorResult = { - value: undefined, - done: false -}; -function iteratorValue(type, key, value) { - iteratorResult.value = type === 0 ? key : type === 1 ? value : [key, value]; - iteratorResult.done = false; - return iteratorResult; -} -function iteratorDone() { - iteratorResult.value = undefined; - iteratorResult.done = true; - return iteratorResult; -} -function iteratorMapper(iter, fn) { - var newIter = new Iterator(); - newIter.next = (function() { - var step = iter.next(); - if (step.done) - return step; - step.value = fn(step.value); - return step; - }); - return newIter; -} -function isIterable(maybeIterable) { - return !!_iteratorFn(maybeIterable); -} -function isIterator(maybeIterator) { - return maybeIterator && typeof maybeIterator.next === 'function'; -} -function getIterator(iterable) { - var iteratorFn = _iteratorFn(iterable); - if (typeof iteratorFn === 'function') { - return iteratorFn.call(iterable); - } -} -function _iteratorFn(iterable) { - return iterable && (iterable[ITERATOR_SYMBOL] || iterable[FAUX_ITERATOR_SYMBOL]); -} -var Sequence = function Sequence(value) { - return $Sequence.from(arguments.length === 1 ? value : Array.prototype.slice.call(arguments)); -}; -var $Sequence = Sequence; -($traceurRuntime.createClass)(Sequence, { - toString: function() { - return this.__toString('Seq {', '}'); - }, - __toString: function(head, tail) { - if (this.length === 0) { - return head + tail; - } - return head + ' ' + this.map(this.__toStringMapper).join(', ') + ' ' + tail; - }, - __toStringMapper: function(v, k) { - return k + ': ' + quoteString(v); - }, - toJS: function() { - return this.map((function(value) { - return value instanceof $Sequence ? value.toJS() : value; - })).__toJS(); - }, - toArray: function() { - assertNotInfinite(this.length); - var array = new Array(this.length || 0); - this.valueSeq().__iterate((function(v, i) { - array[i] = v; - })); - return array; - }, - toObject: function() { - assertNotInfinite(this.length); - var object = {}; - this.__iterate((function(v, k) { - object[k] = v; - })); - return object; - }, - toVector: function() { - assertNotInfinite(this.length); - return Vector.from(this); - }, - toMap: function() { - assertNotInfinite(this.length); - return Map.from(this); - }, - toOrderedMap: function() { - assertNotInfinite(this.length); - return OrderedMap.from(this); - }, - toSet: function() { - assertNotInfinite(this.length); - return Set.from(this); - }, - toKeyedSeq: function() { - return this; - }, - hashCode: function() { - return this.__hash || (this.__hash = this.length === Infinity ? 0 : this.reduce((function(h, v, k) { - return (h + (hash(v) ^ (v === k ? 0 : hash(k)))) & HASH_MAX_VAL; - }), 0)); - }, - equals: function(other) { - if (this === other) { - return true; - } - if (!(other instanceof $Sequence)) { - return false; - } - if (this.length != null && other.length != null) { - if (this.length !== other.length) { - return false; - } - if (this.length === 0 && other.length === 0) { - return true; - } - } - if (this.__hash != null && other.__hash != null && this.__hash !== other.__hash) { - return false; - } - return this.__deepEquals(other); - }, - __deepEquals: function(other) { - var entries = this.cacheResult().entrySeq().toArray(); - var iterations = 0; - return other.every((function(v, k) { - var entry = entries[iterations++]; - return entry && is(k, entry[0]) && is(v, entry[1]); - })) && iterations === entries.length; - }, - join: function(separator) { - separator = separator !== undefined ? '' + separator : ','; - var joined = ''; - var isFirst = true; - this.__iterate((function(v) { - isFirst ? (isFirst = false) : (joined += separator); - joined += v != null ? v : ''; - })); - return joined; - }, - count: function(predicate, context) { - if (!predicate) { - if (this.length == null) { - this.length = this.__iterate(returnTrue); - } - return this.length; - } - return this.filter(predicate, context).count(); - }, - countBy: function(grouper, context) { - var $__0 = this; - var groupMap = {}; - var groups = []; - this.__iterate((function(v, k) { - var g = grouper.call(context, v, k, $__0); - var h = hash(g); - if (!groupMap.hasOwnProperty(h)) { - groupMap[h] = groups.length; - groups.push([g, 1]); - } else { - groups[groupMap[h]][1]++; - } - })); - return $Sequence(groups).fromEntrySeq(); - }, - concat: function() { - for (var values = [], - $__2 = 0; $__2 < arguments.length; $__2++) - values[$__2] = arguments[$__2]; - return concatFactory(this, values, true); - }, - flatten: function() { - return flattenFactory(this, true); - }, - flatMap: function(mapper, context) { - return this.map(mapper, context).flatten(); - }, - reverse: function() { - var sequence = this; - var reversedSequence = sequence.__makeSequence(); - reversedSequence.reverse = (function() { - return sequence; - }); - reversedSequence.length = sequence.length; - reversedSequence.get = (function(key, notSetValue) { - return sequence.get(key, notSetValue); - }); - reversedSequence.has = (function(key) { - return sequence.has(key); - }); - reversedSequence.contains = (function(value) { - return sequence.contains(value); - }); - reversedSequence.cacheResult = function() { - sequence.cacheResult(); - this.length = sequence.length; - }; - reversedSequence.__iterate = function(fn, reverse) { - var $__0 = this; - return sequence.__iterate((function(v, k) { - return fn(v, k, $__0); - }), !reverse); - }; - reversedSequence.__iterator = (function(type, reverse) { - return sequence.__iterator(type, !reverse); - }); - return reversedSequence; - }, - keySeq: function() { - return this.flip().valueSeq(); - }, - valueSeq: function() { - return new ValuesSequence(this); - }, - entrySeq: function() { - var sequence = this; - if (sequence._cache) { - return $Sequence(sequence._cache); - } - var entriesSequence = sequence.toKeyedSeq().map(entryMapper).valueSeq(); - entriesSequence.fromEntries = (function() { - return sequence; - }); - return entriesSequence; - }, - forEach: function(sideEffect, context) { - return this.__iterate(context ? sideEffect.bind(context) : sideEffect); - }, - reduce: function(reducer, initialReduction, context) { - var reduction; - var useFirst; - if (arguments.length < 2) { - useFirst = true; - } else { - reduction = initialReduction; - } - this.__iterate((function(v, k, c) { - if (useFirst) { - useFirst = false; - reduction = v; - } else { - reduction = reducer.call(context, reduction, v, k, c); - } - })); - return reduction; - }, - reduceRight: function(reducer, initialReduction, context) { - var reversed = this.toKeyedSeq().reverse(); - return reversed.reduce.apply(reversed, arguments); - }, - every: function(predicate, context) { - var returnValue = true; - this.__iterate((function(v, k, c) { - if (!predicate.call(context, v, k, c)) { - returnValue = false; - return false; - } - })); - return returnValue; - }, - some: function(predicate, context) { - return !this.every(not(predicate), context); - }, - first: function() { - return this.find(returnTrue); - }, - last: function() { - return this.findLast(returnTrue); - }, - rest: function() { - return this.slice(1); - }, - butLast: function() { - return this.slice(0, -1); - }, - has: function(searchKey) { - return this.get(searchKey, NOT_SET) !== NOT_SET; - }, - get: function(searchKey, notSetValue) { - return this.find((function(_, key) { - return is(key, searchKey); - }), null, notSetValue); - }, - getIn: function(searchKeyPath, notSetValue) { - var nested = this; - if (searchKeyPath) { - for (var ii = 0; ii < searchKeyPath.length; ii++) { - nested = nested && nested.get ? nested.get(searchKeyPath[ii], NOT_SET) : NOT_SET; - if (nested === NOT_SET) { - return notSetValue; - } - } - } - return nested; - }, - contains: function(searchValue) { - return this.find((function(value) { - return is(value, searchValue); - }), null, NOT_SET) !== NOT_SET; - }, - find: function(predicate, context, notSetValue) { - var foundValue = notSetValue; - this.__iterate((function(v, k, c) { - if (predicate.call(context, v, k, c)) { - foundValue = v; - return false; - } - })); - return foundValue; - }, - findKey: function(predicate, context) { - var foundKey; - this.__iterate((function(v, k, c) { - if (predicate.call(context, v, k, c)) { - foundKey = k; - return false; - } - })); - return foundKey; - }, - findLast: function(predicate, context, notSetValue) { - return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); - }, - findLastKey: function(predicate, context) { - return this.toKeyedSeq().reverse().findKey(predicate, context); - }, - flip: function() { - var sequence = this.toKeyedSeq(); - var flipSequence = sequence.__makeSequence(); - flipSequence.length = sequence.length; - flipSequence.flip = (function() { - return sequence; - }); - flipSequence.has = (function(key) { - return sequence.contains(key); - }); - flipSequence.contains = (function(key) { - return sequence.has(key); - }); - flipSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - return sequence.__iterate((function(v, k) { - return fn(k, v, $__0) !== false; - }), reverse); - }; - return flipSequence; - }, - map: function(mapper, context) { - var sequence = this; - var mappedSequence = sequence.__makeSequence(); - mappedSequence.length = sequence.length; - mappedSequence.has = (function(key) { - return sequence.has(key); - }); - mappedSequence.get = (function(key, notSetValue) { - var v = sequence.get(key, NOT_SET); - return v === NOT_SET ? notSetValue : mapper.call(context, v, key, sequence); - }); - mappedSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - return sequence.__iterate((function(v, k, c) { - return fn(mapper.call(context, v, k, c), k, $__0) !== false; - }), reverse); - }; - mappedSequence.__iteratorUncached = function(type, reverse) { - var iterator = sequence.__iterator(ITERATE_ENTRIES, reverse); - return new Iterator((function() { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - return iteratorValue(type, key, mapper.call(context, entry[1], key, sequence)); - })); - }; - return mappedSequence; - }, - mapKeys: function(mapper, context) { - var $__0 = this; - return this.flip().map((function(k, v) { - return mapper.call(context, k, v, $__0); - })).flip(); - }, - mapEntries: function(mapper, context) { - var $__0 = this; - return this.entrySeq().map((function(entry, index) { - return mapper.call(context, entry, index, $__0); - })).fromEntrySeq(); - }, - filter: function(predicate, context) { - return filterFactory(this, predicate, context, true); - }, - slice: function(begin, end) { - if (wholeSlice(begin, end, this.length)) { - return this; - } - var resolvedBegin = resolveBegin(begin, this.length); - var resolvedEnd = resolveEnd(end, this.length); - if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { - return this.cacheResult().slice(begin, end); - } - var skipped = resolvedBegin === 0 ? this : this.skip(resolvedBegin); - return resolvedEnd == null || resolvedEnd === this.length ? skipped : skipped.take(resolvedEnd - resolvedBegin); - }, - take: function(amount) { - var sequence = this; - if (amount > sequence.length) { - return sequence; - } - if (amount < 0) { - amount = 0; - } - var takeSequence = sequence.__makeSequence(); - takeSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (amount === 0) { - return 0; - } - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - sequence.__iterate((function(v, k) { - return ++iterations && fn(v, k, $__0) !== false && iterations < amount; - })); - return iterations; - }; - takeSequence.length = this.length && Math.min(this.length, amount); - return takeSequence; - }, - takeLast: function(amount) { - return this.reverse().take(amount).reverse(); - }, - takeWhile: function(predicate, context) { - var sequence = this; - var takeSequence = sequence.__makeSequence(); - takeSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - sequence.__iterate((function(v, k, c) { - return predicate.call(context, v, k, c) && ++iterations && fn(v, k, $__0); - })); - return iterations; - }; - return takeSequence; - }, - takeUntil: function(predicate, context) { - return this.takeWhile(not(predicate), context); - }, - skip: function(amount) { - return skipFactory(this, amount, true); - }, - skipLast: function(amount) { - return this.reverse().skip(amount).reverse(); - }, - skipWhile: function(predicate, context) { - return skipWhileFactory(this, predicate, context, true); - }, - skipUntil: function(predicate, context) { - return this.skipWhile(not(predicate), context); - }, - groupBy: function(grouper, context) { - return groupByFactory(this, grouper, context, true); - }, - sort: function(comparator) { - return this.sortBy(valueMapper, comparator); - }, - sortBy: function(mapper, comparator) { - comparator = comparator || defaultComparator; - var seq = this; - return $Sequence(this.entrySeq().entrySeq().toArray().sort((function(a, b) { - return comparator(mapper(a[1][1], a[1][0], seq), mapper(b[1][1], b[1][0], seq)) || a[0] - b[0]; - }))).fromEntrySeq().valueSeq().fromEntrySeq(); - }, - cacheResult: function() { - if (!this._cache && this.__iterateUncached) { - assertNotInfinite(this.length); - this._cache = this.entrySeq().toArray(); - if (this.length == null) { - this.length = this._cache.length; - } - } - return this; - }, - keys: function() { - return this.__iterator(ITERATE_KEYS); - }, - values: function() { - return this.__iterator(ITERATE_VALUES); - }, - entries: function() { - return this.__iterator(ITERATE_ENTRIES); - }, - __iterate: function(fn, reverse) { - return iterate(this, fn, reverse, true); - }, - __iterator: function(type, reverse) { - return iterator(this, type, reverse, true); - }, - __makeSequence: function() { - return makeSequence(); - } -}, {from: function(value) { - if (value instanceof $Sequence) { - return value; - } - if (!Array.isArray(value)) { - if (isIterator(value)) { - return new IteratorSequence(value); - } - if (isIterable(value)) { - return new IterableSequence(value); - } - if (value && value.constructor === Object) { - return new ObjectSequence(value); - } - value = [value]; - } - return new ArraySequence(value); - }}); -var SequencePrototype = Sequence.prototype; -SequencePrototype[ITERATOR_SYMBOL] = SequencePrototype.entries; -SequencePrototype.toJSON = SequencePrototype.toJS; -SequencePrototype.__toJS = SequencePrototype.toObject; -SequencePrototype.inspect = SequencePrototype.toSource = function() { - return this.toString(); -}; -SequencePrototype.chain = SequencePrototype.flatMap; -var IndexedSequence = function IndexedSequence() { - $traceurRuntime.defaultSuperCall(this, $IndexedSequence.prototype, arguments); -}; -var $IndexedSequence = IndexedSequence; -($traceurRuntime.createClass)(IndexedSequence, { - toString: function() { - return this.__toString('Seq [', ']'); - }, - toKeyedSeq: function() { - return new KeyedIndexedSequence(this); - }, - valueSeq: function() { - return this; - }, - fromEntrySeq: function() { - var sequence = this; - var fromEntriesSequence = makeSequence(); - fromEntriesSequence.length = sequence.length; - fromEntriesSequence.entrySeq = (function() { - return sequence; - }); - fromEntriesSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - return sequence.__iterate((function(entry) { - return entry && fn(entry[1], entry[0], $__0); - }), reverse); - }; - return fromEntriesSequence; - }, - concat: function() { - for (var values = [], - $__3 = 0; $__3 < arguments.length; $__3++) - values[$__3] = arguments[$__3]; - return concatFactory(this, values, false); - }, - filter: function(predicate, context) { - return filterFactory(this, predicate, context, false); - }, - get: function(index, notSetValue) { - index = wrapIndex(this, index); - return this.find((function(_, key) { - return key === index; - }), null, notSetValue); - }, - first: function() { - return this.get(0); - }, - last: function() { - return this.get(this.length ? this.length - 1 : 0); - }, - indexOf: function(searchValue) { - return this.findIndex((function(value) { - return is(value, searchValue); - })); - }, - lastIndexOf: function(searchValue) { - return this.toKeyedSeq().reverse().indexOf(searchValue); - }, - findIndex: function(predicate, context) { - var key = this.findKey(predicate, context); - return key == null ? -1 : key; - }, - findLastIndex: function(predicate, context) { - return this.toKeyedSeq().reverse().findIndex(predicate, context); - }, - splice: function(index, removeNum) { - var numArgs = arguments.length; - removeNum = Math.max(removeNum | 0, 0); - if (numArgs === 0 || (numArgs === 2 && !removeNum)) { - return this; - } - index = resolveBegin(index, this.length); - var spliced = this.slice(0, index); - return numArgs === 1 ? spliced : spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)); - }, - flatten: function() { - return flattenFactory(this, false); - }, - skip: function(amount) { - return skipFactory(this, amount, false); - }, - skipWhile: function(predicate, context) { - return skipWhileFactory(this, predicate, context, false); - }, - groupBy: function(grouper, context) { - return groupByFactory(this, grouper, context, false); - }, - sortBy: function(mapper, comparator) { - comparator = comparator || defaultComparator; - var seq = this; - return Sequence(this.entrySeq().toArray().sort((function(a, b) { - return comparator(mapper(a[1], a[0], seq), mapper(b[1], b[0], seq)) || a[0] - b[0]; - }))).fromEntrySeq().valueSeq(); - }, - __iterate: function(fn, reverse) { - return iterate(this, fn, reverse, false); - }, - __iterator: function(type, reverse) { - return iterator(this, type, reverse, false); - }, - __makeSequence: function() { - return makeIndexedSequence(this); - } -}, {}, Sequence); -var IndexedSequencePrototype = IndexedSequence.prototype; -IndexedSequencePrototype[ITERATOR_SYMBOL] = IndexedSequencePrototype.values; -IndexedSequencePrototype.__toJS = IndexedSequencePrototype.toArray; -IndexedSequencePrototype.__toStringMapper = quoteString; -var ValuesSequence = function ValuesSequence(seq) { - this._seq = seq; - this.length = seq.length; -}; -($traceurRuntime.createClass)(ValuesSequence, { - get: function(key, notSetValue) { - return this._seq.get(key, notSetValue); - }, - has: function(key) { - return this._seq.has(key); - }, - cacheResult: function() { - this._seq.cacheResult(); - this.length = this._seq.length; - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var iterations = 0; - return this._seq.__iterate((function(v) { - return fn(v, iterations++, $__0); - }), reverse); - }, - __iterator: function(type, reverse) { - var iterator = this._seq.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - var step; - return new Iterator((function() { - return (step = iterator.next()).done ? iteratorDone() : iteratorValue(type, iterations++, step.value); - })); - } -}, {}, IndexedSequence); -var KeyedIndexedSequence = function KeyedIndexedSequence(indexedSeq) { - this._seq = indexedSeq; - this.length = indexedSeq.length; -}; -($traceurRuntime.createClass)(KeyedIndexedSequence, { - get: function(key, notSetValue) { - return this._seq.get(key, notSetValue); - }, - has: function(key) { - return this._seq.has(key); - }, - cacheResult: function() { - this._seq.cacheResult(); - this.length = this._seq.length; - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var ii = reverse ? ensureLength(this) : 0; - return this._seq.__iterate((function(v) { - return fn(v, reverse ? --ii : ii++, $__0); - }), reverse); - }, - __iterator: function(type, reverse) { - var iterator = this._seq.__iterator(ITERATE_VALUES, reverse); - var ii = reverse ? ensureLength(this) : 0; - return new Iterator((function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, reverse ? --ii : ii++, step.value); - })); - } -}, {}, Sequence); -var IteratorSequence = function IteratorSequence(iterator) { - this._iterator = iterator; - this._iteratorCache = []; -}; -($traceurRuntime.createClass)(IteratorSequence, { - __iterateUncached: function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - while (iterations < cache.length) { - if (fn(cache[iterations], iterations++, this) === false) { - return iterations; - } - } - var step; - while (!(step = iterator.next()).done) { - var val = step.value; - cache[iterations] = val; - if (fn(val, iterations++, this) === false) { - break; - } - } - return iterations; - }, - __iteratorUncached: function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - return new Iterator((function() { - if (iterations >= cache.length) { - var step = iterator.next(); - if (step.done) { - return step; - } - cache[iterations] = step.value; - } - return iteratorValue(type, iterations, cache[iterations++]); - })); - } -}, {}, IndexedSequence); -var IterableSequence = function IterableSequence(iterable) { - this._iterable = iterable; - this.length = iterable.length || iterable.size; -}; -($traceurRuntime.createClass)(IterableSequence, { - __iterateUncached: function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterable = this._iterable; - var iterator = getIterator(iterable); - var iterations = 0; - if (isIterator(iterator)) { - var step; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } - } - return iterations; - }, - __iteratorUncached: function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterable = this._iterable; - var iterator = getIterator(iterable); - if (!isIterator(iterator)) { - return new Iterator((function() { - return iteratorDone(); - })); - } - var iterations = 0; - return new Iterator((function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, iterations++, step.value); - })); - } -}, {}, IndexedSequence); -var ObjectSequence = function ObjectSequence(object) { - var keys = Object.keys(object); - this._object = object; - this._keys = keys; - this.length = keys.length; -}; -($traceurRuntime.createClass)(ObjectSequence, { - toObject: function() { - return this._object; - }, - get: function(key, notSetValue) { - if (notSetValue !== undefined && !this.has(key)) { - return notSetValue; - } - return this._object[key]; - }, - has: function(key) { - return this._object.hasOwnProperty(key); - }, - __iterate: function(fn, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var key = keys[reverse ? maxIndex - ii : ii]; - if (fn(object[key], key, this) === false) { - return ii + 1; - } - } - return ii; - }, - __iterator: function(type, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - var ii = 0; - return new Iterator((function() { - var key = keys[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? iteratorDone() : iteratorValue(type, key, object[key]); - })); - } -}, {}, Sequence); -var ArraySequence = function ArraySequence(array) { - this._array = array; - this.length = array.length; -}; -($traceurRuntime.createClass)(ArraySequence, { - toArray: function() { - return this._array; - }, - get: function(index, notSetValue) { - return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; - }, - has: function(index) { - index = wrapIndex(this, index); - return index >= 0 && index < this.length; - }, - __iterate: function(fn, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { - return ii + 1; - } - } - return ii; - }, - __iterator: function(type, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - var ii = 0; - return new Iterator((function() { - return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++]); - })); - } -}, {}, IndexedSequence); -function makeSequence() { - return Object.create(SequencePrototype); -} -function makeIndexedSequence(parent) { - return Object.create(IndexedSequencePrototype); -} -function ensureLength(indexedSeq) { - if (indexedSeq.length == null) { - indexedSeq.cacheResult(); - } - invariant(indexedSeq.length < Infinity, 'Cannot reverse infinite range.'); - return indexedSeq.length; -} -function wholeSlice(begin, end, length) { - return (begin === 0 || (length != null && begin <= -length)) && (end == null || (length != null && end >= length)); -} -function resolveBegin(begin, length) { - return resolveIndex(begin, length, 0); -} -function resolveEnd(end, length) { - return resolveIndex(end, length, length); -} -function resolveIndex(index, length, defaultIndex) { - return index == null ? defaultIndex : index < 0 ? Math.max(0, length + index) : length ? Math.min(length, index) : index; -} -function valueMapper(v) { - return v; -} -function entryMapper(v, k) { - return [k, v]; -} -function returnTrue() { - return true; -} -function iterate(sequence, fn, reverse, useKeys) { - var cache = sequence._cache; - if (cache) { - var maxIndex = cache.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var entry = cache[reverse ? maxIndex - ii : ii]; - if (fn(entry[1], useKeys ? entry[0] : ii, sequence) === false) { - return ii + 1; - } - } - return ii; - } - return sequence.__iterateUncached(fn, reverse); -} -function iterator(sequence, type, reverse, useKeys) { - var cache = sequence._cache; - if (cache) { - var maxIndex = cache.length - 1; - var ii = 0; - return new Iterator((function() { - var entry = cache[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? iteratorDone() : iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); - })); - } - if (!sequence.__iteratorUncached) { - return sequence.cacheResult().__iterator(type, reverse); - } - return sequence.__iteratorUncached(type, reverse); -} -function filterFactory(sequence, predicate, context, useKeys) { - var filterSequence = sequence.__makeSequence(); - filterSequence.has = (function(key) { - var v = sequence.get(key, NOT_SET); - return v !== NOT_SET && !!predicate.call(context, v, key, sequence); - }); - filterSequence.get = (function(key, notSetValue) { - var v = sequence.get(key, NOT_SET); - return v !== NOT_SET && predicate.call(context, v, key, sequence) ? v : notSetValue; - }); - filterSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - var iterations = 0; - sequence.__iterate((function(v, k, c) { - if (predicate.call(context, v, k, c)) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, $__0); - } - }), reverse); - return iterations; - }; - filterSequence.__iteratorUncached = function(type, reverse) { - var iterator = sequence.__iterator(ITERATE_ENTRIES, reverse); - var iterations = 0; - return new Iterator((function() { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - var value = entry[1]; - if (predicate.call(context, value, key, sequence)) { - return iteratorValue(type, useKeys ? key : iterations++, value); - } - } - })); - }; - return filterSequence; -} -function groupByFactory(seq, grouper, context, useKeys) { - var groupMap = {}; - var groups = []; - seq.__iterate((function(v, k) { - var g = grouper.call(context, v, k, seq); - var h = hash(g); - var e = useKeys ? [k, v] : v; - if (!groupMap.hasOwnProperty(h)) { - groupMap[h] = groups.length; - groups.push([g, [e]]); - } else { - groups[groupMap[h]][1].push(e); - } - })); - return Sequence(groups).fromEntrySeq().map(useKeys ? (function(group) { - return Sequence(group).fromEntrySeq(); - }) : (function(group) { - return Sequence(group); - })); -} -function skipFactory(sequence, amount, useKeys) { - if (amount <= 0) { - return sequence; - } - var skipSequence = sequence.__makeSequence(); - skipSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var skipped = 0; - var isSkipping = true; - var iterations = 0; - sequence.__iterate((function(v, k) { - if (!(isSkipping && (isSkipping = skipped++ < amount))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, $__0); - } - })); - return iterations; - }; - skipSequence.length = sequence.length && Math.max(0, sequence.length - amount); - return skipSequence; -} -function skipWhileFactory(sequence, predicate, context, useKeys) { - var skipSequence = sequence.__makeSequence(); - skipSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var isSkipping = true; - var iterations = 0; - sequence.__iterate((function(v, k, c) { - if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, $__0); - } - })); - return iterations; - }; - return skipSequence; -} -function concatFactory(sequence, values, useKeys) { - var sequences = [sequence].concat(values); - var concatSequence = Sequence(sequences); - if (useKeys) { - concatSequence = concatSequence.toKeyedSeq(); - } - concatSequence = concatSequence.flatten(); - concatSequence.length = sequences.reduce((function(sum, seq) { - if (sum !== undefined) { - var len = Sequence(seq).length; - if (len != null) { - return sum + len; - } - } - }), 0); - return concatSequence; -} -function flattenFactory(sequence, useKeys) { - var flatSequence = sequence.__makeSequence(); - flatSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - var iterations = 0; - sequence.__iterate((function(seq) { - var stopped = false; - Sequence(seq).__iterate((function(v, k) { - if (fn(v, useKeys ? k : iterations++, $__0) === false) { - stopped = true; - return false; - } - }), reverse); - return !stopped; - }), reverse); - return iterations; - }; - return flatSequence; -} -function not(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} -function quoteString(value) { - return typeof value === 'string' ? JSON.stringify(value) : value; -} -function defaultComparator(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -} -function wrapIndex(seq, index) { - if (index < 0) { - if (seq.length == null) { - seq.cacheResult(); - } - return seq.length + index; - } - return index; -} -function assertNotInfinite(length) { - invariant(length !== Infinity, 'Cannot perform this action with an infinite sequence.'); -} -var Cursor = function Cursor(rootData, keyPath, onChange, value) { - value = value ? value : rootData.getIn(keyPath); - this.length = value instanceof Sequence ? value.length : null; - this._rootData = rootData; - this._keyPath = keyPath; - this._onChange = onChange; -}; -($traceurRuntime.createClass)(Cursor, { - deref: function(notSetValue) { - return this._rootData.getIn(this._keyPath, notSetValue); - }, - get: function(key, notSetValue) { - if (Array.isArray(key) && key.length === 0) { - return this; - } - var value = this._rootData.getIn(this._keyPath.concat(key), NOT_SET); - return value === NOT_SET ? notSetValue : wrappedValue(this, key, value); - }, - set: function(key, value) { - return updateCursor(this, (function(m) { - return m.set(key, value); - }), key); - }, - remove: function(key) { - return updateCursor(this, (function(m) { - return m.remove(key); - }), key); - }, - clear: function() { - return updateCursor(this, (function(m) { - return m.clear(); - })); - }, - update: function(keyOrFn, notSetValue, updater) { - return arguments.length === 1 ? updateCursor(this, keyOrFn) : updateCursor(this, (function(map) { - return map.update(keyOrFn, notSetValue, updater); - }), keyOrFn); - }, - withMutations: function(fn) { - return updateCursor(this, (function(m) { - return (m || Map.empty()).withMutations(fn); - })); - }, - cursor: function(subKey) { - return Array.isArray(subKey) && subKey.length === 0 ? this : subCursor(this, subKey); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var cursor = this; - var deref = cursor.deref(); - return deref && deref.__iterate ? deref.__iterate((function(value, key) { - return fn(wrappedValue(cursor, key, value), key, $__0); - }), reverse) : 0; - } -}, {}, Sequence); -Cursor.prototype[DELETE] = Cursor.prototype.remove; -Cursor.prototype.getIn = Cursor.prototype.get; -function wrappedValue(cursor, key, value) { - return value instanceof Sequence ? subCursor(cursor, key, value) : value; -} -function subCursor(cursor, key, value) { - return new Cursor(cursor._rootData, cursor._keyPath.concat(key), cursor._onChange, value); -} -function updateCursor(cursor, changeFn, changeKey) { - var newRootData = cursor._rootData.updateIn(cursor._keyPath, changeKey ? Map.empty() : undefined, changeFn); - var keyPath = cursor._keyPath || []; - cursor._onChange && cursor._onChange.call(undefined, newRootData, cursor._rootData, changeKey ? keyPath.concat(changeKey) : keyPath); - return new Cursor(newRootData, cursor._keyPath, cursor._onChange); -} -function is(first, second) { - if (first instanceof Cursor) { - first = first.deref(); - } - if (second instanceof Cursor) { - second = second.deref(); - } - if (first === second) { - return first !== 0 || second !== 0 || 1 / first === 1 / second; - } - if (first !== first) { - return second !== second; - } - if (first instanceof Sequence) { - return first.equals(second); - } - return false; -} -var Map = function Map(sequence) { - var map = $Map.empty(); - return sequence ? sequence.constructor === $Map ? sequence : map.merge(sequence) : map; -}; -var $Map = Map; -($traceurRuntime.createClass)(Map, { - toString: function() { - return this.__toString('Map {', '}'); - }, - get: function(k, notSetValue) { - return this._root ? this._root.get(0, hash(k), k, notSetValue) : notSetValue; - }, - set: function(k, v) { - return updateMap(this, k, v); - }, - remove: function(k) { - return updateMap(this, k, NOT_SET); - }, - update: function(k, notSetValue, updater) { - return arguments.length === 1 ? this.updateIn([], null, k) : this.updateIn([k], notSetValue, updater); - }, - updateIn: function(keyPath, notSetValue, updater) { - var $__13; - if (!updater) { - ($__13 = [notSetValue, updater], updater = $__13[0], notSetValue = $__13[1], $__13); - } - return updateInDeepMap(this, keyPath, notSetValue, updater, 0); - }, - clear: function() { - if (this.length === 0) { - return this; - } - if (this.__ownerID) { - this.length = 0; - this._root = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return $Map.empty(); - }, - merge: function() { - return mergeIntoMapWith(this, null, arguments); - }, - mergeWith: function(merger) { - for (var seqs = [], - $__4 = 1; $__4 < arguments.length; $__4++) - seqs[$__4 - 1] = arguments[$__4]; - return mergeIntoMapWith(this, merger, seqs); - }, - mergeDeep: function() { - return mergeIntoMapWith(this, deepMerger(null), arguments); - }, - mergeDeepWith: function(merger) { - for (var seqs = [], - $__5 = 1; $__5 < arguments.length; $__5++) - seqs[$__5 - 1] = arguments[$__5]; - return mergeIntoMapWith(this, deepMerger(merger), seqs); - }, - cursor: function(keyPath, onChange) { - if (!onChange && typeof keyPath === 'function') { - onChange = keyPath; - keyPath = []; - } else if (arguments.length === 0) { - keyPath = []; - } else if (!Array.isArray(keyPath)) { - keyPath = [keyPath]; - } - return new Cursor(this, keyPath, onChange); - }, - withMutations: function(fn) { - var mutable = this.asMutable(); - fn(mutable); - return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; - }, - asMutable: function() { - return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); - }, - asImmutable: function() { - return this.__ensureOwner(); - }, - wasAltered: function() { - return this.__altered; - }, - __iterator: function(type, reverse) { - return new MapIterator(this, type, reverse); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var iterations = 0; - this._root && this._root.iterate((function(entry) { - iterations++; - return fn(entry[1], entry[0], $__0); - }), reverse); - return iterations; - }, - __deepEquals: function(other) { - var self = this; - return other.every((function(v, k) { - return is(self.get(k, NOT_SET), v); - })); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeMap(this.length, this._root, ownerID, this.__hash); - } -}, {empty: function() { - return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); - }}, Sequence); -var MapPrototype = Map.prototype; -MapPrototype[DELETE] = MapPrototype.remove; -Map.from = Map; -var BitmapIndexedNode = function BitmapIndexedNode(ownerID, bitmap, nodes) { - this.ownerID = ownerID; - this.bitmap = bitmap; - this.nodes = nodes; -}; -var $BitmapIndexedNode = BitmapIndexedNode; -($traceurRuntime.createClass)(BitmapIndexedNode, { - get: function(shift, hash, key, notSetValue) { - var bit = (1 << ((shift === 0 ? hash : hash >>> shift) & MASK)); - var bitmap = this.bitmap; - return (bitmap & bit) === 0 ? notSetValue : this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, hash, key, notSetValue); - }, - update: function(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var hashFrag = (shift === 0 ? hash : hash >>> shift) & MASK; - var bit = 1 << hashFrag; - var bitmap = this.bitmap; - var exists = (bitmap & bit) !== 0; - if (!exists && value === NOT_SET) { - return this; - } - var idx = popCount(bitmap & (bit - 1)); - var nodes = this.nodes; - var node = exists ? nodes[idx] : null; - var newNode = updateNode(node, ownerID, shift + SHIFT, hash, key, value, didChangeLength, didAlter); - if (newNode === node) { - return this; - } - if (!exists && newNode && nodes.length >= MAX_BITMAP_SIZE) { - return expandNodes(ownerID, nodes, bitmap, hashFrag, newNode); - } - if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { - return nodes[idx ^ 1]; - } - if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { - return newNode; - } - var isEditable = ownerID && ownerID === this.ownerID; - var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; - var newNodes = exists ? newNode ? setIn(nodes, idx, newNode, isEditable) : spliceOut(nodes, idx, isEditable) : spliceIn(nodes, idx, newNode, isEditable); - if (isEditable) { - this.bitmap = newBitmap; - this.nodes = newNodes; - return this; - } - return new $BitmapIndexedNode(ownerID, newBitmap, newNodes); - }, - iterate: function(fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, - maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - if (nodes[reverse ? maxIndex - ii : ii].iterate(fn, reverse) === false) { - return false; - } - } - } -}, {}); -var ArrayNode = function ArrayNode(ownerID, count, nodes) { - this.ownerID = ownerID; - this.count = count; - this.nodes = nodes; -}; -var $ArrayNode = ArrayNode; -($traceurRuntime.createClass)(ArrayNode, { - get: function(shift, hash, key, notSetValue) { - var idx = (shift === 0 ? hash : hash >>> shift) & MASK; - var node = this.nodes[idx]; - return node ? node.get(shift + SHIFT, hash, key, notSetValue) : notSetValue; - }, - update: function(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var idx = (shift === 0 ? hash : hash >>> shift) & MASK; - var removed = value === NOT_SET; - var nodes = this.nodes; - var node = nodes[idx]; - if (removed && !node) { - return this; - } - var newNode = updateNode(node, ownerID, shift + SHIFT, hash, key, value, didChangeLength, didAlter); - if (newNode === node) { - return this; - } - var newCount = this.count; - if (!node) { - newCount++; - } else if (!newNode) { - newCount--; - if (newCount < MIN_ARRAY_SIZE) { - return packNodes(ownerID, nodes, newCount, idx); - } - } - var isEditable = ownerID && ownerID === this.ownerID; - var newNodes = setIn(nodes, idx, newNode, isEditable); - if (isEditable) { - this.count = newCount; - this.nodes = newNodes; - return this; - } - return new $ArrayNode(ownerID, newCount, newNodes); - }, - iterate: function(fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, - maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - var node = nodes[reverse ? maxIndex - ii : ii]; - if (node && node.iterate(fn, reverse) === false) { - return false; - } - } - } -}, {}); -var HashCollisionNode = function HashCollisionNode(ownerID, hash, entries) { - this.ownerID = ownerID; - this.hash = hash; - this.entries = entries; -}; -var $HashCollisionNode = HashCollisionNode; -($traceurRuntime.createClass)(HashCollisionNode, { - get: function(shift, hash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, - len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; - } - } - return notSetValue; - }, - update: function(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var removed = value === NOT_SET; - if (hash !== this.hash) { - if (removed) { - return this; - } - SetRef(didAlter); - SetRef(didChangeLength); - return mergeIntoNode(this, ownerID, shift, hash, [key, value]); - } - var entries = this.entries; - var idx = 0; - for (var len = entries.length; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; - } - } - var exists = idx < len; - if (removed && !exists) { - return this; - } - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeLength); - if (removed && len === 2) { - return new ValueNode(ownerID, this.hash, entries[idx ^ 1]); - } - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - if (exists) { - if (removed) { - idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; - } - } else { - newEntries.push([key, value]); - } - if (isEditable) { - this.entries = newEntries; - return this; - } - return new $HashCollisionNode(ownerID, this.hash, newEntries); - }, - iterate: function(fn, reverse) { - var entries = this.entries; - for (var ii = 0, - maxIndex = entries.length - 1; ii <= maxIndex; ii++) { - if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { - return false; - } - } - } -}, {}); -var ValueNode = function ValueNode(ownerID, hash, entry) { - this.ownerID = ownerID; - this.hash = hash; - this.entry = entry; -}; -var $ValueNode = ValueNode; -($traceurRuntime.createClass)(ValueNode, { - get: function(shift, hash, key, notSetValue) { - return is(key, this.entry[0]) ? this.entry[1] : notSetValue; - }, - update: function(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var removed = value === NOT_SET; - var keyMatch = is(key, this.entry[0]); - if (keyMatch ? value === this.entry[1] : removed) { - return this; - } - SetRef(didAlter); - if (removed) { - SetRef(didChangeLength); - return null; - } - if (keyMatch) { - if (ownerID && ownerID === this.ownerID) { - this.entry[1] = value; - return this; - } - return new $ValueNode(ownerID, hash, [key, value]); - } - SetRef(didChangeLength); - return mergeIntoNode(this, ownerID, shift, hash, [key, value]); - }, - iterate: function(fn) { - return fn(this.entry); - } -}, {}); -var MapIterator = function MapIterator(map, type, reverse) { - this._type = type; - this._reverse = reverse; - this._stack = map._root && mapIteratorFrame(map._root); -}; -($traceurRuntime.createClass)(MapIterator, {next: function() { - var type = this._type; - var stack = this._stack; - while (stack) { - var node = stack.node; - var index = stack.index++; - var maxIndex; - if (node.entry) { - if (index === 0) { - return mapIteratorValue(type, node.entry); - } - } else if (node.entries) { - maxIndex = node.entries.length - 1; - if (index <= maxIndex) { - return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); - } - } else { - maxIndex = node.nodes.length - 1; - if (index <= maxIndex) { - var subNode = node.nodes[this._reverse ? maxIndex - index : index]; - if (subNode) { - if (subNode.entry) { - return mapIteratorValue(type, subNode.entry); - } - stack = this._stack = mapIteratorFrame(subNode, stack); - } - continue; - } - } - stack = this._stack = this._stack.__prev; - } - return iteratorDone(); - }}, {}, Iterator); -function mapIteratorValue(type, entry) { - return iteratorValue(type, entry[0], entry[1]); -} -function mapIteratorFrame(node, prev) { - return { - node: node, - index: 0, - __prev: prev - }; -} -function makeMap(length, root, ownerID, hash) { - var map = Object.create(MapPrototype); - map.length = length; - map._root = root; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; -} -function updateMap(map, k, v) { - var didChangeLength = MakeRef(CHANGE_LENGTH); - var didAlter = MakeRef(DID_ALTER); - var newRoot = updateNode(map._root, map.__ownerID, 0, hash(k), k, v, didChangeLength, didAlter); - if (!didAlter.value) { - return map; - } - var newLength = map.length + (didChangeLength.value ? v === NOT_SET ? -1 : 1 : 0); - if (map.__ownerID) { - map.length = newLength; - map._root = newRoot; - map.__hash = undefined; - map.__altered = true; - return map; - } - return newRoot ? makeMap(newLength, newRoot) : Map.empty(); -} -function updateNode(node, ownerID, shift, hash, key, value, didChangeLength, didAlter) { - if (!node) { - if (value === NOT_SET) { - return node; - } - SetRef(didAlter); - SetRef(didChangeLength); - return new ValueNode(ownerID, hash, [key, value]); - } - return node.update(ownerID, shift, hash, key, value, didChangeLength, didAlter); -} -function isLeafNode(node) { - return node.constructor === ValueNode || node.constructor === HashCollisionNode; -} -function mergeIntoNode(node, ownerID, shift, hash, entry) { - if (node.hash === hash) { - return new HashCollisionNode(ownerID, hash, [node.entry, entry]); - } - var idx1 = (shift === 0 ? node.hash : node.hash >>> shift) & MASK; - var idx2 = (shift === 0 ? hash : hash >>> shift) & MASK; - var newNode; - var nodes = idx1 === idx2 ? [mergeIntoNode(node, ownerID, shift + SHIFT, hash, entry)] : ((newNode = new ValueNode(ownerID, hash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); - return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); -} -function packNodes(ownerID, nodes, count, excluding) { - var bitmap = 0; - var packedII = 0; - var packedNodes = new Array(count); - for (var ii = 0, - bit = 1, - len = nodes.length; ii < len; ii++, bit <<= 1) { - var node = nodes[ii]; - if (node != null && ii !== excluding) { - bitmap |= bit; - packedNodes[packedII++] = node; - } - } - return new BitmapIndexedNode(ownerID, bitmap, packedNodes); -} -function expandNodes(ownerID, nodes, bitmap, including, node) { - var count = 0; - var expandedNodes = new Array(SIZE); - for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { - expandedNodes[ii] = bitmap & 1 ? nodes[count++] : null; - } - expandedNodes[including] = node; - return new ArrayNode(ownerID, count + 1, expandedNodes); -} -function mergeIntoMapWith(map, merger, iterables) { - var seqs = []; - for (var ii = 0; ii < iterables.length; ii++) { - var seq = iterables[ii]; - if (!(seq instanceof Sequence)) { - seq = Sequence(seq); - if (seq instanceof IndexedSequence) { - seq = seq.fromEntrySeq(); - } - } - seq && seqs.push(seq); - } - return mergeIntoCollectionWith(map, merger, seqs); -} -function deepMerger(merger) { - return (function(existing, value) { - return existing && existing.mergeDeepWith ? existing.mergeDeepWith(merger, value) : merger ? merger(existing, value) : value; - }); -} -function mergeIntoCollectionWith(collection, merger, seqs) { - if (seqs.length === 0) { - return collection; - } - return collection.withMutations((function(collection) { - var mergeIntoMap = merger ? (function(value, key) { - var existing = collection.get(key, NOT_SET); - collection.set(key, existing === NOT_SET ? value : merger(existing, value)); - }) : (function(value, key) { - collection.set(key, value); - }); - for (var ii = 0; ii < seqs.length; ii++) { - seqs[ii].forEach(mergeIntoMap); - } - })); -} -function updateInDeepMap(collection, keyPath, notSetValue, updater, pathOffset) { - var pathLen = keyPath.length; - if (pathOffset === pathLen) { - return updater(collection); - } - invariant(collection.set, 'updateIn with invalid keyPath'); - var notSet = pathOffset === pathLen - 1 ? notSetValue : Map.empty(); - var key = keyPath[pathOffset]; - var existing = collection.get(key, notSet); - var value = updateInDeepMap(existing, keyPath, notSetValue, updater, pathOffset + 1); - return value === existing ? collection : collection.set(key, value); -} -function popCount(x) { - x = x - ((x >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x = x + (x >> 8); - x = x + (x >> 16); - return x & 0x7f; -} -function setIn(array, idx, val, canEdit) { - var newArray = canEdit ? array : arrCopy(array); - newArray[idx] = val; - return newArray; -} -function spliceIn(array, idx, val, canEdit) { - var newLen = array.length + 1; - if (canEdit && idx + 1 === newLen) { - array[idx] = val; - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - newArray[ii] = val; - after = -1; - } else { - newArray[ii] = array[ii + after]; - } - } - return newArray; -} -function spliceOut(array, idx, canEdit) { - var newLen = array.length - 1; - if (canEdit && idx === newLen) { - array.pop(); - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - after = 1; - } - newArray[ii] = array[ii + after]; - } - return newArray; -} -var MAX_BITMAP_SIZE = SIZE / 2; -var MIN_ARRAY_SIZE = SIZE / 4; -var EMPTY_MAP; -var Vector = function Vector() { - for (var values = [], - $__6 = 0; $__6 < arguments.length; $__6++) - values[$__6] = arguments[$__6]; - return $Vector.from(values); -}; -var $Vector = Vector; -($traceurRuntime.createClass)(Vector, { - toString: function() { - return this.__toString('Vector [', ']'); - }, - has: function(index) { - index = wrapIndex(this, index); - return index >= 0 && index < this.length; - }, - get: function(index, notSetValue) { - index = wrapIndex(this, index); - if (index < 0 || index >= this.length) { - return notSetValue; - } - index += this._origin; - var node = vectorNodeFor(this, index); - return node && node.array[index & MASK]; - }, - set: function(index, value) { - return updateVector(this, index, value); - }, - remove: function(index) { - return updateVector(this, index, NOT_SET); - }, - clear: function() { - if (this.length === 0) { - return this; - } - if (this.__ownerID) { - this.length = this._origin = this._size = 0; - this._level = SHIFT; - this._root = this._tail = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return $Vector.empty(); - }, - push: function() { - var values = arguments; - var oldLength = this.length; - return this.withMutations((function(vect) { - setVectorBounds(vect, 0, oldLength + values.length); - for (var ii = 0; ii < values.length; ii++) { - vect.set(oldLength + ii, values[ii]); - } - })); - }, - pop: function() { - return setVectorBounds(this, 0, -1); - }, - unshift: function() { - var values = arguments; - return this.withMutations((function(vect) { - setVectorBounds(vect, -values.length); - for (var ii = 0; ii < values.length; ii++) { - vect.set(ii, values[ii]); - } - })); - }, - shift: function() { - return setVectorBounds(this, 1); - }, - merge: function() { - return mergeIntoVectorWith(this, null, arguments); - }, - mergeWith: function(merger) { - for (var seqs = [], - $__7 = 1; $__7 < arguments.length; $__7++) - seqs[$__7 - 1] = arguments[$__7]; - return mergeIntoVectorWith(this, merger, seqs); - }, - mergeDeep: function() { - return mergeIntoVectorWith(this, deepMerger(null), arguments); - }, - mergeDeepWith: function(merger) { - for (var seqs = [], - $__8 = 1; $__8 < arguments.length; $__8++) - seqs[$__8 - 1] = arguments[$__8]; - return mergeIntoVectorWith(this, deepMerger(merger), seqs); - }, - setLength: function(length) { - return setVectorBounds(this, 0, length); - }, - slice: function(begin, end) { - var sliceSequence = $traceurRuntime.superCall(this, $Vector.prototype, "slice", [begin, end]); - if (sliceSequence !== this) { - var vector = this; - var length = vector.length; - sliceSequence.toVector = (function() { - return setVectorBounds(vector, begin < 0 ? Math.max(0, length + begin) : length ? Math.min(length, begin) : begin, end == null ? length : end < 0 ? Math.max(0, length + end) : length ? Math.min(length, end) : end); - }); - } - return sliceSequence; - }, - __iterator: function(type, reverse) { - return new VectorIterator(this, type, reverse); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var iterations = 0; - var eachFn = (function(v) { - return fn(v, iterations++, $__0); - }); - var tailOffset = getTailOffset(this._size); - if (reverse) { - iterateVNode(this._tail, 0, tailOffset - this._origin, this._size - this._origin, eachFn, reverse) && iterateVNode(this._root, this._level, -this._origin, tailOffset - this._origin, eachFn, reverse); - } else { - iterateVNode(this._root, this._level, -this._origin, tailOffset - this._origin, eachFn, reverse) && iterateVNode(this._tail, 0, tailOffset - this._origin, this._size - this._origin, eachFn, reverse); - } - return iterations; - }, - __deepEquals: function(other) { - var iterator = this.entries(true); - return other.every((function(v, i) { - var entry = iterator.next().value; - return entry && entry[0] === i && is(entry[1], v); - })); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - return this; - } - return makeVector(this._origin, this._size, this._level, this._root, this._tail, ownerID, this.__hash); - } -}, { - empty: function() { - return EMPTY_VECT || (EMPTY_VECT = makeVector(0, 0, SHIFT)); - }, - from: function(sequence) { - if (!sequence || sequence.length === 0) { - return $Vector.empty(); - } - if (sequence.constructor === $Vector) { - return sequence; - } - var isArray = Array.isArray(sequence); - if (sequence.length > 0 && sequence.length < SIZE) { - return makeVector(0, sequence.length, SHIFT, null, new VNode(isArray ? arrCopy(sequence) : Sequence(sequence).toArray())); - } - if (!isArray) { - sequence = Sequence(sequence).valueSeq(); - } - return $Vector.empty().merge(sequence); - } -}, IndexedSequence); -var VectorPrototype = Vector.prototype; -VectorPrototype[DELETE] = VectorPrototype.remove; -VectorPrototype.update = MapPrototype.update; -VectorPrototype.updateIn = MapPrototype.updateIn; -VectorPrototype.cursor = MapPrototype.cursor; -VectorPrototype.withMutations = MapPrototype.withMutations; -VectorPrototype.asMutable = MapPrototype.asMutable; -VectorPrototype.asImmutable = MapPrototype.asImmutable; -VectorPrototype.wasAltered = MapPrototype.wasAltered; -var VNode = function VNode(array, ownerID) { - this.array = array; - this.ownerID = ownerID; -}; -var $VNode = VNode; -($traceurRuntime.createClass)(VNode, { - removeBefore: function(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var originIndex = (index >>> level) & MASK; - if (originIndex >= this.array.length) { - return new $VNode([], ownerID); - } - var removingFirst = originIndex === 0; - var newChild; - if (level > 0) { - var oldChild = this.array[originIndex]; - newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingFirst) { - return this; - } - } - if (removingFirst && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingFirst) { - for (var ii = 0; ii < originIndex; ii++) { - editable.array[ii] = undefined; - } - } - if (newChild) { - editable.array[originIndex] = newChild; - } - return editable; - }, - removeAfter: function(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var sizeIndex = ((index - 1) >>> level) & MASK; - if (sizeIndex >= this.array.length) { - return this; - } - var removingLast = sizeIndex === this.array.length - 1; - var newChild; - if (level > 0) { - var oldChild = this.array[sizeIndex]; - newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingLast) { - return this; - } - } - if (removingLast && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingLast) { - editable.array.pop(); - } - if (newChild) { - editable.array[sizeIndex] = newChild; - } - return editable; - } -}, {}); -function iterateVNode(node, level, offset, max, fn, reverse) { - var ii; - var array = node && node.array; - if (level === 0) { - var from = offset < 0 ? -offset : 0; - var to = max - offset; - if (to > SIZE) { - to = SIZE; - } - for (ii = from; ii < to; ii++) { - if (fn(array && array[reverse ? from + to - 1 - ii : ii]) === false) { - return false; - } - } - } else { - var step = 1 << level; - var newLevel = level - SHIFT; - for (ii = 0; ii <= MASK; ii++) { - var levelIndex = reverse ? MASK - ii : ii; - var newOffset = offset + (levelIndex << level); - if (newOffset < max && newOffset + step > 0) { - var nextNode = array && array[levelIndex]; - if (!iterateVNode(nextNode, newLevel, newOffset, max, fn, reverse)) { - return false; - } - } - } - } - return true; -} -var VectorIterator = function VectorIterator(vector, type, reverse) { - this._type = type; - this._reverse = !!reverse; - this._maxIndex = vector.length - 1; - var tailOffset = getTailOffset(vector._size); - var rootStack = vectIteratorFrame(vector._root && vector._root.array, vector._level, -vector._origin, tailOffset - vector._origin - 1); - var tailStack = vectIteratorFrame(vector._tail && vector._tail.array, 0, tailOffset - vector._origin, vector._size - vector._origin - 1); - this._stack = reverse ? tailStack : rootStack; - this._stack.__prev = reverse ? rootStack : tailStack; -}; -($traceurRuntime.createClass)(VectorIterator, {next: function() { - var stack = this._stack; - while (stack) { - var array = stack.array; - var rawIndex = stack.index++; - if (this._reverse) { - rawIndex = MASK - rawIndex; - if (rawIndex > stack.rawMax) { - rawIndex = stack.rawMax; - stack.index = SIZE - rawIndex; - } - } - if (rawIndex >= 0 && rawIndex < SIZE && rawIndex <= stack.rawMax) { - var value = array && array[rawIndex]; - if (stack.level === 0) { - var type = this._type; - var index; - if (type !== 1) { - index = stack.offset + (rawIndex << stack.level); - if (this._reverse) { - index = this._maxIndex - index; - } - } - return iteratorValue(type, index, value); - } else { - this._stack = stack = vectIteratorFrame(value && value.array, stack.level - SHIFT, stack.offset + (rawIndex << stack.level), stack.max, stack); - } - continue; - } - stack = this._stack = this._stack.__prev; - } - return iteratorDone(); - }}, {}, Iterator); -function vectIteratorFrame(array, level, offset, max, prevFrame) { - return { - array: array, - level: level, - offset: offset, - max: max, - rawMax: ((max - offset) >> level), - index: 0, - __prev: prevFrame - }; -} -function makeVector(origin, size, level, root, tail, ownerID, hash) { - var vect = Object.create(VectorPrototype); - vect.length = size - origin; - vect._origin = origin; - vect._size = size; - vect._level = level; - vect._root = root; - vect._tail = tail; - vect.__ownerID = ownerID; - vect.__hash = hash; - vect.__altered = false; - return vect; -} -function updateVector(vector, index, value) { - index = wrapIndex(vector, index); - if (index >= vector.length || index < 0) { - return value === NOT_SET ? vector : vector.withMutations((function(vect) { - index < 0 ? setVectorBounds(vect, index).set(0, value) : setVectorBounds(vect, 0, index + 1).set(index, value); - })); - } - index += vector._origin; - var newTail = vector._tail; - var newRoot = vector._root; - var didAlter = MakeRef(DID_ALTER); - if (index >= getTailOffset(vector._size)) { - newTail = updateVNode(newTail, vector.__ownerID, 0, index, value, didAlter); - } else { - newRoot = updateVNode(newRoot, vector.__ownerID, vector._level, index, value, didAlter); - } - if (!didAlter.value) { - return vector; - } - if (vector.__ownerID) { - vector._root = newRoot; - vector._tail = newTail; - vector.__hash = undefined; - vector.__altered = true; - return vector; - } - return makeVector(vector._origin, vector._size, vector._level, newRoot, newTail); -} -function updateVNode(node, ownerID, level, index, value, didAlter) { - var removed = value === NOT_SET; - var newNode; - var idx = (index >>> level) & MASK; - var nodeHas = node && idx < node.array.length; - if (removed && !nodeHas) { - return node; - } - if (level > 0) { - var lowerNode = node && node.array[idx]; - var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); - if (newLowerNode === lowerNode) { - return node; - } - newNode = editableVNode(node, ownerID); - newNode.array[idx] = newLowerNode; - return newNode; - } - if (!removed && nodeHas && node.array[idx] === value) { - return node; - } - SetRef(didAlter); - newNode = editableVNode(node, ownerID); - if (removed && idx === newNode.array.length - 1) { - newNode.array.pop(); - } else { - newNode.array[idx] = removed ? undefined : value; - } - return newNode; -} -function editableVNode(node, ownerID) { - if (ownerID && node && ownerID === node.ownerID) { - return node; - } - return new VNode(node ? node.array.slice() : [], ownerID); -} -function vectorNodeFor(vector, rawIndex) { - if (rawIndex >= getTailOffset(vector._size)) { - return vector._tail; - } - if (rawIndex < 1 << (vector._level + SHIFT)) { - var node = vector._root; - var level = vector._level; - while (node && level > 0) { - node = node.array[(rawIndex >>> level) & MASK]; - level -= SHIFT; - } - return node; - } -} -function setVectorBounds(vector, begin, end) { - var owner = vector.__ownerID || new OwnerID(); - var oldOrigin = vector._origin; - var oldSize = vector._size; - var newOrigin = oldOrigin + begin; - var newSize = end == null ? oldSize : end < 0 ? oldSize + end : oldOrigin + end; - if (newOrigin === oldOrigin && newSize === oldSize) { - return vector; - } - if (newOrigin >= newSize) { - return vector.clear(); - } - var newLevel = vector._level; - var newRoot = vector._root; - var offsetShift = 0; - while (newOrigin + offsetShift < 0) { - newRoot = new VNode(newRoot && newRoot.array.length ? [null, newRoot] : [], owner); - newLevel += SHIFT; - offsetShift += 1 << newLevel; - } - if (offsetShift) { - newOrigin += offsetShift; - oldOrigin += offsetShift; - newSize += offsetShift; - oldSize += offsetShift; - } - var oldTailOffset = getTailOffset(oldSize); - var newTailOffset = getTailOffset(newSize); - while (newTailOffset >= 1 << (newLevel + SHIFT)) { - newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); - newLevel += SHIFT; - } - var oldTail = vector._tail; - var newTail = newTailOffset < oldTailOffset ? vectorNodeFor(vector, newSize - 1) : newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; - if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldSize && oldTail.array.length) { - newRoot = editableVNode(newRoot, owner); - var node = newRoot; - for (var level = newLevel; level > SHIFT; level -= SHIFT) { - var idx = (oldTailOffset >>> level) & MASK; - node = node.array[idx] = editableVNode(node.array[idx], owner); - } - node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; - } - if (newSize < oldSize) { - newTail = newTail && newTail.removeAfter(owner, 0, newSize); - } - if (newOrigin >= newTailOffset) { - newOrigin -= newTailOffset; - newSize -= newTailOffset; - newLevel = SHIFT; - newRoot = null; - newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); - } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { - var beginIndex, - endIndex; - offsetShift = 0; - do { - beginIndex = ((newOrigin) >>> newLevel) & MASK; - endIndex = ((newTailOffset - 1) >>> newLevel) & MASK; - if (beginIndex === endIndex) { - if (beginIndex) { - offsetShift += (1 << newLevel) * beginIndex; - } - newLevel -= SHIFT; - newRoot = newRoot && newRoot.array[beginIndex]; - } - } while (newRoot && beginIndex === endIndex); - if (newRoot && newOrigin > oldOrigin) { - newRoot = newRoot && newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); - } - if (newRoot && newTailOffset < oldTailOffset) { - newRoot = newRoot && newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); - } - if (offsetShift) { - newOrigin -= offsetShift; - newSize -= offsetShift; - } - } - if (vector.__ownerID) { - vector.length = newSize - newOrigin; - vector._origin = newOrigin; - vector._size = newSize; - vector._level = newLevel; - vector._root = newRoot; - vector._tail = newTail; - vector.__hash = undefined; - vector.__altered = true; - return vector; - } - return makeVector(newOrigin, newSize, newLevel, newRoot, newTail); -} -function mergeIntoVectorWith(vector, merger, iterables) { - var seqs = []; - for (var ii = 0; ii < iterables.length; ii++) { - var seq = iterables[ii]; - seq && seqs.push(Sequence(seq)); - } - var maxLength = Math.max.apply(null, seqs.map((function(s) { - return s.length || 0; - }))); - if (maxLength > vector.length) { - vector = vector.setLength(maxLength); - } - return mergeIntoCollectionWith(vector, merger, seqs); -} -function getTailOffset(size) { - return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); -} -var EMPTY_VECT; -var Set = function Set() { - for (var values = [], - $__9 = 0; $__9 < arguments.length; $__9++) - values[$__9] = arguments[$__9]; - return $Set.from(values); -}; -var $Set = Set; -($traceurRuntime.createClass)(Set, { - toString: function() { - return this.__toString('Set {', '}'); - }, - has: function(value) { - return this._map.has(value); - }, - get: function(value, notSetValue) { - return this.has(value) ? value : notSetValue; - }, - add: function(value) { - var newMap = this._map.set(value, null); - if (this.__ownerID) { - this.length = newMap.length; - this._map = newMap; - return this; - } - return newMap === this._map ? this : makeSet(newMap); - }, - remove: function(value) { - var newMap = this._map.remove(value); - if (this.__ownerID) { - this.length = newMap.length; - this._map = newMap; - return this; - } - return newMap === this._map ? this : newMap.length === 0 ? $Set.empty() : makeSet(newMap); - }, - clear: function() { - if (this.length === 0) { - return this; - } - if (this.__ownerID) { - this.length = 0; - this._map.clear(); - return this; - } - return $Set.empty(); - }, - union: function() { - var seqs = arguments; - if (seqs.length === 0) { - return this; - } - return this.withMutations((function(set) { - for (var ii = 0; ii < seqs.length; ii++) { - Sequence(seqs[ii]).forEach((function(value) { - return set.add(value); - })); - } - })); - }, - intersect: function() { - for (var seqs = [], - $__10 = 0; $__10 < arguments.length; $__10++) - seqs[$__10] = arguments[$__10]; - if (seqs.length === 0) { - return this; - } - seqs = seqs.map((function(seq) { - return Sequence(seq); - })); - var originalSet = this; - return this.withMutations((function(set) { - originalSet.forEach((function(value) { - if (!seqs.every((function(seq) { - return seq.contains(value); - }))) { - set.remove(value); - } - })); - })); - }, - subtract: function() { - for (var seqs = [], - $__11 = 0; $__11 < arguments.length; $__11++) - seqs[$__11] = arguments[$__11]; - if (seqs.length === 0) { - return this; - } - seqs = seqs.map((function(seq) { - return Sequence(seq); - })); - var originalSet = this; - return this.withMutations((function(set) { - originalSet.forEach((function(value) { - if (seqs.some((function(seq) { - return seq.contains(value); - }))) { - set.remove(value); - } - })); - })); - }, - isSubset: function(seq) { - seq = Sequence(seq); - return this.every((function(value) { - return seq.contains(value); - })); - }, - isSuperset: function(seq) { - var set = this; - seq = Sequence(seq); - return seq.every((function(value) { - return set.contains(value); - })); - }, - wasAltered: function() { - return this._map.wasAltered(); - }, - hashCode: function() { - return this._map.hashCode(); - }, - __iterator: function(type, reverse) { - var iterator = this._map.__iterator(ITERATE_KEYS, reverse); - return type === ITERATE_ENTRIES ? iteratorMapper(iterator, (function(key) { - return [key, key]; - })) : iterator; - }, - __iterate: function(fn, reverse) { - var collection = this; - return this._map.__iterate((function(_, k) { - return fn(k, k, collection); - }), reverse); - }, - __deepEquals: function(other) { - return this.isSuperset(other); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - return this; - } - return makeSet(newMap, ownerID); - } -}, { - empty: function() { - return EMPTY_SET || (EMPTY_SET = makeSet(Map.empty())); - }, - from: function(sequence) { - var set = $Set.empty(); - return sequence ? sequence.constructor === $Set ? sequence : set.union(sequence) : set; - }, - fromKeys: function(sequence) { - return $Set.from(Sequence(sequence).flip()); - } -}, Sequence); -var SetPrototype = Set.prototype; -SetPrototype[DELETE] = SetPrototype.remove; -SetPrototype[ITERATOR_SYMBOL] = SetPrototype.values; -SetPrototype.contains = SetPrototype.has; -SetPrototype.mergeDeep = SetPrototype.merge = SetPrototype.union; -SetPrototype.mergeDeepWith = SetPrototype.mergeWith = function(merger) { - for (var seqs = [], - $__12 = 1; $__12 < arguments.length; $__12++) - seqs[$__12 - 1] = arguments[$__12]; - return this.merge.apply(this, seqs); -}; -SetPrototype.withMutations = MapPrototype.withMutations; -SetPrototype.asMutable = MapPrototype.asMutable; -SetPrototype.asImmutable = MapPrototype.asImmutable; -SetPrototype.__toJS = IndexedSequencePrototype.__toJS; -SetPrototype.__toStringMapper = IndexedSequencePrototype.__toStringMapper; -function makeSet(map, ownerID) { - var set = Object.create(SetPrototype); - set.length = map ? map.length : 0; - set._map = map; - set.__ownerID = ownerID; - return set; -} -var EMPTY_SET; -var OrderedMap = function OrderedMap(sequence) { - var map = $OrderedMap.empty(); - return sequence ? sequence.constructor === $OrderedMap ? sequence : map.merge(sequence) : map; -}; -var $OrderedMap = OrderedMap; -($traceurRuntime.createClass)(OrderedMap, { - toString: function() { - return this.__toString('OrderedMap {', '}'); - }, - get: function(k, notSetValue) { - var index = this._map.get(k); - return index != null ? this._vector.get(index)[1] : notSetValue; - }, - clear: function() { - if (this.length === 0) { - return this; - } - if (this.__ownerID) { - this.length = 0; - this._map.clear(); - this._vector.clear(); - return this; - } - return $OrderedMap.empty(); - }, - set: function(k, v) { - return updateOrderedMap(this, k, v); - }, - remove: function(k) { - return updateOrderedMap(this, k, NOT_SET); - }, - wasAltered: function() { - return this._map.wasAltered() || this._vector.wasAltered(); - }, - __iterator: function(type, reverse) { - var iterator = this._vector.__iterator(ITERATE_VALUES, reverse); - return type === ITERATE_KEYS ? iteratorMapper(iterator, (function(entry) { - return entry[0]; - })) : type === ITERATE_VALUES ? iteratorMapper(iterator, (function(entry) { - return entry[1]; - })) : iterator; - }, - __iterate: function(fn, reverse) { - return this._vector.fromEntrySeq().__iterate(fn, reverse); - }, - __deepEquals: function(other) { - var iterator = this.entries(); - return other.every((function(v, k) { - var entry = iterator.next().value; - return entry && is(entry[0], k) && is(entry[1], v); - })); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map.__ensureOwner(ownerID); - var newVector = this._vector.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - this._vector = newVector; - return this; - } - return makeOrderedMap(newMap, newVector, ownerID, this.__hash); - } -}, {empty: function() { - return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(Map.empty(), Vector.empty())); - }}, Map); -OrderedMap.from = OrderedMap; -OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; -function makeOrderedMap(map, vector, ownerID, hash) { - var omap = Object.create(OrderedMap.prototype); - omap.length = map ? map.length : 0; - omap._map = map; - omap._vector = vector; - omap.__ownerID = ownerID; - omap.__hash = hash; - return omap; -} -function updateOrderedMap(omap, k, v) { - var map = omap._map; - var vector = omap._vector; - var i = map.get(k); - var has = i !== undefined; - var removed = v === NOT_SET; - if ((!has && removed) || (has && v === vector.get(i)[1])) { - return omap; - } - if (!has) { - i = vector.length; - } - var newMap = removed ? map.remove(k) : has ? map : map.set(k, i); - var newVector = removed ? vector.remove(i) : vector.set(i, [k, v]); - if (omap.__ownerID) { - omap.length = newMap.length; - omap._map = newMap; - omap._vector = newVector; - omap.__hash = undefined; - return omap; - } - return makeOrderedMap(newMap, newVector); -} -var EMPTY_ORDERED_MAP; -var Record = function Record(defaultValues, name) { - var RecordType = function(values) { - if (!(this instanceof RecordType)) { - return new RecordType(values); - } - this._map = Map(values); - }; - defaultValues = Sequence(defaultValues); - var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); - RecordTypePrototype.constructor = RecordType; - RecordTypePrototype._name = name; - RecordTypePrototype._defaultValues = defaultValues; - var keys = Object.keys(defaultValues); - RecordType.prototype.length = keys.length; - if (Object.defineProperty) { - defaultValues.forEach((function(_, key) { - Object.defineProperty(RecordType.prototype, key, { - get: function() { - return this.get(key); - }, - set: function(value) { - invariant(this.__ownerID, 'Cannot set on an immutable record.'); - this.set(key, value); - } - }); - })); - } - return RecordType; -}; -var $Record = Record; -($traceurRuntime.createClass)(Record, { - toString: function() { - return this.__toString((this._name || 'Record') + ' {', '}'); - }, - has: function(k) { - return this._defaultValues.has(k); - }, - get: function(k, notSetValue) { - if (notSetValue !== undefined && !this.has(k)) { - return notSetValue; - } - return this._map.get(k, this._defaultValues.get(k)); - }, - clear: function() { - if (this.__ownerID) { - this._map.clear(); - return this; - } - var Record = Object.getPrototypeOf(this).constructor; - return $Record._empty || ($Record._empty = makeRecord(this, Map.empty())); - }, - set: function(k, v) { - if (k == null || !this.has(k)) { - return this; - } - var newMap = this._map.set(k, v); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); - }, - remove: function(k) { - if (k == null || !this.has(k)) { - return this; - } - var newMap = this._map.remove(k); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); - }, - keys: function() { - return this._map.keys(); - }, - values: function() { - return this._map.values(); - }, - entries: function() { - return this._map.entries(); - }, - wasAltered: function() { - return this._map.wasAltered(); - }, - __iterator: function(type, reverse) { - return this._map.__iterator(type, reverse); - }, - __iterate: function(fn, reverse) { - var record = this; - return this._defaultValues.map((function(_, k) { - return record.get(k); - })).__iterate(fn, reverse); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map && this._map.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - return this; - } - return makeRecord(this, newMap, ownerID); - } -}, {}, Sequence); -var RecordPrototype = Record.prototype; -RecordPrototype[DELETE] = RecordPrototype.remove; -RecordPrototype.merge = MapPrototype.merge; -RecordPrototype.mergeWith = MapPrototype.mergeWith; -RecordPrototype.mergeDeep = MapPrototype.mergeDeep; -RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; -RecordPrototype.update = MapPrototype.update; -RecordPrototype.updateIn = MapPrototype.updateIn; -RecordPrototype.cursor = MapPrototype.cursor; -RecordPrototype.withMutations = MapPrototype.withMutations; -RecordPrototype.asMutable = MapPrototype.asMutable; -RecordPrototype.asImmutable = MapPrototype.asImmutable; -RecordPrototype.__deepEquals = MapPrototype.__deepEquals; -function makeRecord(likeRecord, map, ownerID) { - var record = Object.create(Object.getPrototypeOf(likeRecord)); - record._map = map; - record.__ownerID = ownerID; - return record; -} -var Range = function Range(start, end, step) { - if (!(this instanceof $Range)) { - return new $Range(start, end, step); - } - invariant(step !== 0, 'Cannot step a Range by 0'); - start = start || 0; - if (end == null) { - end = Infinity; - } - if (start === end && __EMPTY_RANGE) { - return __EMPTY_RANGE; - } - step = step == null ? 1 : Math.abs(step); - if (end < start) { - step = -step; - } - this._start = start; - this._end = end; - this._step = step; - this.length = Math.max(0, Math.ceil((end - start) / step - 1) + 1); -}; -var $Range = Range; -($traceurRuntime.createClass)(Range, { - toString: function() { - if (this.length === 0) { - return 'Range []'; - } - return 'Range [ ' + this._start + '...' + this._end + (this._step > 1 ? ' by ' + this._step : '') + ' ]'; - }, - has: function(index) { - index = wrapIndex(this, index); - return index >= 0 && (this.length === Infinity || index < this.length); - }, - get: function(index, notSetValue) { - index = wrapIndex(this, index); - return this.has(index) ? this._start + index * this._step : notSetValue; - }, - contains: function(searchValue) { - var possibleIndex = (searchValue - this._start) / this._step; - return possibleIndex >= 0 && possibleIndex < this.length && possibleIndex === Math.floor(possibleIndex); - }, - slice: function(begin, end) { - if (wholeSlice(begin, end, this.length)) { - return this; - } - begin = resolveBegin(begin, this.length); - end = resolveEnd(end, this.length); - if (end <= begin) { - return __EMPTY_RANGE; - } - return new $Range(this.get(begin, this._end), this.get(end, this._end), this._step); - }, - indexOf: function(searchValue) { - var offsetValue = searchValue - this._start; - if (offsetValue % this._step === 0) { - var index = offsetValue / this._step; - if (index >= 0 && index < this.length) { - return index; - } - } - return -1; - }, - lastIndexOf: function(searchValue) { - return this.indexOf(searchValue); - }, - take: function(amount) { - return this.slice(0, Math.max(0, amount)); - }, - skip: function(amount) { - return this.slice(Math.max(0, amount)); - }, - __iterate: function(fn, reverse) { - var maxIndex = this.length - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(value, ii, this) === false) { - return ii + 1; - } - value += reverse ? -step : step; - } - return ii; - }, - __iterator: function(type, reverse) { - var maxIndex = this.length - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - var ii = 0; - return new Iterator((function() { - var v = value; - value += reverse ? -step : step; - return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); - })); - }, - __deepEquals: function(other) { - return this._start === other._start && this._end === other._end && this._step === other._step; - } -}, {}, IndexedSequence); -var RangePrototype = Range.prototype; -RangePrototype.__toJS = RangePrototype.toArray; -RangePrototype.first = VectorPrototype.first; -RangePrototype.last = VectorPrototype.last; -var __EMPTY_RANGE = Range(0, 0); -var Repeat = function Repeat(value, times) { - if (times === 0 && EMPTY_REPEAT) { - return EMPTY_REPEAT; - } - if (!(this instanceof $Repeat)) { - return new $Repeat(value, times); - } - this._value = value; - this.length = times == null ? Infinity : Math.max(0, times); -}; -var $Repeat = Repeat; -($traceurRuntime.createClass)(Repeat, { - toString: function() { - if (this.length === 0) { - return 'Repeat []'; - } - return 'Repeat [ ' + this._value + ' ' + this.length + ' times ]'; - }, - get: function(index, notSetValue) { - return this.has(index) ? this._value : notSetValue; - }, - contains: function(searchValue) { - return is(this._value, searchValue); - }, - slice: function(begin, end) { - var length = this.length; - begin = begin < 0 ? Math.max(0, length + begin) : Math.min(length, begin); - end = end == null ? length : end > 0 ? Math.min(length, end) : Math.max(0, length + end); - return end > begin ? new $Repeat(this._value, end - begin) : EMPTY_REPEAT; - }, - reverse: function() { - return this; - }, - indexOf: function(searchValue) { - if (is(this._value, searchValue)) { - return 0; - } - return -1; - }, - lastIndexOf: function(searchValue) { - if (is(this._value, searchValue)) { - return this.length; - } - return -1; - }, - __iterate: function(fn, reverse) { - for (var ii = 0; ii < this.length; ii++) { - if (fn(this._value, ii, this) === false) { - return ii + 1; - } - } - return ii; - }, - __iterator: function(type, reverse) { - var $__0 = this; - var ii = 0; - return new Iterator((function() { - return ii < $__0.length ? iteratorValue(type, ii++, $__0._value) : iteratorDone(); - })); - }, - __deepEquals: function(other) { - return is(this._value, other._value); - } -}, {}, IndexedSequence); -var RepeatPrototype = Repeat.prototype; -RepeatPrototype.last = RepeatPrototype.first; -RepeatPrototype.has = RangePrototype.has; -RepeatPrototype.take = RangePrototype.take; -RepeatPrototype.skip = RangePrototype.skip; -RepeatPrototype.__toJS = RangePrototype.__toJS; -var EMPTY_REPEAT = new Repeat(undefined, 0); -function fromJS(json, converter) { - if (converter) { - return _fromJSWith(converter, json, '', {'': json}); - } - return _fromJSDefault(json); -} -function _fromJSWith(converter, json, key, parentJSON) { - if (json && (Array.isArray(json) || json.constructor === Object)) { - return converter.call(parentJSON, key, Sequence(json).map((function(v, k) { - return _fromJSWith(converter, v, k, json); - }))); - } - return json; -} -function _fromJSDefault(json) { - if (json) { - if (Array.isArray(json)) { - return Sequence(json).map(_fromJSDefault).toVector(); - } - if (json.constructor === Object) { - return Sequence(json).map(_fromJSDefault).toMap(); - } - } - return json; -} -var Immutable = { - Sequence: Sequence, - Map: Map, - Vector: Vector, - Set: Set, - OrderedMap: OrderedMap, - Record: Record, - Range: Range, - Repeat: Repeat, - is: is, - fromJS: fromJS -}; - - return Immutable; -} -typeof exports === 'object' ? module.exports = universalModule() : - typeof define === 'function' && define.amd ? define(universalModule) : - Immutable = universalModule(); diff --git a/dist/Immutable.min.js b/dist/Immutable.min.js deleted file mode 100644 index c29bee25f7..0000000000 --- a/dist/Immutable.min.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -function t(){function t(t,e,r,n){var i;if(n){var u=n.prototype;i=De.create(u)}else i=t.prototype;return De.keys(e).forEach(function(t){i[t]=e[t]}),De.keys(r).forEach(function(e){t[e]=r[e]}),i.constructor=t,t.prototype=i,t}function e(t,e,r,n){return De.getPrototypeOf(e)[r].apply(t,n)}function r(t,r,n){e(t,r,"constructor",n)}function n(t){return t.value=!1,t}function i(t){t&&(t.value=!0)}function u(){}function a(t,e){e=e||0;for(var r=Math.max(0,t.length-e),n=Array(r),i=0;r>i;i++)n[i]=t[i+e];return n}function s(t,e){if(!t)throw Error(e)}function o(t){if(!t)return 0;if(t===!0)return 1;var e=typeof t;if("number"===e){if((0|t)===t)return t&Ke;t=""+t,e="string"}return"string"===e?t.length>Be?h(t):c(t):t.hashCode?o("function"==typeof t.hashCode?t.hashCode():t.hashCode):f(t)}function h(t){var e=Ne[t];return null==e&&(e=c(t),Ve===Le&&(Ve=0,Ne={}),Ve++,Ne[t]=e),e}function c(t){for(var e=0,r=0;t.length>r;r++)e=31*e+t.charCodeAt(r)&Ke;return e}function f(t){var e=t[Je];if(e)return e;if(!We){if(e=t.propertyIsEnumerable&&t.propertyIsEnumerable[Je])return e;if(e=_(t))return e}if(!We||Object.isExtensible(t)){if(e=++ze&Ke,We)Object.defineProperty(t,Je,{enumerable:!1,configurable:!1,writable:!1,value:e});else if(Pe&&t.propertyIsEnumerable===Pe)t.propertyIsEnumerable=function(){return Pe.apply(this,arguments)},t.propertyIsEnumerable[Je]=e;else{if(!t.nodeType)throw Error("Unable to set a non-enumerable property on object.");t[Je]=e}return e}throw Error("Non-extensible objects are not allowed as keys.")}function _(t){if(t&&t.nodeType>0)switch(t.nodeType){case 1:return t.uniqueID;case 9:return t.documentElement&&t.documentElement.uniqueID}}function l(t,e,r){return Ze.value=0===t?e:1===t?r:[e,r],Ze.done=!1,Ze}function v(){return Ze.value=void 0,Ze.done=!0,Ze}function g(t,e){var r=new Xe;return r.next=function(){var r=t.next();return r.done?r:(r.value=e(r.value),r)},r}function p(t){return!!d(t)}function m(t){return t&&"function"==typeof t.next}function y(t){var e=d(t);return"function"==typeof e?e.call(t):void 0}function d(t){return t&&(t[Qe]||t[He]) -}function w(){return Object.create(er)}function S(){return Object.create(ir)}function b(t){return null==t.length&&t.cacheResult(),s(1/0>t.length,"Cannot reverse infinite range."),t.length}function I(t,e,r){return(0===t||null!=r&&-r>=t)&&(null==e||null!=r&&e>=r)}function q(t,e){return k(t,e,0)}function M(t,e){return k(t,e,e)}function k(t,e,r){return null==t?r:0>t?Math.max(0,e+t):e?Math.min(e,t):t}function D(t){return t}function x(t,e){return[e,t]}function O(){return!0}function C(t,e,r,n){var i=t._cache;if(i){for(var u=i.length-1,a=0;u>=a;a++){var s=i[r?u-a:a];if(e(s[1],n?s[0]:a,t)===!1)return a+1}return a}return t.__iterateUncached(e,r)}function A(t,e,r,n){var i=t._cache;if(i){var u=i.length-1,a=0;return new Xe(function(){var t=i[r?u-a:a];return a++>u?v():l(e,n?t[0]:a-1,t[1])})}return t.__iteratorUncached?t.__iteratorUncached(e,r):t.cacheResult().__iterator(e,r)}function E(t,e,r,n){var i=t.__makeSequence();return i.has=function(n){var i=t.get(n,je);return i!==je&&!!e.call(r,i,n,t)},i.get=function(n,i){var u=t.get(n,je);return u!==je&&e.call(r,u,n,t)?u:i},i.__iterateUncached=function(i,u){var a=this,s=0;return t.__iterate(function(t,u,o){return e.call(r,t,u,o)?(s++,i(t,n?u:s-1,a)):void 0},u),s},i.__iteratorUncached=function(i,u){var a=t.__iterator(Ge,u),s=0;return new Xe(function(){for(;;){var u=a.next();if(u.done)return u;var o=u.value,h=o[0],c=o[1];if(e.call(r,c,h,t))return l(i,n?h:s++,c)}})},i}function j(t,e,r,n){var i={},u=[];return t.__iterate(function(a,s){var h=e.call(r,a,s,t),c=o(h),f=n?[s,a]:a;i.hasOwnProperty(c)?u[i[c]][1].push(f):(i[c]=u.length,u.push([h,[f]]))}),$e(u).fromEntrySeq().map(n?function(t){return $e(t).fromEntrySeq()}:function(t){return $e(t)})}function R(t,e,r){if(0>=e)return t;var n=t.__makeSequence();return n.__iterateUncached=function(n,i){var u=this;if(i)return this.cacheResult().__iterate(n,i);var a=0,s=!0,o=0;return t.__iterate(function(t,i){return s&&(s=a++e?1:e>t?-1:0}function B(t,e){return 0>e?(null==t.length&&t.cacheResult(),t.length+e):e}function L(t){s(1/0!==t,"Cannot perform this action with an infinite sequence.")}function V(t,e,r){return r instanceof $e?N(t,e,r):r}function N(t,e,r){return new fr(t._rootData,t._keyPath.concat(e),t._onChange,r)}function T(t,e,r){var n=t._rootData.updateIn(t._keyPath,r?_r.empty():void 0,e),i=t._keyPath||[];return t._onChange&&t._onChange.call(void 0,n,t._rootData,r?i.concat(r):i),new fr(n,t._keyPath,t._onChange)}function F(t,e){return t instanceof fr&&(t=t.deref()),e instanceof fr&&(e=e.deref()),t===e?0!==t||0!==e||1/t===1/e:t!==t?e!==e:t instanceof $e?t.equals(e):!1}function G(t,e){return l(t,e[0],e[1])}function H(t,e){return{node:t,index:0,__prev:e}}function Q(t,e,r,n){var i=Object.create(vr);return i.length=t,i._root=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function X(t,e,r){var i=n(Re),u=n(Ue),a=Y(t._root,t.__ownerID,0,o(e),e,r,i,u);if(!u.value)return t;var s=t.length+(i.value?r===je?-1:1:0);return t.__ownerID?(t.length=s,t._root=a,t.__hash=void 0,t.__altered=!0,t):a?Q(s,a):_r.empty()}function Y(t,e,r,n,u,a,s,o){return t?t.update(e,r,n,u,a,s,o):a===je?t:(i(o),i(s),new Sr(e,n,[u,a]))}function Z(t){return t.constructor===Sr||t.constructor===dr}function $(t,e,r,n,i){if(t.hash===n)return new dr(e,n,[t.entry,i]);var u,a=(0===r?t.hash:t.hash>>>r)&Ee,s=(0===r?n:n>>>r)&Ee,o=a===s?[$(t,e,r+Ce,n,i)]:(u=new Sr(e,n,i),s>a?[t,u]:[u,t]); -return new gr(e,1<s;s++,o<<=1){var c=e[s];null!=c&&s!==n&&(i|=o,a[u++]=c)}return new gr(t,i,a)}function ee(t,e,r,n,i){for(var u=0,a=Array(Ae),s=0;0!==r;s++,r>>>=1)a[s]=1&r?e[u++]:null;return a[n]=i,new mr(t,u+1,a)}function re(t,e,r){for(var n=[],i=0;r.length>i;i++){var u=r[i];u instanceof $e||(u=$e(u),u instanceof rr&&(u=u.fromEntrySeq())),u&&n.push(u)}return ie(t,e,n)}function ne(t){return function(e,r){return e&&e.mergeDeepWith?e.mergeDeepWith(t,r):t?t(e,r):r}}function ie(t,e,r){return 0===r.length?t:t.withMutations(function(t){for(var n=e?function(r,n){var i=t.get(n,je);t.set(n,i===je?r:e(i,r))}:function(e,r){t.set(r,e)},i=0;r.length>i;i++)r[i].forEach(n)})}function ue(t,e,r,n,i){var u=e.length;if(i===u)return n(t);s(t.set,"updateIn with invalid keyPath");var a=i===u-1?r:_r.empty(),o=e[i],h=t.get(o,a),c=ue(h,e,r,n,i+1);return c===h?t:t.set(o,c)}function ae(t){return t-=t>>1&1431655765,t=(858993459&t)+(t>>2&858993459),t=t+(t>>4)&252645135,t+=t>>8,t+=t>>16,127&t}function se(t,e,r,n){var i=n?t:a(t);return i[e]=r,i}function oe(t,e,r,n){var i=t.length+1;if(n&&e+1===i)return t[e]=r,t;for(var u=Array(i),a=0,s=0;i>s;s++)s===e?(u[s]=r,a=-1):u[s]=t[s+a];return u}function he(t,e,r){var n=t.length-1;if(r&&e===n)return t.pop(),t;for(var i=Array(n),u=0,a=0;n>a;a++)a===e&&(u=1),i[a]=t[a+u];return i}function ce(t,e,r,n,i,u){var a,s=t&&t.array;if(0===e){var o=0>r?-r:0,h=n-r;for(h>Ae&&(h=Ae),a=o;h>a;a++)if(i(s&&s[u?o+h-1-a:a])===!1)return!1}else{var c=1<=a;a++){var _=u?Ee-a:a,l=r+(_<l&&l+c>0){var v=s&&s[_];if(!ce(v,f,l,n,i,u))return!1}}}return!0}function fe(t,e,r,n,i){return{array:t,level:e,offset:r,max:n,rawMax:n-r>>e,index:0,__prev:i}}function _e(t,e,r,n,i,u,a){var s=Object.create(Or);return s.length=e-t,s._origin=t,s._size=e,s._level=r,s._root=n,s._tail=i,s.__ownerID=u,s.__hash=a,s.__altered=!1,s}function le(t,e,r){if(e=B(t,e),e>=t.length||0>e)return r===je?t:t.withMutations(function(t){0>e?me(t,e).set(0,r):me(t,0,e+1).set(e,r) -});e+=t._origin;var i=t._tail,u=t._root,a=n(Ue);return e>=de(t._size)?i=ve(i,t.__ownerID,0,e,r,a):u=ve(u,t.__ownerID,t._level,e,r,a),a.value?t.__ownerID?(t._root=u,t._tail=i,t.__hash=void 0,t.__altered=!0,t):_e(t._origin,t._size,t._level,u,i):t}function ve(t,e,r,n,u,a){var s,o=u===je,h=n>>>r&Ee,c=t&&t.array.length>h;if(o&&!c)return t;if(r>0){var f=t&&t.array[h],_=ve(f,e,r-Ce,n,u,a);return _===f?t:(s=ge(t,e),s.array[h]=_,s)}return!o&&c&&t.array[h]===u?t:(i(a),s=ge(t,e),o&&h===s.array.length-1?s.array.pop():s.array[h]=o?void 0:u,s)}function ge(t,e){return e&&t&&e===t.ownerID?t:new Cr(t?t.array.slice():[],e)}function pe(t,e){if(e>=de(t._size))return t._tail;if(1<e){for(var r=t._root,n=t._level;r&&n>0;)r=r.array[e>>>n&Ee],n-=Ce;return r}}function me(t,e,r){var n=t.__ownerID||new u,i=t._origin,a=t._size,s=i+e,o=null==r?a:0>r?a+r:i+r;if(s===i&&o===a)return t;if(s>=o)return t.clear();for(var h=t._level,c=t._root,f=0;0>s+f;)c=new Cr(c&&c.array.length?[null,c]:[],n),h+=Ce,f+=1<=1<l?pe(t,o-1):l>_?new Cr([],n):v;if(v&&l>_&&a>s&&v.array.length){c=ge(c,n);for(var p=c,m=h;m>Ce;m-=Ce){var y=_>>>m&Ee;p=p.array[y]=ge(p.array[y],n)}p.array[_>>>Ce&Ee]=v}if(a>o&&(g=g&&g.removeAfter(n,0,o)),s>=l)s-=l,o-=l,h=Ce,c=null,g=g&&g.removeBefore(n,0,s);else if(s>i||_>l){var d,w;f=0;do d=s>>>h&Ee,w=l-1>>>h&Ee,d===w&&(d&&(f+=(1<i&&(c=c&&c.removeBefore(n,h,s-f)),c&&_>l&&(c=c&&c.removeAfter(n,h,l-f)),f&&(s-=f,o-=f)}return t.__ownerID?(t.length=o-s,t._origin=s,t._size=o,t._level=h,t._root=c,t._tail=g,t.__hash=void 0,t.__altered=!0,t):_e(s,o,h,c,g)}function ye(t,e,r){for(var n=[],i=0;r.length>i;i++){var u=r[i];u&&n.push($e(u))}var a=Math.max.apply(null,n.map(function(t){return t.length||0}));return a>t.length&&(t=t.setLength(a)),ie(t,e,n)}function de(t){return Ae>t?0:t-1>>>Ce<e;e++)t[e]=arguments[e];return P(this,t,!0)},flatten:function(){return W(this,!0)},flatMap:function(t,e){return this.map(t,e).flatten()},reverse:function(){var t=this,e=t.__makeSequence();return e.reverse=function(){return t},e.length=t.length,e.get=function(e,r){return t.get(e,r)},e.has=function(e){return t.has(e)},e.contains=function(e){return t.contains(e)},e.cacheResult=function(){t.cacheResult(),this.length=t.length},e.__iterate=function(e,r){var n=this;return t.__iterate(function(t,r){return e(t,r,n)},!r)},e.__iterator=function(e,r){return t.__iterator(e,!r)},e},keySeq:function(){return this.flip().valueSeq() -},valueSeq:function(){return new ur(this)},entrySeq:function(){var t=this;if(t._cache)return tr(t._cache);var e=t.toKeyedSeq().map(x).valueSeq();return e.fromEntries=function(){return t},e},forEach:function(t,e){return this.__iterate(e?t.bind(e):t)},reduce:function(t,e,r){var n,i;return 2>arguments.length?i=!0:n=e,this.__iterate(function(e,u,a){i?(i=!1,n=e):n=t.call(r,n,e,u,a)}),n},reduceRight:function(){var t=this.toKeyedSeq().reverse();return t.reduce.apply(t,arguments)},every:function(t,e){var r=!0;return this.__iterate(function(n,i,u){return t.call(e,n,i,u)?void 0:(r=!1,!1)}),r},some:function(t,e){return!this.every(K(t),e)},first:function(){return this.find(O)},last:function(){return this.findLast(O)},rest:function(){return this.slice(1)},butLast:function(){return this.slice(0,-1)},has:function(t){return this.get(t,je)!==je},get:function(t,e){return this.find(function(e,r){return F(r,t)},null,e)},getIn:function(t,e){var r=this;if(t)for(var n=0;t.length>n;n++)if(r=r&&r.get?r.get(t[n],je):je,r===je)return e;return r},contains:function(t){return this.find(function(e){return F(e,t)},null,je)!==je},find:function(t,e,r){var n=r;return this.__iterate(function(r,i,u){return t.call(e,r,i,u)?(n=r,!1):void 0}),n},findKey:function(t,e){var r;return this.__iterate(function(n,i,u){return t.call(e,n,i,u)?(r=i,!1):void 0}),r},findLast:function(t,e,r){return this.toKeyedSeq().reverse().find(t,e,r)},findLastKey:function(t,e){return this.toKeyedSeq().reverse().findKey(t,e)},flip:function(){var t=this.toKeyedSeq(),e=t.__makeSequence();return e.length=t.length,e.flip=function(){return t},e.has=function(e){return t.contains(e)},e.contains=function(e){return t.has(e)},e.__iterateUncached=function(e,r){var n=this;return t.__iterate(function(t,r){return e(r,t,n)!==!1},r)},e},map:function(t,e){var r=this,n=r.__makeSequence();return n.length=r.length,n.has=function(t){return r.has(t)},n.get=function(n,i){var u=r.get(n,je);return u===je?i:t.call(e,u,n,r)},n.__iterateUncached=function(n,i){var u=this;return r.__iterate(function(r,i,a){return n(t.call(e,r,i,a),i,u)!==!1 -},i)},n.__iteratorUncached=function(n,i){var u=r.__iterator(Ge,i);return new Xe(function(){var i=u.next();if(i.done)return i;var a=i.value,s=a[0];return l(n,s,t.call(e,a[1],s,r))})},n},mapKeys:function(t,e){var r=this;return this.flip().map(function(n,i){return t.call(e,n,i,r)}).flip()},mapEntries:function(t,e){var r=this;return this.entrySeq().map(function(n,i){return t.call(e,n,i,r)}).fromEntrySeq()},filter:function(t,e){return E(this,t,e,!0)},slice:function(t,e){if(I(t,e,this.length))return this;var r=q(t,this.length),n=M(e,this.length);if(r!==r||n!==n)return this.cacheResult().slice(t,e);var i=0===r?this:this.skip(r);return null==n||n===this.length?i:i.take(n-r)},take:function(t){var e=this;if(t>e.length)return e;0>t&&(t=0);var r=e.__makeSequence();return r.__iterateUncached=function(r,n){var i=this;if(0===t)return 0;if(n)return this.cacheResult().__iterate(r,n);var u=0;return e.__iterate(function(e,n){return++u&&r(e,n,i)!==!1&&t>u}),u},r.length=this.length&&Math.min(this.length,t),r},takeLast:function(t){return this.reverse().take(t).reverse()},takeWhile:function(t,e){var r=this,n=r.__makeSequence();return n.__iterateUncached=function(n,i){var u=this;if(i)return this.cacheResult().__iterate(n,i);var a=0;return r.__iterate(function(r,i,s){return t.call(e,r,i,s)&&++a&&n(r,i,u)}),a},n},takeUntil:function(t,e){return this.takeWhile(K(t),e)},skip:function(t){return R(this,t,!0)},skipLast:function(t){return this.reverse().skip(t).reverse()},skipWhile:function(t,e){return U(this,t,e,!0)},skipUntil:function(t,e){return this.skipWhile(K(t),e)},groupBy:function(t,e){return j(this,t,e,!0)},sort:function(t){return this.sortBy(D,t)},sortBy:function(t,e){e=e||J;var r=this;return tr(this.entrySeq().entrySeq().toArray().sort(function(n,i){return e(t(n[1][1],n[1][0],r),t(i[1][1],i[1][0],r))||n[0]-i[0]})).fromEntrySeq().valueSeq().fromEntrySeq()},cacheResult:function(){return!this._cache&&this.__iterateUncached&&(L(this.length),this._cache=this.entrySeq().toArray(),null==this.length&&(this.length=this._cache.length)),this},keys:function(){return this.__iterator(Te) -},values:function(){return this.__iterator(Fe)},entries:function(){return this.__iterator(Ge)},__iterate:function(t,e){return C(this,t,e,!0)},__iterator:function(t,e){return A(this,t,e,!0)},__makeSequence:function(){return w()}},{from:function(t){if(t instanceof tr)return t;if(!Array.isArray(t)){if(m(t))return new sr(t);if(p(t))return new or(t);if(t&&t.constructor===Object)return new hr(t);t=[t]}return new cr(t)}});var er=$e.prototype;er[Qe]=er.entries,er.toJSON=er.toJS,er.__toJS=er.toObject,er.inspect=er.toSource=function(){return""+this},er.chain=er.flatMap;var rr=function(){xe.defaultSuperCall(this,nr.prototype,arguments)},nr=rr;xe.createClass(rr,{toString:function(){return this.__toString("Seq [","]")},toKeyedSeq:function(){return new ar(this)},valueSeq:function(){return this},fromEntrySeq:function(){var t=this,e=w();return e.length=t.length,e.entrySeq=function(){return t},e.__iterateUncached=function(e,r){var n=this;return t.__iterate(function(t){return t&&e(t[1],t[0],n)},r)},e},concat:function(){for(var t=[],e=0;arguments.length>e;e++)t[e]=arguments[e];return P(this,t,!1)},filter:function(t,e){return E(this,t,e,!1)},get:function(t,e){return t=B(this,t),this.find(function(e,r){return r===t},null,e)},first:function(){return this.get(0)},last:function(){return this.get(this.length?this.length-1:0)},indexOf:function(t){return this.findIndex(function(e){return F(e,t)})},lastIndexOf:function(t){return this.toKeyedSeq().reverse().indexOf(t)},findIndex:function(t,e){var r=this.findKey(t,e);return null==r?-1:r},findLastIndex:function(t,e){return this.toKeyedSeq().reverse().findIndex(t,e)},splice:function(t,e){var r=arguments.length;if(e=Math.max(0|e,0),0===r||2===r&&!e)return this;t=q(t,this.length);var n=this.slice(0,t);return 1===r?n:n.concat(a(arguments,2),this.slice(t+e))},flatten:function(){return W(this,!1)},skip:function(t){return R(this,t,!1)},skipWhile:function(t,e){return U(this,t,e,!1)},groupBy:function(t,e){return j(this,t,e,!1)},sortBy:function(t,e){e=e||J;var r=this;return $e(this.entrySeq().toArray().sort(function(n,i){return e(t(n[1],n[0],r),t(i[1],i[0],r))||n[0]-i[0] -})).fromEntrySeq().valueSeq()},__iterate:function(t,e){return C(this,t,e,!1)},__iterator:function(t,e){return A(this,t,e,!1)},__makeSequence:function(){return S(this)}},{},$e);var ir=rr.prototype;ir[Qe]=ir.values,ir.__toJS=ir.toArray,ir.__toStringMapper=z;var ur=function(t){this._seq=t,this.length=t.length};xe.createClass(ur,{get:function(t,e){return this._seq.get(t,e)},has:function(t){return this._seq.has(t)},cacheResult:function(){this._seq.cacheResult(),this.length=this._seq.length},__iterate:function(t,e){var r=this,n=0;return this._seq.__iterate(function(e){return t(e,n++,r)},e)},__iterator:function(t,e){var r,n=this._seq.__iterator(Fe,e),i=0;return new Xe(function(){return(r=n.next()).done?v():l(t,i++,r.value)})}},{},rr);var ar=function(t){this._seq=t,this.length=t.length};xe.createClass(ar,{get:function(t,e){return this._seq.get(t,e)},has:function(t){return this._seq.has(t)},cacheResult:function(){this._seq.cacheResult(),this.length=this._seq.length},__iterate:function(t,e){var r=this,n=e?b(this):0;return this._seq.__iterate(function(i){return t(i,e?--n:n++,r)},e)},__iterator:function(t,e){var r=this._seq.__iterator(Fe,e),n=e?b(this):0;return new Xe(function(){var i=r.next();return i.done?i:l(t,e?--n:n++,i.value)})}},{},$e);var sr=function(t){this._iterator=t,this._iteratorCache=[]};xe.createClass(sr,{__iterateUncached:function(t,e){if(e)return this.cacheResult().__iterate(t,e);for(var r=this._iterator,n=this._iteratorCache,i=0;n.length>i;)if(t(n[i],i++,this)===!1)return i;for(var u;!(u=r.next()).done;){var a=u.value;if(n[i]=a,t(a,i++,this)===!1)break}return i},__iteratorUncached:function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterator,n=this._iteratorCache,i=0;return new Xe(function(){if(i>=n.length){var e=r.next();if(e.done)return e;n[i]=e.value}return l(t,i,n[i++])})}},{},rr);var or=function(t){this._iterable=t,this.length=t.length||t.size};xe.createClass(or,{__iterateUncached:function(t,e){if(e)return this.cacheResult().__iterate(t,e);var r=this._iterable,n=y(r),i=0;if(m(n))for(var u;!(u=n.next()).done&&t(u.value,i++,this)!==!1;);return i -},__iteratorUncached:function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterable,n=y(r);if(!m(n))return new Xe(function(){return v()});var i=0;return new Xe(function(){var e=n.next();return e.done?e:l(t,i++,e.value)})}},{},rr);var hr=function(t){var e=Object.keys(t);this._object=t,this._keys=e,this.length=e.length};xe.createClass(hr,{toObject:function(){return this._object},get:function(t,e){return void 0===e||this.has(t)?this._object[t]:e},has:function(t){return this._object.hasOwnProperty(t)},__iterate:function(t,e){for(var r=this._object,n=this._keys,i=n.length-1,u=0;i>=u;u++){var a=n[e?i-u:u];if(t(r[a],a,this)===!1)return u+1}return u},__iterator:function(t,e){var r=this._object,n=this._keys,i=n.length-1,u=0;return new Xe(function(){var a=n[e?i-u:u];return u++>i?v():l(t,a,r[a])})}},{},$e);var cr=function(t){this._array=t,this.length=t.length};xe.createClass(cr,{toArray:function(){return this._array},get:function(t,e){return this.has(t)?this._array[B(this,t)]:e},has:function(t){return t=B(this,t),t>=0&&this.length>t},__iterate:function(t,e){for(var r=this._array,n=r.length-1,i=0;n>=i;i++)if(t(r[e?n-i:i],i,this)===!1)return i+1;return i},__iterator:function(t,e){var r=this._array,n=r.length-1,i=0;return new Xe(function(){return i>n?v():l(t,i,r[e?n-i++:i++])})}},{},rr);var fr=function(t,e,r,n){n=n?n:t.getIn(e),this.length=n instanceof $e?n.length:null,this._rootData=t,this._keyPath=e,this._onChange=r};xe.createClass(fr,{deref:function(t){return this._rootData.getIn(this._keyPath,t)},get:function(t,e){if(Array.isArray(t)&&0===t.length)return this;var r=this._rootData.getIn(this._keyPath.concat(t),je);return r===je?e:V(this,t,r)},set:function(t,e){return T(this,function(r){return r.set(t,e)},t)},remove:function(t){return T(this,function(e){return e.remove(t)},t)},clear:function(){return T(this,function(t){return t.clear()})},update:function(t,e,r){return 1===arguments.length?T(this,t):T(this,function(n){return n.update(t,e,r)},t)},withMutations:function(t){return T(this,function(e){return(e||_r.empty()).withMutations(t) -})},cursor:function(t){return Array.isArray(t)&&0===t.length?this:N(this,t)},__iterate:function(t,e){var r=this,n=this,i=n.deref();return i&&i.__iterate?i.__iterate(function(e,i){return t(V(n,i,e),i,r)},e):0}},{},$e),fr.prototype[Oe]=fr.prototype.remove,fr.prototype.getIn=fr.prototype.get;var _r=function(t){var e=lr.empty();return t?t.constructor===lr?t:e.merge(t):e},lr=_r;xe.createClass(_r,{toString:function(){return this.__toString("Map {","}")},get:function(t,e){return this._root?this._root.get(0,o(t),t,e):e},set:function(t,e){return X(this,t,e)},remove:function(t){return X(this,t,je)},update:function(t,e,r){return 1===arguments.length?this.updateIn([],null,t):this.updateIn([t],e,r)},updateIn:function(t,e,r){var n;return r||(n=[e,r],r=n[0],e=n[1],n),ue(this,t,e,r,0)},clear:function(){return 0===this.length?this:this.__ownerID?(this.length=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):lr.empty()},merge:function(){return re(this,null,arguments)},mergeWith:function(t){for(var e=[],r=1;arguments.length>r;r++)e[r-1]=arguments[r];return re(this,t,e)},mergeDeep:function(){return re(this,ne(null),arguments)},mergeDeepWith:function(t){for(var e=[],r=1;arguments.length>r;r++)e[r-1]=arguments[r];return re(this,ne(t),e)},cursor:function(t,e){return e||"function"!=typeof t?0===arguments.length?t=[]:Array.isArray(t)||(t=[t]):(e=t,t=[]),new fr(this,t,e)},withMutations:function(t){var e=this.asMutable();return t(e),e.wasAltered()?e.__ensureOwner(this.__ownerID):this},asMutable:function(){return this.__ownerID?this:this.__ensureOwner(new u)},asImmutable:function(){return this.__ensureOwner()},wasAltered:function(){return this.__altered},__iterator:function(t,e){return new Ir(this,t,e)},__iterate:function(t,e){var r=this,n=0;return this._root&&this._root.iterate(function(e){return n++,t(e[1],e[0],r)},e),n},__deepEquals:function(t){var e=this;return t.every(function(t,r){return F(e.get(r,je),t)})},__ensureOwner:function(t){return t===this.__ownerID?this:t?Q(this.length,this._root,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this) -}},{empty:function(){return qr||(qr=Q(0))}},$e);var vr=_r.prototype;vr[Oe]=vr.remove,_r.from=_r;var gr=function(t,e,r){this.ownerID=t,this.bitmap=e,this.nodes=r},pr=gr;xe.createClass(gr,{get:function(t,e,r,n){var i=1<<((0===t?e:e>>>t)&Ee),u=this.bitmap;return 0===(u&i)?n:this.nodes[ae(u&i-1)].get(t+Ce,e,r,n)},update:function(t,e,r,n,i,u,a){var s=(0===e?r:r>>>e)&Ee,o=1<=Mr)return ee(t,_,h,s,v);if(c&&!v&&2===_.length&&Z(_[1^f]))return _[1^f];if(c&&v&&1===_.length&&Z(v))return v;var g=t&&t===this.ownerID,p=c?v?h:h^o:h|o,m=c?v?se(_,f,v,g):he(_,f,g):oe(_,f,v,g);return g?(this.bitmap=p,this.nodes=m,this):new pr(t,p,m)},iterate:function(t,e){for(var r=this.nodes,n=0,i=r.length-1;i>=n;n++)if(r[e?i-n:n].iterate(t,e)===!1)return!1}},{});var mr=function(t,e,r){this.ownerID=t,this.count=e,this.nodes=r},yr=mr;xe.createClass(mr,{get:function(t,e,r,n){var i=(0===t?e:e>>>t)&Ee,u=this.nodes[i];return u?u.get(t+Ce,e,r,n):n},update:function(t,e,r,n,i,u,a){var s=(0===e?r:r>>>e)&Ee,o=i===je,h=this.nodes,c=h[s];if(o&&!c)return this;var f=Y(c,t,e+Ce,r,n,i,u,a);if(f===c)return this;var _=this.count;if(c){if(!f&&(_--,kr>_))return te(t,h,_,s)}else _++;var l=t&&t===this.ownerID,v=se(h,s,f,l);return l?(this.count=_,this.nodes=v,this):new yr(t,_,v)},iterate:function(t,e){for(var r=this.nodes,n=0,i=r.length-1;i>=n;n++){var u=r[e?i-n:n];if(u&&u.iterate(t,e)===!1)return!1}}},{});var dr=function(t,e,r){this.ownerID=t,this.hash=e,this.entries=r},wr=dr;xe.createClass(dr,{get:function(t,e,r,n){for(var i=this.entries,u=0,a=i.length;a>u;u++)if(F(r,i[u][0]))return i[u][1];return n},update:function(t,e,r,n,u,s,o){var h=u===je;if(r!==this.hash)return h?this:(i(o),i(s),$(this,t,e,r,[n,u]));for(var c=this.entries,f=0,_=c.length;_>f&&!F(n,c[f][0]);f++);var l=_>f;if(h&&!l)return this;if(i(o),(h||!l)&&i(s),h&&2===_)return new Sr(t,this.hash,c[1^f]);var v=t&&t===this.ownerID,g=v?c:a(c);return l?h?f===_-1?g.pop():g[f]=g.pop():g[f]=[n,u]:g.push([n,u]),v?(this.entries=g,this):new wr(t,this.hash,g) -},iterate:function(t,e){for(var r=this.entries,n=0,i=r.length-1;i>=n;n++)if(t(r[e?i-n:n])===!1)return!1}},{});var Sr=function(t,e,r){this.ownerID=t,this.hash=e,this.entry=r},br=Sr;xe.createClass(Sr,{get:function(t,e,r,n){return F(r,this.entry[0])?this.entry[1]:n},update:function(t,e,r,n,u,a,s){var o=u===je,h=F(n,this.entry[0]);return(h?u===this.entry[1]:o)?this:(i(s),o?(i(a),null):h?t&&t===this.ownerID?(this.entry[1]=u,this):new br(t,r,[n,u]):(i(a),$(this,t,e,r,[n,u])))},iterate:function(t){return t(this.entry)}},{});var Ir=function(t,e,r){this._type=e,this._reverse=r,this._stack=t._root&&H(t._root)};xe.createClass(Ir,{next:function(){for(var t=this._type,e=this._stack;e;){var r,n=e.node,i=e.index++;if(n.entry){if(0===i)return G(t,n.entry)}else if(n.entries){if(r=n.entries.length-1,r>=i)return G(t,n.entries[this._reverse?r-i:i])}else if(r=n.nodes.length-1,r>=i){var u=n.nodes[this._reverse?r-i:i];if(u){if(u.entry)return G(t,u.entry);e=this._stack=H(u,e)}continue}e=this._stack=this._stack.__prev}return v()}},{},Xe);var qr,Mr=Ae/2,kr=Ae/4,Dr=function(){for(var t=[],e=0;arguments.length>e;e++)t[e]=arguments[e];return xr.from(t)},xr=Dr;xe.createClass(Dr,{toString:function(){return this.__toString("Vector [","]")},has:function(t){return t=B(this,t),t>=0&&this.length>t},get:function(t,e){if(t=B(this,t),0>t||t>=this.length)return e;t+=this._origin;var r=pe(this,t);return r&&r.array[t&Ee]},set:function(t,e){return le(this,t,e)},remove:function(t){return le(this,t,je)},clear:function(){return 0===this.length?this:this.__ownerID?(this.length=this._origin=this._size=0,this._level=Ce,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):xr.empty()},push:function(){var t=arguments,e=this.length;return this.withMutations(function(r){me(r,0,e+t.length);for(var n=0;t.length>n;n++)r.set(e+n,t[n])})},pop:function(){return me(this,0,-1)},unshift:function(){var t=arguments;return this.withMutations(function(e){me(e,-t.length);for(var r=0;t.length>r;r++)e.set(r,t[r])})},shift:function(){return me(this,1)},merge:function(){return ye(this,null,arguments) -},mergeWith:function(t){for(var e=[],r=1;arguments.length>r;r++)e[r-1]=arguments[r];return ye(this,t,e)},mergeDeep:function(){return ye(this,ne(null),arguments)},mergeDeepWith:function(t){for(var e=[],r=1;arguments.length>r;r++)e[r-1]=arguments[r];return ye(this,ne(t),e)},setLength:function(t){return me(this,0,t)},slice:function(t,e){var r=xe.superCall(this,xr.prototype,"slice",[t,e]);if(r!==this){var n=this,i=n.length;r.toVector=function(){return me(n,0>t?Math.max(0,i+t):i?Math.min(i,t):t,null==e?i:0>e?Math.max(0,i+e):i?Math.min(i,e):e)}}return r},__iterator:function(t,e){return new Er(this,t,e)},__iterate:function(t,e){var r=this,n=0,i=function(e){return t(e,n++,r)},u=de(this._size);return e?ce(this._tail,0,u-this._origin,this._size-this._origin,i,e)&&ce(this._root,this._level,-this._origin,u-this._origin,i,e):ce(this._root,this._level,-this._origin,u-this._origin,i,e)&&ce(this._tail,0,u-this._origin,this._size-this._origin,i,e),n},__deepEquals:function(t){var e=this.entries(!0);return t.every(function(t,r){var n=e.next().value;return n&&n[0]===r&&F(n[1],t)})},__ensureOwner:function(t){return t===this.__ownerID?this:t?_e(this._origin,this._size,this._level,this._root,this._tail,t,this.__hash):(this.__ownerID=t,this)}},{empty:function(){return jr||(jr=_e(0,0,Ce))},from:function(t){if(!t||0===t.length)return xr.empty();if(t.constructor===xr)return t;var e=Array.isArray(t);return t.length>0&&Ae>t.length?_e(0,t.length,Ce,null,new Cr(e?a(t):$e(t).toArray())):(e||(t=$e(t).valueSeq()),xr.empty().merge(t))}},rr);var Or=Dr.prototype;Or[Oe]=Or.remove,Or.update=vr.update,Or.updateIn=vr.updateIn,Or.cursor=vr.cursor,Or.withMutations=vr.withMutations,Or.asMutable=vr.asMutable,Or.asImmutable=vr.asImmutable,Or.wasAltered=vr.wasAltered;var Cr=function(t,e){this.array=t,this.ownerID=e},Ar=Cr;xe.createClass(Cr,{removeBefore:function(t,e,r){if(r===e?1<>>e&Ee;if(n>=this.array.length)return new Ar([],t);var i,u=0===n;if(e>0){var a=this.array[n];if(i=a&&a.removeBefore(t,e-Ce,r),i===a&&u)return this -}if(u&&!i)return this;var s=ge(this,t);if(!u)for(var o=0;n>o;o++)s.array[o]=void 0;return i&&(s.array[n]=i),s},removeAfter:function(t,e,r){if(r===e?1<>>e&Ee;if(n>=this.array.length)return this;var i,u=n===this.array.length-1;if(e>0){var a=this.array[n];if(i=a&&a.removeAfter(t,e-Ce,r),i===a&&u)return this}if(u&&!i)return this;var s=ge(this,t);return u||s.array.pop(),i&&(s.array[n]=i),s}},{});var Er=function(t,e,r){this._type=e,this._reverse=!!r,this._maxIndex=t.length-1;var n=de(t._size),i=fe(t._root&&t._root.array,t._level,-t._origin,n-t._origin-1),u=fe(t._tail&&t._tail.array,0,n-t._origin,t._size-t._origin-1);this._stack=r?u:i,this._stack.__prev=r?i:u};xe.createClass(Er,{next:function(){for(var t=this._stack;t;){var e=t.array,r=t.index++;if(this._reverse&&(r=Ee-r,r>t.rawMax&&(r=t.rawMax,t.index=Ae-r)),r>=0&&Ae>r&&t.rawMax>=r){var n=e&&e[r];if(0===t.level){var i,u=this._type;return 1!==u&&(i=t.offset+(r<e;e++)t[e]=arguments[e];return Ur.from(t)},Ur=Rr;xe.createClass(Rr,{toString:function(){return this.__toString("Set {","}")},has:function(t){return this._map.has(t)},get:function(t,e){return this.has(t)?t:e},add:function(t){var e=this._map.set(t,null);return this.__ownerID?(this.length=e.length,this._map=e,this):e===this._map?this:we(e)},remove:function(t){var e=this._map.remove(t);return this.__ownerID?(this.length=e.length,this._map=e,this):e===this._map?this:0===e.length?Ur.empty():we(e)},clear:function(){return 0===this.length?this:this.__ownerID?(this.length=0,this._map.clear(),this):Ur.empty()},union:function(){var t=arguments;return 0===t.length?this:this.withMutations(function(e){for(var r=0;t.length>r;r++)$e(t[r]).forEach(function(t){return e.add(t)})})},intersect:function(){for(var t=[],e=0;arguments.length>e;e++)t[e]=arguments[e]; -if(0===t.length)return this;t=t.map(function(t){return $e(t)});var r=this;return this.withMutations(function(e){r.forEach(function(r){t.every(function(t){return t.contains(r)})||e.remove(r)})})},subtract:function(){for(var t=[],e=0;arguments.length>e;e++)t[e]=arguments[e];if(0===t.length)return this;t=t.map(function(t){return $e(t)});var r=this;return this.withMutations(function(e){r.forEach(function(r){t.some(function(t){return t.contains(r)})&&e.remove(r)})})},isSubset:function(t){return t=$e(t),this.every(function(e){return t.contains(e)})},isSuperset:function(t){var e=this;return t=$e(t),t.every(function(t){return e.contains(t)})},wasAltered:function(){return this._map.wasAltered()},hashCode:function(){return this._map.hashCode()},__iterator:function(t,e){var r=this._map.__iterator(Te,e);return t===Ge?g(r,function(t){return[t,t]}):r},__iterate:function(t,e){var r=this;return this._map.__iterate(function(e,n){return t(n,n,r)},e)},__deepEquals:function(t){return this.isSuperset(t)},__ensureOwner:function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t);return t?we(e,t):(this.__ownerID=t,this._map=e,this)}},{empty:function(){return Wr||(Wr=we(_r.empty()))},from:function(t){var e=Ur.empty();return t?t.constructor===Ur?t:e.union(t):e},fromKeys:function(t){return Ur.from($e(t).flip())}},$e);var Pr=Rr.prototype;Pr[Oe]=Pr.remove,Pr[Qe]=Pr.values,Pr.contains=Pr.has,Pr.mergeDeep=Pr.merge=Pr.union,Pr.mergeDeepWith=Pr.mergeWith=function(){for(var t=[],e=1;arguments.length>e;e++)t[e-1]=arguments[e];return this.merge.apply(this,t)},Pr.withMutations=vr.withMutations,Pr.asMutable=vr.asMutable,Pr.asImmutable=vr.asImmutable,Pr.__toJS=ir.__toJS,Pr.__toStringMapper=ir.__toStringMapper;var Wr,Kr=function(t){var e=zr.empty();return t?t.constructor===zr?t:e.merge(t):e},zr=Kr;xe.createClass(Kr,{toString:function(){return this.__toString("OrderedMap {","}")},get:function(t,e){var r=this._map.get(t);return null!=r?this._vector.get(r)[1]:e},clear:function(){return 0===this.length?this:this.__ownerID?(this.length=0,this._map.clear(),this._vector.clear(),this):zr.empty() -},set:function(t,e){return be(this,t,e)},remove:function(t){return be(this,t,je)},wasAltered:function(){return this._map.wasAltered()||this._vector.wasAltered()},__iterator:function(t,e){var r=this._vector.__iterator(Fe,e);return t===Te?g(r,function(t){return t[0]}):t===Fe?g(r,function(t){return t[1]}):r},__iterate:function(t,e){return this._vector.fromEntrySeq().__iterate(t,e)},__deepEquals:function(t){var e=this.entries();return t.every(function(t,r){var n=e.next().value;return n&&F(n[0],r)&&F(n[1],t)})},__ensureOwner:function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t),r=this._vector.__ensureOwner(t);return t?Se(e,r,t,this.__hash):(this.__ownerID=t,this._map=e,this._vector=r,this)}},{empty:function(){return Jr||(Jr=Se(_r.empty(),Dr.empty()))}},_r),Kr.from=Kr,Kr.prototype[Oe]=Kr.prototype.remove;var Jr,Br=function(t,e){var r=function(t){return this instanceof r?void(this._map=_r(t)):new r(t)};t=$e(t);var n=r.prototype=Object.create(Vr);n.constructor=r,n._name=e,n._defaultValues=t;var i=Object.keys(t);return r.prototype.length=i.length,Object.defineProperty&&t.forEach(function(t,e){Object.defineProperty(r.prototype,e,{get:function(){return this.get(e)},set:function(t){s(this.__ownerID,"Cannot set on an immutable record."),this.set(e,t)}})}),r},Lr=Br;xe.createClass(Br,{toString:function(){return this.__toString((this._name||"Record")+" {","}")},has:function(t){return this._defaultValues.has(t)},get:function(t,e){return void 0===e||this.has(t)?this._map.get(t,this._defaultValues.get(t)):e},clear:function(){if(this.__ownerID)return this._map.clear(),this;Object.getPrototypeOf(this).constructor;return Lr._empty||(Lr._empty=Ie(this,_r.empty()))},set:function(t,e){if(null==t||!this.has(t))return this;var r=this._map.set(t,e);return this.__ownerID||r===this._map?this:Ie(this,r)},remove:function(t){if(null==t||!this.has(t))return this;var e=this._map.remove(t);return this.__ownerID||e===this._map?this:Ie(this,e)},keys:function(){return this._map.keys()},values:function(){return this._map.values() -},entries:function(){return this._map.entries()},wasAltered:function(){return this._map.wasAltered()},__iterator:function(t,e){return this._map.__iterator(t,e)},__iterate:function(t,e){var r=this;return this._defaultValues.map(function(t,e){return r.get(e)}).__iterate(t,e)},__ensureOwner:function(t){if(t===this.__ownerID)return this;var e=this._map&&this._map.__ensureOwner(t);return t?Ie(this,e,t):(this.__ownerID=t,this._map=e,this)}},{},$e);var Vr=Br.prototype;Vr[Oe]=Vr.remove,Vr.merge=vr.merge,Vr.mergeWith=vr.mergeWith,Vr.mergeDeep=vr.mergeDeep,Vr.mergeDeepWith=vr.mergeDeepWith,Vr.update=vr.update,Vr.updateIn=vr.updateIn,Vr.cursor=vr.cursor,Vr.withMutations=vr.withMutations,Vr.asMutable=vr.asMutable,Vr.asImmutable=vr.asImmutable,Vr.__deepEquals=vr.__deepEquals;var Nr=function(t,e,r){return this instanceof Tr?(s(0!==r,"Cannot step a Range by 0"),t=t||0,null==e&&(e=1/0),t===e&&Gr?Gr:(r=null==r?1:Math.abs(r),t>e&&(r=-r),this._start=t,this._end=e,this._step=r,void(this.length=Math.max(0,Math.ceil((e-t)/r-1)+1)))):new Tr(t,e,r)},Tr=Nr;xe.createClass(Nr,{toString:function(){return 0===this.length?"Range []":"Range [ "+this._start+"..."+this._end+(this._step>1?" by "+this._step:"")+" ]"},has:function(t){return t=B(this,t),t>=0&&(1/0===this.length||this.length>t)},get:function(t,e){return t=B(this,t),this.has(t)?this._start+t*this._step:e},contains:function(t){var e=(t-this._start)/this._step;return e>=0&&this.length>e&&e===Math.floor(e)},slice:function(t,e){return I(t,e,this.length)?this:(t=q(t,this.length),e=M(e,this.length),t>=e?Gr:new Tr(this.get(t,this._end),this.get(e,this._end),this._step))},indexOf:function(t){var e=t-this._start;if(e%this._step===0){var r=e/this._step;if(r>=0&&this.length>r)return r}return-1},lastIndexOf:function(t){return this.indexOf(t)},take:function(t){return this.slice(0,Math.max(0,t))},skip:function(t){return this.slice(Math.max(0,t))},__iterate:function(t,e){for(var r=this.length-1,n=this._step,i=e?this._start+r*n:this._start,u=0;r>=u;u++){if(t(i,u,this)===!1)return u+1;i+=e?-n:n}return u -},__iterator:function(t,e){var r=this.length-1,n=this._step,i=e?this._start+r*n:this._start,u=0;return new Xe(function(){var a=i;return i+=e?-n:n,u>r?v():l(t,u++,a)})},__deepEquals:function(t){return this._start===t._start&&this._end===t._end&&this._step===t._step}},{},rr);var Fr=Nr.prototype;Fr.__toJS=Fr.toArray,Fr.first=Or.first,Fr.last=Or.last;var Gr=Nr(0,0),Hr=function(t,e){return 0===e&&Yr?Yr:this instanceof Qr?(this._value=t,void(this.length=null==e?1/0:Math.max(0,e))):new Qr(t,e)},Qr=Hr;xe.createClass(Hr,{toString:function(){return 0===this.length?"Repeat []":"Repeat [ "+this._value+" "+this.length+" times ]"},get:function(t,e){return this.has(t)?this._value:e},contains:function(t){return F(this._value,t)},slice:function(t,e){var r=this.length;return t=0>t?Math.max(0,r+t):Math.min(r,t),e=null==e?r:e>0?Math.min(r,e):Math.max(0,r+e),e>t?new Qr(this._value,e-t):Yr},reverse:function(){return this},indexOf:function(t){return F(this._value,t)?0:-1},lastIndexOf:function(t){return F(this._value,t)?this.length:-1},__iterate:function(t){for(var e=0;this.length>e;e++)if(t(this._value,e,this)===!1)return e+1;return e},__iterator:function(t){var e=this,r=0;return new Xe(function(){return e.length>r?l(t,r++,e._value):v()})},__deepEquals:function(t){return F(this._value,t._value)}},{},rr);var Xr=Hr.prototype;Xr.last=Xr.first,Xr.has=Fr.has,Xr.take=Fr.take,Xr.skip=Fr.skip,Xr.__toJS=Fr.__toJS;var Yr=new Hr(void 0,0),Zr={Sequence:$e,Map:_r,Vector:Dr,Set:Rr,OrderedMap:Kr,Record:Br,Range:Nr,Repeat:Hr,is:F,fromJS:qe};return Zr}"object"==typeof exports?module.exports=t():"function"==typeof define&&define.amd?define(t):Immutable=t(); \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..f75f25580e --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,160 @@ +import pluginJs from '@eslint/js'; +import globals from 'globals'; +import pluginJest from 'eslint-plugin-jest'; +import importPlugin from 'eslint-plugin-import'; +import pluginReact from 'eslint-plugin-react'; +// eslint-disable-next-line import/no-unresolved +import tseslint from 'typescript-eslint'; + +/** @type {import('eslint').Linter.Config[]} */ +export default tseslint.config( + { files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] }, + { + ignores: [ + 'npm/', + 'dist/', + 'type-definitions/flow-tests', + 'website/out/', + 'website/.next/', + ], + }, + { + languageOptions: { + globals: globals.browser, + + // parserOptions: { + // projectService: true, + // tsconfigRootDir: import.meta.dirname, + // }, + }, + }, + pluginJs.configs.recommended, + importPlugin.flatConfigs.recommended, + importPlugin.flatConfigs.typescript, + ...tseslint.configs.recommended, + + { + rules: { + eqeqeq: 'error', + 'constructor-super': 'off', + 'no-constructor-return': 'error', + 'no-else-return': 'error', + 'no-lonely-if': 'error', + 'no-object-constructor': 'error', + 'no-prototype-builtins': 'off', + 'no-this-before-super': 'off', + 'no-useless-concat': 'error', + 'no-var': 'error', + 'operator-assignment': 'error', + 'prefer-arrow-callback': 'error', + 'prefer-spread': 'off', + + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + }, + ], + }, + }, + + { + files: ['src/*'], + rules: { + 'no-console': 'error', + }, + }, + + { + files: ['website/'], + ...pluginReact.configs.flat.recommended, + ...pluginReact.configs.flat['jsx-runtime'], + + rules: { + 'react/destructuring-assignment': 'off', + 'react/jsx-boolean-value': 'off', + 'react/jsx-curly-brace-presence': 'off', + 'react/jsx-filename-extension': 'off', + 'react/no-array-index-key': 'off', + 'react/no-danger': 'off', + 'react/no-multi-comp': 'off', + 'react/prefer-es6-class': 'off', + 'react/prefer-stateless-function': 'off', + 'react/prop-types': 'off', + 'react/self-closing-comp': 'error', + 'react/sort-comp': 'off', + 'react/jsx-props-no-spreading': 'off', + + 'react/require-default-props': [ + 'error', + { + functions: 'ignore', + }, + ], + + 'jsx-a11y/no-static-element-interactions': 'off', + }, + }, + + { + files: ['type-definitions/ts-tests/*'], + + rules: { + '@typescript-eslint/no-unused-vars': 'off', + + 'import/no-unresolved': [ + 'error', + { + ignore: ['immutable'], + }, + ], + }, + }, + + { + files: ['__tests__/**/*', 'website/**/*.test.ts', 'perf/*'], + languageOptions: { + globals: pluginJest.environments.globals.globals, + }, + ...pluginJest.configs['flat/recommended'], + ...pluginJest.configs['flat/style'], + plugins: { jest: pluginJest }, + rules: { + ...pluginJest.configs['flat/recommended'].rules, + // TODO activate style rules later + // ...pluginJest.configs['jest/style'].rules, + 'jest/expect-expect': [ + 'error', + { + assertFunctionNames: ['expect', 'expectIs', 'expectIsNot'], + additionalTestBlockFunctions: [], + }, + ], + 'import/no-unresolved': [ + 'error', + { + ignore: ['immutable'], + }, + ], + }, + }, + { + files: ['perf/*'], + rules: { + 'jest/expect-expect': 'off', + 'no-redeclare': 'off', + 'no-var': 'off', + 'prefer-arrow-callback': 'off', + }, + }, + { + files: ['resources/*'], + rules: { + 'no-undef': 'off', + 'no-redeclare': 'off', + 'no-var': 'off', + 'prefer-arrow-callback': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, + } +); diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 0000000000..4bbd44198b --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,12 @@ +/** @type {import('jest').Config} */ +const config = { + moduleFileExtensions: ['js', 'ts'], + resolver: '/resources/jestResolver.js', + transform: { + '^.+\\.(js|ts)$': '/resources/jestPreprocessor.js', + }, + testRegex: ['/__tests__/.*\\.(ts|js)$', '/website/.*\\.test\\.(ts|js)$'], + testPathIgnorePatterns: ['/__tests__/ts-utils.ts'], +}; + +export default config; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..8e728752a6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,19705 @@ +{ + "name": "immutable", + "version": "5.1.2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "immutable", + "version": "5.1.2", + "license": "MIT", + "devDependencies": { + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-javascript": "^6.2.3", + "@codemirror/state": "^6.5.2", + "@codemirror/theme-one-dark": "^6.1.2", + "@codemirror/view": "^6.36.5", + "@eslint/js": "^9.20.0", + "@jdeniau/immutable-devtools": "^0.2.0", + "@jest/globals": "^29.7.0", + "@rollup/plugin-buble": "1.0.3", + "@rollup/plugin-commonjs": "28.0.2", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^12.1.2", + "@size-limit/esbuild-why": "^11.2.0", + "@size-limit/preset-small-lib": "^11.2.0", + "@types/prismjs": "^1.26.3", + "@types/random-seed": "0.3.5", + "@types/react": "19.1.0", + "benchmark": "2.1.4", + "codemirror": "^6.0.1", + "colors": "1.4.0", + "cpy-cli": "^5.0.0", + "eslint": "^9.20.1", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^28.11.0", + "eslint-plugin-react": "^7.37.4", + "fast-check": "^4.0.0", + "flow-bin": "0.160.0", + "globals": "^15.15.0", + "jest": "^29.0.0", + "jest-environment-jsdom": "^29.6.4", + "jsonml-html": "^1.2.0", + "make-synchronous": "0.1.1", + "marked": "^11.2.0", + "marked-highlight": "^2.1.0", + "microtime": "3.1.1", + "next": "15.2.4", + "next-sitemap": "4.2.3", + "npm-run-all": "4.1.5", + "prettier": "^3.5.0", + "prismjs": "^1.29.0", + "random-seed": "0.3.0", + "react": "19.1.0", + "react-dom": "19.1.0", + "rimraf": "2.7.1", + "rollup": "4.34.8", + "size-limit": "^11.2.0", + "transducers-js": "0.4.174", + "ts-node": "^10.9.2", + "tslib": "^2.8.1", + "tstyche": "^3.5", + "typescript": "5.7", + "typescript-eslint": "^8.24.0" + }, + "engines": { + "npm": ">=7.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz", + "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.7", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/traverse": "^7.26.8", + "@babel/types": "^7.26.8", + "@types/gensync": "^1.0.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", + "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.8", + "@babel/types": "^7.26.8", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/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==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.10" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.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==", + "dev": true, + "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.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", + "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.8", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/types": "^7.26.8", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/types": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.18.6", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", + "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", + "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz", + "integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", + "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", + "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz", + "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", + "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/theme-one-dark": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.36.5", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.5.tgz", + "integrity": "sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.5.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@corex/deepmerge": { + "version": "4.0.43", + "resolved": "https://registry.npmjs.org/@corex/deepmerge/-/deepmerge-4.0.43.tgz", + "integrity": "sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz", + "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/js": { + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jdeniau/immutable-devtools": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@jdeniau/immutable-devtools/-/immutable-devtools-0.2.0.tgz", + "integrity": "sha512-kncZLhyszWkGz0wAr8eoHFvhczuZz5Ud71OiLIhe5PFQ05nnLgsFdr520Qy+eHhMSL6roJYFrZ73ZJTv48/fUg==", + "dev": true, + "license": "BSD" + }, + "node_modules/@jest/console": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz", + "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz", + "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.4", + "@jest/reporters": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.6.3", + "jest-config": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-resolve-dependencies": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "jest-watcher": "^29.6.4", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz", + "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "jest-worker": "^29.6.4", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz", + "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz", + "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lezer/common": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.4.21", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz", + "integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@next/env": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.2.4.tgz", + "integrity": "sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.4.tgz", + "integrity": "sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.4.tgz", + "integrity": "sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.4.tgz", + "integrity": "sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.4.tgz", + "integrity": "sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.4.tgz", + "integrity": "sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.4.tgz", + "integrity": "sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.4.tgz", + "integrity": "sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.4.tgz", + "integrity": "sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@rollup/plugin-buble": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-buble/-/plugin-buble-1.0.3.tgz", + "integrity": "sha512-QYD9BKkJoof0FdCFeSYYhF6/Y8e0Mnf+098xGgmWOFJ4UPHlWujjqOYeVwEm2hJPOmlR5k7HPUdAjqtOWhN64Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/buble": "^0.19.2", + "buble": "^0.20.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@rollup/plugin-buble/node_modules/buble": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/buble/-/buble-0.20.0.tgz", + "integrity": "sha512-/1gnaMQE8xvd5qsNBl+iTuyjJ9XxeaVxAMF86dQ4EyxFJOZtsgOS8Ra+7WHgZTam5IFDtt4BguN0sH0tVTKrOw==", + "dev": true, + "dependencies": { + "acorn": "^6.4.1", + "acorn-dynamic-import": "^4.0.0", + "acorn-jsx": "^5.2.0", + "chalk": "^2.4.2", + "magic-string": "^0.25.7", + "minimist": "^1.2.5", + "regexpu-core": "4.5.4" + }, + "bin": { + "buble": "bin/buble" + } + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@rollup/plugin-buble/node_modules/regexpu-core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@rollup/plugin-buble/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz", + "integrity": "sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-typescript": { + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", + "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", + "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", + "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", + "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", + "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", + "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", + "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", + "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", + "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", + "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", + "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", + "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", + "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", + "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", + "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", + "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", + "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", + "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", + "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@size-limit/esbuild-why": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/esbuild-why/-/esbuild-why-11.2.0.tgz", + "integrity": "sha512-VtoQbbkvFbF314LWEaEp1+IjG0DH+9w6nP//D6Gd48SEAPLoBgqk287mjYTF9WYxg9N5lo8KjpXxEFk4gOXNpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild-visualizer": "^0.7.0", + "open": "^10.1.0" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "size-limit": "11.2.0" + } + }, + "node_modules/@size-limit/preset-small-lib": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/preset-small-lib/-/preset-small-lib-11.2.0.tgz", + "integrity": "sha512-RFbbIVfv8/QDgTPyXzjo5NKO6CYyK5Uq5xtNLHLbw5RgSKrgo8WpiB/fNivZuNd/5Wk0s91PtaJ9ThNcnFuI3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@size-limit/esbuild": "11.2.0", + "@size-limit/file": "11.2.0", + "size-limit": "11.2.0" + }, + "peerDependencies": { + "size-limit": "11.2.0" + } + }, + "node_modules/@size-limit/preset-small-lib/node_modules/@size-limit/esbuild": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/esbuild/-/esbuild-11.2.0.tgz", + "integrity": "sha512-vSg9H0WxGQPRzDnBzeDyD9XT0Zdq0L+AI3+77/JhxznbSCMJMMr8ndaWVQRhOsixl97N0oD4pRFw2+R1Lcvi6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "nanoid": "^5.1.0" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "size-limit": "11.2.0" + } + }, + "node_modules/@size-limit/preset-small-lib/node_modules/@size-limit/file": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-11.2.0.tgz", + "integrity": "sha512-OZHE3putEkQ/fgzz3Tp/0hSmfVo3wyTpOJSRNm6AmcwX4Nm9YtTfbQQ/hZRwbBFR23S7x2Sd9EbqYzngKwbRoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "size-limit": "11.2.0" + } + }, + "node_modules/@size-limit/preset-small-lib/node_modules/nanoid": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.4.tgz", + "integrity": "sha512-GTFcMIDgR7tqji/LpSY8rtg464VnJl/j6ypoehYnuGb+Y8qZUdtKB8WVCXon0UEZgFDbuUxpIl//6FHLHgXSNA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/buble": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@types/buble/-/buble-0.19.2.tgz", + "integrity": "sha512-uUD8zIfXMKThmFkahTXDGI3CthFH1kMg2dOm3KLi4GlC5cbARA64bEcUMbbWdWdE73eoc/iBB9PiTMqH0dNS2Q==", + "dev": true, + "dependencies": { + "magic-string": "^0.25.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/gensync": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz", + "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "14.17.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz", + "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==", + "dev": true + }, + "node_modules/@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==", + "dev": true + }, + "node_modules/@types/random-seed": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@types/random-seed/-/random-seed-0.3.5.tgz", + "integrity": "sha512-CftxcDPAHgs0SLHU2dt+ZlDPJfGqLW3sZlC/ATr5vJDSe5tRLeOne7HMvCOJnFyF8e1U41wqzs3h6AMC613xtA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz", + "integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz", + "integrity": "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/type-utils": "8.24.0", + "@typescript-eslint/utils": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.0.tgz", + "integrity": "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/typescript-estree": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz", + "integrity": "sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz", + "integrity": "sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.24.0", + "@typescript-eslint/utils": "8.24.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/types": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz", + "integrity": "sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.24.0.tgz", + "integrity": "sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/typescript-estree": "8.24.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.24.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "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==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0" + } + }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.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==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "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/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==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-jest": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz", + "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.6.4", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@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-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "dev": true, + "dependencies": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "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==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "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==", + "dev": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes-iec": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes-iec/-/bytes-iec-3.1.1.tgz", + "integrity": "sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001699", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz", + "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "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/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/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==", + "dev": true, + "license": "MIT", + "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/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "optional": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "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==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/cp-file": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", + "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.10", + "nested-error-stacks": "^2.1.1", + "p-event": "^5.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", + "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^3.0.0", + "cp-file": "^10.0.0", + "globby": "^13.1.4", + "junk": "^4.0.1", + "micromatch": "^4.0.5", + "nested-error-stacks": "^2.1.1", + "p-filter": "^3.0.0", + "p-map": "^6.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", + "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cpy": "^10.1.0", + "meow": "^12.0.1" + }, + "bin": { + "cpy": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.97", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.97.tgz", + "integrity": "sha512-HKLtaH02augM7ZOdYRuO19rWDeY+QSJ1VxnXFa/XDFLf07HvM90pALIJFgrO+UVaajI3+aJMMpojoUTLZyQ7JQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" + } + }, + "node_modules/esbuild-visualizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/esbuild-visualizer/-/esbuild-visualizer-0.7.0.tgz", + "integrity": "sha512-Vz22k+G2WT7GuCo7rbhaQwGbZ26lEhwzsctkEdQlu2SVrshoM4hzQeRpu/3DP596a9+9K2JyYsinuC6AC896Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "open": "^8.4.0", + "picomatch": "^4.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "esbuild-visualizer": "dist/bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild-visualizer/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/esbuild-visualizer/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==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esbuild-visualizer/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/esbuild-visualizer/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "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/esbuild-visualizer/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint": { + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz", + "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.11.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.20.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-typescript/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-jest": { + "version": "28.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.11.0.tgz", + "integrity": "sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "engines": { + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.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-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "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==", + "dev": true, + "license": "BSD-2-Clause", + "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==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "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/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-check": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.0.0.tgz", + "integrity": "sha512-aXLyLemZ7qhLNn2oq+YpjT2Xed21+i29WGAYuyrGbU4r8oinB3i4XR4e62O3NY6qmm5qHEDoc/7d+gMsri3AfA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^7.0.0" + }, + "engines": { + "node": ">=12.17.0" + } + }, + "node_modules/fast-check/node_modules/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "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.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/flow-bin": { + "version": "0.160.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.160.0.tgz", + "integrity": "sha512-hqb/1z7U9Jv+2hDdslAgdab6D4AUDrYIcF2zH/CKx9YgQtCeHfnzCcypzCNU7xmBm2+Mi9+1hqeB4OQX2adh0A==", + "dev": true, + "bin": { + "flow": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "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-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/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==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/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==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/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==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/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==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/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==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "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": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/istanbul-lib-source-maps/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jest": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz", + "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.4", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.6.4" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz", + "integrity": "sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.6.3", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz", + "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.3", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz", + "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz", + "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.4", + "@jest/types": "^29.6.3", + "babel-jest": "^29.6.4", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/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==", + "dev": true, + "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/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz", + "integrity": "sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz", + "integrity": "sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.6.3", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.6.4.tgz", + "integrity": "sha512-K6wfgUJ16DoMs02JYFid9lOsqfpoVtyJxpRlnTxUHzvZWBnnh2VNGRB9EC1Cro96TQdq5TtSjb3qUjNaJP9IyA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-node": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", + "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz", + "integrity": "sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz", + "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz", + "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.6.4" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz", + "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.4", + "@jest/environment": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.6.3", + "jest-environment-node": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-leak-detector": "^29.6.3", + "jest-message-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-util": "^29.6.3", + "jest-watcher": "^29.6.4", + "jest-worker": "^29.6.4", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz", + "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/globals": "^29.6.4", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-mock": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz", + "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz", + "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsdom/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonml-html": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsonml-html/-/jsonml-html-1.2.0.tgz", + "integrity": "sha512-vg30gQFD5X+1nY3do43BW9Iiq4F5BZcysXc+ydPNu7O5AxaqxnaI9ikjTjlE9y9KaAvgTwTP6nOpifDqDoYmjg==", + "dev": true, + "license": "ISC" + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/make-synchronous": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/make-synchronous/-/make-synchronous-0.1.1.tgz", + "integrity": "sha512-Y4SxxqhaoyMDokJQ0AZz0E+bLhRkOSR7Z/IQoTKPdS6HYi3aobal2kMHoHHoqBadPWjf07P4K1FQLXOx3wf9Yw==", + "dev": true, + "dependencies": { + "subsume": "^3.0.0", + "type-fest": "^0.16.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-synchronous/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marked": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-11.2.0.tgz", + "integrity": "sha512-HR0m3bvu0jAPYiIvLUUQtdg1g6D247//lvcekpHO1WMvbwDlwSkZAX9Lw4F4YHE1T0HaaNve0tuAWuV1UJ6vtw==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-highlight": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.1.0.tgz", + "integrity": "sha512-peBvgGZZqUw074Vy/N8Y7/6JQhSnR54/T0Ozq2/fAIBzcYfVfExFdQJptIhQxreR1elpwvJRrqhp6S/Prk8prA==", + "dev": true, + "peerDependencies": { + "marked": ">=4 <12" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/microtime": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/microtime/-/microtime-3.1.1.tgz", + "integrity": "sha512-to1r7o24cDsud9IhN6/8wGmMx5R2kT0w2Xwm5okbYI3d1dk6Xv0m+Z+jg2vS9pt+ocgQHTCtgs/YuyJhySzxNg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.4.0" + }, + "engines": { + "node": ">= 14.13.0" + } + }, + "node_modules/mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dev": true, + "dependencies": { + "mime-db": "1.49.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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/nanoid": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", + "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanospinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.2.2.tgz", + "integrity": "sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nested-error-stacks": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", + "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/next/-/next-15.2.4.tgz", + "integrity": "sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/env": "15.2.4", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.2.4", + "@next/swc-darwin-x64": "15.2.4", + "@next/swc-linux-arm64-gnu": "15.2.4", + "@next/swc-linux-arm64-musl": "15.2.4", + "@next/swc-linux-x64-gnu": "15.2.4", + "@next/swc-linux-x64-musl": "15.2.4", + "@next/swc-win32-arm64-msvc": "15.2.4", + "@next/swc-win32-x64-msvc": "15.2.4", + "sharp": "^0.33.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-sitemap": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-4.2.3.tgz", + "integrity": "sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==", + "dev": true, + "funding": [ + { + "url": "https://github.com/iamvishnusankar/next-sitemap.git" + } + ], + "dependencies": { + "@corex/deepmerge": "^4.0.43", + "@next/env": "^13.4.3", + "fast-glob": "^3.2.12", + "minimist": "^1.2.8" + }, + "bin": { + "next-sitemap": "bin/next-sitemap.mjs", + "next-sitemap-cjs": "bin/next-sitemap.cjs" + }, + "engines": { + "node": ">=14.18" + }, + "peerDependencies": { + "next": "*" + } + }, + "node_modules/next-sitemap/node_modules/@next/env": { + "version": "13.5.8", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.8.tgz", + "integrity": "sha512-YmiG58BqyZ2FjrF2+5uZExL2BrLr8RTQzLXNDJ8pJr0O+rPlOeDPXp1p1/4OrR3avDidzZo3D8QO2cuDv1KCkw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "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==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "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/npm-run-all/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "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==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "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.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-timeout": "^5.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^5.1.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", + "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "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==", + "dev": true, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "dev": true + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.0.tgz", + "integrity": "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "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==", + "dev": true, + "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/random-seed": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/random-seed/-/random-seed-0.3.0.tgz", + "integrity": "sha512-y13xtn3kcTlLub3HKWXxJNeC2qK4mB59evwZ5EkeRlolx+Bp2ztF7LbcZmyCnOqlHQrLnfuNbi1sVmm9lPDlDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-stringify-safe": "^5.0.1" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.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==", + "dev": true, + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "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/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", + "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.34.8", + "@rollup/rollup-android-arm64": "4.34.8", + "@rollup/rollup-darwin-arm64": "4.34.8", + "@rollup/rollup-darwin-x64": "4.34.8", + "@rollup/rollup-freebsd-arm64": "4.34.8", + "@rollup/rollup-freebsd-x64": "4.34.8", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", + "@rollup/rollup-linux-arm-musleabihf": "4.34.8", + "@rollup/rollup-linux-arm64-gnu": "4.34.8", + "@rollup/rollup-linux-arm64-musl": "4.34.8", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", + "@rollup/rollup-linux-riscv64-gnu": "4.34.8", + "@rollup/rollup-linux-s390x-gnu": "4.34.8", + "@rollup/rollup-linux-x64-gnu": "4.34.8", + "@rollup/rollup-linux-x64-musl": "4.34.8", + "@rollup/rollup-win32-arm64-msvc": "4.34.8", + "@rollup/rollup-win32-ia32-msvc": "4.34.8", + "@rollup/rollup-win32-x64-msvc": "4.34.8", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "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/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "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==", + "dev": true, + "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-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.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==", + "dev": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT", + "optional": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/size-limit": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-11.2.0.tgz", + "integrity": "sha512-2kpQq2DD/pRpx3Tal/qRW1SYwcIeQ0iq8li5CJHQgOC+FtPn2BVmuDtzUCgNnpCrbgtfEHqh+iWzxK+Tq6C+RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes-iec": "^3.1.1", + "chokidar": "^4.0.3", + "jiti": "^2.4.2", + "lilconfig": "^3.1.3", + "nanospinner": "^1.2.2", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.11" + }, + "bin": { + "size-limit": "bin.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/smob": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz", + "integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==", + "dev": true + }, + "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==", + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz", + "integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "dev": true, + "license": "MIT" + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/subsume": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/subsume/-/subsume-3.0.0.tgz", + "integrity": "sha512-6n/UfV8UWKwJNO8OAOiKntwEMihuBeeoJfzpL542C+OuvT4iWG9SwjrXkOmsxjb4SteHUsos9SvrdqZ9+ICwTQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/subsume/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/transducers-js": { + "version": "0.4.174", + "resolved": "https://registry.npmjs.org/transducers-js/-/transducers-js-0.4.174.tgz", + "integrity": "sha1-1YYsEO/0vj0zIqv2u3QuMPG7b8Q=", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tstyche": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-3.5.0.tgz", + "integrity": "sha512-N4SUp/ZWaMGEcglpVFIzKez0GQEiBdfFDgcnqwv9O1mePZgos8N1cZCzNgGtPGo/w0ym04MjJcDnsw1sorEzgA==", + "dev": true, + "license": "MIT", + "bin": { + "tstyche": "build/bin.js" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/tstyche/tstyche?sponsor=1" + }, + "peerDependencies": { + "typescript": "4.x || 5.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.24.0.tgz", + "integrity": "sha512-/lmv4366en/qbB32Vz5+kCNZEMf6xYHwh1z48suBwZvAtnXKbP+YhGe8OLE2BqC67LMqKkCNLtjejdwsdW6uOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", + "@typescript-eslint/utils": "8.24.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true + }, + "@babel/core": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz", + "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.7", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/traverse": "^7.26.8", + "@babel/types": "^7.26.8", + "@types/gensync": "^1.0.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", + "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", + "dev": true, + "requires": { + "@babel/parser": "^7.26.8", + "@babel/types": "^7.26.8", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + } + }, + "@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true + }, + "@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", + "dev": true, + "requires": { + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" + } + }, + "@babel/parser": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", + "dev": true, + "requires": { + "@babel/types": "^7.26.10" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/template": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" + } + }, + "@babel/traverse": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", + "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.8", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/types": "^7.26.8", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@codemirror/autocomplete": { + "version": "6.18.6", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", + "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "dev": true, + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "@codemirror/commands": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", + "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "dev": true, + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "@codemirror/lang-javascript": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz", + "integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==", + "dev": true, + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "@codemirror/language": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", + "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "dev": true, + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "@codemirror/lint": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", + "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "dev": true, + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/search": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz", + "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "dev": true, + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/state": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", + "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "dev": true, + "requires": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "@codemirror/theme-one-dark": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dev": true, + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "@codemirror/view": { + "version": "6.36.5", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.5.tgz", + "integrity": "sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==", + "dev": true, + "requires": { + "@codemirror/state": "^6.5.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "@corex/deepmerge": { + "version": "4.0.43", + "resolved": "https://registry.npmjs.org/@corex/deepmerge/-/deepmerge-4.0.43.tgz", + "integrity": "sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@emnapi/runtime": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz", + "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==", + "dev": true, + "optional": true, + "requires": { + "tslib": "^2.4.0" + } + }, + "@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "dev": true, + "optional": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.4.3" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + } + } + }, + "@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true + }, + "@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "requires": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.15" + } + }, + "@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "@eslint/js": { + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", + "dev": true + }, + "@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true + }, + "@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "requires": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "dependencies": { + "@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.15" + } + } + } + }, + "@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true + }, + "@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "requires": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "dependencies": { + "@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true + } + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true + }, + "@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "dev": true, + "optional": true + }, + "@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "dev": true, + "optional": true + }, + "@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "dev": true, + "optional": true, + "requires": { + "@emnapi/runtime": "^1.2.0" + } + }, + "@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "dev": true, + "optional": true + }, + "@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "dev": true, + "optional": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jdeniau/immutable-devtools": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@jdeniau/immutable-devtools/-/immutable-devtools-0.2.0.tgz", + "integrity": "sha512-kncZLhyszWkGz0wAr8eoHFvhczuZz5Ud71OiLIhe5PFQ05nnLgsFdr520Qy+eHhMSL6roJYFrZ73ZJTv48/fUg==", + "dev": true + }, + "@jest/console": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz", + "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz", + "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==", + "dev": true, + "requires": { + "@jest/console": "^29.6.4", + "@jest/reporters": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.6.3", + "jest-config": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-resolve-dependencies": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "jest-watcher": "^29.6.4", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + } + }, + "@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "requires": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + } + }, + "@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "requires": { + "jest-get-type": "^29.6.3" + } + }, + "@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + } + }, + "@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + } + }, + "@jest/reporters": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz", + "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "jest-worker": "^29.6.4", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "dependencies": { + "istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "requires": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + } + }, + "semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true + } + } + }, + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz", + "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==", + "dev": true, + "requires": { + "@jest/console": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz", + "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==", + "dev": true, + "requires": { + "@jest/test-result": "^29.6.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@lezer/common": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "dev": true + }, + "@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "dev": true, + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@lezer/javascript": { + "version": "1.4.21", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz", + "integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==", + "dev": true, + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dev": true, + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@marijn/find-cluster-break": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", + "dev": true + }, + "@next/env": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.2.4.tgz", + "integrity": "sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==", + "dev": true + }, + "@next/swc-darwin-arm64": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.4.tgz", + "integrity": "sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==", + "dev": true, + "optional": true + }, + "@next/swc-darwin-x64": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.4.tgz", + "integrity": "sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==", + "dev": true, + "optional": true + }, + "@next/swc-linux-arm64-gnu": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.4.tgz", + "integrity": "sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==", + "dev": true, + "optional": true + }, + "@next/swc-linux-arm64-musl": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.4.tgz", + "integrity": "sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==", + "dev": true, + "optional": true + }, + "@next/swc-linux-x64-gnu": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.4.tgz", + "integrity": "sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==", + "dev": true, + "optional": true + }, + "@next/swc-linux-x64-musl": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.4.tgz", + "integrity": "sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==", + "dev": true, + "optional": true + }, + "@next/swc-win32-arm64-msvc": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.4.tgz", + "integrity": "sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==", + "dev": true, + "optional": true + }, + "@next/swc-win32-x64-msvc": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.4.tgz", + "integrity": "sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==", + "dev": true, + "optional": true + }, + "@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==", + "dev": true, + "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==", + "dev": true + }, + "@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==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true + }, + "@rollup/plugin-buble": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-buble/-/plugin-buble-1.0.3.tgz", + "integrity": "sha512-QYD9BKkJoof0FdCFeSYYhF6/Y8e0Mnf+098xGgmWOFJ4UPHlWujjqOYeVwEm2hJPOmlR5k7HPUdAjqtOWhN64Q==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "@types/buble": "^0.19.2", + "buble": "^0.20.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==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "buble": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/buble/-/buble-0.20.0.tgz", + "integrity": "sha512-/1gnaMQE8xvd5qsNBl+iTuyjJ9XxeaVxAMF86dQ4EyxFJOZtsgOS8Ra+7WHgZTam5IFDtt4BguN0sH0tVTKrOw==", + "dev": true, + "requires": { + "acorn": "^6.4.1", + "acorn-dynamic-import": "^4.0.0", + "acorn-jsx": "^5.2.0", + "chalk": "^2.4.2", + "magic-string": "^0.25.7", + "minimist": "^1.2.5", + "regexpu-core": "4.5.4" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "regexpu-core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.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==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@rollup/plugin-commonjs": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz", + "integrity": "sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "dependencies": { + "fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "requires": {} + }, + "magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true + } + } + }, + "@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.1.0" + } + }, + "@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "requires": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + } + }, + "@rollup/plugin-typescript": { + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", + "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + } + }, + "@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "dependencies": { + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true + } + } + }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", + "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", + "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", + "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", + "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", + "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", + "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", + "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", + "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", + "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", + "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", + "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", + "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", + "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", + "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", + "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", + "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", + "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", + "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", + "dev": true, + "optional": true + }, + "@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + }, + "@size-limit/esbuild-why": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/esbuild-why/-/esbuild-why-11.2.0.tgz", + "integrity": "sha512-VtoQbbkvFbF314LWEaEp1+IjG0DH+9w6nP//D6Gd48SEAPLoBgqk287mjYTF9WYxg9N5lo8KjpXxEFk4gOXNpw==", + "dev": true, + "requires": { + "esbuild-visualizer": "^0.7.0", + "open": "^10.1.0" + } + }, + "@size-limit/preset-small-lib": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/preset-small-lib/-/preset-small-lib-11.2.0.tgz", + "integrity": "sha512-RFbbIVfv8/QDgTPyXzjo5NKO6CYyK5Uq5xtNLHLbw5RgSKrgo8WpiB/fNivZuNd/5Wk0s91PtaJ9ThNcnFuI3g==", + "dev": true, + "requires": { + "@size-limit/esbuild": "11.2.0", + "@size-limit/file": "11.2.0", + "size-limit": "11.2.0" + }, + "dependencies": { + "@size-limit/esbuild": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/esbuild/-/esbuild-11.2.0.tgz", + "integrity": "sha512-vSg9H0WxGQPRzDnBzeDyD9XT0Zdq0L+AI3+77/JhxznbSCMJMMr8ndaWVQRhOsixl97N0oD4pRFw2+R1Lcvi6A==", + "dev": true, + "requires": { + "esbuild": "^0.25.0", + "nanoid": "^5.1.0" + } + }, + "@size-limit/file": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-11.2.0.tgz", + "integrity": "sha512-OZHE3putEkQ/fgzz3Tp/0hSmfVo3wyTpOJSRNm6AmcwX4Nm9YtTfbQQ/hZRwbBFR23S7x2Sd9EbqYzngKwbRoA==", + "dev": true, + "requires": {} + }, + "nanoid": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.4.tgz", + "integrity": "sha512-GTFcMIDgR7tqji/LpSY8rtg464VnJl/j6ypoehYnuGb+Y8qZUdtKB8WVCXon0UEZgFDbuUxpIl//6FHLHgXSNA==", + "dev": true + } + } + }, + "@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true + }, + "@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "requires": { + "tslib": "^2.8.0" + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7" + } + }, + "@types/buble": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@types/buble/-/buble-0.19.2.tgz", + "integrity": "sha512-uUD8zIfXMKThmFkahTXDGI3CthFH1kMg2dOm3KLi4GlC5cbARA64bEcUMbbWdWdE73eoc/iBB9PiTMqH0dNS2Q==", + "dev": true, + "requires": { + "magic-string": "^0.25.0" + } + }, + "@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "@types/gensync": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz", + "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "@types/node": { + "version": "14.17.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz", + "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==", + "dev": true + }, + "@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==", + "dev": true + }, + "@types/random-seed": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@types/random-seed/-/random-seed-0.3.5.tgz", + "integrity": "sha512-CftxcDPAHgs0SLHU2dt+ZlDPJfGqLW3sZlC/ATr5vJDSe5tRLeOne7HMvCOJnFyF8e1U41wqzs3h6AMC613xtA==", + "dev": true + }, + "@types/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz", + "integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==", + "dev": true, + "requires": { + "csstype": "^3.0.2" + } + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz", + "integrity": "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/type-utils": "8.24.0", + "@typescript-eslint/utils": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + } + }, + "@typescript-eslint/parser": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.0.tgz", + "integrity": "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/typescript-estree": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", + "debug": "^4.3.4" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz", + "integrity": "sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz", + "integrity": "sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "8.24.0", + "@typescript-eslint/utils": "8.24.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "@typescript-eslint/types": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz", + "integrity": "sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true + } + } + }, + "@typescript-eslint/utils": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.24.0.tgz", + "integrity": "sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/typescript-estree": "8.24.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.24.0", + "eslint-visitor-keys": "^4.2.0" + } + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true, + "requires": {} + }, + "acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "requires": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + }, + "dependencies": { + "acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true + } + } + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "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==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "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" + } + }, + "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==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + } + }, + "array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + } + }, + "array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + } + }, + "array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + } + }, + "array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + } + }, + "arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true + }, + "async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "babel-jest": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz", + "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==", + "dev": true, + "requires": { + "@jest/transform": "^29.6.4", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@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-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "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==", + "dev": true + }, + "bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "requires": { + "run-applescript": "^7.0.0" + } + }, + "busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "requires": { + "streamsearch": "^1.1.0" + } + }, + "bytes-iec": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes-iec/-/bytes-iec-3.1.1.tgz", + "integrity": "sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==", + "dev": true + }, + "call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + } + }, + "call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, + "call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001699", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz", + "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "requires": { + "readdirp": "^4.0.1" + } + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "requires": { + "escape-string-regexp": "5.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true + } + } + }, + "client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.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==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dev": true, + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "optional": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "optional": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "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==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "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==", + "dev": true + }, + "cp-file": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", + "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.10", + "nested-error-stacks": "^2.1.1", + "p-event": "^5.0.1" + } + }, + "cpy": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", + "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", + "dev": true, + "requires": { + "arrify": "^3.0.0", + "cp-file": "^10.0.0", + "globby": "^13.1.4", + "junk": "^4.0.1", + "micromatch": "^4.0.5", + "nested-error-stacks": "^2.1.1", + "p-filter": "^3.0.0", + "p-map": "^6.0.0" + }, + "dependencies": { + "globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } + } + }, + "cpy-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", + "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", + "dev": true, + "requires": { + "cpy": "^10.1.0", + "meow": "^12.0.1" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "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==", + "dev": true + }, + "cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, + "data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + } + }, + "data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + } + }, + "data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "requires": {} + }, + "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==", + "dev": true + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "requires": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + } + }, + "default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "optional": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, + "electron-to-chromium": { + "version": "1.5.97", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.97.tgz", + "integrity": "sha512-HKLtaH02augM7ZOdYRuO19rWDeY+QSJ1VxnXFa/XDFLf07HvM90pALIJFgrO+UVaajI3+aJMMpojoUTLZyQ7JQ==", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + } + }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + } + }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "requires": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + } + }, + "esbuild": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" + } + }, + "esbuild-visualizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/esbuild-visualizer/-/esbuild-visualizer-0.7.0.tgz", + "integrity": "sha512-Vz22k+G2WT7GuCo7rbhaQwGbZ26lEhwzsctkEdQlu2SVrshoM4hzQeRpu/3DP596a9+9K2JyYsinuC6AC896Og==", + "dev": true, + "requires": { + "open": "^8.4.0", + "picomatch": "^4.0.0", + "yargs": "^17.6.2" + }, + "dependencies": { + "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==", + "dev": true + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true + } + } + }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true + }, + "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==", + "dev": true + }, + "escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "source-map": "~0.6.1" + } + }, + "eslint": { + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz", + "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.11.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.20.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "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==", + "dev": true + } + } + }, + "eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "requires": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "requires": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "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==", + "dev": true + } + } + }, + "eslint-plugin-jest": { + "version": "28.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.11.0.tgz", + "integrity": "sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", + "dev": true, + "requires": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "dependencies": { + "resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + } + } + }, + "eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true + }, + "espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "requires": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "dependencies": { + "acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "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" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true + }, + "expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + } + }, + "fast-check": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.0.0.tgz", + "integrity": "sha512-aXLyLemZ7qhLNn2oq+YpjT2Xed21+i29WGAYuyrGbU4r8oinB3i4XR4e62O3NY6qmm5qHEDoc/7d+gMsri3AfA==", + "dev": true, + "requires": { + "pure-rand": "^7.0.0" + }, + "dependencies": { + "pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "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.8" + } + }, + "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==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "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==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "requires": { + "flat-cache": "^4.0.0" + } + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + } + }, + "flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true + }, + "flow-bin": { + "version": "0.160.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.160.0.tgz", + "integrity": "sha512-hqb/1z7U9Jv+2hDdslAgdab6D4AUDrYIcF2zH/CKx9YgQtCeHfnzCcypzCNU7xmBm2+Mi9+1hqeB4OQX2adh0A==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + } + }, + "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==", + "dev": true + }, + "get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + } + }, + "get-tsconfig": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true + }, + "globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "requires": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + } + }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "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==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "requires": { + "dunder-proto": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true + }, + "import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "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==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + } + }, + "is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "requires": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + } + }, + "is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "requires": { + "has-bigints": "^1.0.2" + } + }, + "is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + } + }, + "is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "requires": { + "semver": "^7.6.3" + }, + "dependencies": { + "semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + } + }, + "is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + } + }, + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "requires": { + "call-bound": "^1.0.3" + } + }, + "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==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + } + }, + "is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, + "is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true + }, + "is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "requires": { + "call-bound": "^1.0.3" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + } + }, + "is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + } + }, + "is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.16" + } + }, + "is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true + }, + "is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "requires": { + "call-bound": "^1.0.3" + } + }, + "is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + } + }, + "is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "requires": { + "is-inside-container": "^1.0.0" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" + } + }, + "semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + } + }, + "jest": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz", + "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==", + "dev": true, + "requires": { + "@jest/core": "^29.6.4", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.6.4" + } + }, + "jest-changed-files": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz", + "integrity": "sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "jest-util": "^29.6.3", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz", + "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.3", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-cli": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz", + "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==", + "dev": true, + "requires": { + "@jest/core": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz", + "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.4", + "@jest/types": "^29.6.3", + "babel-jest": "^29.6.4", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "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==", + "dev": true, + "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" + } + } + } + }, + "jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + } + }, + "jest-docblock": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz", + "integrity": "sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz", + "integrity": "sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.6.3", + "pretty-format": "^29.6.3" + } + }, + "jest-environment-jsdom": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.6.4.tgz", + "integrity": "sha512-K6wfgUJ16DoMs02JYFid9lOsqfpoVtyJxpRlnTxUHzvZWBnnh2VNGRB9EC1Cro96TQdq5TtSjb3qUjNaJP9IyA==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3", + "jsdom": "^20.0.0" + } + }, + "jest-environment-node": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", + "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3" + } + }, + "jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-leak-detector": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz", + "integrity": "sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==", + "dev": true, + "requires": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" + } + }, + "jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + } + }, + "jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-resolve": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz", + "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz", + "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==", + "dev": true, + "requires": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.6.4" + } + }, + "jest-runner": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz", + "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==", + "dev": true, + "requires": { + "@jest/console": "^29.6.4", + "@jest/environment": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.6.3", + "jest-environment-node": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-leak-detector": "^29.6.3", + "jest-message-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-util": "^29.6.3", + "jest-watcher": "^29.6.4", + "jest-worker": "^29.6.4", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "dependencies": { + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "jest-runtime": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz", + "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/globals": "^29.6.4", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-mock": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "dependencies": { + "semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true + } + } + }, + "jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz", + "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.3" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz", + "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==", + "dev": true, + "requires": { + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.3", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + } + } + }, + "jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "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==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "jsonml-html": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsonml-html/-/jsonml-html-1.2.0.tgz", + "integrity": "sha512-vg30gQFD5X+1nY3do43BW9Iiq4F5BZcysXc+ydPNu7O5AxaqxnaI9ikjTjlE9y9KaAvgTwTP6nOpifDqDoYmjg==", + "dev": true + }, + "jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + } + }, + "junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", + "dev": true + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "make-synchronous": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/make-synchronous/-/make-synchronous-0.1.1.tgz", + "integrity": "sha512-Y4SxxqhaoyMDokJQ0AZz0E+bLhRkOSR7Z/IQoTKPdS6HYi3aobal2kMHoHHoqBadPWjf07P4K1FQLXOx3wf9Yw==", + "dev": true, + "requires": { + "subsume": "^3.0.0", + "type-fest": "^0.16.0" + }, + "dependencies": { + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true + } + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "marked": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-11.2.0.tgz", + "integrity": "sha512-HR0m3bvu0jAPYiIvLUUQtdg1g6D247//lvcekpHO1WMvbwDlwSkZAX9Lw4F4YHE1T0HaaNve0tuAWuV1UJ6vtw==", + "dev": true + }, + "marked-highlight": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.1.0.tgz", + "integrity": "sha512-peBvgGZZqUw074Vy/N8Y7/6JQhSnR54/T0Ozq2/fAIBzcYfVfExFdQJptIhQxreR1elpwvJRrqhp6S/Prk8prA==", + "dev": true, + "requires": {} + }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + }, + "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==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "requires": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + } + }, + "microtime": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/microtime/-/microtime-3.1.1.tgz", + "integrity": "sha512-to1r7o24cDsud9IhN6/8wGmMx5R2kT0w2Xwm5okbYI3d1dk6Xv0m+Z+jg2vS9pt+ocgQHTCtgs/YuyJhySzxNg==", + "dev": true, + "requires": { + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.4.0" + } + }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "dev": true + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dev": true, + "requires": { + "mime-db": "1.49.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "nanoid": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", + "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", + "dev": true + }, + "nanospinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.2.2.tgz", + "integrity": "sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==", + "dev": true, + "requires": { + "picocolors": "^1.1.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nested-error-stacks": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", + "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", + "dev": true + }, + "next": { + "version": "15.2.4", + "resolved": "https://registry.npmjs.org/next/-/next-15.2.4.tgz", + "integrity": "sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==", + "dev": true, + "requires": { + "@next/env": "15.2.4", + "@next/swc-darwin-arm64": "15.2.4", + "@next/swc-darwin-x64": "15.2.4", + "@next/swc-linux-arm64-gnu": "15.2.4", + "@next/swc-linux-arm64-musl": "15.2.4", + "@next/swc-linux-x64-gnu": "15.2.4", + "@next/swc-linux-x64-musl": "15.2.4", + "@next/swc-win32-arm64-msvc": "15.2.4", + "@next/swc-win32-x64-msvc": "15.2.4", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "sharp": "^0.33.5", + "styled-jsx": "5.1.6" + } + }, + "next-sitemap": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-4.2.3.tgz", + "integrity": "sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==", + "dev": true, + "requires": { + "@corex/deepmerge": "^4.0.43", + "@next/env": "^13.4.3", + "fast-glob": "^3.2.12", + "minimist": "^1.2.8" + }, + "dependencies": { + "@next/env": { + "version": "13.5.8", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.8.tgz", + "integrity": "sha512-YmiG58BqyZ2FjrF2+5uZExL2BrLr8RTQzLXNDJ8pJr0O+rPlOeDPXp1p1/4OrR3avDidzZo3D8QO2cuDv1KCkw==", + "dev": true + } + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true + }, + "node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "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==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true + }, + "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==", + "dev": true + }, + "object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + } + }, + "object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + } + }, + "object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "requires": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + } + }, + "optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "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.5" + } + }, + "own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + } + }, + "p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "requires": { + "p-timeout": "^5.0.2" + } + }, + "p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "requires": { + "p-map": "^5.1.0" + }, + "dependencies": { + "p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "requires": { + "aggregate-error": "^4.0.0" + } + } + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "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==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", + "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", + "dev": true + }, + "p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "requires": { + "entities": "^4.4.0" + } + }, + "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==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "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==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + }, + "pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true + }, + "platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "dev": true + }, + "possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true + }, + "postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.0.tgz", + "integrity": "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA==", + "dev": true + }, + "pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + } + } + }, + "prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "dev": true + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "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==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "random-seed": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/random-seed/-/random-seed-0.3.0.tgz", + "integrity": "sha512-y13xtn3kcTlLub3HKWXxJNeC2qK4mB59evwZ5EkeRlolx+Bp2ztF7LbcZmyCnOqlHQrLnfuNbi1sVmm9lPDlDA==", + "dev": true, + "requires": { + "json-stringify-safe": "^5.0.1" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "dev": true + }, + "react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "dev": true, + "requires": { + "scheduler": "^0.26.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==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + } + } + }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true + }, + "reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "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 + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "requires": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, + "resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", + "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.34.8", + "@rollup/rollup-android-arm64": "4.34.8", + "@rollup/rollup-darwin-arm64": "4.34.8", + "@rollup/rollup-darwin-x64": "4.34.8", + "@rollup/rollup-freebsd-arm64": "4.34.8", + "@rollup/rollup-freebsd-x64": "4.34.8", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", + "@rollup/rollup-linux-arm-musleabihf": "4.34.8", + "@rollup/rollup-linux-arm64-gnu": "4.34.8", + "@rollup/rollup-linux-arm64-musl": "4.34.8", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", + "@rollup/rollup-linux-riscv64-gnu": "4.34.8", + "@rollup/rollup-linux-s390x-gnu": "4.34.8", + "@rollup/rollup-linux-x64-gnu": "4.34.8", + "@rollup/rollup-linux-x64-musl": "4.34.8", + "@rollup/rollup-win32-arm64-msvc": "4.34.8", + "@rollup/rollup-win32-ia32-msvc": "4.34.8", + "@rollup/rollup-win32-x64-msvc": "4.34.8", + "@types/estree": "1.0.6", + "fsevents": "~2.3.2" + } + }, + "run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, + "safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "dev": true + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + } + }, + "set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "requires": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + } + }, + "sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "optional": true, + "requires": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5", + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "dependencies": { + "semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "optional": true + } + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true + }, + "side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + } + }, + "side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + } + }, + "side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + } + }, + "side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "optional": true, + "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==", + "dev": true, + "optional": true + } + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "size-limit": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-11.2.0.tgz", + "integrity": "sha512-2kpQq2DD/pRpx3Tal/qRW1SYwcIeQ0iq8li5CJHQgOC+FtPn2BVmuDtzUCgNnpCrbgtfEHqh+iWzxK+Tq6C+RQ==", + "dev": true, + "requires": { + "bytes-iec": "^3.1.1", + "chokidar": "^4.0.3", + "jiti": "^2.4.2", + "lilconfig": "^3.1.3", + "nanospinner": "^1.2.2", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.11" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "smob": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz", + "integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.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==", + "dev": true + } + } + }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + } + }, + "string.prototype.padend": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz", + "integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.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==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "dev": true + }, + "styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "dev": true, + "requires": { + "client-only": "0.0.1" + } + }, + "subsume": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/subsume/-/subsume-3.0.0.tgz", + "integrity": "sha512-6n/UfV8UWKwJNO8OAOiKntwEMihuBeeoJfzpL542C+OuvT4iWG9SwjrXkOmsxjb4SteHUsos9SvrdqZ9+ICwTQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0", + "unique-string": "^2.0.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==", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "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==", + "dev": true + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser": { + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "tinyglobby": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "dev": true, + "requires": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "dependencies": { + "fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true + } + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "transducers-js": { + "version": "0.4.174", + "resolved": "https://registry.npmjs.org/transducers-js/-/transducers-js-0.4.174.tgz", + "integrity": "sha1-1YYsEO/0vj0zIqv2u3QuMPG7b8Q=", + "dev": true + }, + "ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "requires": {} + }, + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "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==", + "dev": true, + "requires": { + "minimist": "^1.2.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==", + "dev": true + } + } + }, + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, + "tstyche": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-3.5.0.tgz", + "integrity": "sha512-N4SUp/ZWaMGEcglpVFIzKez0GQEiBdfFDgcnqwv9O1mePZgos8N1cZCzNgGtPGo/w0ym04MjJcDnsw1sorEzgA==", + "dev": true, + "requires": {} + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + } + }, + "typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "requires": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + } + }, + "typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + } + }, + "typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + } + }, + "typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true + }, + "typescript-eslint": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.24.0.tgz", + "integrity": "sha512-/lmv4366en/qbB32Vz5+kCNZEMf6xYHwh1z48suBwZvAtnXKbP+YhGe8OLE2BqC67LMqKkCNLtjejdwsdW6uOQ==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", + "@typescript-eslint/utils": "8.24.0" + } + }, + "unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "requires": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "dev": true + }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "requires": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + } + }, + "which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, + "which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "requires": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + } + }, + "which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + } + }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "dev": true, + "requires": {} + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "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==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 8a9c8ac276..e773736d96 100644 --- a/package.json +++ b/package.json @@ -1,53 +1,27 @@ { "name": "immutable", - "version": "2.2.2", + "version": "5.1.2", "description": "Immutable Data Collections", - "homepage": "https://github.com/facebook/immutable-js", + "license": "MIT", + "homepage": "https://immutable-js.com", "author": { "name": "Lee Byron", "url": "https://github.com/leebyron" }, "repository": { "type": "git", - "url": "git://github.com/facebook/immutable-js.git" + "url": "git://github.com/immutable-js/immutable-js.git" }, "bugs": { - "url": "https://github.com/facebook/immutable-js/issues" - }, - "main": "dist/Immutable.js", - "scripts": { - "test": "jest" - }, - "jest": { - "scriptPreprocessor": "resources/jestPreprocessor.js", - "testFileExtensions": [ - "js", - "ts" - ], - "persistModuleRegistryBetweenSpecs": true - }, - "devDependencies": { - "grunt": "^0.4.5", - "grunt-contrib-copy": "^0.5.0", - "grunt-contrib-jshint": "^0.10.0", - "grunt-contrib-clean": "^0.5.0", - "grunt-jest": "^0.1.0", - "react-tools": "^0.11.1", - "ts-compiler": "^2.0.0", - "grunt-release": "^0.7.0", - "traceur": "0.0.55", - "smash": "0.0.12", - "uglify-js": "^2.4.15", - "jasmine-check": "^0.1.2" - }, - "engines": { - "node": ">=0.8.0" + "url": "https://github.com/immutable-js/immutable-js/issues" }, + "main": "dist/immutable.js", + "module": "dist/immutable.es.js", + "types": "dist/immutable.d.ts", "files": [ "dist", "README.md", - "LICENSE", - "PATENTS" + "LICENSE" ], "keywords": [ "immutable", @@ -61,5 +35,127 @@ "sequence", "iteration" ], - "license": "BSD" + "publishKeys": [ + "name", + "version", + "description", + "license", + "homepage", + "author", + "repository", + "bugs", + "main", + "module", + "sideEffects", + "types", + "files", + "keywords" + ], + "engines": { + "npm": ">=7.0.0" + }, + "scripts": { + "test": "run-s format lint type-check build test:*", + "test:unit": "jest", + "test:types": "tstyche", + "format": "npm run lint:format -- --write", + "lint": "run-s lint:*", + "lint:format": "prettier --check \"{__tests__,src,type-definitions,website/src,perf,resources}/**/*{.js,.mjs,.ts,.tsx,.flow,.css}\"", + "lint:js": "eslint", + "type-check": "run-s type-check:*", + "type-check:ts": "tsc --project tsconfig.src.json && tsc --project type-definitions/tsconfig.json && tsc --project __tests__/tsconfig.json", + "type-check:flow": "flow check type-definitions/flow-tests --include-warnings", + "build": "run-s build:*", + "build:clean": "rimraf dist", + "build:dist": "rollup -c ./resources/rollup-config.mjs", + "build:types": "cpy \"./type-definitions/immutable.*\" dist", + "build:prepare": "./resources/prepare-dist.sh", + "build:stats": "node ./resources/dist-stats.mjs", + "website:build": "cd website && next build && next-sitemap", + "website:dev": "cd website && next dev --turbopack", + "check-build-output": "node ./resources/check-build-output.mjs", + "check-git-clean": "./resources/check-git-clean.sh", + "benchmark": "node ./resources/benchmark.js", + "publish": "echo 'ONLY PUBLISH VIA CI'; exit 1;" + }, + "prettier": { + "singleQuote": true, + "trailingComma": "es5" + }, + "devDependencies": { + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-javascript": "^6.2.3", + "@codemirror/state": "^6.5.2", + "@codemirror/theme-one-dark": "^6.1.2", + "@codemirror/view": "^6.36.5", + "@eslint/js": "^9.20.0", + "@jdeniau/immutable-devtools": "^0.2.0", + "@jest/globals": "^29.7.0", + "@rollup/plugin-buble": "1.0.3", + "@rollup/plugin-commonjs": "28.0.2", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^12.1.2", + "@size-limit/esbuild-why": "^11.2.0", + "@size-limit/preset-small-lib": "^11.2.0", + "@types/prismjs": "^1.26.3", + "@types/random-seed": "0.3.5", + "@types/react": "19.1.0", + "benchmark": "2.1.4", + "codemirror": "^6.0.1", + "colors": "1.4.0", + "cpy-cli": "^5.0.0", + "eslint": "^9.20.1", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^28.11.0", + "eslint-plugin-react": "^7.37.4", + "fast-check": "^4.0.0", + "flow-bin": "0.160.0", + "globals": "^15.15.0", + "jest": "^29.0.0", + "jest-environment-jsdom": "^29.6.4", + "jsonml-html": "^1.2.0", + "make-synchronous": "0.1.1", + "marked": "^11.2.0", + "marked-highlight": "^2.1.0", + "microtime": "3.1.1", + "next": "15.2.4", + "next-sitemap": "4.2.3", + "npm-run-all": "4.1.5", + "prettier": "^3.5.0", + "prismjs": "^1.29.0", + "random-seed": "0.3.0", + "react": "19.1.0", + "react-dom": "19.1.0", + "rimraf": "2.7.1", + "rollup": "4.34.8", + "size-limit": "^11.2.0", + "transducers-js": "0.4.174", + "ts-node": "^10.9.2", + "tslib": "^2.8.1", + "tstyche": "^3.5", + "typescript": "5.7", + "typescript-eslint": "^8.24.0" + }, + "size-limit": [ + { + "name": "all", + "path": "dist/immutable.es.js", + "import": "*", + "limit": "20 kB" + }, + { + "name": "List", + "path": "dist/immutable.es.js", + "import": "{ List }", + "limit": "20 kB" + }, + { + "name": "Seq", + "path": "dist/immutable.es.js", + "import": "{ Seq }", + "limit": "20 kB" + } + ] } diff --git a/perf/List.js b/perf/List.js new file mode 100644 index 0000000000..375155e46d --- /dev/null +++ b/perf/List.js @@ -0,0 +1,114 @@ +/* global Immutable */ +describe('List', function () { + describe('builds from array', function () { + var array2 = []; + for (var ii = 0; ii < 2; ii++) { + array2[ii] = ii; + } + + it('of 2', function () { + Immutable.List(array2); + }); + + var array8 = []; + for (var ii = 0; ii < 8; ii++) { + array8[ii] = ii; + } + + it('of 8', function () { + Immutable.List(array8); + }); + + var array32 = []; + for (var ii = 0; ii < 32; ii++) { + array32[ii] = ii; + } + + it('of 32', function () { + Immutable.List(array32); + }); + + var array1024 = []; + for (var ii = 0; ii < 1024; ii++) { + array1024[ii] = ii; + } + + it('of 1024', function () { + Immutable.List(array1024); + }); + }); + + describe('pushes into', function () { + it('2 times', function () { + var list = Immutable.List(); + for (var ii = 0; ii < 2; ii++) { + list = list.push(ii); + } + }); + + it('8 times', function () { + var list = Immutable.List(); + for (var ii = 0; ii < 8; ii++) { + list = list.push(ii); + } + }); + + it('32 times', function () { + var list = Immutable.List(); + for (var ii = 0; ii < 32; ii++) { + list = list.push(ii); + } + }); + + it('1024 times', function () { + var list = Immutable.List(); + for (var ii = 0; ii < 1024; ii++) { + list = list.push(ii); + } + }); + }); + + describe('pushes into transient', function () { + it('2 times', function () { + var list = Immutable.List().asMutable(); + for (var ii = 0; ii < 2; ii++) { + list = list.push(ii); + } + list = list.asImmutable(); + }); + + it('8 times', function () { + var list = Immutable.List().asMutable(); + for (var ii = 0; ii < 8; ii++) { + list = list.push(ii); + } + list = list.asImmutable(); + }); + + it('32 times', function () { + var list = Immutable.List().asMutable(); + for (var ii = 0; ii < 32; ii++) { + list = list.push(ii); + } + list = list.asImmutable(); + }); + + it('1024 times', function () { + var list = Immutable.List().asMutable(); + for (var ii = 0; ii < 1024; ii++) { + list = list.push(ii); + } + list = list.asImmutable(); + }); + }); + + describe('some', function () { + it('100 000 items', () => { + const list = Immutable.List(); + for (let i = 0; i < 100000; i++) { + list.push(i); + } + list.some((item) => item === 50000); + }); + }); +}); diff --git a/perf/Map.js b/perf/Map.js new file mode 100644 index 0000000000..b5758c7074 --- /dev/null +++ b/perf/Map.js @@ -0,0 +1,138 @@ +/* global Immutable */ +describe('Map', function () { + describe('builds from an object', function () { + var obj2 = {}; + for (var ii = 0; ii < 2; ii++) { + obj2['x' + ii] = ii; + } + + it('of 2', function () { + Immutable.Map(obj2); + }); + + var obj8 = {}; + for (var ii = 0; ii < 8; ii++) { + obj8['x' + ii] = ii; + } + + it('of 8', function () { + Immutable.Map(obj8); + }); + + var obj32 = {}; + for (var ii = 0; ii < 32; ii++) { + obj32['x' + ii] = ii; + } + + it('of 32', function () { + Immutable.Map(obj32); + }); + + var obj1024 = {}; + for (var ii = 0; ii < 1024; ii++) { + obj1024['x' + ii] = ii; + } + + it('of 1024', function () { + Immutable.Map(obj1024); + }); + }); + + describe('builds from an array', function () { + var array2 = []; + for (var ii = 0; ii < 2; ii++) { + array2[ii] = ['x' + ii, ii]; + } + + it('of 2', function () { + Immutable.Map(array2); + }); + + var array8 = []; + for (var ii = 0; ii < 8; ii++) { + array8[ii] = ['x' + ii, ii]; + } + + it('of 8', function () { + Immutable.Map(array8); + }); + + var array32 = []; + for (var ii = 0; ii < 32; ii++) { + array32[ii] = ['x' + ii, ii]; + } + + it('of 32', function () { + Immutable.Map(array32); + }); + + var array1024 = []; + for (var ii = 0; ii < 1024; ii++) { + array1024[ii] = ['x' + ii, ii]; + } + + it('of 1024', function () { + Immutable.Map(array1024); + }); + }); + + describe('builds from a List', function () { + var list2 = Immutable.List().asMutable(); + for (var ii = 0; ii < 2; ii++) { + list2 = list2.push(Immutable.List(['x' + ii, ii])); + } + list2 = list2.asImmutable(); + + it('of 2', function () { + Immutable.Map(list2); + }); + + var list8 = Immutable.List().asMutable(); + for (var ii = 0; ii < 8; ii++) { + list8 = list8.push(Immutable.List(['x' + ii, ii])); + } + list8 = list8.asImmutable(); + + it('of 8', function () { + Immutable.Map(list8); + }); + + var list32 = Immutable.List().asMutable(); + for (var ii = 0; ii < 32; ii++) { + list32 = list32.push(Immutable.List(['x' + ii, ii])); + } + list32 = list32.asImmutable(); + + it('of 32', function () { + Immutable.Map(list32); + }); + + var list1024 = Immutable.List().asMutable(); + for (var ii = 0; ii < 1024; ii++) { + list1024 = list1024.push(Immutable.List(['x' + ii, ii])); + } + list1024 = list1024.asImmutable(); + + it('of 1024', function () { + Immutable.Map(list1024); + }); + }); + + describe('merge a map', () => { + [2, 8, 32, 1024].forEach((size) => { + const obj1 = {}; + const obj2 = {}; + for (let ii = 0; ii < size; ii++) { + obj1['k' + ii] = '1_' + ii; + obj2['k' + ii] = '2_' + ii; + } + + const map1 = Immutable.Map(obj1); + const map2 = Immutable.Map(obj2); + + it('of ' + size, () => { + map1.merge(map2); + }); + }); + }); +}); diff --git a/perf/Record.js b/perf/Record.js new file mode 100644 index 0000000000..712c077a58 --- /dev/null +++ b/perf/Record.js @@ -0,0 +1,80 @@ +/* global Immutable */ +describe('Record', () => { + describe('builds from an object', () => { + [2, 5, 10, 100, 1000].forEach((size) => { + var defaults = {}; + var values = {}; + for (var ii = 0; ii < size; ii++) { + defaults['x' + ii] = null; + values['x' + ii] = ii; + } + + var Rec = Immutable.Record(defaults); + + it('of ' + size, () => { + Rec(values); + }); + }); + }); + + describe('update random using set()', () => { + [2, 5, 10, 100, 1000].forEach((size) => { + var defaults = {}; + var values = {}; + for (var ii = 0; ii < size; ii++) { + defaults['x' + ii] = null; + values['x' + ii] = ii; + } + + var Rec = Immutable.Record(defaults); + var rec = Rec(values); + + var key = 'x' + Math.floor(size / 2); + + it('of ' + size, () => { + rec.set(key, 999); + }); + }); + }); + + describe('access random using get()', () => { + [2, 5, 10, 100, 1000].forEach((size) => { + var defaults = {}; + var values = {}; + for (var ii = 0; ii < size; ii++) { + defaults['x' + ii] = null; + values['x' + ii] = ii; + } + + var Rec = Immutable.Record(defaults); + var rec = Rec(values); + + var key = 'x' + Math.floor(size / 2); + + it('of ' + size, () => { + rec.get(key); + }); + }); + }); + + describe('access random using property', () => { + [2, 5, 10, 100, 1000].forEach((size) => { + var defaults = {}; + var values = {}; + for (var ii = 0; ii < size; ii++) { + defaults['x' + ii] = null; + values['x' + ii] = ii; + } + + var Rec = Immutable.Record(defaults); + var rec = Rec(values); + + var key = 'x' + Math.floor(size / 2); + + it('of ' + size, () => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + rec[key]; + }); + }); + }); +}); diff --git a/perf/toJS.js b/perf/toJS.js new file mode 100644 index 0000000000..d924d332d8 --- /dev/null +++ b/perf/toJS.js @@ -0,0 +1,22 @@ +/* global Immutable */ +describe('toJS', () => { + const array32 = []; + for (let ii = 0; ii < 32; ii++) { + array32[ii] = ii; + } + const list = Immutable.List(array32); + + it('List of 32', () => { + Immutable.toJS(list); + }); + + const obj32 = {}; + for (let ii = 0; ii < 32; ii++) { + obj32[ii] = ii; + } + const map = Immutable.Map(obj32); + + it('Map of 32', () => { + Immutable.toJS(map); + }); +}); diff --git a/resources/COPYRIGHT b/resources/COPYRIGHT deleted file mode 100644 index 2ef4739406..0000000000 --- a/resources/COPYRIGHT +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ diff --git a/resources/benchmark.js b/resources/benchmark.js new file mode 100644 index 0000000000..a2e77aa399 --- /dev/null +++ b/resources/benchmark.js @@ -0,0 +1,283 @@ +var Benchmark = require('benchmark'); +var child_process = require('child_process'); +var fs = require('fs'); +var path = require('path'); +var vm = require('vm'); + +function promisify(fn) { + return function () { + return new Promise((resolve, reject) => + fn.apply( + this, + Array.prototype.slice + .call(arguments) + .concat((err, out) => (err ? reject(err) : resolve(out))) + ) + ); + }; +} + +var exec = promisify(child_process.exec); +var readdir = promisify(fs.readdir); +var readFile = promisify(fs.readFile); + +var perfDir = path.resolve(__dirname, '../perf/'); + +Promise.all([ + readFile(path.resolve(__dirname, '../dist/immutable.js'), { + encoding: 'utf8', + }), + exec('git show main:dist/immutable.js'), +]) + .then(function (args) { + var newSrc = args[0]; + var oldSrc = args[1].toString({ encoding: 'utf8' }).slice(0, -1); // wtf, comma? + return newSrc === oldSrc ? [newSrc] : [newSrc, oldSrc]; + }) + .then(function (sources) { + return sources.map(function (source) { + var sourceExports = {}; + var sourceModule = { exports: sourceExports }; + vm.runInNewContext( + source, + { + require: require, + module: sourceModule, + exports: sourceExports, + }, + 'immutable.js' + ); + return sourceModule.exports; + }); + }) + .then(function (modules) { + return readdir(perfDir) + .then(function (filepaths) { + return Promise.all( + filepaths.map(function (filepath) { + return readFile(path.resolve(perfDir, filepath)).then( + function (source) { + return { + path: filepath, + source: source, + }; + } + ); + }) + ); + }) + .then(function (sources) { + var tests = {}; + + modules.forEach(function (Immutable, version) { + sources.forEach(function (source) { + var description = []; + var beforeStack = []; + var beforeFn; + var prevBeforeFn; + + function describe(name, fn) { + description.push(name); + beforeStack.push(prevBeforeFn); + prevBeforeFn = beforeFn; + fn(); + beforeFn = prevBeforeFn; + prevBeforeFn = beforeStack.pop(); + description.pop(); + } + + function beforeEach(fn) { + beforeFn = !prevBeforeFn + ? fn + : (function (prevBeforeFn) { + return function () { + prevBeforeFn(); + fn(); + }; + })(prevBeforeFn); + } + + function it(name, test) { + var fullName = description.join(' > ') + ' ' + name; + ( + tests[fullName] || + (tests[fullName] = { + description: fullName, + tests: [], + }) + ).tests[version] = { + before: beforeFn, + test: test, + }; + } + + vm.runInNewContext( + source.source, + { + describe: describe, + it: it, + beforeEach: beforeEach, + console: console, + Immutable: Immutable, + }, + source.path + ); + }); + }); + + // Array<{ + // description: String, + // tests: Array<{ + // before: Function, + // test: Function + // }> // one per module, [new,old] or just [new] + // }> + return Object.keys(tests).map(function (key) { + return tests[key]; + }); + }); + }) + .then(function (tests) { + var suites = []; + + tests.forEach(function (test) { + var suite = new Benchmark.Suite(test.description, { + onStart: function (event) { + console.log(event.currentTarget.name.bold); + process.stdout.write(' ...running... '.gray); + }, + onComplete: function (event) { + process.stdout.write('\r\x1B[K'); + var stats = Array.prototype.map.call( + event.currentTarget, + function (target) { + return target.stats; + } + ); + + function pad(n, s) { + return Array(Math.max(0, 1 + n - s.length)).join(' ') + s; + } + + function fmt(b) { + return Math.floor(b) + .toString() + .replace(/\B(?=(\d{3})+(?!\d))/g, ','); + } + + function pct(p) { + return Math.floor(p * 10000) / 100 + '%'; + } + + var dualRuns = stats.length === 2; + + if (dualRuns) { + var prevMean = 1 / stats[1].mean; + // var prevLow = 1 / (stats[1].mean + stats[1].deviation * 2); + // var prevHigh = 1 / (stats[1].mean - stats[1].deviation * 2); + + // console.log( + // (dualRuns ? ' Old: '.bold.gray : ' ') + + // ( + // pad(9, fmt(prevLow)) + ' ' + + // pad(9, fmt(prevMean)) + ' ' + + // pad(9, fmt(prevHigh)) + ' ops/sec' + // ) + // ); + + var prevLowmoe = 1 / (stats[1].mean + stats[1].moe); + var prevHighmoe = 1 / (stats[1].mean - stats[1].moe); + + console.log( + (dualRuns ? ' Old: '.bold.gray : ' ') + + (pad(9, fmt(prevLowmoe)) + + ' ' + + pad(9, fmt(prevMean)) + + ' ' + + pad(9, fmt(prevHighmoe)) + + ' ops/sec') + ); + } + + var mean = 1 / stats[0].mean; + // var low = 1 / (stats[0].mean + stats[0].deviation * 2); + // var high = 1 / (stats[0].mean - stats[0].deviation * 2); + + // console.log( + // (dualRuns ? ' New: '.bold.gray : ' ') + + // ( + // pad(9, fmt(low)) + ' ' + + // pad(9, fmt(mean)) + ' ' + + // pad(9, fmt(high)) + ' ops/sec' + // ) + // ); + + var lowmoe = 1 / (stats[0].mean + stats[0].moe); + var highmoe = 1 / (stats[0].mean - stats[0].moe); + + console.log( + (dualRuns ? ' New: '.bold.gray : ' ') + + (pad(9, fmt(lowmoe)) + + ' ' + + pad(9, fmt(mean)) + + ' ' + + pad(9, fmt(highmoe)) + + ' ops/sec') + ); + + if (dualRuns) { + var diffMean = (mean - prevMean) / prevMean; + + var comparison = event.currentTarget[1].compare( + event.currentTarget[0] + ); + var comparison2 = event.currentTarget[0].compare( + event.currentTarget[1] + ); + console.log(' compare: ' + comparison + ' ' + comparison2); + + console.log(' diff: ' + pct(diffMean)); + + function sq(p) { + return p * p; + } + + var rme = Math.sqrt( + (sq(stats[0].rme / 100) + sq(stats[1].rme / 100)) / 2 + ); + // console.log('rmeN: ' + stats[0].rme); + // console.log('rmeO: ' + stats[1].rme); + console.log(' rme: ' + pct(rme)); + } + + // console.log(stats); + }, + }); + + test.tests.forEach(function (run) { + suite.add({ + fn: run.test, + onStart: run.before, + onCycle: run.before, + }); + }); + + suites.push(suite); + }); + + var onBenchComplete; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + var promise = new Promise(function (_resolve) { + onBenchComplete = _resolve; + }); + + Benchmark.invoke(suites, 'run', { onComplete: onBenchComplete }); + + return onBenchComplete; + }) + .then(function () { + console.log('all done'); + }) + .catch(function (error) { + console.log('ugh', error.stack); + }); diff --git a/resources/check-build-output.mjs b/resources/check-build-output.mjs new file mode 100644 index 0000000000..1cfffc5b84 --- /dev/null +++ b/resources/check-build-output.mjs @@ -0,0 +1,45 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +const packageJsonContent = JSON.parse(fs.readFileSync('package.json', 'utf8')); + +// remove "dist/" prefix from the file names +const distPrefix = 'dist'; +const removeDistPrefix = (file) => path.basename(file); + +const expectedFiles = [ + removeDistPrefix(packageJsonContent.main), + removeDistPrefix(packageJsonContent.module), + removeDistPrefix(packageJsonContent.types), + + // extra files that are not in package.json + 'immutable.min.js', + 'immutable.js.flow', +]; + +console.log('expected files: ', expectedFiles); + +const filesInDistDir = fs + .readdirSync(distPrefix) + .filter((file) => !file.startsWith('.')); + +// There should be no extra files in the dist directory and all expected files should be present +const extraFiles = filesInDistDir.filter( + (file) => !expectedFiles.includes(file) +); +if (extraFiles.length > 0) { + console.error('Extra files found in dist directory:', extraFiles); +} + +const missingFiles = expectedFiles.filter( + (file) => !filesInDistDir.includes(file) +); +if (missingFiles.length > 0) { + console.error('Missing files in dist directory:', missingFiles); +} + +if (extraFiles.length > 0 || missingFiles.length > 0) { + process.exit(1); +} + +console.log('All expected files are present in the dist directory.'); diff --git a/resources/check-git-clean.sh b/resources/check-git-clean.sh new file mode 100755 index 0000000000..3ea73552f8 --- /dev/null +++ b/resources/check-git-clean.sh @@ -0,0 +1,13 @@ +#!/bin/bash -e + +if ! git diff --quiet; then echo " + +$(tput setf 4)The CI build resulted in additional changed files. +Typically this is due to not running $(tput smul)npm test$(tput rmul) locally before +submitting a pull request. + +The following changes were found:$(tput sgr0) +"; + + git diff --exit-code; +fi; diff --git a/resources/copyright.mjs b/resources/copyright.mjs new file mode 100644 index 0000000000..7323639f46 --- /dev/null +++ b/resources/copyright.mjs @@ -0,0 +1,8 @@ +import fs from 'fs'; + +const copyright = fs.readFileSync('./LICENSE', 'utf-8'); +const lines = copyright.trim().split('\n'); + +export default `/**\n * @license\n${lines + .map((line) => ` * ${line}`) + .join('\n')}\n */`; diff --git a/resources/dist-stats.mjs b/resources/dist-stats.mjs new file mode 100644 index 0000000000..7c6079db38 --- /dev/null +++ b/resources/dist-stats.mjs @@ -0,0 +1,92 @@ +import fs from 'node:fs/promises'; +import { deflate } from 'zlib'; +import 'colors'; + +const VERIFY_AGAINST_VERSION = '4'; + +const deflateContent = (content) => + new Promise((resolve, reject) => + deflate(content, (error, out) => (error ? reject(error) : resolve(out))) + ); + +const space = (n, s) => + new Array(Math.max(0, 10 + n - (s || '').length)).join(' ') + (s || ''); + +const bytes = (b) => + `${b.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')} bytes`; + +const diff = (n, o) => { + const d = n - o; + return d === 0 ? '' : d < 0 ? ` ${bytes(d)}`.green : ` +${bytes(d)}`.red; +}; + +const percentage = (s, b) => ` ${Math.floor(10000 * (1 - s / b)) / 100}%`.grey; + +let bundlephobaInfoCache; + +async function bundlephobaInfo(key) { + if (!bundlephobaInfoCache) { + try { + const res = await fetch( + `https://bundlephobia.com/api/size?package=immutable@${VERIFY_AGAINST_VERSION}` + ); + + if (res.status !== 200) { + throw new Error( + `Unable to fetch bundlephobia in dist-stats.mjs. Status code is "${res.status}"` + ); + } + + bundlephobaInfoCache = await res.json(); + } catch (err) { + console.error(err.message); + + throw err; + } + } + + return bundlephobaInfoCache[key]; +} + +/** + * + * @param {PromiseFulfilledResult} promise + */ +function promiseNumberValue(promise) { + if (!promise || !promise.value) { + return null; + } + + const value = promise.value; + + return value === null || typeof value === 'number' + ? value + : Number(Buffer.byteLength(value, 'utf8')); +} + +Promise.allSettled([ + fs.readFile('dist/immutable.js'), + fs.readFile('dist/immutable.min.js'), + bundlephobaInfo('size'), + fs.readFile('dist/immutable.min.js').then(deflateContent), + bundlephobaInfo('gzip'), +]).then(([rawNew, minNew, minOld, zipNew, zipOld]) => { + console.log(` Raw: ${space(14, bytes(promiseNumberValue(rawNew)).cyan)}`); + if (minOld.status === 'fulfilled') { + console.log( + ` Min: ${space(14, bytes(promiseNumberValue(minNew)).cyan)}${percentage( + minNew.value, + rawNew.value + )}${space(15, diff(promiseNumberValue(minNew), promiseNumberValue(minOld)))}` + ); + } + + if (zipOld.status === 'fulfilled') { + console.log( + ` Zip: ${space(14, bytes(promiseNumberValue(zipNew)).cyan)}${percentage( + promiseNumberValue(zipNew), + promiseNumberValue(rawNew) + )}${space(15, diff(promiseNumberValue(zipNew), promiseNumberValue(zipOld)))}` + ); + } +}); diff --git a/resources/identity.ai b/resources/identity.ai new file mode 100644 index 0000000000..44a1d29661 --- /dev/null +++ b/resources/identity.ai @@ -0,0 +1,2208 @@ +%PDF-1.5 %âÏÓ +1 0 obj <>/OCGs[5 0 R 6 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + identity + + + Adobe Illustrator CC 2014 (Macintosh) + 2014-10-30T16:19:54-07:00 + 2014-10-30T16:19:54-07:00 + 2014-10-30T16:19:54-07:00 + + + + 256 + 108 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAbAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A7vhYuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV 2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K uxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KpJrfnXytoV2lpq2oR2ly8YlSNw5JQkqG+EHupwgFICm3n7ycl9BY PqkK3dwImhjbkOQnUPEakU+JWBG+NJ4Smup6np+l2Mt9qE621pCAZZnNFFTQfeTTAgBJT+Y3kkWC X51aIWbytAk1HoZEVXZfs12V1OGinh93zCeafqFlqNlDe2My3FpOvOGZDVWGBBFJF/ysjyOZZ4hq 8Je2DGYDmQAhoxqFoae2Giy4Cr2fnryle2F5qFrqUctnYBTeTAPSMPULWq13p2xpHChB+Z/kIwmb 9Mw+mGCFqSfaIJA+z7Y0V4dr2+YWr+af5fswUa1CSTQDjJ3/ANjjwleH3fMJlrPnLyxot5FZ6rqE VpczKHjiflUqWKhtgQBVT1xooAtGavrOmaPYtfancLbWiFVaV6kAsaAbAnrgUC0ntPzK8iXUoih1 u25nYCRjGCT7yBRhorXu+aM1zzl5Y0KaKHVtQjtJZl9SJXDHktaV+EHviAnhRN15g0a10VdbuLpY 9KaOOVbohuPCYqI2oBX4uY7Y0ikmj/NHyBLIsaazCzuQqikm5JoP2caKRH3fMMpwMXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXz7/wA5BD/ncrX/ALZkX/UTNl2Pl8WEuvu/SxbzmUGqoWFR +jdLFabj/Qodxgj0ckkVK/L7yreaPzC1zX9G0zTL9h6WnL+9etTczCoSR6/yx0+kk99pRj3NRlW5 /t/Z1WXlF8kWgAFBrt5QU2oLe27ZEf71tmAMkh/tn61TQvzC13R/LN/oVm/G3vt4p6nlbcv74J/r r08Oo3wmO+7UDtt/Z3/sSbSmU/XKDiv1GYDx+1398JH3s4kHly4D97MPJ4A/LrzxTb9xYfjXIdR7 /wBLKYA/0v8AvAhfJ/lfSNZ8u+Zbi9nlgk0uNLmzWFlUNIIJSA/JWqKqOlMkL5sMsgJcPK5foCh+ WXljSfMutS2mr3M8EEFsbhGhdVJkWVVAbmsgpRvDJEHoGuWSogyP4soHz15gXX/Neo6iG5W88pit W8IIv3cbb9OVORyMRQZ2OR67ft/033PQ/MXmL9O/kXFcyNW6t5YLS7rufVhcLU17svFj88jEVJEj 6SfxzeS3JtxzXifUV5vUJdWXiR+6CIByUqQamvh9JjyHwb8+05A8rl3edUPJlPnhzJpXlEvcLdH9 DN+9B5D4WkATfvHTifcYjr7x97EAGv6sv9w9L83/APkgoP8Atm6X/wATt8Y/W4x+l4/ocnlyPUOO qxXskv1pfq/1SeGONV5inJHjkJ38CMRfD8HKyishF/x7cq57bW+r8qaHYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXhf56aHrN/wCbbaWxsZ7qL9HRxmSKNnUMJ5WIJA60OX4gSGucwLsjcd47 2OeZ/LOvT65bD9GXMkDWWmRyMsT8R6dpCsgJA2oQQcYwLbLNAWCRvXUd6/V/ywv7Gy1OaJXvPTkR NLhiq7mNmDO7KvdR8P3nwy84yHBjqozoX069PJTuvLvmF/Jdqg0u69UaxdzND6T8wjwW/FiKdCVI ykQPLyc2eeJkZWN53zCK0n8rrq7j0i4nD2sMqt+lrd6rIDG7cOKn+daD265fHETTgz1UY2B5e4/2 FLfKvknX7u9ntbmyuLOOWznQTyxsqB+JZKkjoWoMqMCT8XJGeMYncfTXMd6GTT/PGm2uoaQlnexw X4ijvYYrf1klEBqnGUBqU/yDv3wGBB5MxljIXZ5Dly5V8NnoPkXydfWXkjzHJfq8d/qEDm3s1oWH CGQRqaV+Ji/TCRKPLqGk5IZJ2T9Mr/HyYZ5X0jzPptrrDrpN6LqawNtahYXqZJZkBPT9mPkfmMdw eXNncJAbi4+Y57/rUtL/AC+80XlpK6Wj2qsPRkiuJPRZ1Uq9eJjOxYA9euIxz/H9qZ6nANjfL+cP +JNfNVstL83p5X1rSjo16LS8a3uIy0MhAnhcKwBAAq6vU7fsjIiJBHe2TyRkJEHb3jnte6DbQ/Nc 9ulgmj3Bi+stcoZLf025uAtDMx2T22/oxhKqr8fJOXPi4zMG9yase/8AnH7r6Jv5p8k67Yaf5dtE tZrxo7Gb6y9sjSqkk8sj8BTb4eYB3wGMiTt1CMebGKs7VLu6iupCIml/M+88pXeiXllevpMVnBHa xPZCL+5uIBGFdV5NRFPfBEerzTk4eHY7VzND/fFJdO07zfYzlrXSJmMswkpPYJKQSezyK5H0ZIRk BVfj5Lky4pSMhLnK+YHP3T/Q+osx0OxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KpDr0cjX iFVJHpj/AIk2Z2lIEfi6rXRJmPchryGQ3KfCePCOv/ACuWY5Cvm1ZoHiHuH3KbWtFcjc7cB9OSE2 Bxc17Qy/o9BxNfWY0/2K4OIcfwZGB8Mf1v0BatrXgTt/OMJmxGLk61t5CzhgVBRt8ZyC4sZ39y1B eRxyRorem9PUoKg06b4TwkglA4wCByKNsLRTZzmQkOBVVHiAaZTln6hTk4MXoNoW1hlCyngxfj8A HjUDLJyGzRigaO26mltMVPRa7EHJGYYDHJWiS5FlPGY29NipBptyB/pkZGPEDbZES4CK2UPTnKBO GwNa5OxdtfDKqpEXltIkFqq/HRCSR0qWJpleOYJLbmxkRiPJUL6k9k8UqH0AihPhp0Zab/LI1ASs c2d5TAgj01+pCwrcIwATuDuK5bIgtEBIdGWZqnfOxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KpbqUbtOpVSRxHT5nMnCRTh6iJMvgpTwyGZfhJHFK/8CMlGQprnA38mntSquR8X8gxE1OKrcYp fqqjia8yafQMeIcS8J4Pi2trXgTt/OMTNRi5LYIJCzAqQCp3wykEQgVoW5RXQK3FvtUFQae+G4nd FSFhFWtuRby8vtEVA+g5VOe4b8WP0lQgimUSURuRWi0HeuTkRs1QiRey1LaYg7UrsQcJmGIxyXIk 4t5EKHi1CDTuDgJFgsgJcJFLPTnKhOG1a9MlY5sOGVVSpcW8ixwqByopqR7muRjIWWzJjIAXVvGt 2jdT6YUBdvAimD03afWY0eSlGs6EAJ37iuSJBa4iQ6J1mG7J2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxVQnVi4oCdsnEtcwbaZGLDY0oP1YQUEG22gIDEb/y4iSmC3g/pgUNa/wAMb3RRpcsF eJO38wxMkiC1I2JIIIqOuJKBEtcZRVaGh64bC0VWONljavUjpkSd2cY0FNFdQ3wmpFBhJDAAhywy EHt88TIKIlwV+DLxO+NhQDTXCQjjx2rXDYWiueNgFAFaDemAFJiXfvShUg0ptt747LvTSiQdF/DC aQAUTlTc7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWTf7hv+Xf8A4TAyd/uG/wCXf/hMVd/uG/5d/wDhMVd/ uG/5d/8AhMVd/uG/5d/+ExV3+4b/AJd/+ExV3+4b/l3/AOExV3+4b/l3/wCExV3+4b/l3/4TFXf7 hv8Al3/4TFXf7hv+Xf8A4TFXf7hv+Xf/AITFXf7hv+Xf/hMVd/uG/wCXf/hMVd/uG/5d/wDhMVd/ uG/5d/8AhMVd/uG/5d/+ExV3+4b/AJd/+ExV3+4b/l3/AOExV3+4b/l3/wCExV3+4b/l3/4TFXf7 hv8Al3/4TFXf7hv+Xf8A4TFXf7hv+Xf/AITFXf7hv+Xf/hMVd/uG/wCXf/hMVd/uG/5d/wDhMVd/ uG/5d/8AhMVd/uG/5d/+ExV3+4b/AJd/+ExV3+4b/l3/AOExV3+4b/l3/wCExV//2Q== + + + + proof:pdf + uuid:65E6390686CF11DBA6E2D887CEACB407 + xmp.did:5962c3f6-6a0f-4199-90f1-c6dea6f71387 + uuid:15bcb097-31e4-8d46-bdb6-d8c19fdf6524 + + uuid:1abccb90-0c26-4942-b156-fd2eb962e3e1 + xmp.did:58fdc1b8-1448-3a44-9e20-282d8ec1cf95 + uuid:65E6390686CF11DBA6E2D887CEACB407 + proof:pdf + + + + + saved + xmp.iid:5962c3f6-6a0f-4199-90f1-c6dea6f71387 + 2014-10-30T16:19:52-07:00 + Adobe Illustrator CC 2014 (Macintosh) + / + + + + Web + Document + 1 + True + False + + 960.000000 + 560.000000 + Pixels + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + RGB + PROCESS + 255 + 255 + 255 + + + Black + RGB + PROCESS + 0 + 0 + 0 + + + RGB Red + RGB + PROCESS + 255 + 0 + 0 + + + RGB Yellow + RGB + PROCESS + 255 + 255 + 0 + + + RGB Green + RGB + PROCESS + 0 + 255 + 0 + + + RGB Cyan + RGB + PROCESS + 0 + 255 + 255 + + + RGB Blue + RGB + PROCESS + 0 + 0 + 255 + + + RGB Magenta + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + Grays + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + Web Color Group + 1 + + + + R=63 G=169 B=245 + RGB + PROCESS + 63 + 169 + 245 + + + R=122 G=201 B=67 + RGB + PROCESS + 122 + 201 + 67 + + + R=255 G=147 B=30 + RGB + PROCESS + 255 + 147 + 30 + + + R=255 G=29 B=37 + RGB + PROCESS + 255 + 29 + 37 + + + R=255 G=123 B=172 + RGB + PROCESS + 255 + 123 + 172 + + + R=189 G=204 B=212 + RGB + PROCESS + 189 + 204 + 212 + + + + + + + Adobe PDF library 11.00 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 8 0 obj <>/Resources<>/ExtGState<>/Properties<>/XObject<>>>/Thumb 20 0 R/TrimBox[0.0 0.0 960.0 560.0]/Type/Page>> endobj 9 0 obj <>stream +H‰ìWˎGĵ÷WäTNWlŸcħ‡ŭ€Ĉu˜‘ħĞ˙AfÖ£[ĴdRAÓdUV&“ ’Á§ßžÍÓûgg~z÷l.OÏ˙tĉúÉ8ÛRäߜċo7ĉÓġċéWĵŝŭӆlKÊ&ô€ß`üħ)vJ´eóż_ŝsùù=wÔŭ½îŞ·½k³ğúhs1KrÖŭèżĈ‡Ŝ„Öm)ŜÏĊŜ\_/|ġzñŽŸ9ór Ŝ,>ÛX Goc“§ §¤4Àòn}ıSy›06‹UelmÛĞĦÎŬ&~€Ñ˙Ĝ™cĥĠĠǰrqĤ˙B!ĝ—ù¸żMŻÖg—p­j³ïÛm–`s0ÜÒÂ|iFl #À×ËÒlkĈ[XŠ‹œ Ħ†IñçBĴaüMĥòÉoŠ­I}ÓM³UÖëĞá 5lƒ]zYÜv,„ßÁܗËy÷£Ĉ­vZ²Ç@I‚ÄRá9‹ˆq÷ȃQTßx4ĉ½mĵĥŝ^/xH‹Ĉċsġa#œĉû£wFqÑÎ^<„ËŽšÜsUĐCœÁ{ä¤zŜĴêMúx8™ÎïÓù•aYcµàĜjŝğŜÀ=…hCĤbiÖԉl•ˆâ?7 +×À̰ @žf§x›iİ 4u¤B̰8ħYMU¤/Šìûf f!U°QRVš 3ñxn§EX–½àܝ†;¸ŬÒ%„§wöö“|61Ġ£½x48“ÎÌn‘‰d•Îqaa|œŝ÷6%U^†˘×0-Áŝ~„Ş/BŽ#ètŭ;¨6· ĜŠĝJú­j‘ÈCàĉšÊÍĦ`8qŻ—Ĥ! +}¸*ĝş‰ ÈÂDı^şu€&4@~E÷ pvef¨ĥ YÑĜglŻDvE3ĥgFĊ‚p·ƒ™ŽàF;*b4³4áCöŬ6]'Z#Ä x^ħòxlĜ$9sÔ|ʚbE^…0èċĝHöCÌüìkÌQ*šŞAO +T˘­*'­:iĠIĞŠVŬ·ÏoHĞîûÁiU´ÊiUò_@ĞĈâG!(ƒV=˜Ġ+­Ş'­:iĠ´*ıïGĞúƒÑŞvÒŞ“V´êkhĠgÚç·£U÷‡ŭà´*Z”VĦ,6Öâ/`>]?nl+~ ۊĊ[&Ûz,ĞWĥĠOĥu²­·ĜVĝnl+ùÇb[ɝlëd['Ûú*ĥuß>ż!Ûş;ìÇd[RĝTâ߈PV…Ù#Eš§´`d_VµwpÀĝúe< Œ tŭı°zÉ1_sҐ @+ ²–]rĵRM\Ùf£PI œ+ĤĤ[ħk5ñÁ|·:j[½Ç›ÌleTiŬİ3A$MT^~ԚŬdıħvġ„òuu‘òuġöáUìÓჳhìtˆà.´[Àî> endobj 20 0 obj <>stream +8;Z\u5n8N$$j;VR-9:UhT)'<$0@%\#iB&n#M&p=M`b5lXt>9a/<+@KdI>\';9_Ob?VVFp#qBr +6`>t+Opn?\"-,&u;UKhmW#jb?),s)kWS;mu=QT4(Es1c*Hs+$IogkoB7r@q*WQF\3 +W#eMkTStuRhFE':++9f0-UJ(^KFgHU\Km4:!!e-hiW~> endstream endobj 22 0 obj [/Indexed/DeviceRGB 255 23 0 R] endobj 23 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 17 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.427 0.737 0.859 scn +/GS0 gs +271.996 378.559 13.56 -40.02 re +f +q 1 0 0 1 289.6611 378.5591 cm +0 0 m +10.56 0 l +21 -15.36 l +31.38 0 l +41.94 0 l +41.94 -40.02 l +29.16 -40.02 l +29.16 -25.62 l +21 -37.62 l +12.78 -25.62 l +12.78 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 335.707 378.5591 cm +0 0 m +10.56 0 l +21 -15.36 l +31.38 0 l +41.94 0 l +41.94 -40.02 l +29.16 -40.02 l +29.16 -25.62 l +21 -37.62 l +12.78 -25.62 l +12.78 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 397.1504 337.519 cm +0 0 m +-2.52 0 -4.8 0.321 -6.84 0.96 c +-8.88 1.6 -10.62 2.56 -12.06 3.84 c +-13.5 5.12 -14.61 6.74 -15.39 8.7 c +-16.17 10.659 -16.56 12.96 -16.56 15.6 c +-16.56 41.04 l +-3.78 41.04 l +-3.78 16.14 l +-3.78 14.739 -3.49 13.67 -2.91 12.93 c +-2.331 12.189 -1.36 11.82 0 11.82 c +1.359 11.82 2.33 12.189 2.91 12.93 c +3.489 13.67 3.78 14.739 3.78 16.14 c +3.78 41.04 l +16.62 41.04 l +16.62 15.6 l +16.62 12.96 16.23 10.659 15.45 8.7 c +14.67 6.74 13.55 5.12 12.09 3.84 c +10.629 2.56 8.88 1.6 6.84 0.96 c +4.8 0.321 2.52 0 0 0 c +f +Q +q 1 0 0 1 423.2202 368.0591 cm +0 0 m +-7.38 0 l +-7.38 10.5 l +20.58 10.5 l +20.58 0 l +13.2 0 l +13.2 -29.52 l +0 -29.52 l +h +f +Q +q 1 0 0 1 460.8916 350.959 cm +0 0 m +-2.7 7.02 l +-5.4 0 l +h +-7.5 27.6 m +2.1 27.6 l +17.28 -12.42 l +4.68 -12.42 l +3.36 -8.82 l +-8.76 -8.82 l +-10.08 -12.42 l +-22.68 -12.42 l +h +f +Q +q 1 0 0 1 493.0215 347.959 cm +0 0 m +3.039 0 4.56 1.16 4.56 3.48 c +4.56 5.799 3.039 6.96 0 6.96 c +-1.44 6.96 l +-1.44 0 l +h +3 18.42 m +3 20.259 1.999 21.18 0 21.18 c +-1.44 21.18 l +-1.44 15.66 l +0 15.66 l +1.999 15.66 3 16.58 3 18.42 c +-13.801 30.6 m +1.859 30.6 l +3.859 30.6 5.689 30.37 7.35 29.91 c +9.009 29.45 10.43 28.77 11.609 27.87 c +12.789 26.97 13.71 25.85 14.369 24.51 c +15.029 23.169 15.359 21.6 15.359 19.8 c +15.359 18.52 15.199 17.43 14.88 16.53 c +14.559 15.63 14.22 14.88 13.859 14.28 c +13.419 13.56 12.919 12.96 12.359 12.48 c +13.239 11.919 14.04 11.199 14.76 10.32 c +15.359 9.56 15.909 8.6 16.409 7.44 c +16.909 6.279 17.159 4.86 17.159 3.18 c +17.159 1.26 16.819 -0.48 16.14 -2.04 c +15.459 -3.6 14.489 -4.93 13.229 -6.03 c +11.97 -7.13 10.43 -7.971 8.609 -8.55 c +6.789 -9.13 4.76 -9.42 2.52 -9.42 c +-13.801 -9.42 l +h +f +Q +q 1 0 0 1 513.6592 378.5591 cm +0 0 m +13.32 0 l +13.32 -29.52 l +24.36 -29.52 l +24.36 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 539.9697 378.5591 cm +0 0 m +23.58 0 l +23.58 -10.5 l +12.78 -10.5 l +12.78 -14.94 l +23.4 -14.94 l +23.4 -24.9 l +12.78 -24.9 l +12.78 -29.52 l +24 -29.52 l +24 -40.02 l +0 -40.02 l +h +f +Q + endstream endobj 18 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.427 0.737 0.859 scn +/GS0 gs +271.996 398.559 13.56 -40.02 re +f +q 1 0 0 1 289.6611 398.5591 cm +0 0 m +10.56 0 l +21 -15.36 l +31.38 0 l +41.94 0 l +41.94 -40.02 l +29.16 -40.02 l +29.16 -25.62 l +21 -37.62 l +12.78 -25.62 l +12.78 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 335.707 398.5591 cm +0 0 m +10.56 0 l +21 -15.36 l +31.38 0 l +41.94 0 l +41.94 -40.02 l +29.16 -40.02 l +29.16 -25.62 l +21 -37.62 l +12.78 -25.62 l +12.78 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 397.1504 357.519 cm +0 0 m +-2.52 0 -4.8 0.321 -6.84 0.96 c +-8.88 1.6 -10.62 2.56 -12.06 3.84 c +-13.5 5.12 -14.61 6.74 -15.39 8.7 c +-16.17 10.659 -16.56 12.96 -16.56 15.6 c +-16.56 41.04 l +-3.78 41.04 l +-3.78 16.14 l +-3.78 14.739 -3.49 13.67 -2.91 12.93 c +-2.331 12.189 -1.36 11.82 0 11.82 c +1.359 11.82 2.33 12.189 2.91 12.93 c +3.489 13.67 3.78 14.739 3.78 16.14 c +3.78 41.04 l +16.62 41.04 l +16.62 15.6 l +16.62 12.96 16.23 10.659 15.45 8.7 c +14.67 6.74 13.55 5.12 12.09 3.84 c +10.629 2.56 8.88 1.6 6.84 0.96 c +4.8 0.321 2.52 0 0 0 c +f +Q +q 1 0 0 1 423.2202 388.0591 cm +0 0 m +-7.38 0 l +-7.38 10.5 l +20.58 10.5 l +20.58 0 l +13.2 0 l +13.2 -29.52 l +0 -29.52 l +h +f +Q +q 1 0 0 1 460.8916 370.959 cm +0 0 m +-2.7 7.02 l +-5.4 0 l +h +-7.5 27.6 m +2.1 27.6 l +17.28 -12.42 l +4.68 -12.42 l +3.36 -8.82 l +-8.76 -8.82 l +-10.08 -12.42 l +-22.68 -12.42 l +h +f +Q +q 1 0 0 1 493.0215 367.959 cm +0 0 m +3.039 0 4.56 1.16 4.56 3.48 c +4.56 5.799 3.039 6.96 0 6.96 c +-1.44 6.96 l +-1.44 0 l +h +3 18.42 m +3 20.259 1.999 21.18 0 21.18 c +-1.44 21.18 l +-1.44 15.66 l +0 15.66 l +1.999 15.66 3 16.58 3 18.42 c +-13.801 30.6 m +1.859 30.6 l +3.859 30.6 5.689 30.37 7.35 29.91 c +9.009 29.45 10.43 28.77 11.609 27.87 c +12.789 26.97 13.71 25.85 14.369 24.51 c +15.029 23.169 15.359 21.6 15.359 19.8 c +15.359 18.52 15.199 17.43 14.88 16.53 c +14.559 15.63 14.22 14.88 13.859 14.28 c +13.419 13.56 12.919 12.96 12.359 12.48 c +13.239 11.919 14.04 11.199 14.76 10.32 c +15.359 9.56 15.909 8.6 16.409 7.44 c +16.909 6.279 17.159 4.86 17.159 3.18 c +17.159 1.26 16.819 -0.48 16.14 -2.04 c +15.459 -3.6 14.489 -4.93 13.229 -6.03 c +11.97 -7.13 10.43 -7.971 8.609 -8.55 c +6.789 -9.13 4.76 -9.42 2.52 -9.42 c +-13.801 -9.42 l +h +f +Q +q 1 0 0 1 513.6592 398.5591 cm +0 0 m +13.32 0 l +13.32 -29.52 l +24.36 -29.52 l +24.36 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 539.9697 398.5591 cm +0 0 m +23.58 0 l +23.58 -10.5 l +12.78 -10.5 l +12.78 -14.94 l +23.4 -14.94 l +23.4 -24.9 l +12.78 -24.9 l +12.78 -29.52 l +24 -29.52 l +24 -40.02 l +0 -40.02 l +h +f +Q + endstream endobj 19 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.427 0.737 0.859 scn +/GS0 gs +271.996 418.559 13.56 -40.02 re +f +q 1 0 0 1 289.6611 418.5591 cm +0 0 m +10.56 0 l +21 -15.36 l +31.38 0 l +41.94 0 l +41.94 -40.02 l +29.16 -40.02 l +29.16 -25.62 l +21 -37.62 l +12.78 -25.62 l +12.78 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 335.707 418.5591 cm +0 0 m +10.56 0 l +21 -15.36 l +31.38 0 l +41.94 0 l +41.94 -40.02 l +29.16 -40.02 l +29.16 -25.62 l +21 -37.62 l +12.78 -25.62 l +12.78 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 397.1504 377.519 cm +0 0 m +-2.52 0 -4.8 0.321 -6.84 0.96 c +-8.88 1.6 -10.62 2.56 -12.06 3.84 c +-13.5 5.12 -14.61 6.74 -15.39 8.7 c +-16.17 10.659 -16.56 12.96 -16.56 15.6 c +-16.56 41.04 l +-3.78 41.04 l +-3.78 16.14 l +-3.78 14.739 -3.49 13.67 -2.91 12.93 c +-2.331 12.189 -1.36 11.82 0 11.82 c +1.359 11.82 2.33 12.189 2.91 12.93 c +3.489 13.67 3.78 14.739 3.78 16.14 c +3.78 41.04 l +16.62 41.04 l +16.62 15.6 l +16.62 12.96 16.23 10.659 15.45 8.7 c +14.67 6.74 13.55 5.12 12.09 3.84 c +10.629 2.56 8.88 1.6 6.84 0.96 c +4.8 0.321 2.52 0 0 0 c +f +Q +q 1 0 0 1 423.2202 408.0591 cm +0 0 m +-7.38 0 l +-7.38 10.5 l +20.58 10.5 l +20.58 0 l +13.2 0 l +13.2 -29.52 l +0 -29.52 l +h +f +Q +q 1 0 0 1 460.8916 390.959 cm +0 0 m +-2.7 7.02 l +-5.4 0 l +h +-7.5 27.6 m +2.1 27.6 l +17.28 -12.42 l +4.68 -12.42 l +3.36 -8.82 l +-8.76 -8.82 l +-10.08 -12.42 l +-22.68 -12.42 l +h +f +Q +q 1 0 0 1 493.0215 387.959 cm +0 0 m +3.039 0 4.56 1.16 4.56 3.48 c +4.56 5.799 3.039 6.96 0 6.96 c +-1.44 6.96 l +-1.44 0 l +h +3 18.42 m +3 20.259 1.999 21.18 0 21.18 c +-1.44 21.18 l +-1.44 15.66 l +0 15.66 l +1.999 15.66 3 16.58 3 18.42 c +-13.801 30.6 m +1.859 30.6 l +3.859 30.6 5.689 30.37 7.35 29.91 c +9.009 29.45 10.43 28.77 11.609 27.87 c +12.789 26.97 13.71 25.85 14.369 24.51 c +15.029 23.169 15.359 21.6 15.359 19.8 c +15.359 18.52 15.199 17.43 14.88 16.53 c +14.559 15.63 14.22 14.88 13.859 14.28 c +13.419 13.56 12.919 12.96 12.359 12.48 c +13.239 11.919 14.04 11.199 14.76 10.32 c +15.359 9.56 15.909 8.6 16.409 7.44 c +16.909 6.279 17.159 4.86 17.159 3.18 c +17.159 1.26 16.819 -0.48 16.14 -2.04 c +15.459 -3.6 14.489 -4.93 13.229 -6.03 c +11.97 -7.13 10.43 -7.971 8.609 -8.55 c +6.789 -9.13 4.76 -9.42 2.52 -9.42 c +-13.801 -9.42 l +h +f +Q +q 1 0 0 1 513.6592 418.5591 cm +0 0 m +13.32 0 l +13.32 -29.52 l +24.36 -29.52 l +24.36 -40.02 l +0 -40.02 l +h +f +Q +q 1 0 0 1 539.9697 418.5591 cm +0 0 m +23.58 0 l +23.58 -10.5 l +12.78 -10.5 l +12.78 -14.94 l +23.4 -14.94 l +23.4 -24.9 l +12.78 -24.9 l +12.78 -29.52 l +24 -29.52 l +24 -40.02 l +0 -40.02 l +h +f +Q + endstream endobj 26 0 obj <> endobj 13 0 obj <> endobj 12 0 obj [/ICCBased 27 0 R] endobj 27 0 obj <>stream +H‰œ–yTSwÇoɞ•°c [€°5la‘QIBHĜADED„Ş•2ÖmtFOE.c­Ö}êÒġ0êè8´׎8GNgĤÓïï÷9÷wïïŬß½÷ó '޵Ġ0 Ö ÏJŒĊb¤  + 2y­.-;!à’ĈK°ZÜ ü‹ž^i½"LÊÀ0˙‰-×é @8(”µrœ;qŞ7èLöœy•&†Qëñqĥ4ħjž½ç|ĉ9ÚÄ +V³)gB£0ñiœWו8#İ8wĠİ•ġ8_ĊÙʨQüÜĞQÊj@é&ğA)/ÇÙgş>'K‚óÈtĠ;\ú” Ó$ĠşF½ZUnÀÜċ˜(4TŒ%)ëĞ”ƒ0C&Ż”é˜¤Z£“i˜żóœ8ĤÚbx‘ƒEĦÁÁBÑ;…úŻ›żPĤŜÎӓÌıžAü om?çW= +€xŻÍú·ĥÒ-ŒŻÀòĉ[›Ëû0ñĝÎ}ĝĤy)7taġġġ>jÜÇT7úŸż@ïĵÏÇtܛò`qÊ2™ħʀ™ê&ŻŞ6êħZLĄ?â_ĝóyxg)˔zÈ§L­UáíÖ*ÔuµSk˙SeĜO4?׸¸cŻŻĜ°.òò· ċÒR´ ߁Ŝô-•’25ßáŜüÜÏ ú÷Sá>Ó£V­š‹“dċ`r£n~ÏôY &à+`œ;ÂA4ˆÉ 䀰ÈA9=¨- t°l`;ğÁ~pŒƒÁ Gp| [`Lƒ‡`<Ż "A ˆ YA+äùCb(ЇRĦ,¨*T2B- +¨ꇆĦnè÷Qètş}MA ï —0ÓalğÁ°ށSàx Ĵ‚kà&¸^Á£>ĝ0|>_ƒ'á‡,ÂG!"F$H:Rˆ”!z¤éF‘Qd?r 9‹\A&‘GÈ ”ˆrQ ˘áhš‹ÊÑ´íE‡Ñ]èaô4zBg×Á–àE#H ‹*B=Ħ‹0HĜIĝˆp†p0MxJ$ùD1„˜D, V›‰½Ä­ÄÄÄKÄğÄY‰dEò"EÒI2’ÔEÚBÚGúŒt™4MzNĤ‘Èŝär!YKî ’÷?%_&ß#ż˘°(”0J:EAi¤ôQĈ(Ç()ӔWT6U@ ĉP+¨íÔ!ê~êêmêĉD eÒÔ´ċ´!ÚïhŸÓĤh/èş']B/˘éëèÒÓż˘?a0nŒhF!ÀXÇĜÍ8Ċĝšñ܌kĉc&5S˜µ™˜6ğlö˜Iaş2c˜K™MÌAĉ!ĉEĉ#…ċĈ’°dĴVÖë(ëk–Íe‹Ĝél 𗽇}Ž}ŸCâ¸qâ9 +N'çÎ)Î].ÂuĉJ¸rî +î÷ wšGä xR^݇÷[ŜoĈœchžgŜ`>bŝ‰ù$áğñü*~˙ ˙:˙…EŒ…ÒbĊ~‹ËÏ,m,£-•–Ŭ–,ŻY´ÂĴâ­*­6X[ŬħF­=­3­ë­·YŸħ~d³ ·‘ÛtÛ´ıi ÛzÚfÙ6Û~`{ÁvÖÎŜ.ÑNg·Ċî”Ŭ#{}´}…ŭ€ŭ§ö¸‘j‡‡ÏŝŠ™c1X6„Ĉfm“Ž;'_9 œr:œ8ŬqĤ:‹ËœœO:ϸ8¸¤ı´¸ìuıéJqğ–ğnv=ëúÌMà–ïĥÊmÜíÀR 4 ö +nğ3Ü£ÜkÜGŬŻz=Ä•[=ô„=ƒ<Ë=GTB(É/ÙSòƒ,]6*›-•–W:#—È7Ë*˘ŠÊeżò^YDYÙ}U„j£êAyTù`ù#µD=Ĵŝĥ"İb{Ċ³ÊôÊ+ĴÊŻ: !kJ4Gµmötµ}uCġ%—K7YV³İfFŸ˘ßY Ġ.İ=bàá?SŒîĈ•ĈİşÈş‘şçġyġ‡Ĝ چ žkï5%4ŭĤm–7Ÿlqlio™Z³lG+ÔZÚz²Íı­³mzyâò]íÔöÊö?uĝuôw|ż"ĊħNğÎċwW&ÜÛeÖïşħ*|ĠöĠèjġê‰5kĥĴyŬ­èŝ˘ÇŻg°ç‡^yïkEk‡Öŝ¸lŬD_pßĥġÄġÚġ×7DmĜĠÏîoêżğ1mál {àûMĊ›Î nßLŬlÜ<9”úO¤[ŝ˜¸™$™™üšhšĠ›B›Żœœ‰œ÷dÒž@žŸŸ‹Ÿú i ĜĦGĦĥ˘&˘–££v£ĉ¤V¤Ç8İĤĤ‹Ĥŭ§n§à¨R¨Äİ7İİŞޏĞĞuĞéĴ\Ĵ­D­¸-ĦŻŻ‹°°u°êħ`ħÖ²K²Â³8³´%´œµµŠĥĥyĥ·h·à¸Y¸ÑıJıÂş;şµğ.ğ§ĵ!ĵ›½½ +„˙żzżġÀpÀìÁgÁÂ_ÂÛXÔÄQÄÎĊKĊÈĈFĈÇAÇżÈ=ÈĵÉ:ÉıÊ8Ê·Ë6ËĥÌ5̵Í5͵Î6ÎĥÏ7ϸ9şÑ<ÑÒ?ÒÁÓDÓĈÔIÔËĠNĠÑÖUÖĜ×\×àĜdĜèÙlÙñÚvÚûۀÜ܊ŬŬ–ŜŜ˘ß)߯à6à½áDáÌâSâÛcëäsäüċ„ĉ ĉ–ççİè2èĵéFéê[êċëpëûì†ííœî(î´ï@ïÌXċñrñ˙òŒóó§ô4ôÂġPġŜömöû÷Šĝĝ¨ù8ùÇúWúçûwüü˜ŭ)ŭşŝKŝÜ˙m˙˙ ÷„óû endstream endobj 25 0 obj <> endobj 24 0 obj <> endobj 5 0 obj <> endobj 6 0 obj <> endobj 30 0 obj [/View/Design] endobj 31 0 obj <>>> endobj 28 0 obj [/View/Design] endobj 29 0 obj <>>> endobj 14 0 obj <> endobj 15 0 obj <> endobj 16 0 obj <> endobj 11 0 obj <> endobj 32 0 obj <> endobj 33 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 18.0.0 %%For: (Lee Byron) () %%Title: (Untitled-1) %%CreationDate: 10/30/14 4:19 PM %%Canvassize: 16383 %%BoundingBox: 83 -268 726 -4 %%HiResBoundingBox: 83.2057291666688 -267.358072916666 725.64453125 -4.17317708333303 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 18 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -560 960 0 %AI3_TemplateBox: 480.5 -280.5 480.5 -280.5 %AI3_TileBox: 102 -568 836 8 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 2 %AI9_OpenToView: 57.5 -4.5 2 1192 711 18 0 0 121 293 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 73 %%PageOrigin:80 -580 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 34 0 obj <>stream +%%BoundingBox: 83 -268 726 -4 %%HiResBoundingBox: 83.2057291666688 -267.358072916666 725.64453125 -4.17317708333303 %AI7_Thumbnail: 128 52 8 %%BeginData: 12290 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFFD81A8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFFD04A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFFFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFFD81A8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFFD81A8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFD04A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFFFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFFD81A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFFD81A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFD04A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8FFA8A8 %A8FFA8A8A8FFA8A8A8FFA8A8A8AFA8CAA8FFA8A8A8FFA8A9A8FFA8CBA8FF %A8A8A8FFA8A8A8FFA8CAA8FFA8A8A8FFA8A8A8FFA8CBA8FFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFFFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FF7D5252A877527DFFA8FF52527D7D4C7DA8FFA87D527D765252CB76 %52767D5277525252FF7D5252FFA8A85277527D7DFFA2524CA8AFA8527752 %5276FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFFD26A87D0027525221277DFF5227007D522700A1AE7D0027275200 %4CA852004C272727280027A85221277DFF7DFD05277DA1002752FFA82821 %270028A8AFFD1EA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF5928277D524C2753A1284B4C595327 %5228A828522752524C4CCB524C4C7D522E27537DA82752277DFFA8275252 %5227537D4C277DFFA9284C2E7D7DFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A87D272777522728 %27282728277D5227274C272827284C522752A8522752FF7D00277DFF5227 %272827A87D282752272753A8272753FFA8282752527DA8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %FF5928277D5252274C272E274C53532728275227282752524C4CFF524C28 %AF5928277D8452272E27287DA8274C275227597D4C277DFFAF284C27274C %FFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFFD26A87D00275352272827280528277D5228272727282727275227287D %52272860592727535A2727282E27527D2827592E27277D272752CA7E5227 %2E527DFD20A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FF5928277D524C5253277D284C597D275252 %285352275352282752272828FF7D28277E524C4B4C4B52277D284C4C5227 %527D524B52277D2852275252FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFFD04A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA87D0027775200525A5959 %27217D4C272784528427272884FD05277EA87D0027524C27525353272727 %4C274B27287DA1004B27274C52274B214CA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFFFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF845A59A8 %7E5A59858484597E848459848485607E59848485597D598484A97E7E597E %7D7E5A85847E7DA8597E597E5AAFA87E59847DA8597E595A7DFFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFFD26A8A9 %6085848560845A845A855AA9848560845A84608584845A85A8855A848484 %6085848560855A845A85A8855A8584845AA9608584FFA8845A858484FD20 %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FF848560AF848584858485608584856085848584856085 %84858485608584FF848560A984858485608584A9848584856085A8856085 %60858485848584FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8A95A8484855A84848584845AA984 %845A8584845A8584A85A855A845AA9A8A85A8584845A8584845A8584845A %85608484A960845A8584845A855A84A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8FF848584A984A9 %848584A9848584A9848584A9848584A9848584AF848584AF848584A9A885 %84A9848584AF848584A984A9A8A984A9A8FF848584A984FFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFFD27A87E8484 %847EFD0684A8FD04847EFD0484A8FD0784A8848484A8FD0684A88484A884 %8484A87E8484A8A8FD0484FD21A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA88584A984A984A984 %AF8485A8AF84A984A9A8A984AFA88584A9848584FFA88584AF848584A984 %8584AF848584A984A9A8A9848584AF848584A984FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFD04A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A884 %85A8A884A9A8A884A984A8848584A884A9848484A98484848584A8A8A984 %8484A984A884A9848484A9848484A9A8A884A9848484A9848484A9A8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFFF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8A9A8AFA8A9A8AFA8A9A8AFA8A9A8AFA8A9A8AFA8A9A8AF %A8AFA8AFA8FFA8AFA8A9A8AFA8A9A8AFA8AFA8AFA8A9A8AFA8A9A8AFA8AF %A8AFA8A9A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %A8AFA8FFA8AFFD27A884A8A8A884A884A8A8A884A8A8A884A884A884A8A8 %A884A8A8A884A8A8A884A8A8A884A8A8A884A8A8A884A8A8A884A884A884 %A8A8A884FD23A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A9A8FFA8A9A8FFA8AFA8AFA8AFA8AF %A8AFA8AFA8AFA8AFA8A9A8AFA8FFA8AFA8AFA8AFA8AFA8AFA8AFA8AFA8A9 %A8AFA8AFA8AFA8AFA8AFA8A9A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8 %A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8A9A8A8A8A9A8A8A8 %AFA8A884A9A8A8A8AFA8A8A8A9A8A8A8A9A8A8A8AFA8A884A9A8A884A9A8 %A8A8A9A8A884A9A8A8A8A9A8A8A8A9A8A884A9A8A8A8AFA8A8A8AFA8A8A8 %AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8AFA8FFA8AFA8FF %A8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8AFA8FFA8FFA8FFA8FFA8FFA8AF %A8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FF %FD81A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFFD04A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AF %A8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8 %A8AFA8A8A8AFA8A8A8AFA8A8A8AFA8A8A8AFFFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8 %FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8 %AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFA8FFA8AFFD81A8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFFD81A8FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8 %FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFF %FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8 %FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFF %FFA8FFFFFFA8FFFFFFA8FFFFFFA8FD81FFFF %%EndData endstream endobj 35 0 obj <>stream +%AI12_CompressedDataxœì½ëŽeıu&ĝûÎü0 5ZÇĵ“[Ó N\ÜrK– ÉŬB:+,e;+³•eĉéçûÖ"÷…Ü'"ê^= Ş2␇››—ĊuŭÖßüżû/n>}˙/żgsšŝĉon?<úĝŝ/OòééWoß~ùĊÇüègż˙ùÉĉ³A£›_•Oj˙ŝĝá‹7ïßŭòdËÙHċżŭ³_?>ž.ŭŝŬÏO?û9>ŭ›oñù?ûÈß>ŭ…ŭy{~÷ê#*­ù[oŝֆSĝOżû ĵz÷ïŻĝâÍ˙Ëêä‹Çg—÷_ûôÍğ?]Ŝ˙?ż<ú…Kċ”]:ŭ" öżùŭ]“³31ğÙ&ü”Â/䳏Ċ´ÏíxN!Do]D7g›½ÍُgŜ½ŭċgï>ŝîû׏_|qûŝíû_üòtû×WïNżyġ'Ôĵ:ŭߏoß˙ËéòöĠë›0Gñ“‡7o1Ÿ½úx²ž“só+ë>ı|ùĉí§˙ċg˙òĝÓĈOŭ'Ò?~+çÇù“_}†Oŝĝñ#^Ïüŝŝï.ÛQàC)?ûçß?ŝéĴ&ôŝĵvûáŭ矽úoüîé1™ÓŒ˙ŒVŝññ³Ïßbĉe–B1gĵğ“ĥÔĥxigcGӚNuëì<ŝû›Çżüòôïß=êÜ|ĝĝ]½ŒÑ˙kÍïż|ûĝáß½ùˆħ%~4ë$üĉŭ§oÑ~ùŝÛWòîRìúmÇWŝôĝkŝŝí—e'–öÌñŻ_ŭġ‘ ċôżŭüñŬß˙wcÌgYëxr'kgwÊÖb9´gOnöË3íúíšħ›Öĉ&ùÖê·ŜüéÍğ_Îv1şˆ÷áͧëfw*ú?y‹3†ËÁÌn~é'³üädcħÁ½äÌĉǏïêc;Ŝŝf³żÌù7À›Üżûôöŭg\Ò/xà°ħŜaϽ}˙'­[~—|ŭËÏuZäïO°úżûĉûœŝAjÊ'ż{û%Şŝîû/?˙Ġğ}?ŭLéË| "‚ òéé·˙òżȅìùÓ?ĵz÷ÒĉüêÍç?²;ĵ܇ǓVâ›ògû÷ùoß=ŝ+ëúuŭôŝŬż?}˙ùĤ[m÷|ż{ûêŬĞ'ù|éî×oŝ5Ż0=k‡lĝĝñŸ^#6Ûç˜éCšt½?Ñ`SġüƒŝšğäéòáË/ŝ|úû÷o—GìĞ–w¨˧l˙xĈï^}ü3(òğOżX:×?×^ı"úًúŜŭöv<Žĵ6èG2Ĥßùjc˙Ŝžµ|çè9¨üßċ·ŻŜ}ó§Ż>˙ó›×G9¨_ž·­û*ÛĝݟŭËû·oĝlŬ½›O~÷êÇ7Żß>ŝáŻ_||| ͨkz˙é½+‡üÉ6ĝËЏŻ˙üë7˙òävĉĵŝë›wŸâŭáË7×z˙ÙçäžNĝóĞÏċ ZË?,ĈOp léü/~ñÄ`ÓéònS˙w^}úw ĜÁż{˙öÓÇw§ß“ÒOğżp;ĉÓċÓéŸ'S‹•NóÉċô_&Ó˙Ĝ¸Mñµ„Z˘ü×Jâŝٖĵ”bĉ]ıٔ Êm-w›ro&óÊn`Û·)~SÂD-“ü“mBÉòoٔyWnìe)·KıĜ;”ö×Ŭ„?îċ£;û°-Ûİ“Áµż)aS˘K,“ŝòĤŽŝ˙fS.ZĤ˙ëh-Ż­Ĥß­gĜĴêşĥ(Ó²ĵa³ÈşŞÛĠ-(ü—ĞZvë;oV˙ŸêR·Ċ,ËĴ˙r•ï·Ğ˙ë9\k7íÚc]ù/W–kœ¤YċÜ­M-ûµĊZòŸ{)wŬ*ĥ‡zYuÍXt‘Ú’Íuħ°@S]#Ġm-wRîky`i'‹/³]K+ĞêÄ™‹’™'/Ÿäġfy•;ħ­#L²e0„IžËç8HcÁ'Ÿ!Îŝ‚rç°Ú6ĝá-äPÂnÂ%܅û€‰tÑÇSÌqŽ7ño}|˜0 ‹]R¤<˜ĉt“.é6Ŭì‹i9ĉ”Kžó%ßĉğü€}b‹+ĦĒJ.sı)—rWîËö‹›f?‡ŭÌä¸/óí|??`ÓĜnâMş)7óÍÍÍċöĉîĉ^v’ „KĵäKı̨ş\n/÷—ì.;ÉlûÛpo1€Ûùöĉör{{{wû€ÍfeÂ]ĵKwÜ]ı›ï.w·w÷w÷ëâï}şÏ÷ċ~dzîoïïĤûûûîˆLĜC|À›>`ì7(xäùŭ`- Vsùû~Sî6ċvS.›r³+s+ŝW6%oJڕ¸)aSüĤ`N–= [‰ŻÙŭ~ûs·+·Z&ùç²)7›2oJٕĵ)iSât—vĊoŠÛğ)f-mʧúËvô۟ÛMıh‘“ı[Çŭêí×Ĵ­Ö~‰ö˂˜6Ğħ_‚ŭÄï§ğNs7·2£Ó0™u +w³·ŸħŬ<-Û²>kêfDgĤ–YJİ%KIµÄZ‚_‹›äìĠ+SI˙²ŭġ½Ú³ÚÏEÊM-³”R Îö„˙Z˘”P‹ŻEIo#ô  m-ïeŭ.²^EÖ'ʂpŒLûLólĠ,ódŜĴÌÔ½LÌE&˘LòîQŜ•/hä…îändÈYFdDöË=&ótëôĞ€Ž%P³Şĉ@Í̈́tYÑğù+7„0‚ zÜ(7ìVüÓq™o@6˜A@#İÇdq?`#Üaš. ĥs)oĊƒ[\ÜĜ!w˜Kİ.9ƒhGonqÑ?`ïÜab/ 3}ı ûÄß&3aßcoq1Üà‚(¸&RŒ¸0<. ŜáÛíkqÁ2rÉ!ᚠ¸n.ƒ}]q‹‹èR™p3%qGyÜUĵÊv薏·(ŻU^´—/bëŒ%•]ÚڊíZ+i‡—:ù7Ŝü³pÊ)€wŭpċqҍt~™l‡[ †Ô+I˜ħİ"6”Ċf:ÚJŜrûGo +璷P”ÓÛn˘zñ*Âm&@žÍûnıìvY9¸îürŬñ²ğáċË Çà+š× L½° ĥ2qanĥÓÎY Ÿf´Kü!ÌܝüÉÓ˘g]ˆË-*ġòĉòÖş 7•ÜûŬÊ +KhĤG9c\d/tÜA›ŠX/€Fqĥ4gŬ*+ŬÙRĦ=:ĊähOž£E:ġŬiüĈ‡ñ²°ż­Ĵ‚Lى8ıŠ=ZâN2ŞÒÒTi?ʐïdÔ=˙Òî˜E@[8})—i'ĜŬ +Ŭ„ŝ;wte"ġ·451s)a(~(î ÔŸi'éOܖI[ŝ½;, Ó"ißVaì˘ÒÙa™Ż–Òäi#äkI/,ĞH·eÚ˙ı(ÖßÇâŻÙ“q/,G|PĤ6|ñϑìŝ~µÛ½h—U.µħÙwµ(‡Ġ”MIQŞ,ܔġ¤OUlnÇğİEÖíߟĉĈĦĥÓğ=°=ÇM¤Ok^Tİ–¸(VŬßéù“‰ßµÄޞêŽc;wÓFݵUr]e§dUĤôç³ì´lĞvĤihŽŽèò÷4œÌŝއòÉ2 +£“úÔùíŽç´ÑA~3üÔ9ŝáŬ·Ŝዺ•~FùGù‘Qŝi\ˆĦ }/ÜĈ\%żTù ·H?Ž#ï8·‘€n!‰4A˘¤"… #Ê@·˘üQ9¨,rŻr%Ħ[HA‘ƒŠ¨’Â$˘•ñ RñŸ€ïHB* Qr* ‰=TÁú˘eßF΍ĵ[ŝ-ħ=½0„‹w*NžV×bċҔ3+"@ħ„iĦÔ×µáħš&U˙Ŭà-‹$ü´a‚vDu œ;ÎeG#wqÚñ$,m;$kOp#Ç22q•||›ç¸J‹ZĥjŞíÏ^-·Q5nua"H™ê/nWüìĠnħ+iWò´SċċNÍWv*ÀıJĥÛréË´èĵZıÊĝó0–ĥÇĤíMŬé=Ğê˙°ĝR5yc‰WJşZ]î´SìfQ7?UĉgÊÍÔ)”Êċ…Eˆû´Ó\?Uî^VĤƒñĊeşZġ5ĈKôëvT7f?]µXhi*LUh6ġfi?çZŞntŞŞÒöÓhzlÚz4ÊÚDäĈÉ7-­êl$J#-i)ı–²”ı–›\h~Ĥ@‘ĤUuL6thşB„QŸkTgCi.˘ıNkž 1;˘R Ëô$M9 $ϑéişñ’Ñ‘†iK%6iĜœ÷k„á…d`<ù×ÏñÓċ{:Ç_I‡şÓ˘‚eğUe§aÉgù&pzic‹½€¨=ÖT‹,m²QĴ² e³ÌŜÑ6‹ËE³^XQhó$üi³ÒÒN{/–ZµĠzr—bŻċmĥ7ÂÓnˤĥ[ZoÉXŠw#n!§-†Ü ¨ÑŬbÎ5`˙ÈIÒĤ0TŜÒd’8R¸AÍ5*’h7ݲ3ğ†ŸfAJS„X+˜Sg}[µ'ɇüÄm?ˆy36 rëk˙ £yH†<è&›‚a*DŸ¨Ìd6òFÈ{á/è"HŽQıĊÑßġ.ħêŝÚl‰jQ ı8S]‡Ġ ùŝŠ?ÁâNŻyÙŭ\÷£Ŝš=bUç‰~Y}nÄëfñğéUÌıúߨNġÁ%ó}uıê´cÑâWôBŻ˘­UaĦmu:ÙşĴŽ'·Ê'oœOÂÂÏÍċN׉PġAÜSš˙İH;ê}ZDÂĦdCı&b(ÌÜb³`bu5½ËêYÁi­;ĞÏÎÎċ§jÍb/ż½²*’sU‡jk²Ġ„òBWĞò2?+u%Y 'êŞáÔ+zŬU¸ĉùVCJĴnêĜf„ßù_l\Œ'cUĵĞ'…_äÑ(2iı4‹lZĎp#êETRw“$"ŞÂŞú sŬTbU™u•ZEn­žÄêK, 7ñ$âkñµ °w;!ĥcĞËoŝĈ"É6Yvê„Yî‰ış ߊ͗Ÿĉ\Ŭ™WWĉĉÂ\—•ÒË ;~Úp#½^ġYÔ`Qè‰ŻW^ú{cúÍbLÏBĴŞA}.`µŞßÉàôÚӋŻ]}Ëċ·\íocıq NġÜŜ„Ûğpëuĵ÷;Ŝ{/Ǔ2>ĠĥŜ{_ó?~ÂyÚ8=~-·GĞTù(Ò ÷§"Ô`µ™T+Ê´xĜ÷>ö×ŭì7žöµlí§g|íŻïÊR-O›ŭ´ñ³ßzٛe£>T¤™öYöĴîÚYî:ÙğSŬIÂuûêLŞ´\Ú†ŻÓuğñÑ͍2Ġžë.O",‹˘¤W(¸^êQ Ûŝ^ĥl~ġž92ïöÁ4}9ĥ!ğŜ,4„Û†Ŭì#A†œiŒéEŽqúœ%,g %#sĥĦ%υçĝéj„ÎaŒÎ3ç'g:<<—r=?Û3´9I;½ïy“‰“o|0vYdéBĊž#ŸK ¤<$èK1FämcAǢïéBHŞ˙ó=­QœŻh=çùŒW•ò; +Ñĥ•”fk2¸tPACÍU˜Á}02x¤/ıޞù¨ġê4ŸĞ>/Áϕġ=żÓ§È{äàA1e³Á…Ċï9ŸqoYÜ8Îejo˙UI'OáŒï>˘ÂsUcb ÒFážcWŝ÷ûTĠŽb&<™ñ9WDUŭ\¨˘œg‡‹—Ÿ`ïo =𲂴œ9çe£ òúr>Çhĥ*Şï÷İ_IiġċgŸ=~ ŜJġhĠgnĝëĈöny×m˜s^\j›/îe Rżo’:éSnhBL\$•ĵÈ#k¤q ß +kX¸ĠÓ&޸,^ÔkÀ·z\Ğ˙ġuÉ>Šl/âĈ´‘7T°Ÿ7rÇ2 ÷M‡„/Ŝ…ĠA[úŸl“H“8$fqOTqż‰ü—Ĉ…Ô Y•v5.˘Şbí5Ĉ)Ş•% Wj™kİĵ@Ĵ|G\XžĊó£9ù->ŜÓLâ——²ŝä”Ü,ċ²–)ŬnÊê ³7‰nŬĴíĝM‘ı›rXJܕñ§te>(7SÊí•r÷DYÌşÓħO‰¨Pj‘<÷m”1F~’ÏKœüe=vïUäP^ÖhĊİ +ŭğ˜19f)~uŬ˜kœÚŬFÚù lŞgâVĴ÷f Ĥ5œˆRóĤnç{Ñxq{QîĈş7İïşÈNĵlnNöÑê²q#.uŭėيÌċE Ù4\ETêÔp‘­í–İÚ­(ş-uјğŞc'tÂ*Żş-2Ġó˘Ŭߌé÷ŒĠAcŜhĥn%jŸjċûêçğĝfLsF dġ€kN*WĴnĞ‹ÛêÜ&k5uNiçÊ6Žl;‡çÚâ³Ĥ2ßŜI­1ż½/Úèƒ6úğŜN^g‡Ŝf[é`ô:[Ët z°À5{ş^ór}²ˆ>Äncê[4}‹£oñókì|>\Ŝ,‘“"MUZEi É/ĞĴ²ÂïCà7ÇÔŻÂÄV_…­ĝ½ß[İ{:şAƒÀŬIÛUŜžî½È½ş÷bwİ +çĵ\vqZ„ïUo"¸[`qÌFĜˆ÷‹ĝµDíOíÁ7ëÏĵ”²”ġîZŻá¸”°–İJïĞ ï6’ĵŬJôı~-[yWÖsÚHŠ·ğrÊMWŽ~Ê$ät_onQ¨]/ 4­żv%|ċ"7Ĝ4ûo£|u4…§ñ$„yêb˜GL…}$óWa‹ĴPM Ó˘ŬŞDïë6]ĠĦ;e¨ZD›h³ŠŜ´ġÍu}tB]ktğ@/Ì]đ_5˘U'zŸï&9ñÙŝs5faN›XĠ£Ğ‰xo$^#‘²ĥqŞáHj+vğ¤{ĦWûÀ¤Y˜’ĵ¨Qceϗ‰:UÑŞ>ÔKîN´Ğ·•RlC–4hIÙĦş¤ÁK*VˆħgZ˘˜ŞüĦÔS‰ÜEt²7U/Û›ĥĦMİJUHñ~Ù§…ŒÛƒĜĠkÑĞ-jħ>OUüš7 èµ ġµ„£öĈ>ŝŒqĤ×ÂUĤá£ûŻSžò€7²sO9Żî1ÑwŜ$ĵšÍÎLÎĥPÀöqıúĝ$èD}GçŬó=áĞhŝñŬğWŸ=~zúSŭèd>}¸zS {ĊEfÙ {Ùëĝ +sñP*ĤênŜğšïÁ:öNĉjħWkŭÍηâÉ´8–Ï{cäŞ* ƒ°ĠŜÀ5Öá÷/p™ô Şò¨#OxÌOëûĵ|À—:à d;Ûğùžê„ÛŬp·â5”c?­Óż„}@Dß ÑÍ´Â}‡ÈI? ¸ xc‘!ƒÔÍ>[zŸ’Î9pnÎ9¤µ?Ü@‹4\>YF´ûì›Ñkc)6>F×qG³]u$ġ¸×/~)³P Ò3/~"³ègïATYT„¨{›,ŜL‹w›b›Ey·TlŜm-LgTÌ58GBsš'Ó´¸2íŬ˜ŞÓ.'VMÏ>gĞïıŸĤEé£NMJYĦŞZ€NŞ˘ZŜV‰¨ŭTĦoŞ"àıĞNPÛ²†™í€0VÖ}™Yt-ŝ°„+%îËÔ}^Tòġ2]­*_ŻL_ĦñÈ:–éeÍ^^~ê Á“4ž/-TD9='|GŜ!¸:ñ<ËÂb¨ +ze銿™!máĉÈLl1[½¨™Su­Ĵ‘‹CċêLıN‹e‹ÜG.$‡”C< :QĤEĊ ú3Ġx[í÷54ÌÔè@[…ŞĉV—(ÁVšĈDnĤJYÚĵڙĤ³YĠ9kìÙŞŝħ}™ĥ¨d;]’ßQğħÄĦ-œ6ĞXf”UVĤí/*ƒ^j_Ĥç|ĠòÒ_ü3½ĵé˜ŻQJ0÷5t!ŠÌr£­Á0UA?“~Tp"S"v^·à>S|X|îóY TÍ{kœ:¤ †47샘âC*ÒèH&Vİ“›%Q5~OKVz⪢h*ħjQó´!,ígŬ£{ş²óꝣ…™"sĜ¸+£8Ó säh)ÓS•_£Ì—H|vG×âHÓä}N)ÌÙÍĈúÜ,á\Ñ2Ù´vĈ‡ĥ–cä'Ċo ĵĴÙĊĥ½èĈKÙt`Ğ˙1 ޚdŭ)Ú³ŬñğšÖDE²g"Jœ|8'ğâ=Ñb˙ŭŒ^£¨ÌÙğ9|żoħ|?珃íÇßéÀ;8:ĝĉt° $ŜwîÜw[÷Ġ"÷ċÍŬPnżZÑnz×mŝÛ<ó‚Ç#+™“ Ĉĉl£ .ë眍K§HäİFÈ*Ü`xÑ'ÇŝN?šisÄĴÍT/4“ggpŒ.FWl žX†_¸<ú›‚q`WAĦ“­ŜşĠOך(…OYßùğ|ŠÇaVlĞü Ż’‹Ä}uûê{ oñ5ŻSsĠ}Î×6ĥG‡³rpÌÄüDïÇoqìxĵ{Ÿİ½Ò×qğ}Ö%wS‹Uùĥaä S‹†yŞ÷ŻàÒşï‰ĥÙSç²qĥÜÉâ;÷ĠôG{ŬïözġtĝFMŻÖû|›Ô™Šax™$ƒ‚„“nBIW˜ï´À{ßÔQŬ·bdÔXw'‚zĦ=W‡ĴYLŽ—È~_+Vç,ż‰Q§²LIÑiˆaĵù}-÷Ġ+4Š9rÜ0ıËüĤÁi‹áäąˆcEqÚ"9m‚—ĤkÑKKŜ¤ĵTZÒ·ċ‚}|Ú^î‚Ŭííï}dHĞ'ÈÊ Ö߃äċ™R~óxZ)kċÒ{Ú"˜° ŜŒö[êòrxÌË|vAXl‹Û<Íċ¸òĈ²ġ†œÍzuZÜ ġ ÷‹ç´Ù¸­_m_Ĉ|a‡Sz[½ ĵßKġġœêdH>F'û>° + œ‡mTpĈu„Çe¸*×´„V6ı°÷ĥ€^½/wM`W ċ½ÛÑ9Pşİ&‚kñµ-JÓ­QšúÜġñIî h°ċi+]şˆPW7YÈЏh£Ó½¤ż›%ïżXÌ!Ġ3Ĉl#yífQ={tqw0(^ê˜Ábcùl'IJwÁŽÁŜ³àßy#Éĉ¸4uñ1_÷‚ĵÏχ3Ġl%}’ıËqÚ@Ċ.O–ĜŠĉxœí šML;€5>bħ pĜĈ),ħJäüÎqû “Ët³§œDÉ[G6Á#Çá#iyĠĵs]Vg× 6oÜa—ĴğF {½ĝŽëlŭ9W×ÍĠEs sYŬğİ:nÍ:Ìjñ0ğrÄá. ûĜŭ$~cQüĊnĊŐo]ÂîĊ ,ˆÓ½è×ċĊwk—,şZÑGJGV1Á›ñh„Ċ<Ċ<€ÄÔ$àÓ7É^‘·/?ìkl¤2ğ†“„–.)_"ÜFè#x/G6-mC+ŒĤdż’Ġm=¸İ˜wŒÜK>YĦ XÁM’šר”¤O+ŜàŒ2;YŝĈ€{ÊRc9]"Bá˜Ĵ0¸wBpɀDżËĜá^ôÉ2˘äÎ3_u§Ó¨T ÷ƒˆÚˆì™|ˏĊlĠJ÷“!¤4ĜccK|7$ìÖÉıĈÚé'Ï@¸A²#³ġ`ݚTœÉ‡Ħ`ÓrU†8Ïr(œŭ8Ĉó„ğp$ۅĠK€âˆWVjòIüÑ.EĤŭx¨Pdĵ–\_y£ûÊ ùŞú!ğ3OUës·h}ì­f­5kĊ6oĊ’êm›ém“&|ÚçÇìRcîÓbncHö)17É1·ĥOgñ}Yy˜Z’ĊçËßĦjƒâ};IM/ġğÂWîqö—şÏ f°ŭÛʸ n„rnä+Lߒ§"T<ÊĤğîàĦF 8Qԅ@RbĤEI§ oĤġ9QÓщĤAM–Šê¸F;ÎĝcgżXìPü•K˜J8,éë–éëġ[êP·ĈŠ3ÙÀ7[ +ÍŜ \sŭoŜ|ŜRĴà[ö'ĈÊ-Ĝ˙ö˙üw›<ÁlÒ(lƒ`^+óµ~~ê_¨É• N-¸‚y­{aógo2ĝN˜{²ödìÉ֓İW͘ĤĜòóâívß0ô KW½ĥnjvÍ`²Ĥ!òS͒R“İ´Œ,KV˘5ïŭ’ñ~—îmùwşšçŜċ*ÎÔĥLC>Ğ}ùî×ò[ïPUp·b+Èb'p;ÇRZžeÁfy:YÖ´$†J{eÎrÙ@Â5ğJƒ…ÛšVl1SµŻáĝ*ŸGŝŽ\Ù82o7"kóß{ŝO?{ùĴ‚LË-§›ë½ Ĝ\Ñü’"n/iÎÓFÔ,¨™wBj-UTù†3ü|/>-\Kƒ[Ët˜j°Ï¸g)g˜E‘ŠĤêw½M×rğñş~XÜíûék²É´˙Ĵh +˙ÙĴÇ[ûñSäzu^•Ô)ób-ÜcŜ +J—ÍӐH~[͎üCsĊߤ+²•R%ŽiAFae/Ìl䜣Ô)Ӛ)–KE$Z˘Üo°‰Ì‚OôBÑ5ĞùÖfžvIco7 c›&н™vŞlWÙEì½·˘żĥbñ0ġĠêJôƒsĊßE‡OÊӕŠëÌŭ‘̳JDÓ&ïÈZĥĠ*f5<‘UKĠŒ×Ä$Sân6ÙInw–…½mĦċ'Y]KS5%TÁԝ%Ÿ\8çŬ{}§OùFFxd4Œ;żïCżŝ^~1½òÊJúŝïiÇm3#÷ÌK0•KŜûĉ!ŭĠ¤ĞXÜ!TO—5UF•‹ŸÑƒŠż÷63Ï&Q阚gŜ$Ŭ'ç Kr7]Íϳjn6j82Ġv¤{|NJrRŽm‰8¤³eeLf8ĴÛ Ömŭ;¤ìïè š‘ÑX\lKŸzéŬ0Ñ7½ġ’A³+ñGsçK~ì˙ŭġ˙ÍN˙aĜGü)Ÿâ>ŝ÷‘ĉ£sŽO‡XFû‚XĈëÙSŞ$˙-Ğ▛÷E{ŭEI&ÚÑY­İñ.)żÇ+Kzĵ5A^KKŜ’wwáwBëwgà;{‚f²íöôµúo´Gó!+šSñĥWcUŸÈñ³‹W8„]yÂtt6Ŭ7 W܅Ù^];,]dmŸ#gíqPíu‚äïŽÂġ;ä·È§ëeӋ2Âô™ä-VܔŸBuNĊ>7êGâgÊX֙„[ÓI=•ĞçĦżĈr5'xw |ÛħÀ˙Ïo>>ŝçÓċíĞ×˙†#¸ûóûÈ­5Şxżfv­iVoiĴúRŭnIöğÏɰÔoé!x_aÔŬ&ffÏs= Ì6 Ìeáù&!J·›Ì.£4}ŭ Z¨HÜĞ; ßw™µl°|íĵe“Ş씆Qk˘hŬ,+V,~ ³„)5qáĤ#A>‡żj¸ŸÒnż,&lL*ôu£Âö 6kRĦĴèîçE[ákäƒ3ßVF¸é`#ì ĊV½Ŭیáml’2<µžK̰OËPMSùfAxŭĤ¸›~Ŝf‹l6Êt%ŭÔĝèÛĝ+ß˙ŭuxdEŬšJ·Vè u›ˆÛLtˆ°żÇׯAÓ7ŒzÌ÷¸†=N_?îħZÁ.ŞEż ÎĈàêŝâêğIĝġÔ­‡)§Ż˘p]üN›×i(½[!J§ŞÈ”Ò¤ôîE0{Ò19}³IE¨Ö39}ŭ IñĤïMŞ^Ġt¨Ĉqzè€ÈòVÙO[á§­ÓVĝi+\(üÖĦñÀÁïê ß•Ş |òïßŭî›wßĵûÓ/~ħ‘Û·Ó?|ÎŻ5ż{ġñ‡wèoŜŝġ‹/^A”Żżœĉù<'hé)ù“ áL#;o<ĥçÉÙtĈŝÄFŽ`SÂ,#ż‘˙˙Ó_ôGüóüÚĉâŸŝ*ŝ=~ŭ_ĝ/˜“ÓoN˙ü?ÍéSŭĉïñO{t˙„Óg¨|v§_µjŻñëM˙GŸöö˙ŭí͇wo^|óŝŬĞ=ŭR´'{y˙ŝ-&ïWu"?ı˙ôÍÇ÷>ıĵzŭo˜ìOŝĝĉí'ż|ŭñç§˙Œ/üŸĝݟùġ?})ŬŬÉ'ż•è˜âĵY²è(k-NĞóôuv’ô—n +8l‰rLÌİBâöÉĠːâ7ltı.ÇÓ?½’ÇïÉ[{6`g†½ƒXœb9{,ş˜.ħf†ÄŒi;ĊùœÀ0ž@ÏÎxD˜!YLâ)fĉ€Ç´|ğ8†litñlħ6§×ìĴÄ3(UFŬ †_rçÙ[ñç€/€ c\>…ù ‰‡iíÓق6á $áüôĈĠŜĉ3ġiŒy 'ĥY†ëĜ2ö…)ĝàŒâżĉg £·oèòsgµğÎÏ@Ĵ .›O.âƒKŒ qĈ‹&ÌÄÉ;}%Vgs •Çä@"îPiñlM^°M‹ĊáJù VOĦ +˘Xş›àûÛ1˘=X~ˆĴÀÚ׉KĉÌə1xYÌC:3màÉa=ì Š‘ÀÑß%Ĝ³ç\ ßñZgö YïC,}lœ6 .E†*z¨áÒ9H¸es²{5ÚI:ÏÖ£ħnñÄqĜ2Ë{àAxD “ŭ™ätĈDaŠS´³v‚I‘…òˆò|ú…=²àşûrĈÖĤdR°Ğ°!°‚*0Xlîû„׃Ĵ„Gí; q·ÒkO6×Ù Ù3_ _8JìŜċóeƒxlñÚ „Q~ìMLv ŸœHD¤s\‰¨(”ÀçA7UÀfÄq +ñœŠŻ›ÊÛsá.ŞşÉSLXU‹ [BQ̌†ž}:pĤ†ä0>@| cÔîpÊĴîÁÉtà9Ĝ£ÈÒQoŠ5ñÀÎFwĝ6*@ú|´ÜòXô–p°°ıÛ"ñáÂ9·|a NŜ`z0ñ3fğ`šJ8o•„BĥĊĴb-q8qíëÂK“ÁÜb×ÑIĴ8*&ÍR{ÍsÄÀħôÄ[ĵ ˘“ž6é ;2éžÀdêE#c=×­dCRy•tħ—{'›µ<Öñ,D~_ÈËgG•89DM–í?ƒ+Ça#DgÁÉÔ2';uÑxúıž +ĵĝ6Ôe ÖhŭV§‘²żß<£Ğh#k§~_‰3<'~Ğ{ ĉˍckˑŬĵÏú~v–Ç\™ĥ6𠈘nCŜ6Î8§ìAqŽ>;Ĵ zÌĜoè;p "MP"0=âġN3XpİÚÙÌé ²nä$|œĊ9€Àâ#™APr‹-È +á23CŜ¨LŸOZę\ŞŒ'Ĵ"‘L‘ӁÓÇÈ ÙÏÈ +|½Áż7`€yjw¨”tâ`qùsz4êÈ RÁ €ıÄÉMd.qO³ğ+óŜħE¤I˜iÌ@ ö† vĜgGuœEò­˜5ĈgâsÈpxaœ‡;go@ÙÛçŻÛJƒëäJƒ½_żĈقĊ‘VŻí3úŠ:0íĴŻÄĤÍKÔ=%syCGÖ*´·îuÖouïż<ċxÎv‡Ïžn>˙a.HK‰Ôĝ‡E<ğ­´Ż‹Ĝbĵw0‰6S1î=½7rc-ĥéRĦ÷DyJ2وċĉ[X]HÁsF“Lúœ˘Nğë+ó™êÓÓĝŭ˙Ž£ĞÚ]˙NË·şIXsˆyĤĵ/D|6t§Ájv›!µDşĊ‘ĊġĠ’Ĵސƒ V|Bíҝç íIѧsT)FİÈ=fɓ'iŸĞO 5%ëgâ’£¸m€•ŭ-ĠáĤݘg£İğJƒ­)0‡ôP83Dc( °³è~„}'S@ZéŬQ…Îa9![$Ù>|}XY[]&d?çÙµïôŭÙ¨Ûcİ‹W·Y†²ĝC ­pgb"¨ ĦOġ  Žw&S'DÊ)î5ô£‚™{ÚğD…ÉĜBžî?ô!òt=Gŭ¸ê‹öÚ¤ħô-úwj~]ĞĴ^ƒÙPSNX¨ìƒĜJe_4ÜÜ;ġ-ôIŭÜ ŭŒĞċÙuúñ /ƒ'~NÄ[ğzRµ>ï6ÓìG·BvqgAàá‚wŝ…´#i´ Ŭ² Á"Ÿ™°­„Ó=-úµ‘Z +ZĊipOÉŻ%:ŠF’áÜÔù ŠĵIŽ6F‰ɒ ñ"K6Óĝ×{%R£„—£ŜÚzĴÑħ{"µÛD‡˘vߣŸ"ïrH\h‡E²Ôja´˜;×ËŜs‘<§%-—Š­àˆĈ8•ÔöŠîèËH³f·x‹ĉżÙğ(R3Iƒ9Zı"օŜğ^ѐy@è¸7ôA;^|DYÜĉú‹d˜áĉú(ú@\▃‡ĝ@zusKVtÇΐ"GÊhÎƒÜêIß >RF÷H+‚P8vm=ĠYÔÖÓ ip“¤¸Îˆríìżdàêâ\$Gċb¸â8 W&:ûyô ´ä bÜÈLċT})ĊƒëG>ŽÍÜ9Ur™h˙À28ï½+i˜çġèħnô³ävÁv§œÍâÜ;\ŠšfeŞÙ˜†iĵtĈS’{… }.˜àˆ .bcBÖ=NǘNœÊÄ2͔Z£OĤ<ˆĞĊy:ÜvΙtp°+ê39ˆ’éݐ)΃—&­ŝ˘9 Lô†+l×§ ÑWXĵš÷ÚÖqÓ9ŞbÁÍs3:0xp:rBTéavċ+ƒ+'-"B™ˆ^W޽mé¤-Ñ3²1܍-ߜ;İ 6bê•ĉÑËs¸[žq÷d{í†ê{ì÷ÉË(Ì{à¤Z;8€ÒD¤ŒGî–C‹C§ƒ~:GσĦ -şW:tċċHD P*ÜqâeŜ…Šl\ŠlžÇñ†G¤Ŭ ³; ċıUşêf +…÷ä!O óöŠż)MnA­ĜžÎ£)ÎĜ;zwĥŠCÇÓġ[{'҃çġ şaı˘òDħcÓµ'Œ.ݎú<êZ‡A׊C—Ôġ[,ġÏ{n²’ÈŸvÏĥz;&Ş'yéÓ +}MùËY½qrĠÊĈĠñn‡dc@ŜÁşaÔ#š­İ·œjÜÜXpGċ=>"…u6€dXĵ:şjK[x\tÎâxŠÑíL.n&…iRĊ8¸7Ş+ĊDî7›,w˘î—o ‰‘~ylĦêR_=fqyxè‡İ_ó|'| Wò$p´|’\ÏêsA'ŬgW§ÓŒzj_İêM‘v9<ÊèŬ& Cylí³‰Ü?6úÊ"CsQ*ŭçÇŻ÷>ñĈŬĞú֋QŒ¸Ŭâ˘N£“=s…{ ĜMYüäëĞô‡n÷_fsÂsĞòóÈ'Ë’{#îb‡ĉ‚ĦU3 ŜÍ^À3*vÉD4&ż[{ŻXÌ2Ĵ~F›Ċ^@·%lU’DÊób/ aMŭ +N‰M;{Á`Żoö‚ÁĵŜltáÉ̖.î–`ŒĥŞŭÁŒ,ŸÑ¨=µĜ Úß[ó@ûl° +‡'‰1G@}`ŻÖ×dÁÛ1 $Á›h—΁ú—Èûû¨Ÿa%{óÀókŬ“òè<*ş×#óÀĜŞWɋUT/8¸Â£ÔĞġù¸-"Tñ*uÇĉħĠòġäu€SYĵċìcÏó†2´8Ò¤´ê4òPzŝĝFGĈqfĈ~†5†òÜ*‡"|˙îL!֋ŬƒWĦĤžN@˘F2yœóĜ*ĞÎ7ApÍÈŞû45ÔY&@˜$Ŝ)&*ċ°ĝelÑ\Ÿ$p#nĊ£~(pYĥôÏÒĠwŻÓÈ]›Y­|‰êħY/ŭ(À+Ϥ% nÍè6}‹ĉyµ›”ħ›a^‡Ħ<·>?ĈàÇ+#‘Ħ€Y$è0Ğr0ÑŬ2T;“‹gŠĊTa‚ÒéĊb0W8;uƒÂ3ĝI<ӞÒ+^’ LHìcĴT/;qxï bŜĝËAċĴDF‰{ +5Ŭ,Ħà²-˘’Ŭh'˘EûA ÁÄsCQ`üĈĝğ Ö ĉ^Ħ’‹(ŝÓJçié°ô­Ìò$Ŝ3|áíĊ+_ŭŽ¨ÓˆşÛ<Áñ°ÛhüŞŜL”Ò-[§;$91=%‡+ıToÜbĊÏÖÑ”PĦ,áìŞżnŽ#„׍YtĜ½4]”Âù ĜGsĉƒÎz &kZ2ä‹h×£S€*e~œŽ­=Ó¨s°m†,ù!œż@]ÈÓ‡{³è%$8¨1!<¸…OϟÄN+ïh$£hÈ cjñÑ#$>3ÏÁgÇ­ŞİŽ–(ïĵX( ’%žmœ9ÊÄgÂZâó fÊdƒ¸@ö-ôäúV‰3–óA+ +/$^Ĵóéh,C‹îôIC+:SZQÔ͆6İq,NE ìV⓽SעQ£nn†~†ùĈòÜ:ŭèÔ+8`KáY·3ŝˆ‰­Ġ·bDŒ`н§Ċ˘’—Ó-.@ğ7‰gŞ+&‰@z‡ñÌEB€ +,%Ê˘ÍÂw×Ë'K’£Ĵ–‚Äèaì˘, §U=ïfÓ:L9k¤ìĝUı$HK÷ìÔ (… #fUÔŞ2Óié§ÄĈÙj^î´ +M ħ†ğoè&ÏÊ+DÂhI(Ü\µĤ3Qi5<@ƒĴ°SL:hĦŞ“ĤÊ1 ÈMŭ„ Sž¨Rà DJ™h^§ÙwhÊ\ÚtZÈ ƒ´o•½*{"ċ)Ğ–|‘#p“X9Q3“o8Ħ˜˘IŠ´ġf½ÌôĞ +ÔZ=k8b$ùċQ+UY‡Ĥ^x²Ô&mâu0ׁbˆ‚ĵ˜ş:A2֌-Ú-İñÎ@:>h+ %Á5J9]W@ÎèQènÁ.t(ŽÉEœXdŜ#Ŭš+)u É#j_Š˘]Tġ—dTSW£ĝİ38FW8ĜW*qô\&² —‹µĥ(´VŻÑ@f!EŒ\GWkb%üX–êÔ`ݏw²4ï}§” /fñüpê§˘>>à¨ċIġ"Îtl?֘Ts*ĞOi5ŽK×òġ;“ĦXql%1­ö‚ÔĞ” È"ĈŬÒ%(ÂÓÜûBo[!P™”˘mŽì”ÏÛŜkFnĠ×9#v£ŻÚ7²‚~às‘(V1eˆFÊ2Ŝ +:!WÁz2|÷Y:Ù]Ù$KRŬ`u†Ċ‚„ûġ³F`“ fP Ĵ"0€Ċ* },ĵa¸íiàĥ§k—p²=ÁŻ9[‰w-”àbó8™$fì'38Ñü䏆Ò7è^HŸÓ7ŠgbgÒy‰šöÓÁ@h <9ù`^¨kĦ&f觟Ûa(ÏĴ≢ĤîÛ +Ħ‚"eÙA5 cK>;n5Wg† y DV˙”…N̉AI}“ëŠ UĈ ›™Íú­Ĉ…YĈ°Ò{ÈŞKÇĜ .%ĊL)×êÁP†Ŭ+µ'u­²jÁh̎Bڏ…ÑtJôÒñv|>¨Ÿ™ħ›av‡Ħ<·JËzbkƒÒÂCµ£™L ”T+ĉŠVc}j²x‘É ĠjX(™BÜҝ+ <*Ú%2.A܎nb_ÌÌGéŸĴÁцŭ›è“†VñɕâÎVÏË~,Œ„£ĵŬŜ ŝ­wj÷Ú­í8­ŭcžĝĥDtp*4£5Â#1 „Ž”B]ċJÇV +5ĜBİg3ÛÀDîUÒqÚްÈĤS!CNŸà #ÙkjXpjÑ1µ0=& ™T3`†"|ë1éħ¨Ü§OJ|ÖÀdÄ*҉÷)Fĵ,ˆ9 Z#-.'›–Ŭ)ΰÛĉ¸gqÑĊxN”YW-~qáÀz-ħ½:İÑ´šF -Ĉ½êÀĴ8t÷ˆZä”ü|Q‹óŒż9Ïô÷#´$dĵ['VoÛ§—¸ç÷ÀQü[ôñTË0"áu‹şcOUqÀ{JW%’T’3ŞNWÜĠâuÛz°Ĵƒn:˜­ƒĦô-ú7jZëUÑ Ò–ŒÛRŭ9Hߢiaö2öÓO|À3 rlGûĦ!½ÄË܉€è-ċۋÎ: ğp°x̙•š§"‘ç=ŒÖB-¤ +×A?€×:„Ħ˘{}À +2é1eĴÒLû!du£í?ˆNjx•E3övS2ôÓOĉ0”g–dáèĊˆÏw˘~tËÌdĝħÒ6¸Ş—ì[AüFİÁhR;³b>‘İĤ U~¨`èuá SĊĤħ…RSܳA.:fş:èĈĊ@ – ˆÂÁ†ŭ‹´‹}ߊžĊñԈQ}ÄvC!ta•ì†ċàúŞ +Ñù=Ìä0€gWäÇhô ›H£z”œÊî°ßDù€kJ”r1up$½‘ JLnf…îÀà¨z¤³%”mQWìPáÄ_o<ûż‡‡£h 6M\ɋlƒ'nhĦ˘´Ĉ_ï1à¨ÍS]˘ŬÊ´˜mÓtf: W=t×J$' [ÙTN”5˘ G˘t9òCŞéäċLœ=̃şd<0%Ê<‚ÈqŠ‡ÖcòA‹D[dbôĊbµAb&ÛÌÛ(ÄdŽ1Ŝ¤FüèAĉ†*‰ïAĉĈnzt8FŝóÛĠۃ͌IE‰óM>´²g İíÁċœ8CSE·qjÈ{p9Fk'™ħD˙ f~îÀċèœ*t=LÀ\ŽN VÂÚd/8<=¸uĴ² |\Ó7tĜr “°KO÷F 0ë°ċDS‹ĠMmŒaD™XEuË܆Äl^ŽèeŽ‚ôJÀċ¸Y•ğ²LËcG”9²À–ĦxÔûûÙÍÑD&A[=ÜYtyÇÀ?cqç"Öı£ġxg<ĝ…kˆ74過+êęKˆâE'+4縭}ŜŽíömŭRwĵĦE7n}ÀŞh¸ÏÔSC â€SAĵ@ß@ÔżŝĜÍ0…Pž[ŠE-كšŽ!š 6ħa po}£1ŽDSÜu=FÄ9´ˆŠĵé Y-­è˘€ƒÈNàžƒĦP›çĜÂ{Ó6´'upoŭtˆqcZÓj˜›a,ŭô>³HËjöài<ċYN0Ħ4#‰•‚>H7œ¨îzĜ6[xŬŠ!¨‘Aßú+ĜAĈ ½ô`s@ĈŬ ½ž@ëDçKS1ƒ+­É#z˜˘¸13úè…ö ô‚Ĥïe˜Ù~ ϳÊħçî*˘Ŝ òŬ1@àbD XxFĊ7`D ŝ‡ LŜ1àċ pŜ!HĀ 7€D PzHDÔ;ĆÀġpˆf݇Ü÷Á!½bàÀ!Ĉ>ŽÀ!†¨aft%bé;‡èñúlˆ¸Ż‰üĥ ‚ßѐülˆÒïbÁöë‘ ÈßÑàŝ îßüĵ‡xó0t‡8€:T”ÀC(‡.°‡rh°‚€¸…p‡HpŒ¨ê!1ĥà€Ŝ0€ è =Úà!xC;8`7ôĝƒ†óDżFé ġ1ZuÀ ¨ßCb8 €‚c7=á8”ħĊàÁAĞ8aËżÒ!„03Ŭ ³ÛċÙUÚ²’;|żC ‡ƒVĤBl úàşaÀ,\żĠĦ§a(hgıœq[ĝ5ĵQßBߨ›˜ħ›~nǑ<·FËJ•- VN‰ƒl3İ3áç o.(]+î<Ĥ_?H¨¸'„…ÓÌQÌâà$ #êĴ¤`È +Ċ17Ôë 3šŜŭ”éĴ?èĴ2]”páSĤ>Ĉ {›Ĉ­ +isâq¨½ }-ÊĝúħvÚÏ@ûÊÁw{n ~¸ĞÂöW…‡¤DÇy*eÔv­ħôÄĉĜ06"t½£m[šˆO¨á£èÍÇ V€È<ĈĠ“ÇÌq¨_ı¸˙léĈFĵ3ĊĵÀôṙq -ş×iòĦ•ĤÜF´ÏuZ3ˆ-u`íòì×ï¤ê?l˜Š+mÒWÔĦ5cĠ÷†$”“5…Í8ĥĵÉĵ3ĵP­§ >çêÄ­1$Ú[fŞÖ<•m‘I1?;ĴÄr‰VcF2§†ž“3i‰˘@Tkın— +e\ĉjĜ nrÓò-Fû‹Ñ~Äݏé?ŻcÓÎş:Ŝ§CHçù`hµ˘E”ì_hùV?í9×&îÇCoEL“ĵMĥĞÎɅÈ~Üö­¨xH‚à;—(½NÚñ³ŞL“8;Û.!ĊQ²Š$<´hW2s,òŜ+â0<ö5šĊÛĴH>Ùq,C‹îÚÜµÊ +_èF5>ŻKİb]ö³¸2ŒïÔµhR\77C?ücyn~HqÛS.V·2Í£¨J5ñèażĠmmlEŞDĜž]5ŜXPOĝ4#ÈLġ3Ğ ĥè׃çmë— +UĵñœÄQìwÛo™ê\°°9<Żo[ûZC”U Ċ„ùF ö^^Öàë3uí ô-ôIŭûŭ =ŒċıĝѨÈz¤š½ĠJ(c‰ÄJİ +˙VéŞİ”£‚ŞĝIÂŝ4^£úó=BĈ_.FĤƒ +U†û3Dd~ĥwôus‘ û†0´èŜ İŬğVôbÍw5Ŭ0–t.„”aÈCvÛWé*ôL _o“8<ùÊÔ˙xhŠXS ñfŜŞaƒÊ[·ÉŠVî¨VîP…pKlü~… ‰Ä/ BKŒĤĝY²„Ħ^§šĥ2A/ˆVrĜħЇ£CdÎWÄèeeœAĂ £ĝ;, +ÔŜ!bĈfĉq° +“ +.@a‰ae4Îm€Â²„ó‡,ÏgŠq#,˜(zŞŭy@£ŻŬşfÈÒu¨‡³‚FB—w°ŠF@va]›fMÉ„1ĈV¸žŒb¸Dñwh`W7ġŜ­£*şcìŻµ²ƒÙÂ.β){„.fNâ8ĝÊôŜL‚2Ŭ +S÷ÏY+ŻÖÊ0k}N‡µµŽîŞk}§ŝ[Ë,tÏı:wÏşx~˙1‹î‚‹ u‹Z­iĞìħµ²à¤úR Ü3Ö@Z’óĠgÑóÑr½zÔ,*}Fˆ+ ÁL<ÈÉJwĴ}.ĞGħ"|ñ,TcF˜+sŒkeF +˘C ˜lĊŻrT]A­˘Ċ`DŞrġ5z\)ĤsN镊zê£ŽäñU¨9Bž’ä:ÖTÔ5ĤP%‘¸R<£9†NŞÔ7éA¤xĤ`~ˆ…Ŝ”HWÈ(‡#PT²Úù< şá¨PtĜIiĂ*ın(+ Ÿ0Ÿ™ˆ$Ŭ”œğôé0îİ2/Ħ ĵÚÓZف)I6ä9Ž0Lä|8qâI]È%BÙY;>f­8€6Z+;`¤ġ9¤Ò2¸@ĤġşÊuşÇ\ı6Á4*+ĤÜÒZÙC‰Ó(AöòH%ÈîÙÎGHJgî£#Vqˆ›Ô*{Œ˘öœŜ¨îİP_·Î@÷”ĞóÖ&ÖKš’+¸GKe6DŠ&—BSòkD‹wsDĴ ö_"&~ßŭcZĊ6ZÙA µÇT,˘eHܢeü­Í2 }_×Ĥ§ÍSU[ñv?%Z+;üŬĴè (Xóŝy(H/Ìߢ÷vÎÏY* xÖÊÉg}N´ŽîCh}§ŝ[Ë,ôÏı6wmrik‹ŝ +@RÙ£ò€¸ÌŜú~˜ç+x@¸Â‚Ë•tŭ6ß?§UéĴ•{žċ1µgÓÙgyÖf™†ŻkÓsäÊèÇt?™â¨ħÇ +cĞ€ÙĴŠFÄH?€SGŠġQX`³+qW0GĊĝÀâb`İì +–çôàËèŽĈ—ë[Ô?ùù‰ŝZ*›ï$éÛµ(êkĴ¨Ż§żŭŭĞŬsĜïûŸüñÍÛÇOŝǛO?ŝYû§żŭĠğ ÷áñßß<ŝzûĊĠÁ×ĥwo>ĝß<~ñÉ{üës­ŭĝŻ?Á?|x˙îúĵ´ñ˙ĵoëéšH3B4ÜßÓŻú_ßüéÏ_ĝż˙—úÑ\í–/ûğÇŻß}\ß6\ëš˙ĵú DÖ÷×ï_Żßé–ö~ú››_ùOîß}Zğż/zó~òËÓÏŝŝÍż?ŝ|ÒD[”tû +Ÿ7âäOŬ,ˆ÷àİ5ShĴDMeù˙?ŭe~> Ĥ)sú{üúżá_¸ÓoN˙ü?ÍéSíà÷"ĈÈHúç,ñŒOŽĉôë£V[ŭz}ÎSu‡½ż{ñı­ëvyġúßŜĵû“n˘ß?ŝ¸[³§3/ž~+żù€Ĉjʂ™B4};O(cŞ]Ċ×#5…V+FkÑ>¸Ċ݁*Ô(~ ‡éİy˘Ç#ogŞclk)+ÜÈJ&½È4œÑè† +fé`E£Ï +ĞZT:½£RÁSäó%…ˆ@ñ3W$O·ÑGG‰ŭQ´WĊN#à˜!;ó* şävRïç$dKĈû2”^Ó;z+ÎxRğè1g^ú²‹D„s&ĞĈW–Tġ YӃ29Z·%CiX2é›Ğ ˙¨pVt¨ —ƒ +fïf…oҙôĈ¸~ö&w˜?ı8fĉˆe]|Ġm‘Ñd*Ħf_+ĵ[&LÀż˜ŠR0!¨/̝lİ'6ŜPó:TȵT–déË@ÔÊĵ‡cˆż"gB]Ì +9*˸6gĤJ"܍š²‚ZzT”L%4ĠG`bD}”LË%y*$+J&:vK?^œAħùT .*ğmŒ>GRW£ž9´E!ôe?Ù"Ȋ +ĥ2WV|KĥÊòàĜ¤yĞÊsé‡ áĝ$§ÉtÏ"iˆ-5$'Ce€Ğ>ÈĠD/¸#d>fLœĤ7#èAŠd(JĠà˜Ş˙eÏĜ:L˜Ú¨áÛDSC1މ)†Eç™| +D`ŭ:^˘á!fòŭ Tm44ËçÌDF+™tĤJj˘—Ô'QE gĤC£Ì!cZñèèa¨ViŬÓQQ-­îÂWR,ĦTDïc9iŭGi +Äšû–ÄßÒ²/y]Ĵèiù €é‡ûƒGԊš4ĦтêĤÚ"h ɳ`ĊKZĜ%Mİ´˘5X<…ġI3³ŽCTT\vŽ% 81ĠĝŞÉd:( iâŞñDdÂ;9AÌ'ž1ĉ›-|jĜP’ €2FmEЁÂ…"ö“VdQ•Ò“Ld2£+ŒULġ ·ç‘f•ıe[4ú*LÏÉ·r +rRMĉÖ0˙"W™Éb K•‰FĝÊ´ +÷ğxN\†ô$ǜô™zRD¨:ßBħ&XMè)ƒ^X3„-U†ĉ›"pžĉ™I'™>SN˜“hÈjʤ$ġKސQ +}Š ”›„)ĴôfúMşäy|E‘ Bj–…ŬHXÔX[DĊ½Ê0ö$N0ëÑ˘Pnˆĵú:ÌÑq*Aá’„‘c #Ĉ&dšċıxlsĤe†&]ú +ÓÀó&£#"UqI c“„JEҐÀ9KÈŻjA=NĉxĤÛGh @Ÿ4ÉÉÒb#ÉAšM'b‹ 21LĴ³>. ŒNä(RK&Dm‡@‚& +œiïʚK]aÁó’7§Ŝİœ ñÇcV. 7ÏníŒ&qÖĞΌ4ׄꂖÄK”’â"î=ĉ`lĵ|šJŠÌ>0™htĴ$ܙà@€ĥñħ(ÌIHô1њƒÉĀ-)âÄI}Íí¤Y"èEŽ%žğNa3UT§HĈ·¤¨‚^Aä3ħRQ‰P^”•Lè—€ĈEçQD²ÀómE ˆÀµZ*€xn‰â;ĵ\uqdzÑ ßœéN‚ÁñyŽS/FQy y4İÄÊB!·¨1Ü!-²Û&ì—QuDħbúùiɊÔdB„уıZÈwôÌ,j<™ó³@*MëìDÚb+IĥWjáK †Ċ×.ѕüŒP ^1N*™5ӕx*j°EhĤ˜‹&In!ˆíÖJEjÓn˜ï…aíàuxıħÒ×yÇ0µ·˘i×ıÁŞ=˙uŬ–Ìe`Žvĵ.Aɸû¸-AÛI/(~‹1W¨!qÁŽ$*HžU‡§ÓdëÀôêË êçjĉ µ› s\“ô 9H’X" +U4œÓ YI*ÈJú 'FÏ5]ı@H$ߢëƒTèsÀeѲÏ7*˜J_Ĥ¨F´;ĵ˘‰ĊŻĝŠ‘PȏœT¸&ÒNÌ@‰ž‹ÙTàˆÙ“iĜsŜş'{w˘y’ Üó"ġÔü›7I·"0TÔ%VY5‹f'×ì*sú6ƒ<ù&²39ўmçĈ:EÍEħÖc5N!é>3>G3)j– +Ckğà¸ÌRáıĈ°‚ ÎP"Ó •`ĵĴTЉ9‰ĵ TÜJwı˘&ŬL+;+ĉıAĤ$ሉ[Rˆ?“hèèJ ó[:9ݲNœ:܀œşÌKšÖäàf%ìó‚çTÜŞÁÏ 0"ÁËÄüĊ1%8Xèĉ¸!ƒD)÷žk~Br7âcµ™“ú͘Il£5¤è€;–+WŻrĊL#ħŻtgIÖYQš“˙يY˘ŭèÏAq×%‹$.´Ğ\G<~Öò™ÏÌN“ĝÄ {ŬĊĴñw’‹ÍC™ÜePûGDâ·)ĵ +„Llô•矈­Ž1’ĥ$™',¨l$0s–0zĴô˘ĴżUĴ +-­tÙ£F›‚,İ$Ӄ5´^J½ô]Ċ€ä,ĈF^=òıx†ò àˆdr†^“Ħ÷fB$W2ŭ6Cœd½‰İ{³î&‹,“|îjŠ ċ_ ,0™{c(\7D‡Ê`Ë4,WŜ_0‚ +s%ñ†ŞB+˘şŞ:…qĉ­Ŝ°ï¨‡=KŜž&*ï…'/C‡.˘ĠJ¸Ŭًı„ĥ\"ĝDLàZñş*g<éV2dÂú­èôX‚)dVÔÍ\sLEš•§ŬÓ¤Œ2·µ3I´™bD„ôY ­`ÂëœxĦôµĦ‡V²šHE‚=‰sé ·Jegƒ I5hœċ>g8êóH\;ıâ~Ŝ~nİŭeÂ3ê›Ù™mYLİ£Â4“óôR9gŭ–€€³Â +\£”Uô’ĜµÈĜĦYĈšT|¨˜ċ–>TŽ~œ•¨>T*Y›,ĵĴ8‚ıƒÏ 7^\ĊZ£úVŬ<+Äm7C&Œ[ĦçeâìŻĦŜ¨¤MŸFĥèŞĦi–‡;ÓÉR H’HPşUhÚÓ^LŽ"bŞáDÖo–ş\ÍV˜sŝíé &pç°-H>(?§ÓSŞ÷íLxR!êjŠ„äG3ɐ½œz_JöÍ$~0İä¸^…İ·˙”ĥ8İĴPn˘ž ÈuA4`Vˆ—Kë¤5‚Iĵêt8²còwLêˆO4äÒ +k´p@ÜÊġÀ@¤c*ÑçĦ–GšŜ8cRJ)V`GéŠï+ÖŭÛŞ?ħ\ dé[E‹Ĥa†Â§ÈQ˙)×Q¨ĝB„7 3àΌÂÁ’ŭÇy ŻÖB!ÁY–›¤ÑT·+ù…,$ĠŞqöuÓĊ։şx^ĴĴÌb*Š’žÈÑapĴ$dž.‰D†˘Ğh‘>KwrÊS¤—vHÌeĴ(âiÉë}fÖî(4³;SV¤…2[Ż^ÈT# sĦfeĤĊUŒ›î˜‚@×SYAévôÄ!Tm½ *P"ğegeöœĝ/e}Uş¸Dj!¤rÇĦ–TîT§µ +((!˘ˆ½ĊͰ~‹Ô³x)&ĉ˜=ÉuBġ˜ Ċ”HĥÚÒ´ğȇTˆ +ÛH•)A™ÜL×7K$ċÖ$}+ġ€ĈNDŸ%ßdVŠ •†g™•^ìeĈ„ÏÌŻß’ÓĜcâ&+ äğ9KÌ0[Vêŝd…pf&óçdSáWšŬġ¨Ê!Y•–°é½'F_ÑËdl'RhĦÜsH5̄â`à2ëBˆ$s„Çûèİĵé3”­$Òĉ6ċÏÉQ>$şÜ†ÈPĝ™8ĉ|!=Á­–Ç +IEí¨OlÌëaÏ´²RvgĤ *ÏÖt¸ò-+dçñı“D| nŝ]ښ1wˆ81˘°ı/$RŠ`i-ħŭqE8+eŜĝÁĦ²Te·€‘Ċ[eÀ˙SuÊkÑ›ŞşÏtJnëab ı3ñn_İJš„×ĤzV4âät† +úĊµÈ’6ê`è Ĥ# _%êëÈéôÇ/0îĞï’ÄÓ< `5 °R÷Ĵ=gNfÓK `QUVr+PĈ‰á"p£4—aröĝ ïĞ:1Q£*.NVˆK) +yC’égéĊ›°:‹ż5>wŸ½êòÄíŸs)¸M\İŸP>K>Ù'ëŭœ/³Ġœô×u-£×ƒ(e™e]v|Ğĉ%c¸YĝÑD\|znï#IĦ.iR™Ç¨:,şŞ ’KǜÑÙÒGSž‰"żL•#CiqITÊQ1Q’ófjX‘ĞáûG(ŭޤ;†;ë•L$-•.ĞŬbŝvPzĦĊ%ĞĠ‡ ‘+Qħĵ“Ĵ6dF¨Ğ•H³Ä̔’E˜„0äêRM™\Zu ܤ „UÏLírŸlö‚‚Ĵy‚*¨‡0¸pRkETU:ßë…CNÄ j£XEĉQ/x£ˆ¸ …érbñRŜ îüI!N!Ìas?ްüÒVvHbòÉs΁‹ÊN(LÓ°C8JGAĴú³Rĵ­’‚Šps#)‘f݈Ԋ;Ğ +5!b?6Ú]l ­ÂġÒ2ÄĴ ž ÂHşĞƒ˜‚à‘ċdffñÁ T7'ħĞY2ydVêŜW:*ß=†IH‡yıëàt‡ îĴë˘ırτq_Ĝ=*Ĝ7 ~&\jYÛVÔP0úⓖëEÉ +j/ÄËP˙Ş‘jŬ‰2‚¨ğ’L²üxù–äzÄt?¨P“Œsi&OI¤ÙÙ,Ç)ˆD$“ĞÀĜ“w +‡jšSŜ âRÙ4”Ĵ(”šÌĴNµo/8'0™ |<ÛD·Ġ0ÑüàòÀúC#jÍ7g9ݘÑ@uQŭĵéwÔ ˘i7•’À@mfN}hNPß͂°„ħÙ†JÚĦ£šàÀDÒÀċbí_\'°/NİLUI4Qï™˙€ŻI³1m5̉S²SĊô‚Šp)ÉA"%ĝ"9ŠïZ!èNÂ×25rPĤaÊŬ²fŞY’ÄT Ô1ï. +ù…‰Îc"TÒ`ùġdrġiĈ˙Dw³ò'Ĝ"Âr@bP"Ó£|™yëôÒF=CŸ˜Ĝ!I/Q×i3‘ĜìEYJ6ßdĉÂò^ğ`R!ĥÀŒ¤ċAŽT ­…tü ÇC`î+ìJR‰âŠĥpĈJ ÁB&×è̝‰¤Z–')Wı/Ċu‹–b°–äËI v ‘T_OĝÂè%9‰—<ıœÔĜ‰ûŞà}QÈW/İ“²0ÎÔĠ°[ñ¤c4)r3Œ„*ôA'ŝ¨p)DŽĉ$ÁxëLÊ~ \èCP§š%=œDzxĥàN•4jsM$Ż´Pû§<żYJƒpHÀE‘ +´­™h=‚Eé´löšKáİ™Ħ&×X]i!Œ˜²­ë 1/À0-ĞÙê8ĜH³“Ż{žAI$™R*F=’JA##‡ËèXš5;>ÉŞĊ\ĥÊ í Yé‰ŜŒ de;ĵœ:ñ¤ĉŬì$ƒ53Ήiç–S^îγ‡°n5Ž×I”÷Ĵ`nDTß.IŸĞĥ5âS‘}Ÿ#hYפ”fŞíñŠ^TŠ #)Ê[ Ä,Ü%ÌĦ'-Àu0ˆP\C<$0ŭ’…L­3I˜Ú–Ü€ĉ\- ™µUV@% [4†“nQ.Ìq”ğĵfg 1Ħ… m1Ċdĉ••˜Up^ž$"-m6k?Q†ËÓYtĢ÷C $­¤ ,ҏW$.z Ԋ™šT˜–ğŽj5ŻÀ™, Ñ"™ 2 ä%#)ê‚X5CIŬI>„ga0.÷mJçR]¤rÓàÏÔ¸ÚZQ|Ñw‰â·5·{ÉÔiĴb]ÖnxŠĝ#•”àüò4Ì..ŝÌÄ4RMKĤiÄÄ>Għ˜*Sé$а|ÒKÔ ˘ġ%·(ĵ!7*3ƒşQ§Ĥséœ&v Ş]fhÄ*ôW#\³òE”Ê™†£€żêZ <ñ$ñz>.£Ë ‰&2=­ĴāVÈzŠ(LfC–~ +KݐV’i”ŸÇܒ²ŽöĈ<ô5Œ’@—÷’@gɆ#y]ĊPEï­,ƒ#(ĞV,.Œß´5c€‘‘KŒ9çùĉê)˜?B!}ŬÉÌ ‰j"ÁOÔí&£T5µò;Sés Oá[,‚'=@v–hıĉRÇJÑs˘Ò(ÇÈÑ˘`@Y\Oü~ŸÓÏRÒµŠŽI:£­{éLTµÏ ‡ž“ž$qŻ„N˘Â"Ä ÉÄ|Á +VĴ¸ûÈ0Ü$sš¨$ë˜ħ5Zqŝ?öŜfWv&;ÓğŬŞúšŒ[e聣=°g‚P-\*AV|÷ŽçYLfĉŝ\“2à38›Éd’Áˆk½?Šo…›DÊX×r8„Ñ2ĠŒ~…ZĤq°&nMDtŒê ˘ÊÄè0ng =ܞĞqÔ) Íl˘ … ™Ë{Ĥ’F†n^ +4Zc²[Û÷,Œ†k•lò\b™I+(5îSgw!9~Ċq´pT³Ċ4Ċ0·öc/Î[ëFŭb˙‰Êža™–RE§7kógĠ~D8àĦ‰ÚÓü1Ş`ë—V¤€ŝ aÍKb·%JÀ*c9™Íü¸dĵ§éâ“(=LÊ N7‘Ħ"Lôbu˘—î9%6Wġ`„_Œş ÷Ëú +Ĉ2A‡ğr+PjÇÓ#­ñŽëĜ‚„”\ĵ͍iäÈÁ&YS~IYû6áe m¤CÒÛ¨ĦjŻkçÜ!atZÁŽ=x9…š[üm5{z`f—yv”¸¨äù>CĦ'÷,Ë|šŒ”ûŽÓñduˆ2—MıŒ J‹äO§jߑfIñÏß œŸžċá áıbà²´^çŭËǐ%—0ôĴù~³¨ħ£Š˜™V•• jĜAû€`°êŽÎXl_„nZCÙu$çÚ ó(f_ê´Ċœr}A‹µġááĜ'V şŞe쳄‘m³ògıB+ |%Ġ˙vŻ1_–#îNj‡JˆÙ…ôċ1â0tfW +°'-L#‹áû‘´!§Í<ßÒĜşIMM ôÎŞïŬn0ôǟˆ`…ë cu + n-…îK#ßĤ!!Ú?żFT…‡ 4ISÙâÌi´AKŞĤ·Xû½Z^­!£TztÀAwJˆ6ƒÎ:7Ôó~ċàž˘š:*ÖGëCbÎ!1;òċ  8[]>mÁ˙S*³ˆ|)겍@ è.(ĝÀWÍ <ĉ:ğ; :íĠĤ†3 +÷h8‹ĦĦġqœìíûŸML(=\Œ…ç2Ú)Ëĉğ@쑟ËüŒĈï†x–YÈĞ3{!n Ĝżìè–? +ĝˆëïmDŜ=ˆÁߞ+#›QèZ)äN,…czA-Ż\7t•6çlĝN ÚêB{7qesÚ— ²Pé)|î³ÁŻÂMÂCÑcK-8„´>ƒŭ4 3ì Ú4Lhó‡=ċéé^ÀQàœÂ H„‹W,7ˆ)Ó£˙3·Íó?P8 +!FRƒ…dĴ% Hi¤&òášv ‰* rœŠ*Y6zELS Ë"XG}ûœv Ş`ÍżƒMA°7ÏRÓ-ÔÌĞ{†f4콍-ì?BëEüfż£ŽĴ/â¸3~bpGŠhÎvìÑc‡PàSħ†|ùç´Ĝ]rߘÙdĦ ò‡ġâ2 ’J9ê|J6 +ém!šDrŽ<‚ ÒĉKĤğ½9o„)ÎĥĜ !ß~Há´“ƒ6µ-ËÒÈß×ë$ËĠĥ|ĥPN †*µ>—qĝ<<œZ|ç ÙÂ0Ĥ‚KĦ–W1´\ݎtQRŒĊüpğQÁUÏ?é9ç/amKˆ,Ĝ?hcÌa&ŝ­ÄĊĤ­6hót—¸´ŭKŬ܃ÈwOÍ- ËG +U!ò|j‰ĝ lòê_×ĝpˆ$ı7G:j'×RödïÌq ³! U~ú~Öĥ Em‡;np” ıA‚Ô*&<óŭ8'cQiލÛTçró[LmñçG@ƒŽ^ĦĈJÔ)Ô.bfí_yÌX÷z|êê+‘ÇžaĵĜVž'%Sf'\†<Ÿµú‡]1•)fËvà=Ž%âLVñÏe%ĵw´bÒû$ĤT*Ĥó§”Î돐CÊ‰³çëħ‰—î†ċĝ|ÙÊ^µ@r|¸,Ŝ9àżFfÓ €gó*ŻÈ;7€÷ê;ÍöÙv-n9,Vlö(Ċ÷•Z5½4ġ2ğŠË0 2³€(ñİ ²Î½ŒDœÍ—8Q)‘݈XèîġEĦ‰Ĵ4µé}ß<˙ıàâÏZıïĜèM7JhÀ™Ġ]½5yÎĉ›²7Ž1¨Rşd’dYl=yÙ›E‰pކà•ĞŜw_L!Î;!œŬÍN?P G…k6ĥÌHĵ~Ş„š)H$Š(’´Ò˘ö²Ëa~=͋“Ħ£Ç™oÙÜârUO _7·t˘~o燿ù ş}•Ù\vĵÚS€)uÌÍIŻĦMaâSwôŝ }҆–߇OÀRŜžĦéğ @1Bʰ'p <ĉŸvĦŻXPÙfc0³Ĵ͒û$<74°j[S÷Ÿ;ï\!ŠVÑ·€‹sĝùĠZ³B]ĦûÏàÔ²Ġe"^ùÒsı1;š\p½Ö?³•h³‘ÊTƒ?+ì:W‡ık(#8j‘l+nb +ħ_ 3ƒż¸ĵu+ıŬŽš¤\”û½W­¸D‰fĥ‘™§-Ċ|R¨^pÓ2à2œ Né¸Ë ²aìn^Lĵ ™ĈF}ĵËdÄ,/r÷xV×ûöĵï> ŻsZ/ÛBÙĤójŠÇgDğʀ¨‚-Lžu/ˆ?5úJ¤…™ÁP–x"CTĴ ³•ùœ Ld8¤—|>Ŝ24θÚ(9LïR*…˜f½]Á=°Áì4óÄ`?Äı#eç牌ւk$„5j ‡{ž‘ayŜm&µsCèİÔEŬµSVyEĥ°~jGYĜMĴ3É sŸŒJ'äK*&İWn€LšÓž6ŽUÔS!G`YċUšéĴ̔+,m2˙•6“IɄ‡™Ö$ì'\K€J¸wghŻÓ™nĴR,+-ċġù=Qî +úŻW)¨ô†ĵŭ -ÊŞœħtñğŒĝZ 9)]ñ7R^Üáw¸á_gÛżÂ2jeséàžÊ"e7j’sîF‘•T¸Rú $é +³µcCÄŞašşTܐ âbàîÂùF“â4÷²ÜKèÄyyKjšg·ĝ_<]Ĝ°ħ1cî’ŭTçî3ß.ђ#Ĥŝ·vw RĊGıĊ H!ĜipÍÒ˘9ìRËqcĜ |Ć´ñA:d× 2½qT2§êĴReFœ33Žƒí2Ĝ'š£”rÂĥ·Dœît#’V#xJ˘uĉK™:)D}•+|„“ÂğÓ#‡%èfâÛFĠLú*g +†ÏküÄ| ‰ù§soqŸ.İ.?CtÒ +5î×À á(0çµ:„¤ĈÂÇ7.Ż÷½AÄŝġ˘1@óƒz!sĈ=Pg¨.÷€„Ê3˜· r™´JŞ+ˆŝĠ(Û"ҝN)?‚´Á–" rß|´5(LŬ^m8‹Ï6Ôĥ¤ŠĤy(e‚lPñ–8›ıûÙ@(mh^ÛÏŻ˘Ñ-p]8D@R0'CHƒ†_‚A5xż{[[ħË˙ĈċÏ'\spö$ó_£6E0Mşh/R‚ Àz1²ÌçŬ¸s#àZÀƒqĈ&Qcb#ĝ””ş¨.şċxAG +a˜9" ½Ÿ< ŽÏ%TÀߗmĤmmW9ÇûĠ‘9 +3À3¤Ù3Šb§œÏêÔ1'çÙĉ²£v-ìüĝڛ‚ÛÔŝ•çúµS5-şFïO†Dœ4Ĥ9ÏíLÍıĦ¤9'ײ´ca+è@Íĥ%2†! A2ĴùëÎKrÌéÉÁd–Ġĵ. †DhIP%‡Ó/I‘§‡²œ”xAùE#f-úŠìĴéâìÁ×ĦK[£0AŬ‘²Is¸]¸ËóëeZÇmĠÚİëtĤjFˆÙÏŭäŞ^‘ b$ĦÚ*v²* ‚Gkx ÒŻÔĝ”B&èĵÁW4ŠŬ§šòLëU‚ş„s£Ÿb%²ADÌl`qçĝ.Žp}Ċh ,hje'1O× NNL ^ځ–—Öv…,ŽpÉn\%§N<Ĉ'ރRÎNq.ÁZÊ睨ëï9 „š‰K1‰ÑpuQb"Û&Ĝ%}t£ë…‘f˙ĉ PPiŠ´ûᙎx^Á^ŬÒ#"Š%ÇİÊnŬہ´p™*†ĜĽĵ•ÂRiíĜ:#עa³:iT½Ğdq>6 ͆P‹ž@gÇĠÉŝCOcG_ßÔPŠjŝ˘ı:ó-ƒTLûH%ĵ&ġèĊÒyo$3ha ~̘ĠÏe/&Kynq%Ìs·-ÙdÌżDž'‰úú@ğéżraf°´ÊÇl&ìQC€ɑ£F‘Q:éX/Ôì5_•Ġk„tÔé~‘Ġ ĉ)”%'f6+’MngO=|ì‘ûÂÒN÷ሞ ëVÄġÁÄO:üÑ- ’d@sżÛ ŬĴ(ġ½(y~ôˆM%bĉ/Íŭ§ó\kŽږ9D;iÂá ßĠsۛÇF^†\”Ċñ#ğÎ%kĥ29ú'ÌİRáF‰ ü‚j&ǒĉeñ äN¨\buêŻÂ§JcYmöêG|\‹ n„ âCá]eÌÇuEiT +úÏ~ç Ž… k="ÚCŞ\ĞùŒ˜ÚéQcwÌŬ£/ñŞ4Z*Qt )!AÑ!Ÿ +~A†½óp1ÓU˜úÜÉĜ!£÷Jç´Rùu=Ö§½w/âÑ‹jHĞbM* =‰jĞ)äwúPEĈ²N;ğJc¤=ıwx`ö ›ÒžżŬO’GˆñIMŜŽm›V¸ƒŭ v4‹Ö¤%Îùıe BZ*´ Óù $ĜĊŠFÒÎ<ËC?Ôw,GĠ ´“:m·Ĵżd} ĉ”ÎŽ­U§´“˙<ċIȖ‚î§`óSè k1 ZCl™5wı‹îiFà‹mŒL T"ë\z­˜Ħ@“ŭtád•IŻ´gĵݰÔr×M8˜‘’Ô¨‰U&šUFöLĵ!LŽâv^´°áULÛ=!‡–g¤ĉıšC— êcŸEs˜9wL§Šò³é7ëÄÂL2G àÓŬĜ\ĞÀVW¸ö /•ƒÙxBiÇZ³Ù^Ĥ@tÂ<>ċàßDçΟY™šAÊ, +Q]pe6ÀĥÓT猳‹¨ĊŬş9FĊَġì1<ë2ú#”–@&?cœċ•i“܁„"dz¤6UyxâÒFğbĠ* ÚlúÀéġ(+äÎgğ!°8Ì"çĞ3!-:–ÔUĜëġ…Ieӑ@ÇĦwXhı÷0ÉQ›ƒ=UԂ ’údX|=VV€[sšfŒ”€ĞˆwœräG! Ÿsž})ħçc²š KİlPĴ#c!L[Ĉ†Ċbbœ4_~ĝ@arà8ÇA½ +G|Ż$gÓĦ£EeƒŻKcídħħ·2}µ(!ĵ°ġÜô+ìñ=˘8¸£p|–ïŞĝÂzË,ı8~* +=ĝèElîôœ¨Ĵ"3§¨Lês”€îzm%ÇĤ–to†ÛUZrše\Ċbßœ'(„€F{€şğ"•Ĉ‰FqÚñ)n7TÂê^CÀ‚‘ÑcEñµDf=NWc›ÛëıÊ.{k<ÉdC!ñĨ£Ï†ıuµ&§ûlÌ+—]–şÏĵˆCŸ“3’’*W7)ĵâ%]ÛÀŒ$&dûSy%°ŠYxÇ}ƒüŬ€héÎF~6Ž $Œ„‹¸ Ô.x5SÈçK +ĵċ*ۉ/R*ݵ´™O’NÚĜ&1ß³iU.ŽÍ\z…Ç7Ù·×PqY@"”ŞëW¤öZ€á°i€‹He6X˘&¤9JÇ­˜äŒ1àîÙèÙŞŸ`Ħá¨Ï…Ñ“b~‘.Ëqp ı{…bU,{ĉ²>7D°ŝ3B4˜^Gà£×ĵ.ß] †ĉ2É Ó9ÄI~Í“ĉŻĵLIYüĤ-ÓOĝ˙!z7·OCókBžJ#B×çĥÀ_ÀĤ<çé˘a?ef3Tĉq™^5CÈ Á€ ĦM;#ˆámÉâ/š_m_d€ +lç4_Ħݨ(t,ËTr†H‘Ïjüù>Ò´‘j{œ£/TDÁÀ/ŽÊ8CpN—ï-­WԂf. 2mĜ3ˆm‰ÉÂç§L¤R,†Iu ĥġŜ.ÔI”ŝohê˙)‹A­/ĵîħĵÑŜ”°ë|ċòĠ0tĤ7’ĝežv™µê˘?JĊİ§ċµkG˜öĜŠFuËÎCI@-µ'˜Q"28z҄cEqÊb·ä&גAŠe Ğô‘IĠ8˙œĤ^żh,S<‡&|–< QĦÖ|x4˜g¤@ZĜĊĉıÊi_²…([eñèó‘1ÄÏpı³AÁä}K(ÎΈcIĉ@ €ƒ2?0w0`ÔJfƒ@lk‘bŸ­,´ıê[šVˆ"üÀ„ƒçr°òÜwü +½ŝç. ĜßX +ġ„2+Ú €µ'<“Ú–%)KÎäq+Uۚô)Nhìè´bÇe(˜2€&Ͱ’–΢ċdí•Ë-UÚòŻQhġxÒ·,˜TËs›Ÿ•C”#³ÏöĉZDcèy-9ÙPÁŞÖ€ÊyœÔ~c˙(Gn?ÎFÙäüUˆÍTIú!Vj!p.’Úf—´ïeié7ĝQÄ #ó1ʘżĵ82YÒq>Ĵp¨£>ċ“e8Ôââ6V“Ͱ'ŻÜĴ- ĉĜg—Xĥ €Ï#ÒfyĊí³‘|Šß0/ŞÁz˙ĥXšiĜW'}­áĈ~Xv]û +îLNÎĈPÍÒBJ덺}+ĜL/ž£‹S‡8P” +Tß³ħ S.pŝ,FYzmÈ´hûtġ7‚gF°W^u¤}–ÊfĈj„*!Ú@mq6ÌIÀÓ/=SŬlŬN(0Ɇ×EġPNÇç ĤĜšBÄÈ:ü‰êìjĜ­ô(ĜKBġÁĞÓ){ĴĠŽ}zJVġMNJS‰ž™~óxm!²) í˘‡û1@˘ĞĞ8RĠ§‰)Ş`ù¤ñ7Ż}G˜^(ŜĠîû$CIù-$`4áä½Ä_²‹f7ĥħq|óUÀ}ÂBÁŞÄ9wp/ÓÔ:ğ‹ú +9İ'‡`ŠÚ··VŜçğ ÇX1Í)Ĝˆ‹°R”·)éû°`Š—ŽĝÔW¨Ib¤H‰ ĜP-ˆœ`Ž39޲˜–4pWê…Ċ[ÖSŬ‚ġ٘£1ËB"ïÄûŜ#ò$;–ìŒ Žµx\€…ƒ}çbğ3×h:s3†)vY†Ò‚ĥ˘ĉ˜R9wġ–Éî‘ğŒ]V[/}U¤‡;§R­nŬ,ȍ"sÈ )˜ d§Ç XÌm‘|L`&uCŬċŽî½Êġgñnk%ĴuŽá&Y%cùj—UÔÓ(&z ÂÏ9ĥġaĠÈ]e|¤Y™(-ġ@FÇBC ˘.0ĜĦĥŻûä6%YÌ×^šŜž[M•ŒÍi>2|Ô/­U£"ĝ{ż?üw—ró˙'úóœżŝß˙ùÏ˙ÇŻżŭO˙ùúÇ˙÷ú·ù‡˙üŝù§ŭ§ü÷úŻ˙0?gùıß˙ĝ˙ü/˙‡?˙ë˙ġŝßŝáż˙Ż˙üï˙żŭùżŭëÛ÷^żŝö?üú_˙—żıŝÛßü$6pŝòù–Œ'ü3ԐƒÌÑ*ĉLÖ0Ò$ĦтP;`—[UàÔ-FP˙]‚·ĜÀù&5€şYË·Ġ`Xü0€½¸5,Öo‘Ïlż@q׿×b–u!>9fާ"´=ß*äû`cŽJÔ°áĜ ۋ2›Gà8ä6{·!8rE:iDe?ÂċŒ´·™8:‘OYWleĞq8EŜ×g–d'Ġ,Î;C+ŝÖN(İ*.ġPĤŭ +& 2ŠÉa°t.°˜M”޽b6AŞüì÷çUÏq‰Ú—{ úcW{ä$ˆ4AµÇ·=ß,ûôíu_p}ċg‹ûÂEDùtĥ/dÒ·Ħ}RÜ~öħ&Q!ì닝]ëĞ!e3Ї)Ûsŝö¨½ŝmMO‰*żHOÚ=ċŝmDÖçĥ—3  óÏóUˆlŝĥ›ŻÜÓÔ]ĉmhġgsùŞċiùö”ç{$}8ÉWp×Ïòœ˜Vá5·í#˙°‹'Ÿĉ=ŝÉ%^NĊ”&’Ó§t’óċż ÒV?͖vŒNÄċ§!ú… ,2äË}ċwĥûùEÛŜMÏ9Ĉ\°½ÎÉ@³œÈ-ż™†ëC5ß íŜ„”µÛ"œò7ÁÉÓ\)ÌÖ·!8$ë'KW ¨X’Ŝìż‹BDívŭĈŽUc›}‡ĊáğÇwÑ"àċñ]T³ınkoŝĈ…óéè}Ÿgy ğ€ïFŜ…}*Óóż;Ż9zÛvS .ĴáÖM@K:ûéÖmJáşMşS‹ç½ı?ä]: ˘5!ÏÈï–Ü(‰¨÷Nܨ˜×Ònn˘֟§ïĥ"ċǸíĥĊ<ċtğlóD’žĉÚìV‹R áİÍ÷ ɸMħkŠíà@[}jLœÖħRbÔmğl¤Ÿ6ÙhÑ*Ò½Üħ‘a…¸MħĈ ÎùôÂĈŻö ÀĠ4.¤žġñç{âax%{xc+5Uîyı[ó7Yğ§İu10·—µïçy[Xß>œĞ‹Jçí\=÷Ċ‰èpVW)қO5ĝĈò9*÷T5(ĈmO͖€ğŝt&xkċ6£f&ABc›QÓÌSxzPs)Ü£m= îBìvœĊÊÓgšCËOZÎ,ŸáEm ‡éîÓÓVš0“ĞŬnÒ0ĞHo7iÜXñŸ&Ò£œd<"ùŞí­Ñi.o^ÑbcÛ,“èb6ìş½Ħñkfr~ZBA‰ÒĊr‚v#–ómA¨/ò÷žMfV_vÏ€Özğ<ó7ˆ¸§ıs"`›b{:§(l'g>šŝoÎ"qÒĥmÎÂHÒí֜›4ƒhIGŬŜ̐XÖu͝Èy½91S&Où>Z×-öö]ïİë›ßòopkêö[f‹'´–|dlËğğ2ş ġaŞÌFéè//ċ#ĝäoʘl…srsÊË/ùpš{ş$³0Ħ ·]’!ħPÜĉÈĊMÎÓ/cօÛ™Rvi/+ä+L4Ŝ•ŭv@FÜĥÇéXĞÑcIaijÜ&ÇöÉéenLħ.ġen ˜Ĵ><‘}Ş×ËÊx˙ŭt0ŜÇĥqñ‰•e>Œ!j閭Ž’YŜŬ½Hı]‰ïżfÄûĜö Fʅ³ŜÖk˜=‡/>Ëm4œ#); cÍ ’ĉé,|CÑ·µ0hXĊ¤·!û!7+aŜNħµÛCĝï„"€ŝĜîÁ‡J|á&}O8ÈıµÀ……Y0QUî·G°UZßĴñÚC%jYÏÁâx[3™ŒüîÌ*È:äÈñp˙Ûĝ—Â|Ôӗ{i0²~ÜÊeš,§_rLŒO‡ßŒ9_ĈÇò–Ú~dĵòx³ñ°SHş-÷^àjȅi/ó[Ú§W/+ +ĉnÛ˘ĦXV“í̋ërÍù͐—µßĥsÑ'SÄzûò÷ +ïUçç4êĝ-×]SaŒ{1ĈrWñöĜ%;y[ërƒ7Ú8fȄ=t÷ħíŸ ²tÚÌç QFúEî€ÍXÙ&ı`혷7.í)ĵroK\Žqó·n^úÛpYŞoĥ·@Ì4³]n·ˆ~^ßò8&ğmħĥnSÚoK[f67˔ĥ’Ž7úp°%`Wb#™JÌżŭj÷ßO›ÚûĜr§­,~b}†Ĵ; %ÏżÓ<ùóGSZʁ*>IĴ¤Û”ö,K{hĵoSZ@{×ÒÛÙ^´g^@ŸVş†_^´|ŠÄÊĥ =yÍDo#@™ĥ§ëğ­ÎòíKƒ£VCFúË{öTóİrŝ9q÷ŝ³÷,C%>*Ëö›Ĝف'Ż|Ñùí=kt èq´ô³÷,×›šS$=?ĵgµò• ñëúöž  -°+îGZJċYCàıîŻâœœVyùÈċpùĉAĞ!) $,órnŭò µ×wúܖZ™Š<™O Z´xáJüƒm8ÏĉxĴh} +Äŭúĥ˘ġ#‚Éd­Ü#i$‡ßa!ûӊÖbğÔù€²úaEë`”%–~ĥ˘”m ~ĥ$̗-Cà >—-€ŸV´ñ†Ħ(uÌħGÄö“­ ˆ½sXĉüt˘ĠíMÜ>sżiùĥ¨'^8ݝ?;Òr‘\|Ñò[…´Pxù6˘ġJôİG̟iġ'#ZAçÂô/j#ġۈ–˘§…úx3˘µ‡sf*Ëböˈ6àííÛÖUÜ2>ŭgéĦ˜ĉL䟍hġM½¸‡T—-é~kCÖêz;ŜœhM‚73£µÈŠûɉVÓt‡Í-oü‰Ö„äeññ§o#ÚĞb.~öŸEĜ˘ÁòĊ^.ôm7;ÎħN˙e7Kcqzó›ġ3ŭÛe–/ıçÓ\–œA˙á)kFœ +*>™OYn• óžQ3L?zÊ^×oa<üi%{‘﵊ñá Kò,?ûĈ’­?Jûĥ‹â‚Ë·K, Û`öËvF9Ê·), $^żÜ`£âš6ER7²OïW³ÑD|`(ü|yżŠúCŜĦŭgïWïxrpĈù´~ulUjĉoŭÛúŻEOÇ×K-­ş^É[È\ŝü]ÚÓĠ•#ˆZl3WNpDN[W óÍşġ>göΑÇË5jqŽŒ˜V·‡+³´ +·ŭÀjâúÙĠe¸İzŠ_Ž =„’ò·™ĞÏÉŞGħÌŝôrµ¨·€˘İëíċjĦħĦ.)·—Ğ ĝ:ÀŜùiĉĠm'yM%ßfQYŽâ!×mĉ•íUÀíz3sċNo![§Ŝ^Êt €L6Ûԕğ$ûĥ£ô éÛԕıSpáœ;EmSW˜ê€’J)UŸ İ8˘”ŒŸĤ6ŞCdşoSWaeÇÈIë6uAÉg|3@‚>]]iÔ"ĥƒšŞçíêjƒñȁ‘Wş]]m¨ŞüÎ%­Ġ7WWùJ Ä)Ĝğl{WÖlT@˜ĉÁGŬöĴbç²Ġ¤Ë?|^ƒÓ”§ )›ċó꧌9ç§Ĵ&-Ÿ×Ó<1Jžpyóy1ŠƒÎ“CµJŸ×/&TĝĵžÚtìkŸ>Ż4͇á9nŸW¤Ĝwxñ·ÍĞÇAärĵ–òfóJ "œ}ığB’÷jˆĤsÛĵ‚Šġ|Ĉ#çš ĥı*jŬa!‡ĞÏv~=ġ$(MÇ4ı֚Žğ5cïöt~F‚•ÙHNp;żú5Y…LĈíüJC‚—ĥàÂÓù• Z Ìĉ¤Bf;ż†‚@ +6†Ëù•‡^˜iÄĵyż†Ì۝ùÒùö}_Bô<#Ĵ1nXˆ2ì`-Pn{:ÀÊ:Uú ĦĤÑoXœ$fCR/,`=ŠHbIëoV°6 +¸Ċiùĥ‚ rĞüÚùbġ˜JßĴ`½J ì³ÇÈ9Êİ_^°ÁjŭÁ–½j6ĴŸdLğ°_Ġ§Ĵûb™PL*bN?<`yt²>(—ovĜ›,ĴíŒ0àËú•Ĉ³¨‡(ôċKé é#}{ÁÚÍS:œíúÙ Ö^鈆[ûò‚ġJœOÎ#֟^°³ċqÍĜPŭìˈ'+ïü§Ĵ´[ˆU+€on°ìÁ€™™ŒÂöXŬ?ĵUïCËSu‘ŽÛWO²OĠ^£`z÷aoÑ_Ĉİûï‡_ê}hÙ¤Îkœ³ŬQz{adşQ/a9Ûo/ÔÁ:sŽÛuq?ŸŜ§|Ĉlò²< ÈşN‡*?éÍàtŝÁ`Û×TXHTgô5EĽ‰§İŽ‘zVâ>$ŻÛ½”Úk+ožşóö,ċo`@ÛŞ´‡+èÓ ´ „³|IİǒÛv¤ÖgS{³!m²çmCÊk8“ŒíPOQ†ş†ħǸMGٚzŜ^£-|îa1êĦœngQ>˘Ûċ2Ċ‹@ÏËPO“ÜoQp}.-ÚTAñ0TÏÛçÒDTcÍWúöı4ĞŻ£ÖËŜ’Ü4Híj‰‘üƒmf)%<•7K4(¨!lëÊ£·Ûħ²+=Rߌ*9–‘ZJ@B&QG…Ŝb'÷´kÛQö°³Û.”Ŭ"Zz3Ÿì8ĥ|{Nö²WËi’0‰ §Ád§LFœ³ &{‚pYĠX²­úĈÓO |JSÛF²EĠd›G*Rí3’c(Ë*’3\ËĤqò[PïÓR,+›„Ġİ9ä~û@rċ, OHèËÀâ·ŭ£Êt)ŬX%0?ŬÙᤸ&aA5µĝz;µqڛ§#݆ê:î'Ê +¸·ƒ#Ëoy7‚•·üÁq“KŬ68˙Ñ}ş3˘"äk™2Ö}ĥ#^HˆO FŽħsÛŒ`Yĥi"Ĝ`m×֋µ›h;.Öü£ÇgPÄzóWDŽ2ùöWÜ{íŻ3zâÓVŭSgğ)BžÈ]rƒÁŽÂĜÓD‘cĵ:Û;ħş˜ŽÛ2‘ëÈA@şQi™–S"İŝâ1 À˜K³Eä—^‹˘ +‰½,v› "§„‚×ÓûZ›Ùí}¨†W\öĥ/äïŭ-Ûµâ¨bEí“mZ¸Ğ—ÛĞ’<~ O‹BTVÌ8,gB]zı ŻçéCHµVéŒù;3AUÛĠ³Ú╇·Ù:!u/Żl‘í|3"´ÑÒî ĴÜF„§&gɆtŜ}ĊÜ%Ä7İùÑóiDH$ÚĦœĉmDH4sÄÈрż×ì*NĞC|}2 ¤AUè>aĉۀP2(ErŜԘž„„„AŸc…4ŸÛñY)“ur ۀpĦÓF ÓBżòċ˘K8\‚!Òn·Ħ%ĞJó™bÔ½ /¸Ŝ׿ž˙à%¸áúVş˙S4Vù˘ŸnƒTw6öi2HÜrjÁ—·àFÔ,Ŝ,i köċ$ÈéÜÑŝd ¨€LlÍŜlŻk1e?]ŝ"%ü;&A@ġŠëˆŸùñó ƒĤù ‡¨ĥO“ÀoÁ$=xLkš9.çÍ$ >¸ş9a"IñëÓ$,ĝ’:ù²î3/ùÜAËp%·•G#ž˘Í­Q6V;Š™šßû‚V‚ úf $vÏı?Ëċח% =)uv.ßÂOO@Ï뤓TŜżM}4îR…ş½MżŽ?M­" Äŭê\eô ÖpNîèԝ6ÊR}Öñ³Ċˆn÷ĥ¤!%_!Nk·7 Ğ$ja•7k@#àôr¤êİVÁ2´ŬĦÄ4Ĵo#@/ß§9׏+Ĵe(Çû LSäˆU –ž:”,(CKı‡ Îs>"oğmp8%Kívtñ +V- +ÏċÍ ¨?~vAküv¤AQ¨ÙôÂ]N€4 Œv9Ñ]כ 9!ïYGßN€˘bÍÓ@Ğ(· ³ŭ°KÑġfhŞÈg]§Ŝ†€L Y·` }r }üf¨”èYyö2 ä•CwuÜ&€”.×z‘İ™*7[…ŭÍŸómHÉÙíŭP‘ …7@ŞJc³£­ +Ò ĝ`¨¨ĵ<=™˘ƒŠÁÓIHG£žÒí¨ßŠ*ÙxĤt;ò Dğš7o€`YÙo?'eë¤\dAÎĝ÷›¸‰ğà!œ­Ô—ŜŸ"˘ kx +­çíüGÉÚq]˙tŝ£ħhŽrµċü‡–¸SsĊHyQtġ)u‹uÏwގ7ç?}(L i”nç?¤ħÊ·ñŸÇ5e˜ƒ‚9ùiü§`7óÎl šíüJŜ‡v•·óŸ§Ó!e~Í ×žĈ§|D,Ĝ2Îi`˙ĦnEâ”vı˙´³kĉ›YΧïŸ(‹óZ(‹qŬŜ”öÀ™§°mÓĝ_E~‹KÒĊß~§zÒE+ĴU€9Ç‘ôù°7ğ?5ž Ĥ2aÛŭù)or펷m÷ç÷ ǎ">qÛŭqñ˘f@QtÛŭ1:5h˜˜ÇË%çφ§Ŭßw²û""%Š{ ¨eÜwÊZi1—JÔGžv€4+mo//@$ĥËßŭ÷Üo۞~§ +~SQ n{ú}½ˆOO?ÑH@ÑZž3cI·§ŸzTÀ۔Ħ›ëÙöô÷ ĴôħîÜÓÏĈ+^ßĞijİ˜CÒΠcĉx{ú C[Ǜ…í$ ŝ #ğĵüÔż˘Zô[Çċċgol +8ĴËOËJò¨R¸ŜĤ~ÂC +@Y?ĤġÍÔϤġ¸^~ZïàrŽX÷zL'Jè‘û.?Xù9?ı`“뛕ŸN‡’n*o+?Ž·˜Ì­L;o/?b7r\'“§—ĦOœ³żĵülh*@cI×o/?޲\ô|šú9 ³„„ŜĜî~BĦ$ r­âÖŬVM"!$K_‘ŸÜŭIJŠ>Mŭ”Trüs—oS?]ˆ7‘F}sġ' pœ$rÛĠ]•ʤ,éêÇğX4?‚d”C*ŭŜ>Ús6|AD`ĝûÙá6—vYQŸFöú͑ƒĊñƒÑŸWSÔqDĵnmàžF҄|ĦٗÀx½ŭÑ#Ş s;×7mŭs ˜2afĝ°€á‘Ż_*½JŜ/qĦ7Ç?é*fú9uġôtüûjûrü3ü†bŝú6–żü›ŸO~@’šO/äĠ—ġ½âġE¨ójżĥġ au1ŸJ]9‚7ë??*!k€lż~´ŝ³—½ŻE:x:˙…ÓZ·JV~8˙Ijqé½DÍŝhü'‡ÈĠeĜë›ñXbıĠHù¸Ğ/?ġ“ ƒWöiügġ3 *HSôo?•ƒ`Ñהzĥ<üœĉ|h —ıßʐYÛÇġ/Ÿżğá'{żW‡ĞßE>ïŠêӛ›ßïĤ6ŝŞY”y£ġÉxš÷…²Ŭy{ö‘1Żĥ­ú(nĥòîGĊ@˘Ä2ĉkA*ŭĝFÈè½ÙÍcĉĥu¨V*OۏŞÎpß=²uíù‘Ò6ٓìw{ë!£ôlä) +ĊuJâ2§O=˜Ĉêú†quĞĥÍĉ‚È ?ŭò8yÛäQħ9ĈmŽ™\פ‡'¤dÀžÛż/PAË +ż×zZái]ˆ˘Ŭ²Âƒr­vĝ4X›NŬ/7 éöğƒTĴëR4Á+ݧğ¸kj‰ËÔ.“™ ´ĵì2ŠCovDÎlĦĥoUĠ0} ğ:gJKĥtۛU½Î7{³rèv𚧰߲ކèŝéc&à°çÛ ùO^œċZĈ€Üó4+Ĝħ\ĊXS0ŜĵĠ›,[?ß,Éĥœëv"ËŞŽm@ĈŸ‰_ġnÖn,3ôBMUp_V.ż™‹!vĦÜIäËÇĥCJƒ˘ÚÓALĤvŞ·qXÈı_·_œÖß\ÂR mĦmĈßçh·'ÏĝÍ +,Q?êË ]äZĥñWuLo~_ÚċcĜ|Ŝ<ÂÍ+Ä!ĉíO£ı{U„›r‹š°6o//2Ò$úž^—RiçËıĞ(4ô2ìbŜŠaôòéŞ!ı{ûtkÉ\ö\ …r™r1‚7ĥtjÙی‹Uџû0áB „žR2bïÂB´•ŭÍq äl}m‘áŠ/Ñb()„ñaĞ5šŒ·›–üžŝ²Ñ‚:Vòğ{9\^ĤYż0ßVYÀdÎöîE ñ/cĴߘvûaͅż„Ë+G²ŬŻÒZ™·é•jVŒ˘‡×ÀÈÖo‡+vW5LÁÂÙ + Šü0´Â‰·Ü>V &Žݘ:Ŭ˙İÄñ°­ + `Ï·]ġ QĥÛŻêPá)ÊÛ§ŠÚgĜ=.£*„çî2¨úŠs˙šA4Ó&!üӏ +`[˘³°ċ›·û@Ó)R9P ĥ×J_d‡ĥĊ”B{ċzs–bRÓ´nÍ;‹1ÛGŠżûğ{TM!ĵM£€ŠP×Ü^QŠfRóyXDĠ"›ğD…βé÷ċñ„Îċ+܆Pĵá0#áħ„a–?]Ÿ8ĈÜfO—†Äi{<á˙­·³µ4V½mè^İíĠĝ‚§}Ó`n‡u°\›ÂL(ŬK}DuĝiÒDĥ™ĝbk#H ےi˙ŭtbÚÇĥS_ĞëĥRêŞvû.ÁÈŬŜFUƒRÍvYş˙~˜+ícÛSI?İĞÜVJ})>” —(àıŒ“U_³“YĠġŒkˆ8n›¤.\óe‚ÄÎñ™ğ&ƒ#J‡Û iäX·(÷¸Ûùˆ„ŻB¸KÓżóËùÈÄĝùĉw4–ĥêĥ92e;ÚmoD&µ´7S#“òµl/#/Ħ[ìZ€˜7ç˘-Vğ‹Ĉ ä/£˘ħ^Âŭ‰†X”Q/•=ž·-Kĝy,L…\€ñ:îCPİ‰ÉžĤCŞ ôë6ÒNŞŸÛlHĈpz³B%¸âvb Âyŭ2òîgĦĦnrŭĥşöĉÓ5H„:~v ZW_.A\żŠCŜ@0ž ùɈó)–Ùû|ı™û4şÏüƒíÏĜe÷3,ĜÖÛÌgOOs(İ·ÛÓgœñ ĵxzYzä?Yù´ħü?İĠ^bÓ¸GĈÒ(?ûġ >‰é—M²”P?íyú >]y:tĵĞ|›ñ0K‚äûòà™ !I˙ƒ÷N³şÑ-wÚħL>vÁÎëXĝê´%§úċ^ÒÍò„ŒÍ—Ž0ÌòëËD:ñ֐zçċBêË2§\ħ ú²Ê‘×~pÈ)Êŭúч‚òıŬyž~8el“‚œ2bJûÑŭĤžħè}™ŜPœŻġĥşÛÇá(ğml^quF”GŠÌ‡pÚóñóŻ))€ż_ĥ5ENf>Ŭj +‰³?frŝÁ¤Ĥ¤zÓä~²¤‰ò¸h>#½?ü£È˙߀ĉ˙%Şš’­S‘lÀè!Ï]’Ĉ^J=ÔáóTĞwCdûrÔġċÌ*ÖĜ +Ô@²V3wzz½)láùç(z!BT!²H¸ñÍÉU´-ĵĴpŝbržalMsl³İkWxbͽU[ŒÇa&8Ÿ‘Ê16@¨Aİ8Ĥéû‡†hĜşż9·ŸF.sÙĴÄÄʞ‘TĦS“Y–S1žCğ”òöœk°(;%ŠzÊ`÷4Ħ–1~ß{= =„ÇU~Iô¸(äà;ymŒ˘À3pá}‰Ú½NĞ Ĥ'X+ĉ‹ĵÈëqˆŻL0|¨bĤµ{ Ü3B=­9ĵâQ+ѽ¸`§p.8½÷µ3ìs‡ĥ”S’>ŽYGĈkÖUú´!NꝚĤqğİxÙ/²­X>Îùq´ÑĞÀÀ„„€ç!cÉ2—ĴĉfzU´żz†Î›NqÑhn͙³+ȚBôI×$àH" ½èmsöuĵ§‚V›½TM³W%ŜjsëE”9Û Ż„];ßT´ü:šë¤0YíAùžkE3äчäç9)ï :"}3‹&Ï!ì2WŞE$)ħnò#tÀHŞ£üSĊŽ5ϑ6­•ÀŜÌßVÓ)¨ï nâdI+äĝx'=µ‰Pk¤@eœ,6X +ùDÖOğ5hT­¨ŽıÒC´Ħ(5p)0°rX7úÌı%‘rGÉ+ a_À ¤7F),šĊ¸a +Ô|l'ÙŜ”ÚW­eôĤ°O:  +ŒÊM¨×­˜EĜÏmRĦ³Ĉ*(1ĉÉу}Yڗ—(^6Ċb·/r_ŽƒstÉaĈ&Œa†,òİÊ\ 0_ô(ÉñAÄÛí΢iŝ şzœŜ<ÓŭMĤ-ÙVÛÔÇ:ĵ°´ÌĠ7W$BÁT–UƒpèqÀl;‡9hzˆÎŒóPF›÷ż"\Êû×َPLÂ) ÉĤıómÎ$OfŸÑtW@~]ċçÙıí ĥAz ĵ2Îĉ‚0MˆPVg…Ìü_#è i+l‰Ż¨=¸NÎĴàZC @ÒÄÌÛö̜·6Eި5ÔÙ ü²~]†§A²ŠdUè 9 9 u44†i>_iı^§GñŒ^+范^ ,q +ïIŽódÜ/gŭq“ŢüúĞĴŜŒğ€‚M²ižÑz‰_Ğç|³ÑÓĤı˘„SċžàOL +ds9À—Üóá+sy SċDŒE´S–"œż2;Ċ#Ú7L‰'~äĵY +ıİ‹8ÏGĠ3ŠċĵIëç:'b† +=;dŻúù}İ…aĴoy…‹~Ċ[[–·ŝGê”uw §â³Ġxö@ĝ2NqàZ5¸Z_Ä[.<‹ûğèdW÷šžG9€˘Oĉ|:ż4˘rSôĵNa&ĤèzRë›J(Ş•Şì/ÑĵtéÔkšŬ×Á“FÁĥĈ8/„X[ĥK?nU£3օ ıG–Ôz ]×cÊşih^zX[€8F|ĵtǏ=ƒ"ŸŬÑIV:Œ§”íŸp›ĦçHÑËċdN gĵWĠySáŞÒ£Ĉq¨ÒE ÇñӇN,8îó+|@ıÄÍVnqŝ¨‚ YŠ–ÁüÔJïÓ/} ÍÑòqa\£Wp)Zß +2ó*Utûx6èÜ7²Šâħ ħĉ­CjŸ ġ$œ]wŭ\Wá´z9ŞÖNŒW_y[˜XŸ‡Z ,B™`p½OĊûÄ"?ÍòWKzˆ+ +½PS˜ËŜÜôÊ'c{°ğpáZ`nÄ-s/c†Z:2Ëv˜[ĥJ‡şé$ö|v\M'¸ü³S#ää1ÁÒĊéè10™Ÿ§ĦòLYgL$ݽ"Öü²R`ÄŬqBAˆ°Ç)ä*T²W^žÊsıVŞ—ĥ1çÒÊçÚ³xtlX8Hê!2^ ϵóġ ıÈ3o°9ğ44ĉ²ĴFTYĦ÷ıdï+2Ħ#âN‚^âΐò¨-B™†×ïżö€,Ï^m˘(Çŭ­äĤԌ#NVÌIN×ZPgҎp? Ìel.zuÖĤÙkçêEdž/Ô´Ĉ_‚ìa+@ˆÊÄÇŝ’9Á´è!5`öWżżK˙tp§0Ĥ0—ô%?Ö.·ÍËNñâTwÍ9äRћ?@ĞĦŬ³óĠy­Z>Û+B:Ҝ>l³fsâJÛNîxZCwßÀùîñĤCf'ìLf˜ +˜§Fudġüškח*İ,CŻÓ2ċ<˜j(mé@$%Ž˜íéÔxça_ #]CŠ-!#şí˜ß,$İî´,³ğëâ›g ċÀÜÉvĈĵ[!DıU™Ë`~Ĝ£ż§nÉ9-\/Ŝ8lT†$$„·oĝUÙË$’°+=Xb²™Ħ“Íun­àïˊÏυaÁĝ-Kë{Îê½lkËştqĉÑÉà´f¸äža½ËıÉçiíeX6d2ā•듁=”•Ċ#ÌQsŞiAˆUŒpw:³SÜ`fx3ì>çF§ĠHeĥš˜?DŜƒIë/Ù’8ĉġ²ÚùûËIŞ]ħâĞ[Ö:òˆ`t¢?­FÑÏóĤ5ġ1é5È>ÌAŠäÔî‰!27уµ–èa>·ğc ÊÏĜŝĊ\jÚkçŒt>½P^D§ ëߤF =ô)G—1Œé|cé£y5ĥ—êùZÛ$ÓÖPDß ùêJb°×Uà8ŭàrg[B$ŸßTR”D.ÖÎù“F9bïĞ9f½Pžìß="Ŭ€5ìċŭĵòy¨Ì3—!z(£_–ğG½‚RsK7žz– Ċ Î-§¨ġ£;džQœ —Î6_Êڄ>ÉH‡à__‘z:£“݇ġ0RSï=Sè3u Ŭğ#ĉ˘z\k‡á=;%n[‚çÜtF~ìq7 ih/:⋭l£ó£ŜC¤ċ²ìNÂÌ]ŬozˆÌÇ`z£âT"ÓÁj.wW1˘ÙQĠġ”Ĝà.„—R`XV¤OfN{Á§‰4×ÑŬCŞİŒÄ~C9½–ŸzŒp›“vĦ²ħSwÊ2_EŞHuĈuИ2qw4~œ ì˘OB™ì91IĥZŭXfŜ% €H@h(™P8›ï…/‚Ê&]ˆçèĦ'Kî‚öU‡pÈ#ĊĵÎżĊĊ>!ŽauÙ6}aJ.uŠöÙp‘H Yċĥ„İĝ$(†Ż[˘ÙĜ~Œ^äE`Şk<ËJ ?nRÛĴ §QAĊхÏzo$EĝJf· $’şê-KŻa[Iħ>êÌa‡ġü°6P"+“–šÌ0qíÑÜPQzÚ*zĊ]Ş}Ĝ+ö‰£): ßwĴĵŠ(5…Ŝ–‚AZaş—¸Ĉµh–Ż;Ġ÷Œ’Ċ… + -• Sŭ“Ĥ3ƒ“,½†ÄʇdTC7BÇÔâN^yif’N fç9ĵ8ĉÒA0/ˆ•*i ‘‡Û.ÌĜf^Ĝ ĦÇİ~)Irê>G}ü} ŬŸ”İFÊŞúEÔĝ_ĴX˜W—ŝ:ż‡S 3}@–8ŝJXŸħf²!"2›!Ñıi„вn‘3gvĜ ùdĉ\SĤÌìĈ†‰ŸDGÀŒâŽè!g‡œ¸3Ôi2ğ³Gß~"§Sž@ì`c[Àn˜mAŽÓ@Ô²ƒ”.ÔQ)Ğ2(˜Ì‘ç‹ÔÇÍÓbgÑΝà,çŠ ‘ğÒîĞ­}u%—\}Ù(‰²VÀC7$…ÂJ}Hh1²Ô1\ +9˜ä0Ì[ŭƒ×\Áċ,omrlÚkµħZq`Ì=4xo§v5esğ+üî?td´AqàŝpÒaä='MŞ_ˆä³ ÍÓ: û颚òĊj+½5÷ LGñMÁ÷™£ñŠ<<†˘„îŝ´ŸçħÄ u…[/24Ħ[~„ÜwŜ!è@)ġÇqRœ„@#éR–’ ĜÛıϓÖy´•!²Mú4ĊFBz<…ôĝ‡ W—˙8GĈy.s/)\Ì\6è?ħSB ó¨iÊtÙ#vbŝyÛ$36êr%d '̘áŠìR#Lw#Àĉù<ċĞċb—p¨ƒÑKAĜ¤·[† i˘Deœšd×y’›Ù‰L‹ï܂ž“^_vUŞP6â“sí"Ğf,–7g  ?€FÙ¨:Ĝ‘fóïè1÷dnUëµTlĉÀÓŒĜáwĥ˜rŠ”bÎş*”ì7icƒÍÚe#4§ïĴ§—BèR%XĴġ>‹iEPY§öáKĠ”tŸ5 ÜS…„döȏ}ġ˜‘ÁÁ>ÌÒĉC_½Ĉ*~ +qˆµltRìš#ÓHÁ,"ì( ÷C†˙G{̈+ ‚µr•_'YxÌ µĊïĠW—utüÔCĈ:˙gcĠñ—Ûì:.Z^%Ĥ5Pċ3­Gĥü0O!ŭ}-/‹zSAĥ-N\ÉXL›°XÂvz J8ıÔĤ²Žħ ƒëN3bLç^vÁġPh,FĈéiP›MŽ;G+’38Dtan‡ÈÊÄĉuŸ5w˜Zìpu#e´çù4Ú2¨Î­€ ~”\Ĝ§˘‰ Ğùʸxûĉœ³áWšÖ´jÁúCß`œ!è àĈİ´é [ eŜġ€:şàħœÌ¸×USĜ`HŻM]†ıwĝRnò dYûɐ‡J9›hU$…bĥÎİ8<3Ìtϳí–Xıb§Ë§ÑƒSS}Ġô¤êŭäK†=jŽĥŸ%Şèê÷hˆP-@!­›(7D/|üé:µ)$÷2S}‚‘["ú‚<¨hδ='‡]_ eDj,ÌRxš˜\1żIw—ƒ¸íçĦñPdž¸kAĤ°…5¤Ŭf4ŬŻ]b·ĝ“Ü"YÓXµ‘&ÒR%3ŭ‡^Gì]órKIħAC­.`N;–ñg”şâ˘j·:ìôbók^^œì֌Ħ5×D×_]3zFBì1‹Î„óa}êŒ7ÜNb5\ï™ +.‹f™ĥlñqÇĥeĉ¸ÌŒâ7 ƒt;_ ÷M3Ŝ~äÎfŽû P ˘×c“lI‹}´ï:<ċÈ+shü×F4/¤Ê²Çú‚Ĝ„Îǎo4“gÔÎuȵWF9½†=[ˆĤ,™•9ysÏcúL1}2YĦïÛxċDÑ(6‹äw¤ç,^ÊW/5šk“DR·;sGġ›â…iŒ×#$_1BħxÔ] àıŬ˜8ĉ°—KKŻ#iz˘Ŝİ=TôÀá +”oÄ_˜Ĥ° 2A>{„ °^ÊìÏ2”…|š½ĉÇBú¸ëjĜ-/—%D\–DËĥċŽĜçÏeÉÈ䐑ñ€pTÓK×Ĝ…5çF#ŒL^6~“ï\[ŝCÔ#˜]” âÒô˘jî/,ÖMêf_!'m#Ĵı~…¤bJöáĵYéÌĜê†K)µN0âŝcZÓŭtÄŞ‰.IĊŒ|óüÎ3Ú÷àtZ Ħ1o:0茇J+GŞ)~‰W0ÉYĥy:äefŻB2î'Òk ,UXîa–6{ cb⢌˜H@V=ê—4`Ĉ=>}ŝŜĵd׏'˘ĜĉIEl8ÎË´l4VèĦ‚wlöŒöúÀùX2 Wáݧ3)óz!KmŬ*.X)żçˆQnżÌYêXгYJ8(€dLĉĈW jBéiÌIÈcž˜ï7/]Éş›×2Ç:ÁYG2SÓBeoċ#“žïÜè\ J™|³M™ż¨ĉÜ,†Ò7dċBVÔ}Zö 3CeXşiċ•ç‰/!ŝ€$BRıò=ĵ† c rsW ْŜò>hŒ†#P“ó‰Ô#Ċ@s‡Ë@Ĵ­ï{vüĥJáèá\ÑkDŻÂօâä˜ÉŠ/ …—3Ä?PÎağÊ^ü”cìÚ´½ˆÙA tOé#ÑĞAލqÌra ͇ç1 ÷§œğáê6ìĠ?ÉÖ?xr½é$‡Z@ÊñÚ +ŭ, ĜÚı&Š& +àG8,ÎqèœÁĤŒ0ˆT_Xgì2Âô-[‘q3$8…B]áJ>%flÚÓİ”È/P,Ú"Ï11˜a~m(JĝŜlT/aBĦT“Öb”°hY>œîTÍ´E3^8ñœ2Gv&&²/?|6(ôÈy{”8[ü1÷—ş%u͝sßÒÖƒ¸%p2‡À›?Îë\b½ĝ1Ŭ ö˘ò_²šúç +½ Ùü²^ö—%G<H”ÓèqKmkĤLC­#b›¸ v PŒt[,UûYc.fġä#ÍsÛŬ4&‹ĝ£$QĈL@Qi†Ĝü¸v4Ä üĜƒĜìѤ#AµFvĥšÑáÚ^XtJH-ÍNhÚk€›6Xœ†t=Ù(ħ!Qj.ĥ3ñ5èÑȑ2X;„Ô@A€J'% |%g‚fÉ"›F^ Òıf àn†-ˆ‘–VhFù(­Ï†'h-”òÖW3w‘k8d–ğ{Sǔà)÷öÜv ,{€°Œ,ŝIÔ PÇMżSƒĵĥĴ^-PRM%ˆ €vQËú´†Şô@L9z ÒhéĤ‚Ì’i1 ß/şšôê5İh{ĥwp훚ĝRÒ ,"Àò‰Ħċħħ’Ĉ,rFCäw’¸³cM§ÔÑıNNSÌŻ0İ*ZûéTrż<˘`FZ}óŬkÁê?ÛÀl˘ğ~\‘œŒ(t4{šOèoġ—Xš(swW÷„{BácÂĊĝš \#Œl/Әô¤Ĥ°MËñpI˙ÛÀêDóM ŭhGȖqŝv­ÍĠó[ |'ÓRÄSÇùµdäQ\Dר–Ŭ_’4(²Çc]›zħrĞàğpá<ôtÚë:҂5_ÁĦ_2¸BħĊpÎ- v!Ëä &ıÄ Î+ìçu˜4BôÏ9vŜĠê:~Ĵ%£ÄĜdüXSXĝԙ—tZ"“ ß:5°lŝ|­‚5곐R²“ÑÔÊ{ħèħX°Ê.pġcc½ +ŻĊ%–Nq,v ,Ċ°ż“3ÔD:½œá†A‘ìiŸı`ÍCu=cY´ZKKu^ÈÉLħê^×U!‡\t:id”_Ö54…~Ù A£ŽNÑ0ô9-°€ÍĊ‚Šb[ïb?ŝ*6ĉžˆRı~ÜÁŒĉ.‘— ż€ÀšyDì.i!{àô˘–ÄĜ+/Ż_ +S…$“há­ôċyÜÍıZÜŞ9xjM{z(ħGYaìé7ĠméF/÷µ³×)tG7İT †xZñS2êIñS. b³&µñSŜĜŠFğVT²(D)AC' ‚żkM*)²­s28ˆlĊû^ +âS”ĝŞşÒքv³€8Ï´#­)ù™­`23³³Œ/ìPVdĜÁS[l’èEĴYÀ‡EH3@U‘Ûö +z³‚”ö GâeW$z _Ğ!~@éÛ;]<‹Ëܜ´jÌDŜĈı0àĥˆšÉHñħ4˘Ïéŝ8ïwħ>ısÍ:EWĜ5öù# žg5ÏË**yŽ.bM$cŠ:ĉ„š°¨Vù˙"’ݳ™;ŻŭCÁfŞ1­^—qŬIċi.4p2µ"ğŻ ëÇÌ˘Úc\u…Áĵasœċ=oh3×!>{UccÔY>ıN€½³Ç(Ü$îЁc_ÀŠĤÊĵUs†+żÌÙ5ÙĦ-RŞgH.Ï÷ƒ<+P4ĥ/‰Kë£ûf"„"D›ùˆ)$âµHf8J=h‹z°¤´H½0™ŸqÈ ßc8Ŝ€$Í'I•—ŭüĊUĠV^éAä`ıÊé YçŜ%y—O]X*ĵŞĝI ħŒˆH1âĥQzZ“Ú[œ&³eŝŽçòÁíïĉtN‚cÊĝsM/˘ zé•–6o*O€/<pBg0 ,) 'ì4ç>ŭHĞGü€ıœm•Şş ĝíÓR˘MvPYğU²0ÙÄ{ +s””÷ ސGLFŠty^ [ĥÛΖ E:Wv›2›"ÛlO!R²k&Û´6›s˜ĥ!šT!F'v-EpèpžIAşĴV›@$Œ”]Â[ +ÁËĉ(İEr`'Ğ"w{ž ;ĴJjF2ê‚Ôĝ€J¤Ö\ĈçGtPGì½kÂċ=,ßÓc.¤¤Ĉħ·mrI“§İ}èè9mÌñ˜Ò3kD\= ,Ù rÁĥì/§Bï¤)‰ıŭ šaM+[şJŒÍ™˘\ȋ[0ğĞ„¤1YÍTĤŠz ’>MğÙâ0’â¨ġ†( &èh;n=WʄïmE§‚„üġŸġfCòxׅ !]Tâì GèOÙë +ì´˘lĊ^—c,ü€½,Ĉ? +p½GhT”…×%9ÑTVuùìCóDà@ !§bç!8ĥts@Ĝhjü_J˙È8bÒnX7ìĊ…êóĠ(ñ Pb=cħRÓĵŸ£n֕l9€z ŽîV4¨ó+e§~öp+Š’O„Ì#˙Ħ-;m}ÉAÇC+›ç8ÇB÷>$ŽZl‹dvrè›i™"ˆ_É/-‚a)w&Şèwĥ@”BNŒ\€˜ĉJZœmÛLfòBߚñÈM²ĊİjZĴ^áFäkcÙ.Ïéó<‚×%P£˘câı7\ ƒ8̸ŸİفH—€=L6ĝ‹2j5 ĜÇŸ@%XŸÁžcVbÌgÈäĜ£–m?ġ"RÖ!gî]Ò¤.™*ݸ+>;`àD@BÙĉħ_”i8Dí!BKÄïĉ­bCMTL˘Ĵ~Ç,Ë, +Oä1F˙î£.–òû)ÌAeCäx+Jk͐Iìgˆ2³ŻaŭÑ uË~ >07%¤ŝħ™óFœĊó@@ÍċM~^½ *]HÇïóXÙw ¤×eadî"4M@ûœEeŒ°üœâÎGĞ1–_Ĵ Âڂzuħ™Ê÷×4I=³ÄgÀon.(ĉ56@gl€:;pz@ĦG󙍓k…+tÖĠ#E›@2Êbd’Ĝ§ „ü—v,Ĵ£ğ>dg.5/öao§xXĜİ"èÂ|’6^ˆDpğ¤kQŸSà–루)jö9vèqG³<ÀƒŒ¤6j$*ېŽĈÇjòû84ùìú"Ñ 2—s– ’^0`<Ŭ‚.İĠ[˜ħ_‹§N­‘ 6RgñM!â1—ù'şfż)ì+úXTñpXóRX·ı”MNƒ“.ş¨9 f¸‚]ÎLHïLU#ˆf‰Àv˜k5ӘvŬwÚxcÌġ/pCÎHßéҍ†Ç! tŞTByŽcħy)t(vÌëKŭY –}ŬGd·è%żĉà;Î^ĊÄç\Ì7™~ˆ(†Ä?‚#ėhÈñgŜ`1h_²ğĠĝĠĞ(MĤ%‘|ġÖĦße}îz|³VZ³GjñÉ`—à‰—_ ÇċVX>`½Ö´{Şż07şY” 2hbÏJLUKЇ³›Ġ§DKâ‘,›ŞÀi/ÏÒÉÍ8’V ’8ċmĦ•#p¸T™K- +¤'ŒġÛÈÛâô˜u·W ñŝĥêĜxÉé;ÈoFtüe_Oݲ „@Ŭ>^´ı`ΰ4Ĥˆ Àá +&4:œË=Àı Ñ·ŞÏû Iiö˜“ù~›`DÚ +3½ύ bAÌ_qD×  ê)⋽Ï÷:ûÑÁ#(ĵž +KhÍNpżû˘„9Ò(°ŜÛ@{`$)FÏy?8cáYŜzÄBKô½ċ˜ÉġÓy*„.ĝhèÈožĦ†lèÖ´ŜÈËF°ŜƒyìW —w9Ĝ~ÉFĤÎháHO5|z'¸m³‡Ztk§†A|E$z¸QkŝƒóÂÑ”^¤+1‹Ä Èt |,ƒjöhéŠó‡\ċ,ëÉàÖ7QK'ġy uX£¸Ÿ1ŠÏ]ZCÈğĥÛÊŬwÖö'ğԁğIżĞp½^’òÀ(½FPp +òbċZˆħ,ä‹çaĴmâ-}Í)Tgyê1ĥžÁ²V!7–D²‘™ú=U°nÖ^ZK(ƒŒáQ°Á`%é7*g@B11ÀAàÂ6"Aı9ò3fÒ]€ +HĤıÙ÷<Ú] `œ&*¤÷l£uhö8…jqŽòÒ1ɔ÷M:\Zi.£µC <A18‹;EWɂ‹T ñĊcïDxZjRÖqÑ/‰ÊK3Ԃ"˜=ì_¸ÑċĞÒĵÄ LQsE*ħżĊÀ¨RŜX^äR €Ì‰˘rŜğ,de >óîġRc +Nr’ĴÁ‡dÍÙ7–ħF‡hj6”8Œ ×ĜÚşxċHth)×OĵŜŭ3$˜•ş4(GLàlô”ÙT ?GÔŝÓ Xy•î…áBüük…;„s§=ĉ´€O„2pú6z†ûíġ×óċÒ~‰Âİ·…áŽßÊSNlN˘T<”€Nä4e°(ZÎö:„f-‘Ö––ÒLZŠô ıJ€ÌŸrĕ1:Ž,ȧIaûF-=ÚħzÜos^‚+sè@ ˆbŠsšz˘¸V˜YšïìQ"û#šÚ,óċŞ9Ż'ñ‘3cĞÛĤÎYIÔıÊuwŬ›òŜÇ †Bš!dsR‘š†)³R tR ìŒĊ˘âÊ,L QskÊÀÄO>C?ô\ÌU° ŭŒ!ÜğŠ7>£Wġüsäĉ8Ş‹³GĊKüÇ/BˍE…|Ż‘Y†k/ċĴÓ0Zĝ²aF˙םé•Ĵ#OûR‡×ËŬ/:'‘Ġ&˜ÏV˘8~ +Úı,…(â^Ħŭ>&à²ùĥ@ž1’iê´W[r†yÉžûÎ×µjĝTû’"Œ:ˁŭ=Ü*ÌŬŬ·R„yI–ÄKhi†,˘ùg‰×uĵnÑXÊîDœZB @Ĥ ğĴş.á]‹]Ŭ3œŒj\$AŸœ¸…N5cj™n}^ıh÷úÀ¸.“3¤ÜM¢f­u³-‘>„pÉġ۝œVŭĦ/0Ġ|!GIĦ})k—Ž3–ŞŜšħ`ı—×4R +g ĜwĴSCûm6ö0E*Q›{µÖĞKßr°Ċ§ĞïûœVR +I<‘ÏĜyŸuuP8|†{Ż6;•@ŜÎɢĜ‰ÊŒ[B”{QĈÏL§q;Ú(×߁Leô “Hq‡ÓעÊô3ĜÛTTVCöĝğ{ŠtqÖ¸Âr™ÄAô•€iÜg‰•öı%00UµB‡t ÌBUż†ÉŻ4ñŽĊLOQŻIÇà˘Ĝ€1p–âÊĤé‘!òċ/€„ûÊv5ž03 ;LĜh _ÇM{ŞĤ%jÍĉÒÒ\ħÁcìR¸ĝ‚ Ë'żŽ^KSD'g‘,ĝòp½D%äCPĴ AìÄÚ:"DR´o`g{Q‚u½ÎJzj*Ĥ9]05ĞùÄÔƒË i ›.Ä2³ ŭô"é|\ 6+és=<sT3¤ÛcĤMĉ4rHc‹î+Ċ‡îŬ7ŭC²r܀ë-ŝ +\”+ò‰ôB10dCzPñ‚V kLƒd|ġpĠ.$/Té^¤Êj·S$DFnbâŠ+†èZ‚J[ŽcĤÛŞ€ÖÚöŻżœˆÚ żŠëŻù6··˙7kïĥĞ[r\é=ßaŬPàÖ̜yš—RYnËn Bğ[‚ahħÔMCĊ(ÊBż½ó#"˙Ukí"}AA‚jç̕˙AÁïŠüÛnŬñäԃ/€ĊŒ)&b5ïòsżt%d¨$˘^Òhhë• t'8äž)ΘÚ ÛL˙’D­É}›}ôô$ô˜‚ğ9uĵê6\ˆli§Ĉ˜²— ˘tp™é'=d 1ÛIòÉäԐxñ#ò1M@Hİ4²–3H*Bú“ön5ĝ6’镜ˆÓÄ)¤/îĞœOÇU*€7bÁLĞĦu~™FĝLž„Ü0w˜ÎRúExĉżTJx÷gŽ*_¤ƒ€gPDĤñîê!é•m:=L /ŝô ×> İVàUĤzeöŜ…è’$Š {ÙwĤêvŬğ" Ù +d$(.ç[ÌzĤ€Ïċàë÷ìĠ:ğâùBp܌>ûµŜŜBĉ´0ûĥ’5ĉNŜ[†Ž4`BDILù>^Ëù0ÄÚt +?ddġ4²şËd…|żÀâîn:–DtNßħq-óG–ßZN)HĥTkĞ)ĝ ÷Wò¸0ô4‰âÌ×J˘U*Ġ fùZ ½ïĞğööMÖħŝıä Ğşš'ËzÎ`ì–ËÉK"½QF JT J;Ü(ÁԜĊ”u~`ŞB_ŞY<—Ĝû—–€;°7ïkĠ•Pv0(0¨È^!°uÇöĈ‚iòĊ +z†ğWi+°&Š‘öö#Š# m†ËQ2”ó ¨³  ÏĉS8=ÁˆĜbˆ’‚Ï8 ùmĜ…à3@rÈ^è—Ċğ×ñŸúYì=ÎÉ䒣ÔÛIêuz£}yïĵamhÔŭcğ$¨‰8HÓz/°um–dŸTŭÁ 'é§²Œ´jìtÖñdўŞËK֊!°NžGÄÈYYŞv–.ÒC›.‰ƒÁròSĥ%Ġó•?Œ (ċ]Ĥ™f{âħ÷7níg-–Ğ]&ħrpôÒÔıo<M44¨c@[E4sä –LY%í ֐…%T!:ö”_ċZöLÓ8vHKÉ1.ävI DНuc‚á-FĤà,7ż•h%¸·zHŠôòF¨ù #ħvžĥU.ß Ä>`%uò,Lœ°XĴt(aµMNeßkhüÓ?té '{;fÑ=‰'dxÄôéSşï ?É÷'`ìh\Ĉ9/°_)U‹Úƒ/&§ İM­ñàà.³/­PñVa”^ׇzôŜî5ôÈHH=)LÏ2cJ÷ċ"ß?ÔĴĉ‹ †êĜlK§îUš”ʸĞ"K­‚^,Lè$êFìkżrs,Ĵ0œZħnèĦ¤vµ„˙È×,>ME ·wábKéÏy¤8kwoĴ à)³¨‡˜äejò´(üR‰ziq(Ĉı'7)ö FŜ‡%ŭ§¸Ê"£‚4Ï ĝÔĞşT*ç9C‡ôcÙ´şĥċğݸAû–ŞċĊ•ì X)Ÿ{x‹< ÎIRpŭ4ÎÉüĤħżì:ġeïImÍŻġÀÈIWB°œ?özz@lw˜E*ʉÏV×L(³şÒ÷çYLhŭ[=ö\P’AĠ°ü6er[ĠB"Ĵ€ĵ§C>uĠ™GËú³ì5…îğ"Ÿw„|UïŜuĉ½•óӌh?ÈT<êċĠħıĉqP˘zäXWŭÂ^Á=ƒlş³3Î _N¤îÉB3ċ;'ÑätìÔÌ˘zˆ]Ğ7]á êZÜ2z DĦ\Ég)‚áY€â;5ÌV¤ì)+#€ŭî òĈÑğʝ ìLì“c–6œİƒr ZԐç€òUCŞ‚Ï÷cgC/H&uèxâÌr+!ĈMR=_v›Be*£-HŠ=HŠ‘ú£™4zQ’°”DUö|żħŬœŻÇÄ"‘ÔĦ˜yë"c=ĊùéÔ×CBù8\!^¤}Ë9jÑ&gJ”’ G·G=P£ÇĜ81 9L1KlÁ&ZçY˜~˙„üfnĊÓïÏzwk ËäFj*ú—&9ô°š¸¨ŜœGnŠmúùsԔĜêU$DAĈğZÇÇݲŭâ\ĊéĈg* gIïá şúKġ™`ı߈üŽfˆ·(ĤŠMHÁ–ƒħ ~ ·KTŝ½*“ e~š ŒĉôÄħ ĜÖFîӔ@ ô!ÑÛB×gċ†^ôĉ‰ŬÂ&¨ +àux5x EZ‚ ‚x˜YÍ#ôŒš4ĵ§—Çñ!A²,#ÌË —|ĝ$ŭuˆêžùŞ5nàš#7 JA°U}Äż‹‡r)Ĝ7ĥ^[xbżĞşcÚgÊĤ‰0ö½Ÿz•àa£%r‡d‰$L÷˙‚ò-ÑWÁ9„väqêíµı5^W`b•Pü%äjÈ;-żTĉˆĜ·ÔKœ¸ ìÔ(İ]¤_Żޏ4z=܉˜*û|•LmΝ˘‚b Fœġ°QMm!ħç@ÑɀTÉhŒħ†‰DcĤ-™uÄ1-Y%듆‡”`š×iXƒ˜Î³B¤ì‘ç4ÓOĸ€%Ŝ!U—³§L˜û.…šÀ ‰ˆ8AIÔ헨™}9˘òÖùxmYĤy£NŠžJoS}èq`-¤“Œù4ÎU?ĤbĈ~Ž-ùÂfŸzÔeœ(ږTÜϽ†uá†rfTĠ§öŸ²%ck=œ%àÛM†ŝ)°Òˆ¸0ÉMÖPÖwÚÈV6Ĝbî=˜ŞPĵ8‚’­lt£ĊW>³*–ˆ\ۃ˸×{1Fı5ĈsÀ(µEċxŻ$ŞşĞ~q Ö²TUĜ_ĴeCWh5–îDÀÑíßm÷WʲħŽ8u˘:œcAUZèߨ“>ü)SÈtzWğ8ÙS/¸ÛÙÚIù‘-_ ‹Z:Ô¤%8F ’¸:<ˆc÷¸l›ŭá,ŬCˆ˘çD#:4Àëc½ğŽĦBäuɤĵ¸–µ7[7„Ô’¨Êh[[żtĴf$žIP`A@½ÈàÜŒr‰ÓÓĤ^L7j +ìU‘`w%ò:êÖûoğáHRObw߂TBĞ$ıSħŽž¸‹Ġwħ¤Gp`j~ŠZÎ&Oö(²AžĥAÖ1tPtJ=ŭ‚jÔd—7l…#öâôÒ-!₸ŭsoiu"§GÜ€Ż+ ĵ ”ĵİŻt2öĜċ+·c™<ô½ñsptÓɂ½™^!l ]‹,ş£ +„"Ïѽì§]e c4ĉb3…qkLǨ~!Š´Çòñ2–}êĞJ1A iµ÷¨W¨¸^·01¨A7óP(&iÍo–Œ0‹^X,!£Á‹†ñ†;…Ħ‚BbâĤπ6yL•;Öè³YzX@NŠ67\v½ä]…×(09ÑЉ˜/ܨLyò˘‹8u\à˜É>í²(Ğ=r0ĚVJ~’Ó'ŭa¸óìpSûŻGŝkĠM0 +ÖëBlŒ‘lèċe'kîhA$żÊ˘ÇŠ=İ|ıokPÔ³`´‰?µÉêW²à€R”¸vž(B×.ÉÈ˘·P™D;V’äzLÖà˜E EE@L4<#cħ5hŜ”ħË\R? °gwŻX’ş %“1ù…KhcO­|{ê9Fé˲á"SŬFŻH݉ÏDü³eVx àrÔĥ×ı íëSˊ‰B˘Ó˘kr§=e­0áĦFô”¸İ&TË[^ƒk†íŠh8˜~Íè ö0ĴTÍyĠ•YŜı1ŜqWÑФN¸Ú€²ċŒ”˙OM [ ċTœz’ÄZMbUĜB}ĝr…Ž_ˆLƒXnІĞ2ƒYgmí+dĠ%ç˙GdÉsù}Öw“$Ë?Gğ\˘TĵĤ}Ĝ]y¤) •h|÷0['›ĈÖŻ/ŭ|ïĊĥ]x iƒ!6è\qYô\çO +˘•0zm)‰&Íïä_~ĉ(Véêe"I#îo‰iÈç'ı= ­‚ċ>6íŜ=¤î(#³ĉ‰âWĠS/5Ož‚ĵoÂŭöêŻou‘^!âVÂOŒm8Ŭġ÷ĥRîĴKÔÊ´ĉeÊ{ ħoŠ”Q Ö0À“ĴĈ”î°Eó¸ÓZÜ,ólĜê‘l୐üx•B™ğÙDô)uP#"ù¨R›³¤w“%ɳDp 0ûŽÍJĠ|1C4ƒ´ka& Wž^]Ĥè/u#óÍŬ£7v‚qÔ×5ìŻ BñîўPu˜ŒjŞ’·ŭ„ğ}J·âȍ(Ċ}mĥ€5ĦĴ™”ožnĦúhFœ<|G‹8Ùo²lÓË{_5$σĥ) 3Ħ§ú‹Œ£9ĜÛ°O‹Ú"{ĕŒ¸’î€QBŞ›ÔĤÙc3ëi{Ôǜ•c-Ĥî™~“Ħ[Ĵjb îGqı‡A§{Œ™ŻÁ{èA¨Q£—üÖöùˆ-ğ{$6½6 +5D +0ğ}XaZĦ‰Jĝ“F*2=ı=Eħ—‡êˆi?“ê¸\ÓÊsÉ;\Â9ŞĠ.é'xĊ[&Ôéf?™îpÈÇĉŝ2äɁçe;‘ìé%VyħfŻŜıLOıF(w•ËF H-TÔ‹<$½FĜ‚üĽĴŝ—Ġé\Pn·)Ñe}’S jXò‰éß2í|Š˙¸ĝ(×)èĞFóŒ'œÑĝŠċż`‹2…Bì{ /›&OĤĦ*k\6ŭ%›w[̰áF;Â&aWl'— UĜ ’˘Üı†E2'À‰e…„½Ħß§Ĵ6½„Ċ_ÓĤvQžgK°š¸Ĵ>0ÄSBÈĈ;CÏ…NBÁù<+ĥ%Šİñ§Ç(B +,ÀMĵQÖ´À*R4ç–ĉ!M,ŠÈĞK ³Ŝb|ĵ†ŽO„Äm9$ž [$TR ‡dĤċ4ùQ‘)=ħœâ”óBö=íIÌUÔ.W˜Ÿä +ö˔ä’=T‚Á­¤ó°{ÂŜƒ`_éœ; ÷ôzB5A{vORm‘UJğm•rçĴyĥ­AĦ>ùÔkS/Phôş£×ċŞ›ġ4aNoïÌÁ’cÎp™I—sh÷¨Ğ›×ö”×qdGRrĜ·WÚуšR‰ÔŒ6¸0 .O‚Êíéi?˘'<oŬÛGÙ§Ĥ˜3r3#&Ë.Ċj1’lĈJ2}g0SàìĠr§é-GÚ­YÎ~ìĤ ÙŒQÎQ(ióµïwdhò›Á„ÙóŒ^tħÀ‰ž• Vïm˜6ş, Ĥ͏àÙ́ċ´êú?D6r€^Ù½š&zAúe/$öƒàcMB(Uáċr•ۏê +ë--cB‹šçÄĦ’ò?7joD”zs•‡Ġ%öyP}³“^{û™Ò?i^ÖŞBˆò ugÍà|JÇvÁ¨ì&7Ĥe.t²lLT™ÇÈĞ˛…÷Ê_ĥ×eX˜íg–LY÷ T%ÂÓË9š.In´jÜ{ÖÔm‘ĉ£·Ĝu³ÙêËIĠĴw ĴĞè!í#vh÷+–…~yâ§ÑkL&"ĴÂ\ï)XîĴ ƒ`ĞŬC{d”%‹ÉrW¤ĝĉ˃XP;œAbpͰ_VCĊ/ÏHÇŬ¨bŽë)9Ñ,m­ ­ŭv^M„œ!9Ñyk?PLbŞÜÀ@Y< ‘-°ĝĵ_˙6—2w Ñ É­eçgúÙwŻñUö˘dß ÔĊŠ)9>W`o +ĉYDËĤòċ£^޵´ #ŭë§ 3,ì~(.-÷°{?ŝDÉWD ëù%m–d½&ç šŬK:œ",Áò`°µÏ¨‡x8êsĥT%Ù›Vž˜„Ġ.ĤŞüCVş€ûY¨È‹ċPµÊµ=‹˙ÂbC{Cm=Ğ=ĵ•^ħġosĈWĈA-RryÊf4“?!R)ÖîûSzNLòħĜJv‘366<~ƒ6ĦĜÔjŠMħܐjclÔ@îêáÄÍ29)}~G¸KQĵıo} $?´_ĤżuïYgùĜKÏHħ:sSˆġIÁp_fżBˆôóĥVħ•ĉ҄ôz;j·ÊBÈş½˜bÀ(l½”Ĵ+˜7YÜZT·}o]H{N°Ü{Êb`L¤ÎxKVúˆÑëĥ<·(Ŝ‚ñiï zƒù¤Òh@XY$yĦ,=ôön#½wÄÈÇŝi—ÖŽ_]qBN³5AϐĊĈ˘É‘ѸŠG>œ}÷„E 6Ğ#2Aš˘žÛ9È'êêĊh¸eeÄ’ĵß½>Ĝj+ß./[żÌ"ߣ0µR4Nx0‰}V2bêĠݜ%óT•ùÛ튟”c! ĦRJÇĤ´Z–¸Ĵ­Ùğí³é.ĈTex˜f–{„ş“%8ŒüÀ’Ü'ċâ×^ÛçŭŜjy–½Ñw4ħÈÒqIi HEQúAl0@˜ߔ‹YàËÚ7’/@ß|71=Áç`W +Šà˘âûŒ_ƒÀeŜÛ&èxğRsħ{h "Oµġ‘*Qu§OóRĦ½^G +MHÎŞkdD|eĠ”jèÀkFĵNvy3½XöcÀIàQ,P€—ŜÁf˔żÖ’„”×ŬÂóâħ煔;85‘ Ĝ™/ù‰*@È4H‹b¸]i0YĤÙ"£ˆb/œk&ן(+ñÍàNmtáiîÁˆ't(˘—8ĈË+ƒıù%§Ô#â“Eŭğ™Q…‚˜­D$OİI ‚T‚ôXş^à&ˆħ7ŻıŞ­Jqĥ°eÀQôĞNùäV@rUÍ<ğ9›ó;Új5`ċË'!Iıv)ŻŞU~'‹|¸:ĜY²9~*bŸQaY0|’ġ<ş´Ëfá)(;ŝ”Ÿ}Ö%\cqFPĞĥÓWÖO=üdŠëÙli HÈ#KT— ˜ˆġ_ËeôŠ}nŒÙšà˘Ïî…áç^Q‰Â%ÜwH–lÇ!V)dÇġ6¸żH\ħÄ + M9uš·-§é½*Kü[­n —•qáéż–¤ÉL:;ğeÁ‰@żÜGet™Š‰€'ö2Ĵ"#ŒÚ’Zò2XrÓ.bÊ€˙]ĊXzÁ8&äz~+½żd‘.Ùê$µÇ[<-fzUmNa]¸Ü鍷—-I=|êQCòßë83~êUĴ*%‘x‰\ÜĤ •¸ÏPÔ[ ġ ;ĝ™ÄIÏqĤŽfħ…t¸ ,ĞDD›6¨£ĈşI0[Lv3k \ô°´€Qw×ĦZé!jž„ğsáĵÒĊ+H @ĴZ1Xĉp‹,FDJRŻßžgOżòeżòH/>ü“y~Gĥ™ğJ7îó…ħ³Ĵ),Êî!IAáÊ´ĤÀM`yèÁġ¤”eĦ×ġeż“z#ÄÊlW‹ĉW9/R­³ŝĜŽĴĴÀ˙ìöu'wµI}Ô xŞq[Gĥ„6.r +#‡ħá|â9q˔²żŞääed|F•ŞĜö·ŞÀW£x½œ×äI?tŞz€0dlë&àÎîti½;H#ÖĵÜ9JÔ öğ´ê)ɏG¤˘(ÎcLAŠ/Ù×ù‡¤XŬ­X]ÛWŜÚ~…eäŒĠ‹<Ž4aCájĵP?ÌX$`ih3ĉ–€0?ŸTßNOê$4Ğe¸"pĦiá¨^şR ½·úö³ †oŝ„Y éëŭ)ú™qÊ۟˙ċ?ŝÓ۟ŭĊ_˙ÍŻ~˙ûï÷Ûïŝú_ûÛï˙ùû_ŭŝû_·˙À£|½ßĝĠo~ûŬ7?ŝó˙îÇüîŻ~ŭ›ß˙ûßŭĝŻ˙ü“ß}Ŝŝìß½ŭŬùĊQ ü×_|M0°ĵécâX¤ƒb ’(wŒg˘ÂsĦ°ż *dèFJ˙Jp(JĊĝM}ŝ3D``ù‰\ d2­\ä +Ë-g˜Ë~™Ş ˘ĤÄNħ …lž¤˙JÒ¤Ĝr*(nĈyïŽeġŽŬˆÙ>%´ˆ§—ŜsÂŝH†4?ײB)Ħ‰ 2AR9à KÛÁrJĵR8cHAğĤŭşħ°Iĝo-i³¸˜}xËĦŻ“PšET‰d{8Ûŭ &äoò6V&,0\Ú¨@+}XĵyHF²Ġx’œÁpéVDR·‡B2'!HÈsÛÒ}ZaŞ ¸Ğ½)0ÄA£56şO0o³Ï¤a•rFÄc :=Ŝşô.ìsĉĝbYĈŽ;ĥ˙jĜĊF&. ++ĵì&dY Áfït NӞ÷ĤLF~-3“Żƒò’‡'óĤZIñ'¨֛…´šùÛ%ĝÛ+†ğyÁmj£8~D‿ş½JD‘²‰ä[8°_ìa›Á%׌Ĉœèဇċ 'nìr÷m"ڛĴxZïÜQ[WíżH7bt’ä'—8ħ½@엤‰DĤ³½ ×iR£oR…l6”ıCĠŻ ï@YUÀñˆ.`Qd6úĜ`Ĵ{‘eîĥ""×R¨>îAŽƒĥĈÊiñW…އ”˙sXœ°…Am2^DŽì!9jr• Z-L R‡(¤tic<>0äÇêŻ÷Ú}&sHŠqGÜ,šÇˆò£$ó¸Żx|‘ž­‡+.‰"‚„ŽM€˙q˜‘@ıeYƒñóĦ}è‚Ħ¸, @UÒÛ>‘rîaBy+¸ĜóçŝÔ'+ä´h€²ġĜE -·¸b<jéëĴÈ{„Aߐx,öUċMúz ×z ŭî7ëï?>PtİûӉŻ%ĠKĝŭ‰Ĉ@¨ñWÍŝš¨fÓ,i05?~…•p`Ċ#2ácĝeô)ÀzÜSÉk!b  +ÔÏÛlĥm…PĊ ß+‹o›Jj+¸áĥêDâèmuÇ6Ҕŝ!t¨MÎ7=š=¤”µgqEŸ„–óyòĦُŒ|Ĝí?Bŭ‘Qĵ)ôĉSìŭ\ Yf‘[=†vwûŭ²5ĜÌ{Vv|sÖ8 ‹`ŞÓ`{Ï(´-ĥzXlí;‰­ ”2€§Ż{âŜ?#KÄ ŒC/çÁêòÜyŽîĊĤşš.Ö$ŸÒmf"4 oŸux(c“ŻĊğ,=ÜŭóëˆÒыä˙ÎqyĞh +.™ŽG(óûïİ!zu…èĠrÁç²UdTĦéqĵ?”Qİl59„Ìtc!äU4 endstream endobj 36 0 obj <>stream +˘ĉŬ–8Îûš{ô@á†ÒŻñÂYé+êúû/YP"pKF·î×Uß(\Ġl> ^ĵ”Ïé?ĦÑ$D Êé*#éQ€Ÿ.Ħ.yr²(”³mžÈşÜÖĵ²Êqmvû¸ŠĊUĉ~VÂĠMfd)~ġuÀ[ê%•·ggKe$pKN!pĵ1W­ï²İÀĥuÙġ”ÍŽşŸXŭâVí Wñ_ ˘A/WŞ/ƒĜvàĝïÇ7ê|ĤÏgĤïhÓ´[Œ%ö¨&íçö7錭*òœ—˘Â€¸=<†t›Ŭ_Ψ ‡o9'ıH.I÷ƒûÄ5ö§>RdĥÈ`D/›¨ÔĠÀ„1ß (5CÎBZñàTİ*qĦ a›q÷´r} ş„…¸Šû ¨K”5ŸÏbUÚW()*;púöúF.\8é%79]ìx‡ÏĴ tĈËä2‰ĜEÍv=iL>èŒïS°ŸXèŝë[vÎÒ D KAĈ’H)ĞĤm²ZÍ]t—zе÷€­¤!ŬżŬw˘)Ġ-˘öÛzˆÈéĉ*^÷HrŒ(Ŭk‘ÄĞìeêÀ9#Qö½b; 0r²Xô.]|`7Ş/cêaⲔĦÑ$x­BèşâÂF2Z`­ÂÜgâ%­V‘ñîo İ.U-ĞŬàğTŬ='çtA4ၠò÷^~şĞË”÷ıô|ï$ӂ7y„^M’Ó–µKb§oM•h– +Ŝ~ísé—=*z³7W–šL‹S@mÉڋ‰”żêŞŸr +Ï#%)s`öPT]qŝ ì~ĞÛ~CŜ‘bN“šŠŠÇ‘Q}\Ce€FÚq5óו“Ù7ì‚úÚÒĵû?TFßó݈Ñûsĵ,Ù+êtö|%ÄxzĵA¤ĥÉÁ޸Yq ·”ŬhKùġh‚!ĴE`.Oñ%Ħf…w—öĞèŸÀĞËv…šÜ[„£°Nއö ÑÇA£ÜÁ””MèepÌ*a3ñŬġ}§05Û9ÒxĥaKÚÛ#Eƒëĉn€$HË#üŞ›„ïDX‚·Ŭĥ[ÄçŜĞkhÛġÔħ‘ä‹üx°µĝTZ +$½Ü} S> o‰ÏïV–Éo<ԛAWÙú˙Ŝ…iSÔß  €~ż]@uk80‰ú ä=dzŻŜ™}Ĵ2pErġŭʁêĵFğ<Úˆ·}P)4o¤­î|+ô˜`pp…=‡sàš†zJ ז¸s+>ô–„§{ż4{8nİż.לö)€”{w`…ŭÙŭqv×M%, „CÂêgÇ@]ċġn¸ĥÀużêğĦKÓ' ê “Ĉ u{x7µyhÉgQِI÷ÒJÏè‰cDŝ­żŜžv?)HşIHœ=ĠeúI}2 RpŬn.„?ÛԂS Ù*ıd\ˆšR(.‘T¸ÂĦ´*ìɌ(Ŭ÷ĉòĝ\vééŞŝ­\-bö[Ħ9…òĜßèAıTU}Ġş$¨4(êÜAdŠ/Ê~2tX‡ChsûѰèD}b×'öŽ#e…ċp¤´żœœçŸĝްÇÔ²Áb½-Kˆ¨èÈù²dÚs5“ì%µÚTħ$‰œGӄ=,ÈħqmŞ"Ĝ Á(ı}{v¤úv+@5ŭ’cOÁĉmäpЧ„”"^xvß}˔/’\-ĝî"”ÒO˙rî(…~u@\n‘לRŸU·nż Ô'ŭȌ°báğƒŝá€(r–’5œJ͙۟‡³Ĵ0İ)ŭ‘(}ğyBâžúŠ2cšĞ1•´ú'e·°ÌÇr¸ßɳô·[ĝX+_­ĊrÏ ·$q̤ıC3;˘ö—r bu²ĥŭrûK(RÂ~?ò|> 8ÈċŭùĜEò²Wûœ‰ÇŬ%ۍgË@éèħ8Ĥ\Ûq Ê™şaC—¸Aî‹Hr?ĠâIµ‡ùË; ĵGîLĜĴO{ÇMĠ-½Ù0| +“fŝJœÂJÔ{ÔpöJ;9ÜàšDŻeıš&ùKğuÚ³ŜMs_sb?¤xÑnBÚ@5ô ÙQî—ß“¨@úCñaĤ4̃4A wx?"íË×Ġ†]Ĝ +t½½8Ma€ +µ‘ĊÛĊ.eOż¨(W+ä…×aìzÛ^Ž˘›fBĴOƒ¸DÂíTp¤Ém°’UWéE9Ö6ƒé˘°9üW·ß³gEì€8·GÄTà•ŽÀÙÌdY–ş²ÓŒf güŬ{wÁ[&í˙ĥùV]/ĝšò>Š>s ’m]“)wC3Ĝ[­ñË=ÑĠJn·×÷Ĝ1R¤àFèÙ/$ÖÔIÔ­=7|aµ|Ln•7… Ĵ•>œƒ_ü22Ú:.!ûßòj…ġÀw^™‰ŽŜjy/éa. _Ŝ"-í*v^ZŜ~)ĝ˜úĵ˘Á9hMnPSUt^+[PΎ‰¤bm{`Ç|)ŜìXnw •êHIßyÄĵ íBĉWuU„oüŽVážï'<^ ‰(MC·3 +,%ë+ìOY;n‰jÑÌÁìÁq—·ĠGDßG¨fá!áHÍpIí´7Š“ŒgŒò+R“ÚħXR8‹)°ĉ“j#ôúD. ħò~›'-%¨ÖëÑ$q NÓ_ätöL9d;o‘(G1””’ü—šj?†Ċ˜›²Û&Ì6N{ÉÁşUH^ìONnfk +ŞÑ¸íéÉuPċnÈĜz Ħ;lòV‘%à•Ba)½”}{OcîtCeW;É{ĉ‘ +^ÁËAžİ FWìÙBmU<}ħÑşÄxàÛĉ€+Zw€…9pĊšĈfqÜö_“É"ĵ§öĴ79œ,ßJċJÏŝ!vi&żßáÛ°Ú|Às–è°ˆEV0-ÂgŽ— ùÑİ#.lG޳ĥsvŝrj@Ò¤<ħcÑ[ZĦáî§et-Â_Ô°½TnKˆÉXC8¨w‡Ŭ.Œ>¸xˆêÁ¸ĉ +B =Hœq ĵĞĦıM–$³£Ü­0uÚaVżâ0§F((”KDı”qob“M1™ì£(Ü`´ĤdÈĉŝ/ü¨ŽñĜ³şûñà¸\ƒĞ%1êŭ +(<jrğ$~É^›ežöǁŒ(İ0s˘BĝK› mçÛÏî÷3-ÀbĵTL˜Ĵĥoo\9ˆ58–ĵ,̕<*Éáj^1H Ԝ¤1VaŽM݆NáĦ‡ Eĉ“ĵšQtbòTj{PQiĦĊ0 CšH]I²+¨’Psé=Íù ËĞ!VY‡ÔÁbĦĴ›Çy˓{Ä\Ħí¸Í7ĠCe )!9–ŝP˜Ùí?˜[íÏbîùÊPÖLÙÂ\nŸVq;“´_ +]“ˆ°Ĵšq–è·ÈŬh™Ŭĝ1óG~ ĠÍ!Y–GÏ͈/ÊODbéIžaÉ5HÒO{ñèBê…Ù‘V H6+LœŒòÊÏb†{‚’†*İSô„}E:·-I‰ô"SjÑşĞ·t×SM2yĞR=XaÄ?ÍïĥĊçġÏHU‹[^ ÙH4-$Ŝî8™Ç4"äĊB’˘Ùkĵ{K¨ñ˜ÌC½ˆûu‡Ë P<”‰ò„”ĉ:$ގŜŒd/Ö#˙’Ì™ÈOŬ:Ñ[%m8^KFOl§ğ_r•SöHZIVІî ċ3Q¤ÔгÈ\—šŞDBĉAùÄĦÜĞġ̈́†ä9j;VŞ2£Dç•ÒF8%n‘İ–‘)N.Ħ·—˙K“V·­ú·u6Ú +ĵFıF9ë6IĠ<Ò>—†¤­ŭ;Wĝ.H(’Ë"9iÀ—ú‚²*9pŭGì]vàÒ<Ücá¤ö{à‘ZE1Ŝ; fġZî%wzˆ³ñµ$V’²–Pîë2´'‘ÂÉ +„y³C÷%ŜDL¢@Bµ#×"ÁC€´÷?żċ›†¨DşŬ&AáÏT\XıÓ2˃¸bœ%àäŝò˜„í‘\0o@ÏCà MiqBöAÙ[B’ŜĴÜkuš?–+Ĥé‰bœ´é–=0 HĤ Jqì‚0ì)Vî–7R`’¨>tI†÷£"EYQ ^qC¨bTúV XÒú Ü$nċ .F?e6l3µġÀšßĝwžj—r(óƒjá(ÔÜcrÜ[Ò Ħ<ş=ö VuCaÄ×Wĝœ‘ĥĠუƒïĦn7ÑsŜDgV Ô'&ó( Á>¤îġĦ†U2ĤvşîPäġ—Aċ\:ġ´MÉïô½V(Î)zGM`Oû:@>8ßžä}/Òı—ĦKJ˙ûyâr€’ l#ŠY& רéwŠŒ4çĦĤI1S@ĉv`BbùRn%ZÀÖ@0'э‚÷~Ċߑ†0B5Ì@Á|ïbİzŭ $˘Tù!VĈÛŻ˘ĉw*s#£+ĦS€E2£ÍDĴĦ7\ž%tğŠäħO‡ŭċɄ2 ÙĈPğߟ §UŝĤ(³žšĉŬì^€Ò‰J~ĈHÖ£Şs*—-NiRÄBPœœx5aŭĦ½iaY‚ µ…2b¸aƒ1‚uİ]XtÇ+&ĤÄ~Ċz˜Ü(ÒRW+ĝj‚Ueá8ŞX{dRq.R€C†³5 ħ8Ù)$Ş‘6=—$‡‰\7“‚3Ħ< s³T°R +Û~9ı¨UBûĴ…™Ċt–’5iġjšˆĜ›A!Ñ÷&?’ċóNHñTS5.r‡’Ó#*dïáJöt>žèQ£ÇÁŒ`SŽîĉ“Ô˘N{”fĦ2„ 1žşħ! Dn †[çÑJYä¨qÈÚ;‡x8Ċ¤×FD5Á)ÖÖóì Mê6ËLÏ}VKÚna=’QĤEşü½ß“kĵ4 ŞÔ§/„3LŬ۟°V +ÌBѐĊ&[¨Ë;”Ë–,„p÷¸µĈóó=!ä/ ‘Ñ@·w3ëP£ùHùElİ90˜GڅS:ëôè²lÛĞó0A0ÌEŜ‰BÂb–Ħ;ÖBşì€ZìwĤ,ĥòâ˜:dBÉ3‡ÄG°´R ıßEß×m¤ž¨XÁĦ†‚C8ĵö*÷0Z\Rtô½ÇQŽQäM°3u/ÍZf°j–ċċ +Ċ[]RyìIĦC°'•~Ê"cjcŸŞv~T‚ Ç]D‘Ü÷}݇5X 9ß~XiŒš Ûú„Ds]‰_züçV훈ëùàqdêJ–SœÛŽT$…Jùnâç&,›˜ŞêA¨t~Hüz]k„Ì÷2ßË~£xçTJ÷/İşEİ% İ— KrÛızÉÈÙ?@1L܅½şÜ\:$çċr‹–N"ŭv‡T­ve{ŽıžRĠ.użûžc„}Z9ÛHW”L²Óĉ%ËĞĥ’’w”<ġ5ù,ÓEĵëžÌĞ‘ŽD+B² ˘ CR kĞžĵ şŽ•×iİô"²˜ó0B‘Ê[GŜ=¤KV x ó&Jéü’äcè%0ċn JĊI²S{Ê óA6 'R˘bˆ’b½²Én\=ŽG²4šŞšĊqĴXċN›Ö}nñĝˆ"(˘í(âıÂŝù'âJ†LŽ€LŽÔs]Ħ Á,= ûvŒŒÖÎeYOÂ!˘!öŠÀż@q8—nĞâp ğì––ĤT¨š\q&r-˘°ár”Dĉĝê*äW¨Ïu,é[]°zĴÎĞŒzxMqIzIğ„MP —ĝà#.%keÓµ²0Ş7´)‡äú›$p Ĉèá+‚xĥÎ3qĤ¸„íàž¨I/Ħ[=ÄÚıs8ž¸#ùۅÖ0-G)t1Ñp$ŬîQ‘;ŒİtÏGĵ^%ò°TBzR‹Êäâ‘­Ò=Ë6öĝÓù[jóèş9"S#áÔ(Í+œè*b ŭò@6G#lŽ\‡ì&>k]7-wN½`DşşëéNĦp­ŜF‘m‡+‚ħWïBwğVהZUeŠ˘/C(ë§Żëĝ‡-èÀ \£¤£^zOêaĠqv¨Ž‹ôñG³Œ'IÄĈ:Eìٞµ[Œ=;Nç#` Q2b‰ +8M,+1¸Î;ܘa³kĞ™}Ç]À…bBĝ+t­ĠöS’4=£ÛÛı‰)‰ŝ(GìjĦ!À(ÒaÜa ›2t!Ĥ4eCŬ+ñ6 ˘v_^Ñ­¤¤9(ŝ8n9ÜBxĞpÉĵKçG€Û{³éĞz ù܈—Ĵ[9WPÈvž€@y€„•ĵöƒĜpónĴײ>˘ĉf4¤î\LÀ£ 9‰Żˆĉ)óoyĥ´y"Cžbx—yœ?9ÀiN<%žçóAĵ„QI `-ÖqGV|ï·> +ı%(ˆ\@(œp +5‡ğ`•÷Ä)=QM·ŜĦ8@ABäÊ.ŭǎT]Žĥż–êƒè s돗üüW£ڒŸ6/c™DàN™šAöžĝlÙVe–ÀTŽDŽÏ)ämŽÀŬ}< ŭ9ċ¨§}>¸XğuzD‹<ì9ƒúKeĥ…hàëàe~˘8“·²]R{9Òn™Ŭ%:xġZÈñ=×ĝĦOĊ|ZÀSıÇeJ´ġ%•XAñÏk›x_SH_е{‘_XoXOy"=)Yġu™*ƒš|T€Z#Ĝ!ì$İ‘S›Eôüû쇝Ĉ}F3ĝ §|w×98}lU3Tw’—ċê ‘Ċôĥ„ +ĠŠÈ·ñœA{nRT½„½ÇuN²™=‘n{µCÓQâ‹Zğë…{(’7:PüùÚM‘=àžˆ&€İ–tTŸ™ÀÇÊĴr%Cò˜-:ġÈvƒÑ…4Ċ5¸ŬNèфk—À?8ŞŬü‘yŒh6\nÈs@BÓüŒÌf!Ĉ|h'¸A)ù²Îî§”b W`”Ö pAÔ1k ÷Ĝt=‰šônßw–tq<ğß`×f+‡âH}ˆí˘ğ.ŒĴè˘qN5*Š=ŒöA8WnN°Œ&³Jb!ܤ‹ĝ(Ĉ{sĴ.Bƒ£Ŭ·òšú†ú€a³@Ġ!Ñ ™í`ß5`°Àfá•J0ÊIl bÌ/é}T˜AĊÔŭbÎ,Dİż™’ż™­ċĜ. Ky4€â´3ƒ2„‰p x†.§ùX—Ċuû°ċÂĴŬ(Ġ# ;ú­:ŬA˘½|ı¸o³HìÍ9 ++oÒüíŝe}ƒ¤öûŭè‚8üÜsşOÀ2$î*ŬúKŞF3AŠÚKHŝFÚîÌÏÚġòZÊĥ˘‡xŭĠ\19BMĉö7èÂ"£Àn‹opaZ°üü„,EnF<ÀŠzòfŻ$e$('ş|ÄXWHšìÓu$8ž0Áž&Ó0·ÑYçıÔg킭ŭhJġäŬîRùe£$°<€×î T&RµEĞĈV+żB s VîIP³™èŠÇ\RùµŻHÄ^z¨DÔiĊa­1ĥàNx żÏJŒ9šıƒôßUġ|)ŭJ&‹ Ħdîoú†€żL&„ğ—ÀĈ>ÉĦg]n;y• 8”WX4Ì2´/ĜuMı7S³ôB!ÙŬ™ÂTq.AyÊ?ş½ú&6b’ŒĝĴ°`܂Wô”b”@xojىìıWò_ ,$’ÑCcáËë_Px˘=G]A ݰ°›÷ ‚,Á€šžÊ í?¤8k˜ħÑIœÊ1‚Ğ3œ§ üÀ]ŒPĵÁĈŠxĥX p8€ ëç§X{+Y oĜ˘toçĉÂ|BïÙñO6$d÷·ħ“00fmˆGdUŬ†½w’ñe–)w%ĉħ-mı„€î›ànô@ħ’Zİ[A6=_…ı˜ĵÖ8×,ñ@ĵë“,=êd-H Ñġ]:zŭ’.xâÍ7ĈŻsž3âù€˜Áf¤H†'m…lJ/êqìZ|^@^…½.íh {ĵg—Q:ĤHlı/ˆÖCUÍ(ё’lĉˆ}ğżĵžJżŸò âŻˆì‚Œe¸#Ù˘ ñAsB‚'ƒ&OÌUގâ:XD½Ĵġ‰÷8“Ġ‡^+BÄö\5VWIŸSċ•÷/ä#mŬöİĜĤ‡’rĥ%ĜIĴÍòùC7f„ĜÎK%:jİC(ĥ‹Ršpw€ÒìaD$Â`SşäĠĈğÇ0vräĥ-I@ĉ´ek2läBÖÛs4^Ż%xÒŭ”UÂÓBR£dŠş,VÁĜjğP—\$Nû.ÎKà˘-2¤ĈOe‹›-VBŻ (X·H³BH9_³agÒ8ô_[ß5’M\ĠžÈ¤Ô€P“¨6ı€ŞŒÜžeÙÓ-!x†¸jI ßm÷ġÈĜ^uMĜNÔ5û2Q΋%ÒĉNB9$à:…ĵĴıĦ+*÷jŞCN/Kì^·IW g(ħÖĉó´Ä÷Ž +‹— l´O͌(e Ü\äl<}ĥK™–ċĵ.•&eùµĥµ'œ‡ w1~<=°:%4íšc[Ş%‡›˜Öbŝ&9;’˜@°…\ߛĊ4²[<ŠÇĝlİÈ´Ó{Nó>QİÀAoÔw³ ƒòL@—e9"Bá]0²á(û&uĜґwöLh„bà,ġFÌğ¤ë„yğ£F sħĤâ—4AäÒn†ÓoJCŬ6{ /ġe/$”9C$˙ŠôäûĦmĈ%–,Ġ#1&tìZš5ÉZï/T4Ħ+*RÍÖ^àzG`˜Û$€ òUŽÉԌÊAUJPöŜoÑ0ĵ‚vGà×·Ko­³ Ĝİ€pre›7‹BĜ£s0Ÿċ"ş?>²q{‘‚ ƒ4 YÙSñIP_ÜëÛ^ Ĉëdoƒı5 +:ÚS'zΉ˜?›Sü~ŸİPĢH¨…X"BÓEÒlsÊĴ>ÂTÖCIš€g5Šşy? QÂÒC [İı&êáJ쉀‚§9ï$=W“ž ·ÜÄK:`H!  µ.˙'şN@6îÁ˘*Ÿl§è%×'8ğĞc™(y˜KĵCèš/H€Pw[QNn*É$;zżáw$5{8ÈÍM¨Ô9yFÍÜ3ǔ"›áP ğ=eÀ}T5K$Á‡XbKŠÌ;Kĝ§°ŠÊQ™§ìnàĊÍ_ImċkĦÜ'€ĥ'j?Ĵ0­FxÉ`zÎ'…EzÈ Ż a:>ğ’:êö\Ù³%•µoœdòّış€JşÎn)R6VrXĊöá†é/é!+œÜĦpRZžg4‰’8çşïûàŻŒ/˜Ħż(-’Ĥñ;+ğYÁG‰èLkÁŒ"ÜĠ½èKn`~E7 KïÒĵUħnDl9"W¨‹ħîĥ;.Q³Ú*Ÿ À”|m²5ϗ̣=™Çœ+èè +îK“öl·…ġö\-dá´?B*‘í@ĤCħ9q½ƒqéjŒ8LJ²Ż,Ô„ëù€dĜ–̏#¨(áğnߝ‹œT$bĠ›f]GÀmĴÈS"5ux‡ĊàjÊöÍÜ\ĉIR÷zaÔ$ÙġUñ96n—,sE–䏋HÌ;‘½àNçËİŜw…ÜÌ ì_.ëèW9ċ.†ÍŒÏjĴCİĉ'µY +}2F iš`á n•`8ĵ:Ñú>ލ(çgQ kȌp.Ġĵ-G­›^ b™‘ŻÉħ„†i p01˜ +µÁSŒwvQYıj eï,BĜÁ"A)#uÉßʽ¤Ó$ƒ#YêP&BŒÓ…Ž ËW>N@µİ%OìóItğİ1ÉH7L=Á?µËÜÀtÏH˜)‡) ‰4ĦvĈcreçoZ0”²pôÒçIbtYމXúéŭh%JŒÒ*Ċ#[ƒ?ŸËûa­ğ¸g^ıCcšo˜áİ^>cHDrpT0ĜĊ]i%Xż$äö–ppüƒ‰€,"˙)”.­—ÁV"?ñ~ŝÁğ…ÏŻĉ¸_û`³ 2;H5Ċ^E;†²ìÂŭĜNÔñ“Û–EµI‰jUğ2\ħ•,†@¤Ê9¤0NÎċġ +xm“sG" IC%¸„‚şÚéäĴv7-EÜê¸öıdĊŝဧd$§ ĉŝʟ”Oš|e—Hù‘%(’üÊgŒë°9"’;¸A}ż$‘àf÷Ù;dogDo¸"û-cż!I:¨À™âˆˏÀKYŻmQÌG­ŬKú.ĵ˜r ğÂN’ +~ ‡Vġà3޽Á'‚sŝü/PŻ1ħ2-ŝùpPÁgMPè+ÄüîîA&M7óIŻB$Ç4VBK.(Á¨…;Rĝ=v„°v÷SñİGz£|? +âĥ’@J1Uži4#Ŝ›&dîbè-Nġ`fАxP c„J×)ŞL·5D.âB””WŸ6Ĥ=×E‡vY·k/‚$eĜ ĝJe­Fĵ§èöPˆMîîžß‘Fó/óE6˘‚ÎÀO##q^ħî'Œ™Û;V½ċ€ıd6ŒĈ6ÉùöC˘a5Bg²T‡˙ bê5bßì>żçȧ +H™k=™nÚŻ„4ÑÖ³Bêèz šyyAïxX—ËÚ²˙ìŝs½ÄDBBIšD„ÖlÙä(ß:!ÁgëîğÖpµö”7$*šk‰ÑïUt2z‘˘Nċ˜ùѸ1¸‡ƒßFšç…­ÖŬĦĠĵĴâĠżŜ"ĦQrGÛ›À,Ԏ8ĥı“{ĥhZë/ä^Úİ~XäċHíëEĦòÙĊĤ=RÂ&³.ù3àùÙÁZ—Ġ TßĤÎ!ç>Ĉ—CÑŞqb~àB3µ…°}ġ[g(mywó*wÑÇ:œ’ı$­²Ÿ)§Zü>ì•ín S’¤¤b‘z—á +ŠßŠv ]àà—˙°ĵÜÏm:˙#ñnéġsCô İÚşuĜ`ó8DÊB€ŜU‰–°Wĉ!:ğÁ%`Ġjz÷äÒ&8ĠÑ&o_$[‹ĉÇ-³“â²~/Ŭ +F;3n[­wêy1ŠÀâ­§7êžkş½BlçDù˘ċ%ġ¨Ü2Ms/ aî9QI}xĝb™Üš2=Œ-GŞ :Èïüħ˙H@Y°ˆŽ@K`tĴ³ â&”]ëO{{@]'Ì>ن‘óylìe?Ĵ `ӈ5}q*Ô£é@: İÚSÚ˙ +’gìŻŭQm Š‘ŭŻÜqĜÔÊàĊfù YġĜ‘-H3c…O „—ġl˜èÑ%l# OrQQúĉ²pġ˜b·_3•làÓÒşŒTtҒ{\@ŸRAQŻċż’â&eĉċíĦ•Ħö^Sœ :\"Oiz;(g¸šŻñe +d@ÖYO3 Vìiùǒ·ŜÔà%ñvŠz˜‹U|üİĞ[—ĵÈ<ŝtüBŞQZ;2’th]²ĵ;\ÌĞbÊ~òӁ5]ċëéiB÷ıWu]i+—ñ{Ôû:qÒÒ3²ĥĊ„ÛµYUÉö,ñçŝ%eä³X”Òü4NDꂨŻxĥk;€Ĉş2;Xĵ{N´qġZAÇÄ<Núú´šLCÌê2eğäeùqĤ’-Ò­&âägâıü³Ñ[µdb6‰˘Ô/"^@Âĵ Š“,j#Ħì[w0|JͲĵcċLĠƒ+/&ß9/nd›ÇÁŸ…C +WôTñí×Û9ËIŸVĥ(¤IǛTÙÑ` ï€ÔV$­ËkĴċ +ÛOĈ˜*6ŽÇ:ñ-bËĈEŝjì*Š6W7 _$ù’•uÍkşĉuYı]%6 öžĴğ"ƒHxz9²û&·›ŸÑİúšiyjˆ†§X/†0áVŜv`_éíR°ı)lùïĴ“Ĵ“ğŸECĉšC`jSe$ĜJ˘G™MĊw¸?l'ĦÜ=Fà~½_ß˰äôxÄEìÂÎä/Ù:â܌óV}ñúŠı†Ì/É9O“]¸V\ĈŞï[4D_1Ü–YçĦ=/Ó0Ĵìßĵx’íâ‡ßVGÇ+Ĉ uœoUnê%—ĠßÏ˘} œBg÷×iċ _b“f­–Ĝ°é+ç0AĉA“ğiú3C]ğ°½F %~áŭjKËÔWî] Ğ<£îĜŽ üA³2‰ –oŻ`‰Üٟ%ĊfJs·Ks]²o;PjΝw:uT’;™šûX§‡(^ħò(mxuçÖ0ċŠ]·Ž´·}Ĵ?)ÒÇqżÌĴ$"TˆxÀv›µ„ŸĴŽC€^Ú§ÖlvômşñždÖĴħ”yÓQ’/?ö*ÁÈk”ÍŠ!tŸñ€šó7ŝv8Éâ3˘tµ_™D ­Kíĉ~ċ5Ġ˜MöÎÈĞU5j¨j,żzv€_àBlaäÀm¸šĈèÂ=@ˆħù²ú Vp5°"œÏ\uĉɨ‡=:$‚2tjA+Ŝ‹°C==bރ3;´ċċ<|)ìÀgMŠ·µŠşĵ$ıÑcĊ†‡FnÎ*ş"ie£ öYĦGBÙ-PĤŞÜi]6S'قêÄĉN{VĵÍׅè 0i– İbU·½v-Ğ’O=GÜhyó>öˆ ĵ@8Ÿ*]_Ĵtbw DUJy S Še—E£×Á0:mÒ3/ÔxDyñüƒ!êŭö³İĊ?i“wÄO&É$0ħz‡…g.¨Ëêúß•üžŻL£MÓĠ ôXÔBĞÍR;6b޳9“Ô"›Ayz…Xé.j@ċĝ +·˜ñdŸŸt/ÊK—ñ'ú +ÙÛKNŜ@š!´1ï™tOaYšÉĤü×F›2ŝx:P}@`–)—ÒsrûûñĦR ²òÄBú0z8f?’–î]²t3Ŭ7 ‘0Ñ£$¨uu j‘Ċ‚ğÓMÁ|+‹tĊ ŭIí ÚVPǵ—⢋%Ħċq' ‘À9ŞtîJb&ċ‰)×Ԗ£YĜ‘_hÒè  4­Û4$IžAš_·oĴœ‚ùr÷¤•ÉfLuŭ­Í/Òût]µKÛĜŒœßׇĵ›Ì”™Ê÷EêżÙ…Ñ\lĞ0VÜ/í-b‰M‘Ö$˜ÑTĠĵ{Ää#œĈÂIJĤĊb²,‹§„ß!°%•À[팷@uSÇñv I+Ñ­Ö^1;‹£€Ĥ,—4'N‹[÷@_ ›`çÙ¤v&s?İïÁEcqI­è½dƒĜÛ‰ @ğ3$Y:ïI²2ĦÚöM,ĜsĜm:U,ĴĜĦ(Ÿ˜ĵFĥcxSÇ0ö‡=ÁòxĠ†˙ÀĠx`*ı3q:A´\ġÙ˙î/á ”ßĵ!L\öÛ)ŝDX(ï‘ş)à![¤¤TPç û a’UàŸ} Q.b†û€Ħ' ı“'‡YÉ71$iî7šážH­³C*vœ€ş˙JÍ>ƒVgLİH=É0›ƒ<”„Ŭvü€ZQWägĝµİL“—ßĊŝ>04ÄLġµ“¨˜h6ƒk,TÓÀĥ‚cÑ´t—O í„"?{y.˘–à”ħñFÔfµċÁÒs2֜ù·CÄ*&4f™ßípFîX ++$C7]£ŬPİFòdHú<ˆĜ×Ĵ +jĦÀqK€`á~bFğ_P—2ŒEyˆc@$J›G𰈔q‚hAjk¨]"™kӒ=ƒĝ~êh‰ +ÏÖT2ŸĠnĜ÷~Ğşé&Âî·êzOvŒ‹­WJġ™Àd‡v/{‡PċöŸàó´@?êċ`Ċ‡~Ĥu'²ñŭ@HêO_/uÎF’ĜÒ`ĵ]5½ô9ĠĠJPßphı ĠiJËî%<”Ĝ…¤˜nû8 ĥ¤Á‹œµŞ!³¤ħş|)—ŝíSİ%ċŠ…‡Şħµ:ùJíxlħzé t€v ËV†\·Ô[Rí2á\J/qÀYÛĴù´'Ÿ çĤ?Âӈû´oƒOÎPfáQä9ĦY…#é€ –Jš-h ’Ĝ%;ÄîžÙ1SÓ 6Ò(c/ŸğĞnğvŝ#Ĵ+ñìLvä-pÌÁEĠùâq‹ÀɨĊ‘['$Ċñ&ßXˆfp÷Öĉ +˙áÇÁ.˙OäşÌŭ.ùàµS"ÒŬkŞ˙Âu)²>óLŝ{i4'öĈD„²!à,ëc‰`“ +ċġĉoßB´Ò³\Ŝ ·Zž8¤ɜƒÙ¸k„J RHXˆf„ZİÎİGŒ[jƒt>~èL²‰ż2’f‚Ĥh‰?†j˙ÁŒû_“ûnZ,˙”*éĵíË÷ß§ta€Á?EÔïd˙şC`CÀ6C€ÚŻĜîÏAĴ´ŭ† +Ë]+nÈahžŞ›ñħ2ĉA8t$[ÒenÒ2 Ò BK%.kg¨(şPIá@k·ÏBÄ]@•iĉÛ/Fpĵù"éXkûìöŽ+xJÜbïùÀŸşdÛġï!-X²ÍR%GÉ:>/P³(i˙ğ£À'óç Uɂ1İL™¨÷öƒ²“T̔Ä!4ğTDâMÛÊ!B”ÑĦ‡áċ†61l8P}‡K e‘TŒo?Ô˘ĤP¤ħĜ3Ünò"0^ŜyA‹f´ ĵq'sN02} +IàĦW…^$¸ì^A(Ü+EE° +ì\?áRc_5îqX³ża­C˘Û'ĝtĤĠ,x·uĠd{PnşS׸ ­~Éë‹ĥô–5n·eo5ŻĤ/Š~H;¤”bİOxğxQżOċKk@oK_zDŞö‹ôÔ| Sswlgˆ˙%Ĥ/4‚7QŠ—ïRäIĴ"JKó +NB³òÏւGàSÊ­_„ĤħÏ.&·ĦH \]ћb‘è €fŭcCzħ8,|5;Š­Z@Ĝ ċÒŬlĝ´Œïżç¸H;ƒ}E‡(ŽÒè%Aà™eÓùPNƒP!+HŽ]˜-_G‘ây˜ËMŸ‰_.t²:ÜĞŸËü)s ĴĈJt„1†&ˆ¨}ZuJf¨D¤İ*K›²)M¨E4›Żàŭ>bŜ&‘/íêÊ*ıì;Á☣ÂlöĜX‡ìÔ
êĜsĈ.×û5Ûépuƒ›ŭ³;Yß1е…R[ïy\{dùİŠV“³Œ\Ô0£ˆ›÷-Üï 1:MPma~è·ı÷p} <š.¸ßzÍg}Yù·ĉ’°r·­'onhŒwÂ)ݚuJWÔ]ËRŽ%`²‹tA‰f5yNvg)³ +şċ}éÀ ˙nïYtyJĀO(9Y …L[÷~ĝ+:(*×LŒ—n+KšÂCîyöNdÚìÒÊ­Żôö‚QÄï0_ümgĜ|<ˆ˜†T5Öciŝ½–½PËÒ_°’ŬI*¸ì´y…s/ñë×[*•œkĜ1W`èW¸~óá€ġbÒ{>\lLĤ÷K˙úçeUS'²gyPoŸBœ½Uıt[–THp{dsÔÂt9Óéİë†éé.ä‡ŭS@<ÉFÙe!L½@=,@—g\pŠ!‚K'Ùâȃ:²,?É nÇ­‡î4Á#ì×ÛıYżâċ:DwĜ£ &[eƒÍĥ@×Ħ§|=Ħ¨>ìàÚhœ<;8ËÖWÚ‰‘0]Ûá‰ĵ9Ċh(ş²Q‹m()9 ‚ĦBE‰u•t&†OŻä<%‰àĤżB×VŒL˜^’m c§˜×ïi†­ËŽe·[V(…ÍŬ–ÊÙwßü w+Ò·ĝS ô3”·?˙Ëü§·?û‹żŝ›_ŭŝ÷ß˙î·ßŭġż|÷~ġ›ß~÷͏˙üßżûñżûĞ_˙ĉ÷˙ŝw?ŝë?˙dĵçíÏŝŬÛßŭ—?0²”ÁÁŜ#ô½gà?˙Ûïġ“bà÷ŬúÍ?}˙ŬùÍŻ˙ßüŭíÏ˙ú·ż˙JÇżùŬ÷˙ïo˙·}b˙ô/îú•³˙Óo~à~óŭż|÷ż}˙ß˙Xïoż˙Çß·/ùŝŬżŭŭëüŸ~üç}?+ŭÁ+ŭ_˙Íŭoż˙˙yİûżĊöëg‡ċZ˙ĉûßŭ÷żŭŭëbÛÏ Í˙ûĠ˙½ODÏ÷Û˙áġ7í_ŭâĝ‹żżûĞßŝ:†àߝ÷üíßìwî÷ûµûċ/Ŭü—ß˙×}WŜĝĊügŽ,ùËßŭëżü·çÏŝßŝöW?|˙ë·ùï~q½ŭĊŝżżû·_HĊċ__˙ŻĵÔU·˙u˙Ç˙³›ŝí­½ŭ‡·˙ó˙şŜ~Í_ŭí/~‰ +Òß( |Ñĝa7Ïa~oŝöCóŽ,ħŝö ?Ó|ùíë˙÷_°Cä@î°A. kTÀXë’ŭ¸H ;Xżnô°ñ7£T˘d”l‡($b‰ñ(A‹ĝ„‘÷â4jx×aÏk÷ĞÄvaıçòñöP3yê·hDĊW 7‚etcĦ<÷M €O›—÷/~îÛ_ü£L—÷˜ucĊy>–êf +onDĞ(~’ċɍXÄ;Ïc’Ċ‹,ĝ)D#;_qŞ D+ŭÔSž× …â ֕ŭà¤ä;f;cLtôÎ}x`Ç=ĞwôD¸9~żFİÊèWêëϗ|‡u[€ŠĊ)ÍÓH‚ )n8,*eZ˘ıß=Ożë'`Żë˙ñ£ĦBBHÄû!šQîŽĉáçKÌ煚Ó[ =NËO‡ÌßZ_mòÄ˙·Öy‡]ú˘qǁŝèžg½ŻžßäsžÑ³ûyLÄżúûyb(Êúñ"öıïٜHîDşİѸ?hĵ|³ş• żÉ?G§Í#nΚ‹w<ĝöĠß˙£O§CÎW³„êòùj½Ûˆ§Ñâm–ŜúƒH" >À'×sÂD>tĈGÙÙqE™dH#ô“=[‹[AW^{·²ċÏAWv0+?éw_:Í9µÈĥœĈ:P_½€¸2Yo–|IşdÑĴ˘Ş›Ë[)-ˆÏî)ŝ²h+†Ú`4˘ëĈ˘ ïĞ?s!Šçw,tò˘ı\ùjƒ{‹F€Ä~vÌ_шŸŬ“wHċùr£m}/ìeÜX=AÙG8߈K@hŽÇ9ü´³o~Ğ—z{P$VóċuĈ÷½·F-V‹Çı7'żj6nÌ ù°ùHÙç8pgq+CFÂÍ͍¤$â1ŬÙÖk<£ù”˜N~ÒĵPƒÊżŻ-ûkŸž€Ïlá2:üúàv{áus‹7^İŞlÌWħÒÓ8âÛBY§Ĥĉċ³`€zúy~ĴàŭäݽÂxŠeĊİQ™ğâ­˘8t‚œşz<lÀß²ñŠçYs+ìW~.ö’êŜiC6ƒ€Œĉİ›ŻĈYÒX{6>ñ³ıĉĦĉ +ħ/gŝ˜™ŻžAĵWÔVÎ ¤$}jòğcä‰ħ3àekÑÖ£áĞğ½zÄÈċ§ĝ$ûìĞŭt•ù|ŻLöޞYó {M=>™zb,²ñÌÍL˘9µÖÚÎÜ~ċܵ7ğ>9è‡_Ŭ°üWš=‰~hìŭíïóžï:šÏ<,ĈàXğÎŭ½r‘gnş_4Êĝı¸jEù!›)|ùß~šhY<-Ŝİ>}/¤³uċ:-˙›_ds½³oĵ”RzŽÚŝ}>ƒ<5x+#gŞuG@„üĠr-Îüm4ŻQb˜…‹O4Öü44zûê¸ñƒèRżz˙Í#0ı-] +ŭLn|_nì÷ıçjGs}ú9µÓ·žyt½KÍyĜSfüóaŒ{ßy-?ƒĊZŝĠKÈk£yÍw?÷C6_ŻĊêÖ][‡s‰v gŜéÒ~“ÍudßzBNb˘@j4Ŝċ áÄ<.€”ŭŠXEñÄÑ\› Ċ…ÑxßñAÏK”cò€ÏoĤškĈ@İGß 'mĥrïÀü9×9Ñhx˘ğhĞó}Äö3SE4ßıɤ@—}#ra€3×ü\8󊌖lŠ’Ġ+x} +6½2>³o`‘Èt3›ħo£9×}>íóbŽ+óâĞĈŠ Żgğoı_Lš_ûÔĊĉñÛlÚ|÷Hbˆ[âĦíĞĉ +°ùù +ëéŬ:xˆ-'°~àš¸Q.vnĵŜ½Èhşıö@Z€1Àùꕏ˙Aġ›ŻŸĜëKR<^äX@>ßZ@òÒ˙ŭîû“q˙óŝAċhŝÇUx“ôÔñËÑĵWĤ’Ík½ıû“¸(O4Ŝ_êğŒùÂŻĥµ¸×Â˙ş/yWžhğêŠ_Â2ïü=á¸S^ˆ–ŒÎJܤc˘ìx4ĥ¸Ġjn™ħX×hÙ·äzc˘ħç7ù\ħe[ġŭG…¨ÜÏ^sˆH4ÖĞdĴàh%îŭçĴÏ}DßJ!ÙOaĈBÜÈeEh^Ï×}çĵϔì{ÛĜvċÏyÎqöì{ßñÊ d£>w>rȒgÊh­EÏQó šÄġÓsŒv¨Ċ7‘W2î,Ċ̞™—ĥ²ñWyט\×y4Tì|]ÀÎ[ ħòD֛^úî:ċ7[ß½ö¨†F_e—b†ì%x½NûÑ  sÎ|Çġ °—çêeVB-'0XùÎєN”ĥV,߯áüâì5m™Ô„Ft<ßȖ3l›ç[Š[sƒ^çúg$ġ÷mfsWґĈWb^ŠèùŒ\;É^İşĜòÚ,‰äXÙÎÒWòK(ħĈÉîÛŭm4ß%'ä§x6—tQŜ„’R ('/X⁃9^ËÌH'qĈ{I’eIžÚí­Ç‚uŭdaUY¸ùù5Dô¸ŠL·g<ïĠ—ĵa2HO6/7ÖğœàĴĝ9È"“2%_e˜yŭÎfÊönĴg²ŽD1ŻI½ĵ3@Sx—Œ$g9 0Ğ]6÷6Š~âÎŻ‡£­fü†F(ùÔfu‹Ĉ+×ék}_ĉy˜çEĜ…gŒ Ż\/4uŜ2ҒßFókÍÏpwìÎ+-?”Çt _Ä^%jŝùùÒ#ÍDż\E€ßçìÁŸŸŠÔ™]6œı‘ÉÏÌà3Oät9h[ùĈ“}ŻkÑĞîœ'ç‡E @B²Ċí"ûm´„ÊŬÚ=U\Â8œ;ë—?ÖĉıŬy]ÓĜ§ˆWp´ƒ5ŠΎ´ƒLò”²Ĉ™mŻx.Qò3éú’$`HL1À 'Û¸ĉ7ƒŒĜQşħßŭĴ"~ d“ïŭsgH.ÍĊ3ıxÏğϲ•“ó%PZĉYêSc[yÇì(Ԟ>ŽâˆÏyŞpc.ÛoïË$l'ÖONPäy邲3cżrġxıò3{äÊOcÍê lŞèy/WS (@d°ÚŸ™R&ÌùÄV<Ĉíž×0ïÙkĴŒ í‰žĞVÄ’ôϰzßıñòk9Ğñ÷g’‹ùU0):A]ÉżU’°uŽÊÉ);yÈPYç#ġI]_¤sW~a—kqñÖ{ +ߍóLËJÒFÙYïÏ£žúÊ7C{,7ĥ²ÎgsÀGôŬב´ynVmÄDud\]¨y`Z\7d@hÏ+À<Ñ̃g!äŭ6šïzċž•u6_ž8)R°qîâ2ZLêÌ%äYżŬ3•³™ Ši5r¸í'Ñj&ÎŻ(-ìŭ§:J!?§o‡ë4f­‚&4R7§V o£ıœ› ´ëÇĆàQ’ —yÁçġ)ĴüÛġÊyĴPI£ĝ42Ŭ Ìğĉœ˘„ĥëäx‚ħEĈd‘|2ù‡_¸YŞğnŽ畟áùVÖĝ“öğF&lIĉċÎ +òšĉfĈl6„wÍ5Ċ/ĉç^.žDóAdD‚Àù!?‘à[ŭ}2ie†0!áúħZ#I…&–c€uŝ}Ŝëëü8SŜ<³› wô=Ħ ž(ÑX{NÏz·r€ëÎÙµV—İòSg‹25¤ÈÑF|èçòŠ™žkv§ë´ŭ +=óX½³xĊߏ×ğzço]°ñĴžµĴ˙Œš·ƒ\İ%ŬäĈv"gAŝ@ŽÌû,·Ÿ_žA^tĵÜЍL›¨yĉbvĊĞMu³œ>ÑÖ¤àì7•Z=Ù䓐ŻeĴ:.Zœ\Âó‘×ġşŬó9Ëv˘ħŸÊŒŭÍ-&ÍċmK8ŻÏHçâĈ÷ +”sÍXl2Íù{_I}ڈH²£"j˙=EîuîÖUóïO2£vۙî9ÎŻPiġ²âǔĠްÊàh,#§Œ>#v ı0£qÔLŜw”c ĠŝĵÛ÷9@VŝĊHŻÙw~ş1„O ĜÏvásı2@£ċ ü˘ö+ĵWVnj}4ìyeĵûïÓûwÔwi<[ûWH„ÁʓétqöìX'ïL;UôñWÍL7Ï÷\ÖÈĈŝŠdŻHâİ:eĜĉWÈ#EĞl~e–jġ}޲û–ñs5lÚĜDÏ;NݘiĴ³„Ó8?fĞdßQ£1Á[ïJnžï›?7îÉá?GߌD‡£7Ŝ‘˜Ú?6îl,³ĉwó!Ĵ”§=ĴžĜ˙=Ov ĉ0v>ég2Ĥ˜?×ùó’÷Éœü„šG‚˘|ĦĈ³àÄô7¤K‘m-Á*GžüĠ•9%š 13SŻĈyŠ %›ž‘óä8ŒËɵ•šWaÛp‚=<9_›m5Ÿ9İ”¸,öĠ'‹Ĝ½\ŝóänğƒ}vÇĈĉ êD§ÒR˜ŭ×í “˜y\ëf€;g_é:ıqœO£Ÿf´w ĵ–°Vdìr Ô[C#*o1ĉ•3ߨí1]`˙6šgàŠFÀa9ĊĵüµZÌşÏŝJÑwŽZJö3*Ï4ßF\U}‡,–Ö”§8I>kË=NMĜi?™ÒRÎğĈF;sCş gm'yĉË,7*“ËËéô>3F! §É×nlgĉĴP‹ÜĜO€Ş*ÇAž· zS>P9îO³OëŬĊkċżĉ󽸘Ġ£pw+-=OY"CzR8ĝ”lê<˜óĤ’7EĈĵn|Z~VxœAW ‡ Öżü Üude™Ĉw“ó]êk€¸Ĵè\}óúËU³ħ˜· Ío‰ĊŻĞ Ċ|s¸ŸL Ċ +ünUwâĉ{3jż÷³}FÉ=wI]H ĵ5X´|ÍóÎİ<KhÎ8nÖ¸5{‰9#û9îĞ.Ĥ=sé_gÔoy‡ÁíïJU—Ë4^ç d@÷KapWK÷ï@ĵYµ†Ċ`€ ò×r 1Ŝ™[ħ~ş·ìż¸€˘|üĜsgYÉ£qž-Q}Ú ‡Œ³M~ö‘ݧùçŻO=ÍŻÏƒâlÍĊ“zŻgùCïW1µÈŜÑYÉk0³7úŽW]Éy„ÇJžprhŒ¤.ŸkŜ…û]1ä~Î ÀµÎY.çÛçây~ĉ:%aŻr˘Ñxĸ?ì P9˘–U45Ϝ*€Ùß×<ϋ:Ŭوg­~JúácJßYÏD=N)[ܳ½xS´lˆĥI%D’Ğ_vsM­ç&^ïîċö^İcĜMn~)Ĵ֊eUġŭ˜Ş„_‡É2ì%użÌĴ5Ÿ}O•I’& Œ³ŜÔÄĞĦĉ×ġûÜ'Ŝġt=3U_/hÛzż€xùnœĊĤfߌâD2œ}½ĉôä’Ru¨L°wsG‘Y‡ŸaXĵÊAäš áD͜hiŽTžqëuòĞöù÷ĉxU˙îw‘Úœ¤Ú‹Œ/:Ç=ŭùneŠˆ›“3@Ô9ŝžÔNÎhϋTĤ _ĵ :kïS,e’Ĝs€ÌµĴ×y•žiÍòúbÌÔS†fÄb5ïsıW6fċ_áñ`ĉ­)×Êġú:|‰yQÍÉé@İ›\okDêK-%ì9ä•ğ· F}zĵۃ(8Èˤ”BŽĵdlüúT͗ĤİVnç~ġzB·•|GŬ˘`V=‘şqñ[óÎĜ1C´á<Ó j_8uîLî²z#Úï –Ÿ$‹Ġé…ELĥ™3Zϗ#"0ŸBä‚ ÷£NÄ)¸üG\˙:~½ÂŭŸaĜeœ8XĤ½EËwĤÜ%÷V×ı‰Żşžö7IÇ>ÛĜueòsOÍĵ·QĜÁ¸7*‡ͳœwĵçí5­Í|ë'Ÿ˙ŭ *‹\x£ñɉµ·™üħ×WğÒÈJîNìÇúœŒÈ^ÑĝÔzF}w‡ (fÓ·Ñ|_9_ +Z›žyíZ+ï3#´ġnÜûìkĈ”됕Ĉ‰hŒÒȀIÔÏOĵ#4“´YÎĉĴÎÔŝÊŜ÷íü}dğqô|¸'Pŭ +5/šKîàE½ë;œìq:£–uî+ñ:ħFßçEö|%’gfXŝ}móŭWêĈ\0"k•çµżOXŝ¸üÓŜ“Ÿ”żH.Òĵ +Ò/ĥtéŻĉ“Âer-uÍüHk6Ö;_ıúÊa!˙œĊ4wx4?I4NŽC\ó|L.'ÒX²ç+”áçĝr×ç>Żż{ġÊ3™Ğ sü¨¤ŝ>Ü7I[ŸKéY#Qs²ß•ĦÈ4ۋDż_˜“§{MññúŽzʅħ|{\Är’šĝmËʕZçwċ”Ċ$NtC i|qŬŠĈùd–fïz×àĊßzbğ×JXü‹§zĉ2wÚ"}Çk’ċ>{2ˆ´-Ó˘ġɛˆ­èɀj'âw½”ÌÁ&‚¨уÑŜ1·ÖÙVJ8ŝ(x ×^sUŒoˆÔìÙX^AÍà”×ǒ•ôşñŞqôïŽİ”ġk†{ɜ÷@,ŝ“qĈGĝç"cGÎ{$y5³pä÷σ|äFŭîFfĠà‡hĊTJ #‰ƒ}½+|ôjLl%zΚíScıJ’gġçO_ŭÓ)Ä2Żw,lA9ܘ;ĥîċ1(5ÎUqËàɧ;£˘2q>… YĜï|g^ò ô $j÷:ĝm4ç&ÙŒÛ{=SJP ó×éY_ö£µ ĵ@Ž›;מDÌŬ6cżÔMÈĈ$á*ü?%ô™7,ùáôLñ.ÓóÉ;ŝŞoRšïçÓÉ{SOµ|œôµì›S5cÎL4S?Ÿšóô]ݲú}P#)Îí •„CȗħV B¤ÁúYa9­óz‰½dÉĦğC4ĥœW3qû57ϕYVAM*ôˆW2şù…è#Î^[ĥ“Ò7ĦyŬħëùtEÍJ4I’5şKH1@Ééŝ€oîğtçRs€qÉ#jÏBÌĞŻrÊ£ol5X1ցÉhüéÇU=7Y#šíŬ&L½‡mgyc˙šŜòÏc…)_ssŞX ˙:3ġħ˙qcĉğuŬ¸ <$ğ’à˚SⓧşjF=&eġL]‘vŞlĞ^ĝġB[ÍĵW5Şl³[Ôĵ *ŭ„3Ŭ_e4Ŝ§1&ċ)Š\N:UşĈùŒX­`÷ lÎĴŝ+LÒg ´Ȱ–óŽdÏċĥÌ]\‘t£ħĉN%#2FÍĝġÎ}%ż˙¤RÒÊGÓvXà—FħÍ $êu^]4$é·ÑÜïóŬLvŽ“väÎĊ‹ô˘HèyäuMۜĉċF`‚ r›ĜRygJ4bÊCWTó8Ñ ĤÇn|Žä/*m?/=1³àíŠ^rİ‘áX4žž³‘GCğċy͚[¸ùY¨ÎŜÑ·ü9UÜ×ĤâĤyŸ]OÍ·öqĦ8G×ÁYdr’bsz"ŝÒŜ °òk˜ĊÛ 81áˆ2w9NÂOŻ“ízés­G;lS~ù‡„(dĉ.ñŭ3E[VÏŠ2<Ŭä9O2ġ­€œÁ>Ûż˙ĊW‡ĝ´WÏ$mu‚'7ŞíÜïUş'Ë[äûShc&Ü÷Ğâ÷ğĴä…ŬĜëŠbùÀ  RÍ'w’%oġ=êYëÎi?ċÚ;ìP£ïĞŒż›{ĥ“}aŠP"NJ'tĞġèH)äĈĴêjËóB}·À#v§§Ü˜ïĤ$½ö\…e‚áúÁĉ*nJéˆ~HDŭdĊW?Ù—ÔŞ[<ĉ3s´Ü7âp&”„ĥİï‘Ħ"Ĝ˙ÏÑ·Ş‰’ż4˜żdRU7ĥ’Ûd.3~lúӎ·ÖğBħ¸o֝^Ï^YÀËÔv prííşò ĈINĥ™¨éÂó¤ïždż½ÏXu¨Ŭp† ùƒŬĊ˜¤4ĴW÷˙°Ż‹#éڝ q÷lŒdŠ ²7"ĜL{܂ğğğğÄŬ}ž’ 1âĥúÉ˙—[§fş‡•ïŜŬgHÑSŬ]uêœ÷=çÔ)w5Q{XʽŻÊF}µ²5¸"Ġ*IŞ‚8P…ŜĜTdMŞÑ5Ŭ„íwĈPÜ^Œ^éÁ&5eżŞĈÖTeħ Ú ÂG¨ ôECŞŒ˘Bġrħ„Ÿşü•‰İÒ­™êöİ$§ÄSp‚†žàb2Pé|¤…à\ÁAÜUŞŻ‹ÁN8qXu­P8BR”B´†EÜ£ĞtĞš•~'èU=²*?œa$̂z_\k*2İúL…ĤÚà|/aÂMĊ ŻX+S(ŽhŞŜj¤,£lT—QĀMفžXŠ +lħò^úbşèœ{"ÔD,˙e v fPıžá2¤ŻDBpĦħPfï+żŻ'²qİ}ݞÀu T5ħLÄŭöÀÛdj$nǓ*w"/f*Ò%Sa‡—‘/ޞAIoMq"P°ÎD —Ĥ8›Hġ`p↸™×RQ^-웃ş¤‚Äê ğÙaLe4,>4K…Û QS1!FÑPèUĜ) U*_e焙Ty‹a£Ħ@+L•šL úbAĝ:Ŝê(Ş=ĵ9“ŞYMB¤zŞm•zb¤T*Í QˆŽİ8Œ²_=1ĞFŞŜbĴ§ĴäĤĵ™ÒٌEğhhh î@_ô´¨JKA£T/Ħ*‡ž˜ UŞ@ĦġúÄsċ›é+½Jı‘ŠğXDŽŞ {cġġÄ(‘z­ÚŸ(}Ñ5wIK•ġÌTğsġĊڇşâ>XġĤ]İR[lR5›¨|i˘ÔÀĤa|N’êŬt…ŬÌzj´ŻŜ‚nԇûèJ•×ÂZáÁ¤ÊzW°ĞÜPô<âġĤì@]¸WŞŒK¨5ħÊ£€÷°‹. œĜ t` -Š´Mµ ^[Vrܨ +ʂÔß7wfJ…â’Êf=C ¨˘$(ĠĠċ^O¸—à—*ËSŭš¨§×ÀD(‘ Û' e‚* RµÂT•ĉÒïSĠ§ĥà~Ħƒè$Ta\BŞn +E¨K˜ ! +Ü,Ş[œ+¨|.eÖĥò- T5C`ûĥ0·ÊâKĝÈCQ脇’s¤}öŸ!"ӓŞ*,ö-µĴÚŝĴ\öˆ^hĈuQTŞU,KĠ¤°Ò•¸MMġĠSĤĵ .DNp*²_ b‘F##áZİàž2T•˙Ò3Rà+†Fu%XáŝĈ}PzŞjWzĈb-İ2HفqŸ<=ċĥr=ħÒTY/PÙ(ì[Uqe&}Œ.ıIĠĴv™˜ŞjR@£ÈG…úÛ²nqĠħ|ĞTY[ E.+ÖÈ0CžÀ6„¨g*ş‹T™–¤NY×KÉHĊ(‘uCQ2qUFu5ħŻ2+7êŠñ7݁Ĵ&ĈĈ}ùîŠï‹#eÈ Ġ 0ĤŞÒdÀçĊĝŒşÊXíDŞĴŝĦl„#ÊU7S4`)Ĉ³D䃛E"¨ßh˘X¨ +u@£¨5Ô#ĞŻ'Ĥ(‹Îeñ!|ëİʳéġÍà1U1#Ü,şMuuĊkM Ċ‘5ê'銊#Ħu]JlԕúĈbuNe^~V]5F5Q?şY:pݐ*wúâ+E˜Ĥ/ÖÂ× +$“mĠӚŠnf}ĠèĤhêŠċìôĊÍRċvLU£Ħ4UŞ—€žT¨ÑúB”ï Ŭ¤jVÛİ‘TԒ‚~BBù@CĤ†bżĈ†"ŝ5”žTUòKżO E]ÍMżODPÛú"%Y•Mê2¨x˙ŞòëàÖŽë)…”iU áϨËc@³ħ¸8Ġ÷ÒJÊ-f(œ> *¨-|__„‚&†âµ +k&oݵ n€ XŒ@Œ˙ħ1¨ƒBB ‰>×ê÷îBE}ŭ>XÖDżT˜ŠárĦô*úú„\xV„X¤şV Œ‘˜ž'Ԝ4k)óV E*î\ÄĥOĝĥÚİ’v \Z_’‰XÚM½ŝéT5ó1a$oÚóT5‹›– UEdġġÄĵcċ=”84¨RÍu…í*ĊˆŻŠĵèë뉽İĊĜzâ.Ecċ(Ġc‰[e …ŝô +Âğ(›yĵ…I˜7SSÁóŞ +…àFÑ[£Ú°‹E‡Ĵê/¨ +ĜÀÍtE (5Yùf(Òa5ĦâT[çp£Ħ@2nP§‘°Ż^Ġŝ_o&ĤùJġDžú§1€ÁY ĤĞ’íżPNOĦYLî5QaÜ(zk•é +¸Ñ™;"cS—˘rY› ÙCĤ‚ŭWʧ/b4U`HIzE*k,òÀ˙ÂZġÔÍĈúâÍDÊd¨~…?ÓnáT¸?íËĝŸÙg „à…Ŭ ş·Sê‹;5ŝvSĈ_7W¨ĞµYlêĝüÍö'•[]NÓJOħùŻUŒġûœò†áċĤżïc“xÎ۟ŠNçĵÁqÉŞfUòŜŠNàJíŞFħşAŸšÂQ‹pİĦħĝ}ħò‹jëĈßU½N~ûSÁáä7İ3 Äjœ¨Y]K¨gâ†vĦ„ÁßbPŜ<âÎgÁ@àfħĜ—PÀ@d§˘ +ûïĊԕ˙ Tıċĝûbb½üñı6İÏCúc-7á<$a£14K…„V5žS4!Ĵ&662Rn¨ƒÔQħ‚Ê)¤LhKUêš +É·İ&§\sİċİj6ßPĜfd,îĝ0VĤíŞĊ½üB4n,”ÒWE‹Y ĈÊԓż½ŸlTĞÌD™UĞ>ÒI¨Ž¨ò6üñZĠĦ˙:ŠBDLé„F£>W.ŝûcoŝöħ6‰‡€ŞëêC…áP]ñH•]Ċ[LÄÄÂ6Ġ˙6ĤFBa&• Ç}ŠS¨ò×û Ga(&–ÓÎVşH(ġ&TQW6‹RŞöFA°B½>Ġ1Äó ŝĉvêr˙t½ĝbu^LîÄç+!Ş +~B£ħ“Tû)ŝî9„ŞëeZĠ˙Ÿ‹¤Y<ÂÉX,V%6÷—^ĠGKŞyĴžúh)#‘AáÒZâ)‘RĦ6֓B‚2Wíŭk·‚ÔU–DRŝÁH8CU +µâĊ#IMÄòLDÒİ* {ßD]éôż?°şf”p Ÿ´oazĠyBó`Âë+W€ÒpêŠOĴ'Tf[¨`j î^öˆCñÑs*PŠm]=ġöġĈ7áäP=ÑEe¤.ùó—S[#uz™ĦpĈlÖ7Ġƒ—ÊġEħB‹pŠÈßt"hO£>‰Rġ뉲ÊÂÜBµ>u´úMßÉ&ñ=5âÄU%…ƒÔ[ßÄ=P@Ĝ@ÖÎĊÓÓòħpêÍßv+Ĝ.SħäµÊûïİj6 +ı~BŬH‚¨F*½ckĝYu­:,GhŞĴĦFCĦ×?=€QuûÄaî"OU³úè[ĵ%LÈ QŸEŠSˆ7ŭ}'0òaĤ:óĉëPä~›½bƒ‰Íšm+}ü\,ìüŭ}·)W::ğnûCó<ùĥmvžŽ:¸U5χCÍàĜû áz=Ŝèw=]ü?‚ŝa†~qCMA:zş:›uX^WÇd5l1²  Ž !3Ğ /kl gT°Â-›ŝbç–â—ïóĊżmT~w<–7ĵÔf­Ğ‡7Ê_ñĞYÙùĦ·†BO‡Z7léjÇ@W{ÇU›é:ԖaĴü‹ñoè1P—ÂÍxÈVDö½†Ë˙˙bĝ‹ê ŞhÑ ûê™à‘B‚— ›=?Ùj;ğot ġŒ £6 ^ż”ĴYµY²a3)ÙlíςtրÏffІıÜßKû~›Íú­ßÈHÖĥ’˜md%V2—~֎Ñŭ §¨2§Èŝ2§ˆŝVÚœĈšĉ’eß­—lXKKĥîŭĥ(|4ĥÈÜ5֚Q’Ġ+,%ë×ZH6˜Ó ŜEÊÑOÛÒÎ[Sî7Xĉ–4ĜÜ1T{£•d³ùV‰9ëĤamïŻ%sL`eĴµÑÒßÛ̒G}XKÖ,ۀ~ZI,ig Ò9b€Œ÷ÓÜ´É_cIğö#œBúsÛb‡òĦYaÙ1•Óèè’I”kÊ5p;„ó‹Ám‹ÊùeŽââÊĤòħӸȒŻq•:|BĊt.ĵ`"ç7”Ĝê£Ċ˘k™òIĴGĝ`Ĉ%d 7‰Ë9¤ËÇÖêp>qÏÈÁ´GĜ ĝÉş…b½£†°ĝĜşé\DáDÎÇıdœüú+ĥ%ç}Ñŭ2F3ŝi#IïÈ!ŒOòpÒ1´ż5áOF(úÉY{ jĞğë0€tÑĤœ}ú3hGßŝr…ƒ†•œ–Èí<4ißÜQŒ_êHÂ5 ?áìĞM:ùkhli÷ˆAœwâp™“†µÌĥŸ5³µċĜŸrGïï:˜‹È™ÀïšÏÇ4L§ÜBZrŭHûmÖ3n(~÷”ĉÙ|XÑDĈġƒĈ…ñôMĊ¤â£jĤ²ñÍ3è¨ÊŻÈ€äá”jÏC‡ä%cZòÛ4­ìĵ4iïèĦtXñx&²l]ü’1† J…Ç$*"SöċŸ1’rèÏù$`½c†Âĵ6îšmĞaÁ:iXÎĉ”#’ENbnéÔÏÂÊßF NBp~ZÖhŜċ´‡†…Éé&V²ÙŒ“l\/“X.ÖĴ§Ĥ ½aĈŭ{“-Y³z“ÄÂzk?ıkÌ@Ò5i°Ü5e°lk°ĥĦa.sêgnn'‘)Ü4­îf[Ĵ%֜›ċ—3ÊÒŜGÓl3#YıÎ\²Ù +£]Hf[öÚ?wċ™8TFyiX²– +Í èş ĞÌ%r[$‡áŭá9äŒĞ†µM É{k‘NÁŭ9·˜!ĵgôP6 y¤MT>ÈÜt6<<½-n¨ ½/z 68o,Y=™­×á˘J'óAYc‘<ç#Ê'ó!écA~h A„kP.Ĵò+4“Y÷°A|TÙĝ‚)›ʐÊž×HvèmÁƒhÀœOÊE|Í >İŝkEbġ ¸7ÈĵMhÁ$…OÄ0Ŝ7xœ1–Ï÷aüâ†Ëí½´H;?mıƒ·ĥ\á˘IĜ¸j’öÛ´O$ëîу)ß($3y‘SĝˆÂIŒüpÖ)­ƒäá\LÉd>şvœ=–ñˆLşĝġ§ŬÂ2ŝİ#Aö çmZ”£6ï•8œ F²˜<Š͟À§ï]ÈfZ•Œg<£†P^‘ƒAÎı¸êi\LÍ46µi6—Ü:‡ )Ïú%d<†‚lr1ġÓÙ¤ĉŻé’Ë&LĊï¨Ì=sé¨â‰l@ÖhÒ'~¨5ĉÉċ‰žÉslŬ46İq&S>• LIo‹Ly† bCGóħ5Ó途‘´[@6(s ‹äĉ´ġb<´éˆşÉ´gü ĈQcír3¤#×JĴH´Ŝĝ@-+Ĉ[SĈ¸£ıôג£Ĥħy #Ù²‘’XÊìúÉÛ4)ϰA„cZóöŭ,ä +‰ ßuĠmġĠ˘˘ÈíC´IÏäĦ¤{â`èÇBîϒtîgÉ8öƒw`Ü"с…chç¸AÖĵŻ&Üé? ¤ú³îħC§Èx~ܢÉy/M}sÙÖ~2ÎK“rÈş%‘qŜšÖÒ£6^ZĴ[Ü.8oï›9šóŒÂı‡ ⃳Ç)B³ÇÓöAŭ ‡ŝ´GÄ`:"w<“w.›ĥcŽÉšŸÁœWĝ˜Ö7iœ9–óOMıú Ŭ°E^e“g˘Ÿ³Ĝ„ĈlTÑ$&,í4ŒôIJyD Ĥĵè-ĈÉ'šOdo&³Ñċ“ıĜòİHWŒĤÒnÁı ĵħlTùdERó.iϘ7.ĵt’ÔN璷ÏBĝ`*‡t—ş}6—ypè&.uÏ K˜ŽRlCöÙW­}Ĉ=x;x†ìÓKñÚBt#^oèo  Û0™'—ċ·Lİĵ3KÉÒĞR*ëĜ6$w,ë•:œĞœH§X@U>ŝžÎżaH{f7·=íɆŒgs.fò.esŽ.Ác—Ĝ„ÖjĊDÊ9haëĞxġDĝ2Ík²_h=ráe_)âwÌ]z‡²uÑdœ]ĵ”²g.U|Ŝ€E:dÉî .8m ›ĵc“qpÌ#à Ù5˜o&,­a4ĥqC˜ ġóXˆÙ3„óŽĈĈ: +ĉË7}$Œ% :Ŭ“AúÖĴ²ħ€û‘œa™É:˜É@zÉ)<èYĜ´]sCÒÈŝ“h°ÍÛœ>x•}x!Yxb)™{dÖ‚tiÈ(’‡u%ŝeŽĤ3ÇáJ=J£#^Hg˜KîŸMĊĠNĦ³‘Ĵ$Çïç“<Ûçĝ3édߑ> ="É]‚û˝|0Çbk§Ó9ÇħQĠS(_4ÎQaàùhߔá´WÚp*ĵ`ƒÖ—Ĝú5í>t*é†ì+şÈ.c[8½‰8È-Ĉ‡tdmë)s +Ò] ĥ‚AëËgòöŻ-)§~VȖ›sè'â*ğ%íİa…ĝ—ŒC„1·újc{ +ö#ġĜŞş”Ĵşġ “zpí—:‚ €u^0–Bĝ˙ž;†IÙ3›Ê>ħNhAE–O¤"K&Pa¨ÂħTtġW!"k'^édAÚ” £„[â`:( ċ“2LîÒßJá˜ÄÉH;… ÀùefŭóĈ`9@ĥì#‡ĝ֗I#ÙmÑC˜°œħòê{ßPµŬ+0˙v „m"š_yġoäĠŬßy§ħħµSA>ħHĴ׸ċÀVˆL]ƒì֐OÀ‰xŝÑû#<;0?à>Şb +‡ĉÈVÚYd_d_@ćdžƒŠ,–A¸Û!„!Àŝ3ˆ7¸‡ ĈXÙNZĠŽ0 +Ò=È.˘ġ 2 zˆFÏ!|Ö Ĵ)ÏLRŭ 6É.ú~ĥäĤ™òŞGĤ²ÚGßÙûç‚ŭĤœúz‡ûÀÚa‚óÇ2‰;fPHÖ°³ó×"´aÁ¸À=Iß$4Wˆ3Ûxhg¤½#‘ˆû+uhċ$à²rÌġ`mÁú„ñcCRGƒ>‘]ç@6‰tGëÀ1¤?ì1ċ…’OÚ/k$éĉ31ÚB†¸ +aÛ|I€ áÙHàíV´3â!nÈĤ#.ĉƒî~Àg0ÏHgMFXx›~hĴ/°Ít0’Sß 4‡É@÷>$íܵäNŜZ2-lüÒGÈ]CúËŭµ-8´/·f}6 ßı-aa e|ŬĤiN:h>&³ñÖ¤]ÚD÷žNğF dœB€ßáşl,⸠hާ%ïšMV?ú^^Óñ^_ Ç˘r'ÊëÚ£ZŜ›ÉvŭcuÍ S*İ]_ö–Á˘q2G_-KšëGĦw!‹4¤ó.éÓÙ£ċÚàaĵ"‡À`|˘†‚ŜÄ|8Ş|(ˆK—!nQ2U„0wÄPÎ+x0àO.,u &0aċ=Öĉ +ˆk#ŒÔŸDĜ”ñŠÊ!lš5éE„1÷„f"œ^8ëZd³}‹ħÈ=ÒÙȏEknwl)ƒ¸5ĴAÖ=裂 †TÓĞġôg–ÄŽ§Ğ˜ôóï䀯)W„!ŭâ‡QA9£ñĜ#ÙıÜşì5á6¸é] ~!ŸÔá„KĜŒCŒĤ}3Gb\Yƒ°x“`&03ÒÑpÂĠtĈ$“(˙¤äĥĜÁ°Ö@6ħŽEk?‘]Ĝ°v£ĉ]f˘ üq! ċú D˙öDxoІŒvÒ ŬcƒŜĤ‘N˙‡ŒuÑÀ˜é&şr2ß8 )ÖÒÒ1ré9PŽxµ%â4Ö6KĈŸœGœµƒî£\ì:†÷GòĤ |ŬŠG²ÇújÊY´6AœBû:”Ùúiá5†t,ĝ-Aw"§…íĥó‰8˙ÌÑàŒ ĵÙêi€Ñ°ŠŻF]ÒEç€ñ1gD—,=g@î~ĥ™:ÁZï÷MDá]C:Şp"ĴcàqĉÖà‹pÖ cĞĤÈëŝ@ĉžXDù§Œ[D8 {#ü„q+Ècl½~doÁ÷¤ˆİšXô7í‚ùúÎáżÄ÷#™}ĥëPdcA—ħ˜Ż'ĉbާħéûĉ³éğçaŝ]5•‹Żž8|†\XÎx>ñ´&¸ÈüI/§6~MÔŜûž¨ĵiBeŒ&È2Ÿ\1ƒMožK_“۟­"š^”íxµ‚¨¸aBç]G:s&ž<l-á6@î1€ -x•,ğaLç_6¤#Ê'>$]²ñ;tÈòÛĤD}ç€g™¸ĈitTíd*²F‰Ҏ/ Jï˜ÒĠ—3µíИê{+Ĝ‚nÀv%ĥr +RŞĝ´ÂVóħ]ŠüŠIĜƒñ1ú°GÒ9§—P%׍ÌĥÈ$àËıĜĵQĤäëH`M/'ï‡żƒ + œñ'ĴM$÷àçí:œAĵ…›è:pŻ|+ҟöaŭÓ1áۅ”Œ§ +1ĥfĵ³F‚^ĵ>aÙÖ-IÊ-~0“=­MkÊ^ƒvÄĝĤd˘‚l6žZ€Cyż$ìĞ#Šß.öwFLäÒ÷/`Óö΀z" ˜0°U9™ġÁyGekĤÉĞË÷|6#öÚ"k~żœŒÈògÁık€_–p +8Ĉ +ĈŻs¤'0>ŝ[<ûôÁ‡”ĥ{>ö'a˙OÉWĵÂHËPŝŭġ€/á Ä׿¸aàçMüV +2:œġFĝéIÌĦ_gR÷!ŝĜˆ9Ì×½˘‡°H7ò ;ĤóŽ,÷d“f2èw˘öîwtĉŝyTXŜX:ñ— ´Qà_‚’FÒhl^˘3ͧê§cŝ„Kç_BĊ·è0aġ_„ù;Ag[HÖ½\N•<0Ħâ›Ĥ]dÂĞ&QE'tċġO–É*ŻÑÉÛgP9£ 7dóÎIjԁuÀVŜ_AV·GÔĥO_1†÷œœ‹Î›ÈäXBċ[Âd\ÈÄ5LlO#ıĊ.ûÌoYémCY}×·ÀĞY÷¨ÁäV/màëu°“7¸ĴkŒB +Ĉáu€ĉ°èÀÀ€…)ŸŒlX…’ŻĤÄ>F¤sÁ^PĊ˜KĉY¤]À•ާœ‚Àߙ°²‰°Ĥaàӛc–g½d[½´ÀÇÊx"yGú|d2Äáa½°Îaƒ &ħnWñġˆ!àŻÁB¤Ëè䖯ħ¸›sÀÖ?z8È&~<ĉéè˘‰Dñi]rϋMì‘Ñòv[=֊Ì)ví=´CÄŜO 8—;ìxtXîàç›âri£ùÈ˘Ż€Żñġ38dçyżÌÑĜWW=¸2ö—ûÄgCŻCĝô-ĝU|}p,x6- 1™Ê¤ĥÎFÜy>ĉÍQhŝàoˆ7cp>5™{§g²Ž.HT\7Ĥò..²ûƒL'Œ$ \B€ï|€OhçÀ6ñµ3‰²ĞFòŞ;ĤTúĦı¤wöp°iàğf·!î·k³Kì4ĉ’ÈĤs)ͳÈÊ+&d.â•ÈfSàöA6%PéÒé\ċƒ•lÍUlÊáù€1@ÈšGzk0^×ÈQ…Èv•˙hD•\2żĈ·a`ΈÒ+Ry‹e²ŸWZ5½ĝNàë€yhLŻƒÏˆuGkŜ3l0àé[&˙¸.›PĞĊĠMG<ĝk&t2`Pz[ĝ`ìŻIhùš,ş`@eŸ\Dŝ¨Oe[ˆyâJtìŽitÎÙ%dÍ_—Ò^ı#°Ÿġù:wx ›yh!ĝß§Z ¤äë°^˘_O…khANlb·ÏäbÊĤ`n‡ĝ:²ïÀ‘ħß9ıeĉËĉ9œÉĜ9IÙñ5ö3Í=S ÛúȂÙß%§š_mĠ\3%3÷ÎĦ]ј; ,î„pë­Ipš€0÷G: Ö&<ç‡ù:`*à`@†Ù ,Ì×ħ? É“}b1›ħg>W:…Ċ|=óu&uçxFÌ×Á‡|xèP¤‡İüKÉÒ †dŜİ%à[?%ĉj—b]>bbL\ċ*sօDͽoè†5D]÷2„IƒŜžëûl=b†ÈŽÀğXˆ1Ĉ–O‘W]3ĥŜùy³cšqesı„´óÑÂĝŜ#y€ôpxŜ´ĈÑû† µñ#&Ĥq`bÂôZ 6]?­j_ÁÔv­‚÷£<⇀ œŭ2G#Î6É9´ô*Ußĥ’¨D;ûöı?cÓv͑״}'oyżZĥó§5²Š{F`"³Ä=sñ5:ĵwÂpMÀ6lŜQ]Şôš1U{oUy[ĝ=‘M‹N N´˜MŞĠ]ÀÔ=Z͵<ħ„ħ!K/bùLß;b4tÚ~ôÙ3‡Ê>·˜ŽmĠ!ĵ’†ZB|TîŞú•‹kԁy›~ Ò-b ċ7DnŞ ħÚq48Ŝ}B?ĝüGş‹Cşô"ĝçAŝè‚SzĜo5({xŬ½VVwĠ„N­Ġa*§ħYˆGd욧@şs&°˙ _ÂĞ0˙cüKĈ҈‹6·Ü˘Àì ĴG° âžÜ6d§‘Ĵa=˜=Çé€Ûğ…áġ„}è1Sèä=³èÌ# ”ú Ŭ#ĈŒáÙ٠đ?Àq#Àĝ'èd˙`Íb] +şì?`ÄËۀßŝü_c‰USİâSútÎıĜá=<ĜIÎ'u¤Â­—mژ·'f’‹ĤR­O6aû\=~“%/ħ°à$XĤ žƒŜƒò 8…ġv0Ż"İnĵ›Â/o,‰ĝ1bĴlŜYC>qÏ\a:|¤ˆÏ3Ħe&ÄŞĜĴ] Èò[&dġíoİ‚cKوŠŻàZ.ጠäċmĈDċ=S2çĝB*ħv*ĝĞpŒp7Âë3Ċ'Ħġt&ĝfAÂğ"{‡cnÒïLSǢáċ + +q[Àğ€‡xˆa BğxjCĝ‰€óS^i°˙~G|XĉĴmníÔÏl >O Â7iá>ÀŠóÀyÖhí’hÍÈĥƒ? rG)âĞtȎ'jïÏùŒ„càżD˜ŠŞĵ˙›yj ĝÀhÌÈŞÛßʛşWÈĞîšZ7v}8 |—ooY·Abaf.‘!nMĜö£í½´ù„j ğÚbÎK,7ħX>á^ĵ/ZÏà—t +Ĉƒlb^í8Œr >,ĝ=Ò7àGaBrÁw3“Íډ0jë\.ñ'ˆ•{*}]|JÓ>ıaÄeħ|C| Zc\"z–`¤³½ü"ı佒‡c˙Ĝ֜ İÒóRì·÷UĉV §’wÍ[~gÀÍdpÖhıƒ·䆀~†¸*ë‹äÉÒcĞĜĈ‡Èò àKÙ"sè'Sĝkb™?dxö8À÷|@ì˜.Ĥ`²m\Ġ ÛȜI Ë8ݍĦ²q„í6-Eâ@Îa)GßŝĜż[7¸#ĝva˙߼³°Üy=ÂäÖ“׿^NÖ÷Ĵ .êa@òbÇĞĠ°Né€Ĝa‚ġËa=T8ìĜVÊ=p ä§FX{ÒÇÀ-LˆĈ‡Ë™ôÖ9àd€ .ĉĉ’-›,$ˆ÷÷žñàÀŭŸÌá -YWġëHÉêo6JV~ż^²q3%_е+âaĦċİ ¤oƒ³Ç@ ú óù+²™à/´f\4€ża_ rÄ#Ĝ˜Ê)`3“ƒŬÎËĈ"ŝŽĈ…*8+ozşJĥïŭ´Ĥ¤çİıŝğUó ĉ’²ék’–öhœ˙gĉƒĜí&3R²i#!Ħ]"*‚ ĈƒĈŝI—à0ß8ażM˙tòֆħb=ŭA:ñŠB8b=„ħEáI)[qñ;Ĵs‚Żadş´>UzÁp&ĜÙA¤ÈғúĜg™;ÇQŞt Ž +z˜.<ĤG7?1“# zb(ФËSëgħ÷×óÍÖ܎ĉdSÏZyĠ2Ħe:Ĵ:}Ïyċ%„ŭÎ’·MİŞG?†|‹[l$[X/ *Ĥi*•wv)ĝĦĝ´óĝ¤Şˆ΄5¤ˆ+E|4kàZEdö$à‡6Ŝ #(g4NŭI[WM‚uÓÀxbÂÈΓw˛ÒwbŸAĈžy G0ç +™À%íŸKĠżXMïxcF4|\~i6~÷×Ldġd²g-Ñħs^d3€/A~ú@Ü鋑8/"´`rWŝKÓü>4Î)x p~È`ˆ}2I;f’E·¤tԎ)rÏä!dPÁhÂ?o$ȧçŞħnıdĊŞu’ ë,%ĉ´އî$ë.#j .>,kÙgŸŝ˜Oäׇœ/QÒ% ?¸4ĵ;WgUxYÊ!ۆ}ïĦÙcqür9bÊ&Ż”×µ}OoħlyµŽÊ;şdFÎlĠ`ĵµ9ϐÁœ³÷ŜÍ Y5•ËÛ·„)8İÏù§Žߚ5ZOäž ĴÉG–Oĉ! +p£sµYÉy µĠC‹ ÊÇAä\$6Í]òŠġZ7lÙySĤ’ħ"ĥ^ĉüï,äœ!Â%×ÎD8dħĴü”.µ§ÛœÙѵĉ—²óÔÂşĥòÎ2ġžSw5]zŜtĠúĜŒÎÜ3|—8$${,äŝ 1;*ħY‡JÙ7‹*:§OÔ>úizmĈĥ<3'Z?Ĵ“ïè\N§´Ì‚á5@ĉÒ_î–0ˆL=:G^÷ĝ;²Şó;ñ2S|Zl.gß>> +ĥïȖ1y{1g ıŒŭ 1<€lÎíAúĉŠĴŝSs]gYw9Ì/ĝžÉÂËúğa£j§°IûĉÈĞŸ|K\ÑRŽÎ!sÎ,Â:*ó|*˙œ•ħ{`:ŒÍ!xÉäŞċw£Ğ,ÎC†•ŽŜñzà=x}–‡ĵ=$Lé9ĥ}=Ġú|#èĦż·›!³O/$CĞ'ù£ċ™!amï­eIÙö³Dr +„B8­—™ ×´Áñ"s3Bׁn\ȧY˘HÚ1żŒQŻAV#[^sw“wÉç3@ÌéW!ÖËÄTMĤw€ù‘—_–RE'ġ¸Ô}ó¸2ìƒä)Ëg)³ùĴ£K!§C‰iêĤbß;ĝSGa{déWÀÇħ# }ZÓ#pŒ'$u4ĝÁÁ·ÂWĥ­aËo~ŻäìÈ~‡A~ǁ|òöÙà³g|"†(™£Á@‡&˘svͧv·ofε9(NŬq§ÓÌ߸n“ÄŠ“à\ĥ†ÛĞùĤö-̎‡fòÚK& S¨ĉudñu#&i:ŽŜ|îĊ“#€˙Çcќ"N5â˘òrÄMçötòÏWÈêoCĉî™G%6NWĈ'ĥO%ürG’ÁĊcİô³ ˜”“ ZƒyTVóĥiĄ˙Ĥa F ñ4—+:"ÙGŸ„Ĝ×ï5ˆ (Bşĝ„Ĵòĥ1·S‡L,÷H‚dd +•t`6“}hp:Ħq•²iàgesÑ;ùxyû“eç¤`³ù¤Öـŭ˙*ĉ´éÍs¨ê[˸škÙÚĞÉípü +ü+ Cċġ/–3ğş,É=káŝà‹„µBĠ=^Áîï¤ Ż1!YD¸m“½{>nÈŬ…ĵCşà´•}h´çkÈ`sÇĊ°ügŸYÂDÖMı}܌jê^GgîžËD×LĦ÷Ì¤âş )KDŽ_ äa%Ĵ´!fĈ [8ŠŬŜı‘AX|OrĈYòa÷|ÒÈÎvÛ'òÖ&펰ĝA&”ıjĜ^4‘Î=û)`’öÍf˘ +•9ÀS³#žst!—1ëèb:k˙|œñˆ£l ҆8Ä÷ 6> +ÈUàêtp^9â8ç6}ŒÓ<)‘žŝpŽ ²‡Àk@o`œ>‘•“y„_ÁWËÇOċ2v/€ü^ŞäŒ!ĈÌ ĞÛÛ̘ŭ„ĴéĊ2œ£°-a(äBŽ +ö;VŬ˙|&Lb“ÖíÀ‰a}왋sŝ@ïŸE2…ıäĔOÁka^‰Sydzñ ÊwŠÛ>ƒ*8´DŜĜöƒĵêĥ1™ĥw6Z2r"è ˘ħt +úwùU˙‰Ğš9œ\üö¸o¤;AF D”_ÊKÏëażIJë,È?2È “ydUuù[>}ÏœÓyàğk'u˙lbû›ĠLóûÍLґı8ż}0.Km8ƒ›TŻ÷Ç:ñ +´€_ڀ8*pJàŬáeàƒsú Ĵ‹ô]=âž󣜰Ŭ‡9&=‚âÜÖ¨ş)£îCĝ'1PŸ”aVĥÛ4'YÙ8kÈŬ–ŽmÑaroî`"§`Ûì? ÇyMŒĥ…á=}̗HÀŝ^|à­àKMŬ7óì£ !ï Ö3è>ˆM•×?X~üN1èÙ2÷Ï£s‘üž3„kèœ#‹PÛ|àlF–ŭhD6=]-oyş +|ĦTâŽétÂvȳ_ĵú)“}AûÑڀ|=àÛçfíħbyŬƒo‰êĤ @ĥaż䋠>1İ{q,Ä Î > ÈÇ!K’­o6ÈjÚM˙ìQ„½+ΕŸ"Äa½3İĉħ5“Y˙ÌÑ\XÑDĦ50ǁ" û.€˜ĈàÂ\úÎùĜöcŝQ5˙Ŭ=a햄?8GŬ5v0䢀MfĤÌİ·÷Òߒµ—&ĝŒċÛ˘˝CûË!—Ĉ+n([?•Êż¤O–Ŭ5†µ · Bĵ^éXÀĊ› ¸ÇË"rÇÓQ“ /…Î;ݧƒ’I`Sñ3CRÖé%dñ=c˘ò>ösH·‚\Cž¨MBŬט—ŝİĈO6íĜBˆ)*ŭ;fħé;çqÇÓEWŒ0fZ8pžÜ‘…_ÙKĴbk§ĵùç ȊĞĤĜ‰äë<6ë"¤ŒÉúG+ˆš[ߒE§ôq Ĉ;kûl섘ÄÁgœT?'dψúğ?ċç¤8nċ•<œÉq~6÷R§Qç ˆŠĈ`û‰Š+FdùcŞè¨.èe˘éilë LkA6{Ï|Œi‘͆œO&À|lû›{Ö˚:—Q)Í3àZÊjğżƒ˜™wEĝ‹ĵŞÍ”i~ş…l~³ž¨éĝË}îñ%dÙ5#˘ĉŜ·Èf†8*âdžàóf“vÎŭ6‡K?ĵ.8û@ž­˘wwXĠ÷!ӚgBŜÄc·mÚĜŜ!ŽM4ZI4ĵYNܖÂ8‚~„VŞàš\2– +Ż™H'ïŝšlx’mêÚLÔ´}‹ŭ°Ż 8Ä<ƒż ~‡Ä)—„ÁxŻJ잙\ôöéCqwdۗàœdÁ9GŽ8£‹1Gü:aïL*ëè|y)ş/`֊ñò€‚QDdíD2n×tyñùî/ëɽï·Xïŝeìèż·µ!.}ŜJû@“;żl”·|YM4\Cïm͝îrĉ/>öá~ìÜFèá¨Ĥ7ëèòßÚ¤ÔÎVx†żÎ]EcFf@2‰>9gtéúÎUŠ ğÖ{ìÖĈ{rğ†;VlĊġe ƒ|@îXET5cà•DÍïÀ?ĉž3€ĵ ˘öáwH–1çDĜžnyı‰j}ğ‘j|ż†Ş{â&!Ğï}‡ġ\c÷2²İgĴĦëyùì—ĤsO.ŭI4żXş…Şí^ŽxĊjĥċñ3.}ßìKĊù˘çƒƒŸtòžÙdÁédé-#yÓ˕Dc×J²ık=ÛÚeÎ4wl"şWÊëž|Ïŝxvyġƒo@N@‰†Ë!w„Üù֌Ú×mĊé`¨C/ċ֍ï~U=ûFŜúÛZêÌöúK?új'wĤۙ:òŒböĦş–?ĜnCè’ħş÷žÉÙ£ĥô‘W‘[ÈżĦ+/ï0ħjŭiyì͟iwç=´,ïj—“Ío7ÈZž­ÄfĞŸN•^7ċŞïŻfŽLJËŞîéJYñ5]Â'mn²{™Íá6:’MżĴ%óê²IGçħg—ŜĤŞ/1­´“‹Àc§chàƒtÁu#°Ħ‡”Ŝ6aÓO-†üEc ĥñÍAQ)‡ç ŝ4‘Œm™JĈïœ.O:6Ó˘òħžĊáŜ5²3˙–~ċċW˙iG^ŝĠIvë·Zßëµ'ŸŭÁĵy™J=ŭEŜëC_yïc§¸w'žğßĊœ{çDžúȒg>pÜı'ŠÓ[Îíèĥ´Ŭñ˜`kŸŻe3O/h_=“Ìdë—<Ú&Ħy6SħóRÀfHŜ~€8ĜGjÏ sjïKúèsš>ú”ĦÏĵĜʞ~ì̜îÄî~A-×5O•5½ZNïyaEzNQhċ‡>šËŝ²…Úûْ8ĝђ>ĝ‚$½ĥĤOËAĉ¨ĵuA.AĈÈŻÖ2MÏÌ ^Ë´ÙܢĜÙN(öŜg¨ĤöµDC×r}t#Òµ]Ë f!o|ıLŜüvġOĞɝï7{_o–ĝ¸‰Ĝ÷y3qà³9uòƒ‚>óé74qî3O_|ëÂ{µ•ŬŜñàs‚9öDÁïŜJʑ‡^YÙúÈ/›eGÙ"?ġI_úì,ğú[ùı_ĉγî΃ۋ7mOßĜĈ|  vvoĤZŜn€g£ /‚-Àvá#âügž9ú†§>Ĵ‘.ĜşûĤ-]û|•ĠVOMKû-ıwÖpˆ…Ú\˘8{ϛ=ôĈ†9úNÁí{Áò­Ï~ç’iì6c[ŜlĦ›ß˜Ñ'Raé´CsÉâ›Fà˙A÷”~aSÑ:Ïż)e·ż0c_n ŜĴ²nŭy…ĴêƒİĠö_ż·jŭ÷2‹Ğ½rĞ^wÙÛ˙ ĉ><Êf>ĵJ“·˙ìEt˙B½˙œ@˙5Ž˙t3×áíáb·ç{ËısĜ7/3=Orm_Ŭ-vy~šü #GŝĝËVĉÒ7îĉ“0Ċ…_öàS^q ŬÖîĜ]Ï­.…Ĝ¸é~¨·üĵFVóìf÷+kĊħvzß;9Qñüà3fZžnAzÈBħĦÌn˙G›½À7ÉĈkh…Ĥžu䁧VÜÑ.[öü#7ŝ|‡§ìàż6ÉOü,#OP0WŸû0—^ğQgŜ)Èïiĉì {úòs7êÒGòêgêöêÖ;oêÚOĕ9?ŝj#ğ3C\ùbGŬ}íÍ?ż“Ĉż¸•Î>¸A}iG|+#[?m×=˙^Ŝôe5ĴêpIÁqÇşìè4Ġúl£ĵıgÓòÌ\qâ3È·âô]wĉÀSŠÜ˙ڒÜŬ³™9œäŽtÚ1gžÛ{1“üĵ™Ŝ÷\N}a-?ñš ÎżW—~q¤oĵñĤïöĝQ·^{Q÷_úSz|‰s9êĜk +lqîK~)“Ÿx/cw3äċ.êÉÓĉUW²Í‡[…ܧŽYwŻ·U{ŻÑñS ġ¤'Œúñ#ħë˲ٲ‰ÀË Ĥ‰u9Â`À_eUpħĠî˙ĴbŽöüĠ{AN'ÏñUÖRı'Yïûm|˙Że~˘ä§>’Ö­˙X!+gd]óë7lŬ§ Š–§rğCmnŠĞ×Cmî\Ûzëj‚íÛáÜıv~Ëĥ°ÄXeÇğuÀÓHdçèí6 LhÄEì˜*Ğl7–ûŬB~óW{òŬO1ܗ[ÙܧÛÙ̗—ôïŻÓ™/ô/ïSݏïıwrŬžµ{u7–&ßË,ĵ›RîÒ³Ż”ĝĝÏXî}WóË#ĥonsoŸfó/ş2ÉG=Ah<½İ?9Ñ>9ÊZ~[)oü¸œ?ßém{ċn´âäS7ĉâ[gòÈ'‚:ŭšnu†Ĝ>½™ŬéŽ`~ìödo>óŻ?ċo·EÙĥ]Naouy³×ys—:}é =N䏯ĥrçŸ yĵïÉ_í]yàƒtžeÓëoĴ3ÌĥŞh×·:ÖXîµ$żwfŸ?IVĵ›§xߖÇîLcŜw§qo:³Èg/­o˙Żġí˙ħ•ßŝŬIv˙gWòċçĉSG:˙-ßéġñrîKWy˙/yፂÚóÎ\^pM—Ìğ¸”(ydDìŝĵÚĜ³N6î*ÎßġV½ïÈì°Qi³·9ĜfGxÎѧ^*äg^Óô…§Nìċ/îümÜİgìÉöòƒżm–˙hE!ûK_xĉÄŬżÁ>zĞèzf÷úz‘Û˃5žÏv׸ĵ:RéĝŝB9ûña:÷ô~2{§=„ĵĝŜ–ġ̇î~kûĉZ‘ğóeîÏ÷U{w7V<İİ |TYêÛYWáŝĴµÔĉ<êÓÛDYûïVÇ˙µü?œ_ŝ6Ĥy:Q˙rı󣽃è6°]²Ĝ³Ó-ê?QW>ıĜ¸–g˙üRħŬ£+™Ž=gÊz.–1m]á²ëżÙm9ÒğÂ:éìL+‡ŝ›Íl$$é¤ÁFïÁ}loßsħÔóùŝڀÎíÛ]ŸŻħyr3ì½ż›`wvZ²GÑ8ŭx+öñ ĊĊû~ôî. ~˙Sô ŭ˘3Ŝyk9’ıòê[I·3Ë@ß*ħùtı€˙r5ÏŝíñâˆÇĊX&[oǖşS²ŭVBİww}äÖñġÑ×çûÊùrıŬYŻ.”RC­Žġn"Z['Ğyŭ-•xjıçġĥ§ÛŭùS=òĉ˙Y-ϽµÄިm‰ììŻ”âY[†SÏÙJ—§ŞlŜµ2O;âıWOÒĥıQÂżjˢnöxÊ|ħħ>ù/ ٙ7u™u˙Y€ĴŭWêġX˜‡W§Jهw",ŝcyÓC‹–Ĥ[˙{ٖK½­şŝċĉù´ı˘á^|yġŭ„ÊĴö´ê„öÜ˙îú§×GÊùŸïp?=Ëa<Ïb}–ċĉx‰_g}•Û³]vïOZ?ü·‹Ċ­˘öülÎ}†ìüÇuLúñ…tŜuÀT뛍Ĝĉ~Ê3{ŝÛŭTnÓüXĈ×=7£Ğï˙@”Ŭ0"v~^Ç]xĉis˙N<ç~4sꭝĴċ+eE7—ÊsŻ.ĥ*µT~ú“œt'Áċċ™jç×gĞ=w²Ù—íÉ6ŸîvÖÔ$=ÊM|”]S×W‘ü(ğz3•|üÜßîâ¸ŽüúÔ'ie…ñeÍm1Ċ­íQ…{ïGĦ÷-I½—Qšu+£$ë~Zi“ò²­oÑoß&’·?xQg?Úñg:<ĝ ŜüĠ‡AܙWúP7Iïéĥd?wfXê y•êÙ½ĞÊ·{Gw÷ÎZÏî}u|Ï òĉOîV·˙——µ˙ÛUŝà?nĉ×z-6Ÿï]kŜĝZjħó7ìg[ßŜ,uxs”zú6‚şùjuû…ÂÏ\S—µëċ&öHğ‚ıqÏ×ĥÇ ×ç*^œ*q{~¤& Ğq{xgqEò̒È'ıE9’‹šïĊxYtéQHŝÎ ÜëmaWî‡ÜnÉ{0$ïú÷½Ħ·oGğUÔ|'$çNz…wGcı͇‹yìÇöLû×§Šċ˙ÇÇúTŻqä˙XS~µĤŽżcÙ=[™Ÿ-¨ú_Öp;_‘Ôá_IĉNO ˙+‡yġ4™~ġ2‘˙(Ÿûr/Ÿüĝ6žùéE†âíÛwŠİ§Ż"­ÏŝÓZ~ĉœ½ÜîĦèş•Êh˳ŭp­8=·.ëIZƒwˇWgKùw×Óߜ-wy}°Òùġ²§EċyKµE_Zp#$˙bgHŝUôóÒüKBóÏ´EEëáA\éöğqu÷âK“d•+\Î5żÓËXܞo½³wsĝ#Ëû°•?üڞğÚík{ûf‚mÇġlğ7‹Ĝk>²ÖĞäMïWq­]2îÄsGŝjg wÙä ?Ûó폒²îg6Ä<,n°{v½˜ıôÌ]çŸfÖ5OŒe;^KzÇ2]ñuġÏöĠÚğŽtá2Û÷7‹¸_žä9ĵ9ZÖUZSŭ(ĥ˘üQB÷Ӗ:ŝ­<şçqœkÏÁŞ„ìêÄ'™•b‹÷ĥEÂçàƒÈ˘“hž.܍(>3ĤâÌÍè҃·£‹+î$–¸½ĜUÂ~~šĊĵèJVİ/sën-Vĵ½šk˙ĉL1˙ĥ3ٙÍw?Ë`Nüî@ìŭÏFĉìïŽö]wJ|ğZĵş[Н_,ßúî\‰Û3eÌçiò·˙Ŝ½‰gmËqîÙ_j˙ŝDħċ‹^wËîOÎäˇáÎ=‡+âží´y|)ĊübïĈ--żJ·džš%´v´yTíĜ-u]z–÷ŝĊï^EıżÚY‘ß™PQù0ÔéġbËôúo~Ġk³ém/·ñC/żñ}/cöĦ—Úüİ×Ŝò—^_Ë÷żĥ%Ñżµ%Éŝ9zóÓ^nSI×\‹#½ëˆk˙vànv‡Ù>lKw{z¨&êaI}ɽԚĉğña ü›Y̓ÎXúñ‹pöñƒ8ŝ]GoGSmL[QMĜƒŠê½WJO\‹) +yR‰töÙ +Ċ‡{…öo”9½>ZĜ]ېù8£!ĥ½°ĈyK9ġÏ×)dOOóĤéÎ{…NoŽ•{>o­ ì¨(_‘ü8³šùҝAĵŝ)‚èù5ÜêQŻŭ–ë½[6ŝdş)żbâĈÜ]S6Üì]aġê·mìïrRïg–7ŜŒ/FvŻxïġĝâä;YEž]MEN={Ѝé'o¨‹_‘wĤ;{˘]_ĴJ|˜Ssèjlñ…[‘EGŻĈ•¸‡W|úZLñö‰eŽŻ}½ìkĈŭ̊Ó7˘‹/ߌ,hE:ëöƒĵO]A9ŸÑç:Òu‰3Ëe˙ú³áiŻ•ċo½ÎŻö•îèˆ.żŜœŞ#ĵĝhGxInWrûÛŬlö·Y`í>]-ĥŝÀg{—o‰ÌħÎĊ[sµ­żĈ÷֜Äd™Ä›$FĤ+%úF+$ş†ßK-—è™K–É£ú­‰85jMË˙Î_û¸w-ñó‹˜è;EÛ/¤–îŭ1ħ¤JFiĊôÒĈ+‰Ċù—³ÊRvêlİ`Ŝ½M·y}żċùÁ +„‹Şòï¤W7\KĜ~+t e÷’*çYwŝÇŬĉó‚í÷cK/ ŭvĤ3¤àÀ³ü/B +éw¤mŜġEjR4~cö ³]?ën8úİÙñŜoÌÊÏYnċ*™³T2sâםñ³;Œ“ “ ‘ • ’ FŸè_$c%:š$³ĈèH–[J~°-\|vèŠŞOS×vġ³ĝıw›Ġï½Ħ6Îċħï^g2ŸĜ7ÉܛY/÷•§´eWV]K.iĵœXĵûjB1ҋ%ÍW’JOŜŒ.ŝñVd᎛ñ%HŸ½Sü•˜Â+·˘ +îĈ—–ÜOìîÌî}í˙óóÚßßûeyôÔnùgŻûêнÒU‰?Žùž í§÷Í*ÉÜ9:’E‹çIÖĜùhlHÚ9Ŝ,Ħyì×0ÍÙÓu$#%%%$Ú-üż6z/Mô?‰†êßZ¨e(zëÁèŞŝè_š¸m(úÚ°ù]}Vò-‘İħú@ïBĉŭġ„âóYĊg3KŠ/§—]N/)ğ‘RRq%µtû•¤’—K]Š/9w9ĥĝĜċĜ˘“Š˘µyàflñ‘ë1%×îDĤ=ÈŞ˘éIg~z’.˙ŭK\Ó²ò‹ŬÈ? Ê/ëŠ)[˙şwË÷6n’y“ĉ!9žžmz* ü07Cž´ŸDŭüŭÏ˙iශ+a†Iô…~—ô׎ŝ5N2qÔ"É݃durÛxЏÈn|êF:ʑ{ߝċŝtwEëĒ+—c +›Ż%”´Ŝˆ/A:Ĥüġ¨‚Äû9voOċ'ŬÍ­Ù%ħŠ:gݽÂ>{}?Ž‘ȏ˙ëÎQġ+˙küqÍLĈÍB3f …éhmáŬ ^ô·²6ŬìŜĥ\eËĦ %­§/´œşXÔvêj~ÇÑkù­g/ĥ~u¨ġüĊÂĉí×*š +GëÚĥT´ÖŜŜÒ²{×]·s›öä7v”´ˆ~Vnò8Ż\á^vĜ9r³ê˘…+dĠ ĵÈğĝÏ6§JżħSĝĝżŸ˜%j⟏#solސÏá{ñ?ìUġdd 1™›ş!›U1hEHżŞÇ#ġ·ı!o>ŻZĜX{½²%öùîf¨‡÷µ@^u%νš+ÇÍ÷›[£_7Á÷‡o4ŜĈ9û£ûġcınF]׃Âö°wǚp~!sNŻgi6ù˙óÚĞÇ?žëŸßƒóUûgcç­IŒ6BÚĝß2{Ç<ê˜Rû\µÈü3™¸ÍsˆAŽjxìWÚJŜ(3"žV—|g µéÊVb‡ ûšï_,ÚqrAëC<†ìxúUQÏÓù;îßÊm= ÛgËİ˅-;–µĝ~TʗĴ“£IzFdnŭW~ázüyž˙Ġç¤ġǘjâÉùOÀ˙pL4´CÓçH\§4´LÖ²f·ÒÒ˙GedÄ[şÏT´<[ÚzöBQû•K…;n]*êıžßŭċċÂö— š{/—6ċŜnl†GÑhm3ŽïM­wŠ›Â_Üî3˘ô?gé˙ĝ<ĈĵĦyÏj˙0Ĥ*üL˙T˙3P™Œ&İY˘ *&xœŒ°O2Ç1~2Ҙ…&¨ÏDújÖÈ@kšlâ…ĉ­+@Žë/h8_R.âŜ^ÊyKŽš n×µÊİúpĥ6öéÎ&ìcšOc_ًĝÈÉwaßzùzNÓ³§éûq͙ñĴħĊ˙We„G˙7³WùÈÑd5ŭ˙ËĜ ˙WÂ×Ĉ ˜§zĜ+Á9™ŽŸ…&ë/CSŒ‘™ÑJd:É™.GĈz‹‘ñ¸EÈPg!2„ϵ— ]ü{&ÎhĉÒpd´GÍmXi#xŒŽ|r°&îî:È͎œ)mŜcß‹ŻŠž]*ŬùġµÂ·×Jv}wĞpçû;oïçġ>ğ“³cd$Ż ê.—ÛÊÔŝßĝÇ?ŭ œä)0^ĤVÈ@Ŭ5"D~?UÍħ/™†&İÛ £q ‘–-2Ö]Š&[¸Ħé68÷óÈGKı•ċ|ŸêŞê7ŝ?)ĝ7òÚÏU6öEyǵ‹…í·.´ßŝŞpÇí›yí×.ç·ġUAû‘k͗°?=w-Żßr£´ÉġÒyŜ"ç˙ñıüé7ÁGhÏ>îÏÇ?˘ġÇçñ8šjÌ@S8™Ù! ;dfħ™ÏrG–ÖBdf-Ff3…ÈÔÜMšî,ĉ°ÈÖ·­Ê}çtEıHö͙ĵ†3µÍ$oùjkóÉËM87kiğ^҄óÌV¨=]Âù ÎĊnÜÈm~U~óWWóšñ96ùŭ˘ uˆÙĤj½ÌÇ։˙ôyŸO<ƒ:ù|ÌŽÍAm’L@“T'#3mdf°™O^‹fÙÊќ•ñh†]$~Ä óyRd>ƒF“gShò4šdêŽĤLñ"?[$jEĞóèı£ô x§Œ{r¤<ñv_͎/Şšo~YÒñèBñŽë—Švàß~ájnÓ77óÚ>Œĉ´½żŸĠŝáAN×ŭ›y; 'ġùM)·^ĝ?3x˙HŽ6áìq,ĉÁÜû™ŝİ2Ñ4Cĉ:³™î§)Ĝñ÷ġpÄÖû™Ş2Ġ²ÁŝÎ"ì7íıÉZ4m…Ĵ—Ċ Ùk3LB4˵M[—‰,Ŭ7£İîYÈFԈíTu¨x1Áé”rà½r=˙úĞĵ×{jŠ/6Öqbk×Ŭ/K{^(¸xħ j†m·*Ú7=élżŒë„G·²É:¤ôûsċN‡”³ÌÌŭÓħ\äZ#âèŽc™ŽöŭÖÈT}öóÓ°EN"ĥi„˙Ğšàó›Ž&ëX##éĜ7âÇÄyÈÄûkde‚ĴF˘éKbÑÌ5ùhf@#šîSl#ŞÚ—=Y{P9ġħÒ çÁqòŻÏ”&ÜëßVwĤùà™’ĤÑó…-ıŬĵ˜ßpúfN7w3ë~xĠùŝYVÏ­{9]Ŭ7‹{“j+ÍĝżŽÙXü_˙éKĈra-*#o•1ÜwïJ£ž¨{8ĜŝíÑĈ¸'{ÚûÎoiï°µ=ŝ鎐ï7ıî¤rÎêž1slzk´rûk‡‚[şé'ÇŻİĵmà|\9×íÒ9e²e˙ÓĠ²wŸoK~ÒÙġÔäkž„ÚġrA˗×rGnf7<½‘Óüa4żûŝĵê§§9ù7ŒÀG€˙glSëXö ™ħé8sda°͘ï‹l=“ ‰ĉDÖ£9ÇĠm+h.­ĵĦµĴäÊĝEé§ÔċžĠX^vK{yĠ3Ŭċt—ç^ż"â8ǒQ=—“J[—ÊĠëö+­jŸ™¸+çx>Pzú>RJü^*~O•ĵĝ£2=í^[#ä,p^{pMÀ‘·ż = ù§<}ì'‰ äà”u|šŠġœ5˙]Ş’1ż>É瓝É4wdj#Ds\’BŞ - ÊÑ"iZ³WÍöŝê!ċş³x|î(—ğÜQ:€˙[Uŭ`Eô Ú"i²S4Ğ8ÄíĠXS0˘żĥâı‘sÛÏn'•Kq~âċûe°è·İÜOW‹}ß(yŻê›–~ÍOm„ÛŻÚG~ò7ߤHżüe=}÷ÉÀż8s˙(=ñkwúÇŝĜ[ıâä½hÙçɰß)àŞ2IV­fĴößÇ=X™f8~:Îġ—˘İV"4}~0²ĥE³=2‘­¨-ڄ‰Fóíh4g;²ħñ@ VhU­²2ċä8‡ÍWµ]ú˙u†Ç]ĞÏCe ˙[eġÓŻy‘_ïŻ—ŝx­\üË/’Ëò}äĵ˙şÀ§çġß}J;˙PpSɈF•!’Ǹ'r¸oŭ˘5ìġıé÷_W3>dˆn(ċ’;żmà}QR|w{×èÈĉí%£µ­Ŭ§Ï°ZñOĜ*Tm8÷Àó Ÿ§‘ÎLdnÍZˆ–zĈ!{Ş99hUl—şC5ƒu_)çyüĤ •7J8]@ŭu4+ß~Ŝ(ùû½LÑïO3ŝÜàñĞRàù£RäûĞRî÷³2œŭáu‰˙ke°WÍ% ߸F-ÏÈZMżËJñ-exÀï+…ù{'‹O(™Wï b^îëˆzu¨=ċIOÌׇş„ŝˆ Ñ`ëÏ,‘ ?˘ÙÓoeÂŝ–{lêҙ9wİÓŝĞCÛTS{4ÛVŒóÜ-È>îĵĈÊÊŻġ{•ĤĜöVzŭ¨¤ŭŝŞ ÷ûMáóĞRĉòTéè|KıÌŭÒŬ˙ïÊġ™›†oċ7ĥ5ÜĞm”~Ĝö<Î)í=O(íĵn)=O•!˘×Ê$ɇ߳eżÜĞċ~úf‹˙ S@PŒŞó²•ÈÇA%ìc¤úŸ81 ç—H³vZÈâë ĝüÖ̞żûòÇ?у?z2ĊĤ‹³M}#kĈ-X*Dĉz3˙µ ˙°M5œgák‚ šıœGvAŬŞĞk_˙sû‘Ì—PáŻÊ8á_”‰?(#|c_@IÜRR~7”ŝÂGÊ0ÉeVà·ÊXÁ-%pFé%lzi+,9l)è{c'ŭ{óîğñ÷Ê ÑKeŒßï+„ÇĴD;,§‡~ôb>˙ȉÛn.ĦêÎ, şÎ`ŽÜ”ż&“ßşšòèR5êÛû£Û0jÏÖ|µˆ=ŝ” yzZŝĉV`DÉ.YE˙—çŭâ5 4qĵ%2ԟŽëèċhú<_´È?ÙÇP·ßr[wġêzGı +Ï'×9ċŻÒ3Ĥ^q}Ú~GMŭÎ+=Ĝ§·³bÙ×İĝxiûáIħäŬÛÍ—•Ae³İ a½ş`&MA~İ_ËqkżĞJŝġ“RîÉóaùáİŜ") +ÍPîŭ—µÔŜßĵ%‰µú’, ĥááJŝÈ·RÙù§qÜٗaÜĠgħ²#i{>Ĵ•ìŭĊ|ċJïúŜ?ġM(}ñ§Pß3J'·{tĤÏYKêì< qÌX°H‚¸JçܳÜî(|żW*T&û½Wa-â¸K˙ôKŭËÇb?ìĵ7ĴtòD+– €ÄÀ£o½¤Oċ'=ìËxÚŜŝöx ŭŭ‡BÁ¨’÷ÙŭŭBߊ –ŝŸ+ç•}Ż– +NÏ~ŝ›ŭĊ×,ġÙğ@ÉĦżySimFâ d5ß@ ˘ħjD' ô÷ z-™ÎÇĞĜ½ż(.²:h!£ĝêffÈĠRĊ™ñüħŻeü 5ĝ­Ġ~sı¸j˙ ߔf]¸ßfĴGÖŝñ€ħ4™8MçŠĝ&˘Ġ‰Ĉı}Ĥœïŭ’ÁġċzX£óù äü^+yá}e°˙Áqô‹ÈĠö F^b( +FĴ“VĜ;›o½ı†Ğ>aà'BöÓ§ Ǚĉh5<ĉNA.öˆjżh'=˙psú'n½´„Nİš@öŸżó#{˘crµ˜° M’ċ{^ıó½Ż=Ĝú³K™×²ŭO9öîëMÒĞO“İŬs£êÏۊüìC_ŝÁ~(‚½8ù÷êwPoÎö?Ş\'l{½X8ÓJÁQ{àokÓ: VŻvB‹ĴĤ ĉĉHâċ‰B“´#7çN +Ï)Ÿ}bG~rgĵŒ–Žĉˆ?˙‹H|ä/>âŭu—T-Éİ2¤êvÏĤ==šg <ôğğ¸êÜlzóÀdIXĤ8,UCĴAú^öĵŸştñauĉ+jıħXT}r– ˙Š€w‹} +Ž›¸ÈòU;)l›§Ì_‡f8‡ ğzçm÷M=+m=/(×z^ď£Ĝï÷}7Û£ĝ€‘gJ³v@á.“ÀíCÓĞû,…g +úĜ †sמKeġMĤSی¸ÌîÉLî^K&kŸ_çċêÜWŻE"ŻDB$“‡¨J!ŞLQ‡ı¸íòqûâ—ìèĥϗIv\XNí~ëÊ}ÉÑ_~͓}•[;§³…=–ôOùé{‚FF n_¨şy=_~ñŜ&ñŜîWAe7 R·èĝNòĜzÖlmX™Ú‚Uš¤g…ŒĈz×Ħ6‹È9˙òD÷§J7Ÿï”,ŭÓ÷Eôûżĉ‹.(ÙÀ}Jga^‡qàz|-SKġ$ġ§çÑ%½–Ĝ¨3ñş )èïäŽ<–Û£€uîˆgcHŻю+ÚcœÑ0™ˆ‘ŝy öLq§Ġ>²œŞ=nTžn92G:Ì'lœkqä²·M‚ ĤúÀş˙• Óy5]wzĦd÷÷òáŻÙw÷ŞOoUî˙WgIQŻı¸sduú#ôôzE‡+MÜŻ+Ċż)3EUĤâxïŭJIySôNžè$Ež²ġ*ŝ°OŜlĉo½JcNŭÂIRZ ÜÖy#Ħ(‘Š/l¨ŞS6>b9Z9k>Z;o +pqFÁ²0µÔ<Ȕ<£¤ü‰ŠĴÚÉt÷WĞ`Ÿ/òQ0uük5ü£§hÏ뵒ò~KŞjĜš9Jûj%û~ñµ½\&éĝŜžŜ÷Ż~˘ÖÑ%ôĉnS*>[‹Éjœ$î{ĵŠÙ÷Áŝà!ê].Şż0W˙f…¸ÒCxDé0ü›ƒß]á·WiçqIéèù^àóÌó£Òßç‘ÒÏïšÒ7àœÒ7ş’œUúúm;mċŸŻ–¨š ĉí‰ĉMC.ööÈG€è4M69_44#|QhŠ:ĝ 6§ÏœÂזĜ9èTôϖçV™² EşlFë$IïƒUTÏó5LÙ.+&żŒ)h1“`_(?{;6ôĉ™2úÌ·2IùĦâĴí†téљ²SÏċwnÁ>HĊµkYÌĦ÷bqï3Ĥlß fSƒĦ¤úKáeˆúĝS.äEŜ§•Ğ=rN¸'îÑöL;6Á#e÷QċrÑ÷ÊtĜË'ş£ (4ñò BîNŝĝœÜ‘Ğ:äâ° +I³´Ĝ½/ĝáÇBzàİ“$)_[(V èIÑL’j@z÷ÄÀcJOqÍéÙ²$UQX–†$8]]HoPuvtĈóoZ‡ó:µr˘d[g˜7\ +hf€n1š¨H­6–Ġ~ħŒïġ˘ûFœ$ŭwײ;Ÿ{„âà]ıxĝ+]NJÉkÌ– Lƒ^/èçĥî´}ž°ŻÎäÄ?êLz²ğ;ôúĊ"éîwlġ— ˜­gĉRğ>83'_ñâĞ%ûô¤żñ§kÏĦsêŒİüöɢœîIŠCÓġ×ĉ2vy+ÒU=¨x_Y–š€NUġ†ĞHR[ Eëô× Œ$\7-2œŠ\Wı!WÇĠÈßW@tˆ’`J£F¸8I[&J#b5h|ÀQėéƒî–<ıPŸOÊхžanžŸüĝh˜ìsUaĦ$Ğۄjş²D4ĝŜ‰.=8X]BYĴ*…mUzüe¨ìs9½ëw¸ŽTĊELQż%ıŬˆŬ2<´İïÇ˙âxĝg÷À#żş˙´V\up†¨dż8ğs’$ĦLĈĊĝcB)‚Ŝ|lë&tĊñÙÔĤ*}°{Şì è+ŻßĴé‹ó0I¤ijLAżŬñȑí|ĉşÙ gDô„?%ûŜ{@oÓ9şŠÚġę|ĉ +ŭâ4ö)LA·›ŬˆNŻ5 77KšqœßóÁIÜ}oeàŜ÷N’£ï…Ôù× +ĉË×rúÜÛ`îâ×QÔñ÷bÑÁß<èÓï˘}uĦâJuüıap’ôoÑ{~ô–Ÿ~¸!èö•BĊ‘\ĉì[ıĜżyˆ?WjÌôGĦĤ3Ñ|½iĝ£òc‘(z³ĤxfÍÀ°$u*"]SĴĜ¤îäâŽÖb˙ıv…#áħQ)UúLbŽ($RbŸĤ-K-7$̨èL-.,AKÓ­~èħPvèħŒ9üm UÖaAgÔŠ:2ğ^{‚!“^mÀçl7eşÊO]‹ ğzş0úîg ÁgFR˜]ï=Ħ+:8ƒişoÏԝ˖÷YÑġç3µ‡ĉâ{#†> IïÓĠ’Ĉ3ĥ˘á÷Nµ,ìùf|Żïü¸FÔxĊVÔ˙ó*x˙tFéIBŽSudŽdƒ3µë£ èfRĠ‡fSŸÍ’4][,ê(Ü÷ë:qZğĦg@Z6g1²5žìg.BĞ/EnnnÈÛ/ıyáĜ†ócŸ@ù0ÈËC€ĵ|„H– &Éh0íA/£ Z‹ ġÇÒaŞ”û*B•Z/ĴàúžşÑŭϜA³›J,aŞöÌd÷> •‚í²ƒÖ\~ûÄâ÷=H?”óǞ˘ß ¨ÁïŬİ=?yBOŬqÏ!_XgFWí²ï¸fÇ|ȟ~.>7OQÍ9IÍÈaß[ûÀwŽâ²}ӄá9B>IĠG" MW§·ë‹6dk:,ħG‹ĤÎFĞ–ğ Ïu~ĜoŠ0"A^ĥeŻĵûš‡´íÖZàèŠ$ +(`áaĉ7˜AŻ?è•;gC)ŽS™Ü&SĤ¸ËRÒŭt½˙£/5ü½]÷…-ğı”Á‹gÓŞ IO^nû’ß4~µ„è +V›K5ŸYL7œ^Ȕ O§+Îïzµ–:ü]sĝÚù“+µċˆ5èeˆÉjf½Ş(8SŠİ nŭsbħhꉃ35@gôéġ…ÙÜsĥ☠Ġú`Ĝhŝâĵb*“\=NާòµİĜìñ ɖ°–ìxì@zë>·•ôÜt€ŜJ˙‚äÇï„óÇËgGĝ ×Ӈż ”´ŬXĈâĜ/Ùöù\èM„ŝ5ĉÂ×a˘áŸĊıŬĤ┆‰’˘ ñà/NâĦ÷.ï`ÛtïùÉ´À$QɰĤ!…Н–ö‘e˘Ŝöt^˙”Àà u—ĠhġäĥÊ Ûˆi$–…İJ"pm™X¨K'fi‹˘’ĠAI4^ÂÓ4èŒFcêÔô]WEZƒ‰,*c|PTĤ–” W•Geh) +ûg°#Ğ@ë ´1èÜ6SşbÏ Ş˙ñZĤ÷ğçıôırĠ{m@Oîâ,Ŭw_Ìz*ïyë,Ú˙£ }ò#½ü$^zĉézvßkxÏc'vË 5›ß8™Ş;2Orà£7é]>ùF&9ü;;î/§5Pi†Tßûµ’wëèĉkv’Ê#³èĵ.3qùÑ’ô6#gçdżyĴñCÀñ֗XŒ?âĜ#VD¨͏ÒŬD£“‰MšİÄ.ħßdÛ2ƒ_{Rŭ#kĝ´’‰\b–_ÒfI7ž^Än?µnÂoè{wñîo×qíĉÌĉ:côàL`mYġĈlV‹)ÄI6żÍŒhêlĈġ`:ÎĊ‹wMcóÚ̈–df$:!K‹N(Ö!z;•ŸÛİÛ ¨¨ìq 5ρ>|¨ŻÏ҄>iÛ*ÏċĞżXH'ëRá*â öLĊépyŬĉ0_ÄßğŠĵ÷¤vżqĦ?¸KzŸ­áĥœ Úî SÀ ĵt5˘ÛĈ4ĴİĦWžÜà ös {ò…œùü9'ŜŭŜ™Ùöù|ƒ¸!iûjuè?uàoIóġTnŸĴĞI2ZŒèjì3ûž­‚êĵçŭ çڑbžkĦqjÔĉíF°6 éı†nşşŒŠ*ïÉ:ÈùùòˆKİœÈm˜ڔ\ñÀ4|-M¸ôFc¸ĈâĜœñâ Mê˘°x5`v£ŽÀêM iġ<­zŸDş h-m+Ä——‰ûŸĴĈóёi9ı„mż´’îYĊïĵç#z ĉny2;ï¸3{ó˘~Àú:ˆż{/Kñüz•âÁ•èżıx6ƒ;ŝX +>—Ém™Œç³ï­ôâÒûóç™ı{Òh­ŭ:$‰ĞÒezżuażġ}1Ş oФâĜLIjĞ!ä˘.Àl B oCt#ËöÌ&<Ĉˆœq|RġDÂzĜÜdšòÀUÄ:ĊñkQüûb…aB£÷Ë&‚&:½÷x÷[g6£ÚÚĝ‚0 ˜X\W&•ë3=ĉL޳¸`ħŻ`²›L¸ÌmĈLv³ U€ë£ÔmLêvCfS_¤K'•êÑ8¸!„*‹We3êĦż•xïL ĵt¨g*aĠâ:§ŭš=Ċ€\^`3Ĉ›Z24\˜ŭ_ûñ'žÈdGÉıŭÄP#€f4Ĵ ĦŞ}6lyh=ÑM痂ö °Ah\'ÑĵİᏞâçĞ`΀†ü™ä|]¨Óòj×7ĥô€5pwq-50€ĜŠŬ3ÀFACƒŠÏĠ +ÉÁ'¨‚ĉğdCšĤ$&o<]8<Ïm'nˑ9Â0äÖùòˆ +KĠà‹wLqbâ t€ú„Lbıž82UӗCŝl´ +– =štH²:hɰD?{·5ÑR[†fó³ĝêCó‰VJċĦ9TóÙ%„)²ó•§lß*ì³Kё'Τ„ıÁ <ö&zxĴı£OÙċG‰ò—7·„ĵĵX½r U";x…|à1HšX(Á5ˆdÇ {q˙wk$Ġ_Îm(ïê,DĞçŻDŜ¸&M'7“Jtŭ€G,OP†Ĥ¨û +塧 ClX†&hO…·_ ê¸èF´ÓbŠu@+ +¸% ĦÏfÔÓRÇAܖv[zôF Wr1èҁĤĠ~~sĝƒˆ9ò“X¸ë'GĤô°5hĜ3Ġ8§lĝb1›Zg(‹P\-Ûo qêjqhĵ:hûS·èF µİv˘8>ûÌ"6ûş´JCô&3Û'K˘Ò4üŭq ”pt’ c ÛpĴ`í‘-!‡Ĉ§À1àҊ&›+Œ@—Î 8¨ ĊÍWì›zu8†9idíšZwÀ-"šQİ5Ĉ cZ’ŝGk/@X°ÀSm<· ò.îÈs2trĦ$8Z +Ž6‚Ĉ2Ž•’£+Ù´Vc4N5Ċ‘‰Pa#3ÇA asÛÍèԊ  8‡Ç‘ë̳Àà ŞDg£¨Ïbä(BÑĦIÀ/ÂuŠ Ÿ_oL,ˆçÀa²µ`LÈǨâAEžÉlŞ1`˘²Ĉ‰ı˘SāV~nƒ)Wħk&Ûׁn"ğóÓ{ۉk8ħ„hŜmû̘Àî“í½/ ŭòÂĤˆ3_díUmÈĈóË`ŽJÚ/ĜA,çż|Ê_}ž}zPƒŽ+‚}Ù5&­ÇÇ &ıfĴUÑYm&P#ĝIÂTœVû!‡9+‘û:$ +O×ËĠĵqíêê%Äı4Î!фż-”„¨€&7èOƒ~)h˙Óa)b:J•Ŭ¨ÁgÔ3Uĉ€Ŭ&şùúrùŝĵ|ï3†ŻùlÑ.,éœFï}ċ˟|DŸŝ xHéAo9:‹Äà“eµOĤÖ§hĝ E¸³W 8QT–Ĥ§·_$œ2œ°Ùu8Ĥçi›“ŽˆU]LÂĞÄöšP1˜u>ÛXjÉD6Ïĵsà€v‘tÛa[˘ËŒsh64QƒèUĠ[$Ğ9h ş\ÀĴb£4A§ŽmżâÀ×ìŸú†c|<]Yò–‰ÀëŬuŬ‘íż +ıh†nv~Ğ9è`J=–*NŬŬ =ĝ;­„9 l +_KàĤ‚f*“Ù`ÌĕéHÂ7i+ƒKm ŒM°1˜—B.T…ڐĦIXB%½VÌĈ2}Q0ÎO°żí_×z$–§ĠÖğĴhȚfŠÛ-€ûD˜pŝ¸n­t`u‰qŒŜ³që&½Áˆ0 +ş-eċlˆžĴs6_Ä÷zÈvßJ{îy°M§—‚]òĝ÷Ì!ž3mW²=7Ħ” úŸĴr:uj0ĤŒ¤ëħµçGœw?s · Mçó:Íá½yğyàùÄ"&ĤT‡ÚP (W"34İX¸iŜ×<È~örä`ğı;ƒ.g¨Š0$VNĞ7dĥîŸÉ¤Ö€N>èSa˙ +ûQ ĉĥ×{×´˜‰oJÎѕtßr$ú?gŜ†0'R/9Ĉ$VéıĦê‹k/˙@ ÒÏ]%ç‚Ÿôô” //Ŝƒ´ZcàNŽ0™!Ş wHɐ˜U-o˘­Ë%ĤkQ!›4ˆĤ<ö‡\çċĠòó.üöρ]3‘) Ĉĥ^u`ğŻŻŬ/.·Ö„äZm—WÒ½7V‡A^Po.+é™yĠá uHw\víı'˘żġd6–ëKBcĠ çĵlÇ éĥĦùÀdßú0Co}IĴxêL´˜ÊöÎd£Ë´Ù˜m‚ïŝĈïé#ïż'¸#’îĵë ú‰x./”uL•ç×M‘Ö[Êö^wáğF\ħmړœ ç6LÙé8ÖÍ%zzñúÀĤğŻaßûrCoŭaŬÖIAš)ë›Fâ~2öÓ[ö΂ġ&oxŞ$~‹Ú`H%VëQë35lˆŠó7´zĠ:÷„¨(`ıƒÓóÄ t|É5Âu­PÄ":"N²ú³ö„ĥİڐ°iñ<‡k!ġc[Ĵäó[Ĥ€Ž<—R˘OÖ;‹wàĵĞ@_šİ?ŸJôú½0GßÒ˘½?ş2YۍA“Q Ŭ€cÛçÙT=tÒÙ-‡ç€ov"èÒs‘ñAıÍŠün+E~‹%Ô`t(ĝñ _?$á‚U@â&èm7è ÓIDrË,ië…U\ûġĠÀeÍQ€íWœr½Ö )î:żœ;ô„’ Ŝò Ċ­ˆQ#L<.ÁC7YéÀìW™‡nÜBvÛñùtjħhĝ³)ĊúÀ:†lBžäĉ°öÀï´Ígˆ' 3Ĉ” Og7÷O‘DnÖĈŽA—îûΙmıï€mÈ +j?>Ğۜh× nB4Ĉij› \ ˘Ċ]y`áaƒĜù̓~" ÚġHÌġ}ÎâMĜY8fÎPvû`gIäᄝ%ûv–dĝ{W¨áŝV€Er1vV)aĥMJž°)žèÒLŭg°½?ÙY²ÎGn|Ï37bÇxŽ‹Ĝ8U ĥ-`ÍsdÀjĜ\; òiiQï4xO\Tž‘=ĝòòŽûn|ï àQüXU1Bĝ-À ŻĜ3| ÑAĴžÏ5žĥ“vßu]]˙…'h<2]OÖá˜Gtçİú˙¤;oŝïşóßzȏ= ğ|._ĥûĦ€­90—ĴçĦd÷4:µŜĴ+Ö[À´œ_kᢈMê uÌĵâşĵ˙ĦĈö[AÎIxĊÀÁ&˘,RU, 'ıÑĉ^Ÿ¤ \$ÂĞtxŠĤ4ÛMz­1hŸKw?ó'ìĴR|m˙dgU; çw‰z²ÂV Œ•gá¸÷;‹-Ġá<ĜßM‚h.\••żŞĈ…Ċi€Ö2ĞÀĥıìµÚñp#k")e¨è êÀgMo˘{Ŭrv9ÑâÎŽÓJ(Ÿĵş ìş)²­C6|Ċ•hqWÍŝ•l÷=äÈp/‹ÉĈ9S|‰=ĤĊMĝC£ŽDg˜Ï s ïğö-hÖÂ~4ÂïÛĴ5ĥœIŠ˜|]`GɲuĈĜY –잇°>È;K„à™¤NÜw^Ä!Y\şöìĴÉÀÎ"z²³"²Ç+rzĤJëÎĜ)ІgËp<#:ü +µ ·+Ğc +a(fUÇR^d Zúòlì ñ¸J£‹uˆ}ם]ÏÇñpÂĜó ĈžŸÓg šĠ`ßlĥĠôrùցÙAŬ#>!;İ˙îżëÎÓêÎï}*ú?uçı€îĵâ$ì½x!…˜ MYÎ iÁÀ4ITş&ĴIH6lÇmŞ5„ÜĴ*TE@ĞH€£Vĵ×šŻżµò\>Ğw +Ä?`ûÑá›5ĊL°ŠH$EĜNÔ ‡ucÉÂbO+5ċ·YÊÓêĈxm0ç·™Çô?q.Ĵ/ŠqŜlàœ |%ÈÏŬ‹°³ÄœLEÂü;;k:ĴAL(P€ğǗHUˆOòˆÌñò¨,-yt†–4bÓ8>2s<ĝh`q>u^YA›%ĝO6!S â=á]àk˵ž³ĈѧßTiyĞ çúĜ̓5²—n;h+­:00ÛJ;Ĥ1ğîzÀŜX+-n.µÖÁŻ |3ë3䤰(ÎזĊĉéÀÂĈ*éŸë-„ŭ›×oÉlÚ: +KP','3IŒü“Ġsׅïżçk)²³ ŜJ7m7{ĉ³ŞWì,à%CmöìĴ˘1v–×ûÁħê_ݵ“ĝTM˜ğ á/ÛXc9ĝ\yQÛTÂ3ÛÜdĤÈÙn†}àdˆ|Xĉ8ÂŜÂÏJÛfϽġ|>Ôñ²Òž ıM˜}k4]pw_p *ß;Oš]cşÏÀ{&,Ĝ-g3ğŜyƒß @GĜħÀĈ#ÏÇħ֘ö/ì¤[wÍ'Ğ+ĝ°÷ĵü) ĝUħ ıH¨a=;@,CÀÄĉ°Ï`ë..\’O(× † ?ùˆ£ˆR“gU™(JvL:Ôċ„m +q§ü€ ĴlùŝY a{ + fö}çÍ5œ[ĵy`gÀ^I.HĜY†C °³°ƒ"ì,oü÷ĜïòMUF²Ô˘‰Aħ:ÁÑĊzÀhä5Ù i<ŽŸÀîÂ>™Ż˜ D`¨‘µsàšuŽċ:ŻŻĞ4½ÑD‘ßgŒ +÷–;äùpŸr*ĉ&|­]3˜ŜQgˆ-„‘PŽóŽ‚\:>GàrôßĈùֈ‹"·ÉB“ŻœÑh”ëúÊAùàm‰bï}İt÷s! ÚÉwì ;‹Û÷ÎĤ:.vÛ~ӑ°³rہĉ sQ– Êċï²­nÂĤŜş‡°³äÀOvVÑ;KŝìĴ„?ÙYݘ h5ŠĊµ çíó;>‡%è{r`ÉÓÊñül4ĥy>;ĝ(üüà j\*È÷ž_}l>ySç%c:Çğgʵ”Ĉċë>YôĤqÀü–f·™Ñ͗–ħŻ}%=OV˙ +ŽRƒŭċ4~@­FꄸMé05?o)Ѹ&Èż ¤XŞÊo1†uDˆ?PżÁëÂp§İpœ˙䴚q5ŸÍ^°ı}=$È×[‚ ßf£Ó°?7“Uîħ–/É+qÜĉÁŸlÁ>×2|FaŝÁ~+jçSg~×3?Â΍ôĜ -ñż³³Ò˙`gmÒRvÖŝ…ÒşÓv²”ò‰bIˆ +ĵwàm½RyVdYíŜA%½3ƒRŠߚÔY͓‰{ÇUGÂ+Àq¸4DËx„MŜ8™ßĵç^3!²×Vó=£îL×µµtûùÀ€'ka°?‡Ô2=Vp^\KAKö=Ê*Ž..İl×ŭé‹ċAiFlXĴşbC–6×,¸ĥëĞ!p-;Ĉ—cg1„u-żó•ŻtèY ìA†ú€°0 téÈÜq˘¨t *şhüŸì,X_ĉá+mé%Ğ9`++ÜnNâ{a‡·}ß|i—vòŠ €])MÌĠ…½b0ÇaŬD^mĊ6ŸX:ĈçĝҎpcÊ:­àw!vHÇUslħ|ëĦy²ĵífà‹ühuàoçžk?mÏv?p‚ġ5rÏX‚uĜ÷6M–Ô†sl!aŬ+ +ğĴĝŠ>k¸Á@írה-ë³bc²´Äl„Ş$(\b'ÉAÓ?³ĈĜ׃E˘P6l³Ĥ<\ê[yÖöÉÀ<ŸÌm;4_Ö˙ÀŸè ½Šġ9ÁçsÉċú )y‚šPŞ"„=?8ö@.qLžÛ5•ÄH×gÖşHŠkU`àÀúĉS¸ĈpŒC…c(äİġ§ì€ŭya˘ƒçà ׄ}'Àû‚ `ġFä!lÓħĊ|óeÈá +°‹œĥŝÄ"b›À–É&ħh6ßyË ì“ëí÷ëdŭ÷}CïöŸÀĝ?1R•p KzĤñË'À=}&!GîK1 _.ĦÛŻv–|ĝ1#Ùù ĜYìĥŭsĦçƒ+Ŭ3ƒËë³-k†Ĵ9Ÿ™KĜYÀ +ġĴ*lŸċŭĝœù;ĞxŒĊ7œmż°bYoĊ1_ž×nIrMì÷Ùù0ÓzڎŻç]Ŝ;/í›NXóƒ³d§–s­çW-ÜsI)3Päáú~C6\÷ˆ3ß{ǝîYCïÀŻU{l>ì€óĵ'Yċ‰…òÌ63&2NƒŻŬ?Ö4dûîѐ‘µ§NTç„ï„k,RkT]Àw\[Ë·\v„pPe1Úò´JcçĤkPßm!aÉl3\€ĈġP ×ëlی֍Gë$#œÓlmynğ°ğ ĉóğ-ıÁ—îž=&dİhȚ{…ġ˄\m>)_ò0€Áĥ$­>8îgĈ{|ĦžNò}ÈÁ¤e‡ç°­×aMDZÚ?˜ßżYì€-×êQâ‹Z-€YMú\ê//'ĵ ÌjÂ@•gTM" f<6‡òġ8n ò}Âħĵ¨´×ŠĊמÔFÀÍÄç‰íôĤğ·íÈXӐ~$“U°}w\¸ xu‰ˆGp˙Š0jòĤĈpŜ ‹+Ö%ë ˙ÀÎbÏ.#u[ağ_wb ä’ğPżK"35%8ÇgÓ;L€•&-˙ƒĊ‰ë><§q²³Jş§ۈƒ9Ġv†0ÖeĊğĴÇ^·o*Ĝ݁C]½gWwĖm?gḿkÄh6:W‹’'İGîĦKËÎ!|rŻ˜TÓ€³kÛKĈםµƒ{V„yk˜`ċ'ĉÉJöεĵ Ç +ößpMçĈrK2gËĞ>³ğ'c ëMÀ*ê˜ +k×|˙}ìżrÉz|t–šĴ!MĞŸûzĜ}/äIğ ĜöÑU„Ùk„;}l1Ûuc ×yc­l˞9„iÌ[œó‘œµúà\Ĝ_>@Zj ,ĥùô2z×SWŞŭÊr¸ż ÷›IŻcl‰‰IUû灟‡\JšQb@ò”œĉ)òâ.+rOûwşŭÜrŞùä"¸>ÀY‡z^,S~aŞà¸B|^Yìa™C¸ApŜ8$1Ï{ĥfż ‹ós\·,ƒ|BÄa˙„óP&*{ĵoĜ{Ĉî~ĉ @Ö­wÜ^Í6_sâ[9`Íö%ì½Ŝì qÖ îïşê >•Ü›‰Pƒşb,ĵ>‘ {2`-8ElF ħ(hŒ‰˜Ġ2˜*pNpoŒ‰Ü îïsZ)â7bğ€{ÌéیĈxĉŸ/”Ví› k¨prFir‘>abá 9ĵ7yÙi™°>#-ö‡ßŸĴüÈ\.£aì‰`rµÀħÄŻŝ+§s +ÄI)°ìrt`ŭ’oĝr90?X[À†Ëj u6ıœ‹ÇdÀËĞ;d ùáV³½t§5QŸ/',žëŽÀ.‚çzjUl·‚î~ş–ŜqwĝŞë +ɝĝòÁ™TX††DQ j àVAÎL86k;Ž3MĤ<Î?yĜoUħg–Ĵ°ÉœÜ+k:„í–k:o÷陰M·A…ZcYÉN+ŞŠ=ĵ>ı_“ƒí!żËĉW:`EoßoCu_s¤Ú/Ż Z/ÚA/*›­|L6.CKşeç,‡ƒ=$…{fp +ԑe´˜ĞP +,mœrĠ;ħ=0l×\şpï ü Ĥ¤‰™:ìĈr}iZµ_ԏ}T—Yç5İ7óà_Zà+Bb +A µ ÔğpŬ!O‚û­ĥY.>S‹Ĝ60Ĥñ5“uO…½<||ĥĥ âyÉċŻO êAĜ³%+°†½0Żà}ÀŭbizĞ ÔÎàż!$ÜôM•†dϰàÓ·8fLâ<^ħOá2M€éLx°_1·ƒ0ğeûçÖh7WVñÁŸ/!œWX3Áy(Ìqnû‰1ìSìç +Xħ°ÎŽç˜4 _ğ"lg¸>ĵl×@˘Ĉ/—À8BNÈt|ı‚ŻĊŻÏ“Ä€ +üaXçuòôrrŻçDÀg“î|è}tL:ηa/mn[‡g‹ŽÊà>]V1ÔIÀƒıMĝ‡mGç“ŭÀ•ûfÂ~Wà&ƒö Âü"9ĥàŻäù]SI\Ş>lK˜àĝœı­=3ˆVìĥĤ·šOWŸ˜ËĤ7C>GÎ ö½tŜp„ùD[Q‰À  }½VòÙ7Ü7ŝÜàs_şv˙&*MúC ˙c7 8=8Ì%óĜƒ ċúä}“y}|‘òÓñéĝt|:>ŸŽOǧÓñéĝt|:>ŸŽOǧÓñéĝt|:>ŸŽOǧÓñéĝt|:>ŸŽOǧÓñéĝt|:>ŸŽOǧ˙çcÖ,÷ĝp·”=ÖKo–³÷ò üµ(dcJD²^€ŜĴ EÎÉ)nÑa)Ñ ñ!ÉVŽ-Öߏòv³r´²ñ ɈHZd4×j••³÷’ĊAĝ ĝ§s­à_]ĵpݝĠ"QDHĴ•ÍĜ‹Zá[ ’££˘ñ7Ċa!ħcżş +?ô(x +á-¸$oÚ¸^’‚Ÿ?öM—üœ˙ôm*>>$."܊|× +Ûjù\½ĊVÎĝÁĤÁ'z›‡%V‹É?6áƒ?ـż•fµdħ•ż•TĜ*~_¤gkożd‰•½ŝ/ħÂ~ñÂ+Çöû‡ŻWŽ}ôûó÷˙÷ŻÇ~?ŝ?ŝ<ŝ4vi=˘c#Ç>%góÇuĥ™‹ßëİ·È-"5:,ÂĠŸóµbô¤Vĥäú‘7Ÿü{pXıpÙb{{+ıĠüġŠpvë˙ÉgÀO˙xÖVZÙáw°d%ıRvVäôfÍ"ïlÑÊnɊözĴ·ĥ—7ƒÜ]ŭ‘·?ƒüĊá*B&Jŝ|¨Ş€ +Q  SñDŞxùòÈM„||H$YŻ"ŽÈӄIIdŽĤ$2[SžŞ!”%İş; şĠ^ÈۃCtŒJ€"I5@£êá"7ç@äċ!D İ&”ŻWElÔ IT£â +µ%Jµ™˘ ä/E #%KQ—D§Ğû‘żí(ÇŻ!FîëĵñG +ä˘TĦöĵûù“ß ä˘UèÈ MF‘gVO $E~ÇTè͇ŜY˘û[ =Ô¤Wfc•ôĞBż1ìe†ŝNyqû4è]ŝJ:4I] +ŭÖ Ħ› Z³¤g³öÈbèó„ž4>.G›hZàÒ ™ZÒD<İ7}*˘uż=MëÓÇó‘5ñ%úòdü÷7U‚Ĉ “˜£C´"25Ċ£L+T(i˜*èVž¤=ЇÌE$k‚öĥˆâĞĈ%o3€ŝ:z“&•L4i@Ӌ‹ÉւŝKdK‚UÄ|¨ + ŭŭ1ĝü2µeÙµĤ²ŠáıòüiÛ(‹VaÂ6i€V9÷òŬ³ä·ğżô™ÂġLŜj@4‘rğ,Eğ§sıS˜MeúlJ-ŝ~—QgÌDċ”ÇЁ,—˜§K48rZÍÈr˘Sj@ ô"ä·NŜ(ĜOöżƒöŝ;tPŒÍĞ‚Ŝ˘P +şÜ ë,ŒTŠBT|…2Nbèuàb‰>¤żŸùÁK‚ U,S“àóĦ5Ċ_ƒĥĤğ›‚~U‰e˘KµİèrmIhşh @U‚$Š j é FÍnĴ5 KRóñ瑋§ùCżlH†&_3KÙfÀĈ•èJĜU`>*RÔĵñïyğ‚Öo° +hÁû#qPŞ:#OTg"Ó5eòuäqyşÒMeƒrëÀĉĤI³êL`˙şŸ/~ŞÒôíĈ²œĉò‚^+F§UƒŜ#ÑÇʨ0ûábÓ´èè4MÙĉŽ)ĝúšKAç"·ĠBÖtÎAZwÊNž[cżaÛáâÓµ Ghu‘û1ƒŽi`óA™ġfФl=yrşŽ<½Ò4ˆĈĈB} `B6j€ž!èÊAÑjLXĵљŒÉÓf“suĦ?S‘Ób}|J‘42G‹hċ7›C—,½Ĉ˜ÍÑfÖoԝ/ÒۃmŸŽŠWg#’4@CBšŽm#µÌzċûçKkŽ,”§5›qı:lBŽ6Ĝ9ô‚ô–żŒFÒ7[Ĵ ĥ)ËïFt´š/­äÛGVC_$—;Ĥ=Á$éŠċx,°=^ĉlÏÏ[Ú?´.>[›ôd–Ê şĤq›Ê'rÒĈ“Ŝè£ĊFúû"c5¸ìs.HGÈG¨z8ù`éD žoòTuŸ¨&ácXĤ¨Sĝ!â7¨ú(À—câ(âĠˆMDžóa*BJ@żŜèż²áı Ÿ‡‰+ÓM?x!ÈDİ]f|Í6qQ…Zby²ü ı€žfiLèLñÙ½c½Ú _ ü$6&cĵtC‰ŽD–¨&–a?” .ŬP¨#Kß>Iž\e(‹Ë֑ĊdhAoĞ"³Ĉ„ ƒŜ‰LMè›ċ²·‘Ŝ3à€Ŝ{<>ڄµÇèŭ¤WËR* Ħ—‘hó6N"”Ŭ4™Ż9ız'Ħ·z[ĝş‚Ĥö½"/Ûk#ßvbİ|ëŜı2˘ ħsĥ<zìóu‰ÄŝsĴûdì3Ħ÷ìŠôıâħbc2ÇC;ĜŒ<­ĜzaI?3ôŞíœ½B¤ßuS™ħ7ì—ċİUF²”rirĝ9x-˘³cžUCzQIßĝÖ]³ä%C³`ÉJwÎÍĴħ~ÁAkÒoVÒ7M–×iÚ=ŠÂŬÖäoNBRž.Ÿßa½k¤şĴ†zĦÏ$·ÑŒß\7‰è ƒxl6áíâNKè}sêL› +'ÀüXĞ %ï•Vàħ{„ŝì3À>AŠÓ€Ŝ9™ğòñ ?M( ‹mыFŝ~ +$áñóħO˘’5$òHU?DÇ *}ĜĝfIÈ5:"Nzİ}ȆĞ2›5™è<-Ʌż zġ`ctpşô܂ž+Ò'•P„ßsĠÎ/ĦDWšZmúE ÓҔC ôvóD”,VU +}8QÚTp’:è}]U{‰ö…à#d1™Ú ı M.ž´KÙ ÙZ(+ïħ†>h`[| ĥO<ž¤*ŻÍt~ ?—‹ÊOôÈÒĥ“žAEéîÙ¤÷›,ĞĊl,/èž&+˜‰óK(’m˜%Ğ:ĵ|“lË>Eò´-† ­ĊF&j>0< ·à£7Žƒ^WÙĉÊIҍ•|FŬ$!şf ñ0ğ úĜfC/¤ĵÛôÙBŸ"ž?DKŽèĥá÷öÙ`QpN0— ÏUZudéám8· úğ  úĤ Ÿ!Ú;y;,áµAzXÙ$è%Ìוĉağƒŝ7°Ċ-;g‚Ö³ĵlÏ,yv·%ôïże +s zĤĝÄR}£'=ô ċğħTŸÄôŒ&S˜+L<ö ›µĦ÷ĝTìkA‚ +IÄ·žè ƒŻ#ïĈ?úÎáz€žş˜U¨³ĈqaC6èĠ2A)ê\hĤ&è4Ĉŭ"%‹V…üz!Agt@ôàArĥßÄ2]˘+Ó4™MĞ0€^j +çTDş_ ZVÜÖs¤eGlˆŽ\XЇ})é5Ċs2ò:tûŬÔjŭ"Uc#T‰Vö“lp’-ÓùĈçqú‰@l:Éeqy:¤ï”œwƒ ÉÁGĤXž‹sÂü6 bÏ 5ƒc~ünZ“ äB QB|TfĞé)Äñr;C˘É’ƒó¸Œ:˘ñ´İd˘,µÂˆè)aÛEâo2ĥè3 s(§ÙŒôtƒžUFıĦĵ¨gşĴ¨Û +úI_$žŻ0/A·úaŜ€ž‹”èCtN…÷It@ïÛ!èç‘^Ȃ6Ò÷ĥñï=Żm@‡4­ĜÊ#6 ³ Z"×Ág’Mèm,賄Uҏ‰m ´(@‹4\Ĉ4Ò°/Ç×ۗĝ~”e“‹ġc£lÈ4] żr {|bĦô+HĈ6›ZmH4á{)EzԆœñLö}  =ú…xŽaLz÷Aƒ,ĦX4ġhì˙˜˜àÚÀ| ĤŠx/p|ŭ_Ĵ½\UÛş6>ğÌ-vw' Ұ֚µ +ĊÀ•îîî;À•‘îFBÊŜá>çÌ˙xîsÏwïŭßïÜßïƒßÜÀZl™sŽwĵïóĵcÌ灞Ùċqϔ˘sxşÏ-Ä 7âù†Ŝƒ\ĜFè÷x=ónülÖ*öÏ[Ÿ‡<ë5™µ‰›Íz?ZÍÄ5ìcCŜneOLÖAž6“Y‡Ê‰ï†än€gÍñ½sÏXÏóƒ.ÖN?ËÓ_Z˘qµDġ ÍGħmô\İëĠĞ ï0FÇeAS + ‘żE„rÄĤtb/{ÏEü,'GÀAĝ™V4Ŝ# YŸÏ†çpហùuXžqšÏ³bmÈQ0^ç|Ĥ½AÎúċW&à3g”³ &#,| +î›À\4!ħ-âéì ğħ Ñ‡=†@WĈq\74F€Ó{y<àOħ× à3àÁzé0§0W@\a¤Ñ :֒K[‚ĥU°èRÏ Öżĵ6 çZT³Àócˆ{”³‡ġŭ²–²Áy„XÛÙ} +Ö€|úr+“Ñ}ˆÍi7 ĥaQĴcî95Ö=ï: <½Għq ¸ r'ÔkşnAŸBżıúB^“İ6c0L`:ü"0.°O\€µĞĈ휣á÷ŻĴïzÁc +}Ĉy<Ì5ˆMœcÑ\߇ݍ.h¨i0î#ĞQÀŸÁ§vxŝ\ Q-`MeX3§ñ·Y”S ˙‚3˘ü!]°Š’Csi hŭÑÇíǒˆW N£Ï7$ „&#°N%zrsĊîQÛÑ E |´IÑ9YúM@ÊÔz4ÌCÑù‘xŽĦ }KȝˆïÄġ×y÷IàÁ}ÀÈÀ;P­ŝ0ÎU mŝrÖMÍàŒˆ‚Ĥ}½]‡ı3À'oŭŞM…UlŸ˜ÇÀôĝRì‹ +ŝ. #G=ZË\¸2juŭm\Ü +ñèœ˘^VbToĦ÷$uŠ_Xò7h#>Flè·îÍj”Ħ– +Z1 İ‹ùşçtĊŜ>×Wbŝëż@우p,ô Ċ6rëaFû9/{-Ħ’*÷a/KÓ Ÿ‰ġ$öİ@ç&µ‰ÖäE÷F|1Z´q‡ÁóĉŒ,è Q…™qx˜/˘c6`MHâ•ŝ“ŻÛM€~ î˘\Ĉzf-Á=BànÇ,ǀĥ7ÄĤúx?=&¨ˆ§éÚ˘MR*ëƒ:hèŝċ1Áš:Ž19?8|t¨[ğhı‘~kSb‡X tš!şĤ,MWĴí ½¸_. XŻó§–ßd‘5âu@ĊşX|}p,87Ĵ é·@蕽 qçU˜7; ñÖ´š{ Àù ×ĝŬ\ œ^èŸğr"[²ƒ ~µñì1í6•Bü9n=ë@ş§-|Âğ8Ĉ5i1]ĵ|jŸ{+hó€ÉPÓ w-:ƒ¸·KÎ"ĦSŽÔiÌ%QM]4O£ƒŻD5´Ĝb Yœ_*q\ġQbƒ +xĈ€<ŝ •Žç5ŞkLŞ]1Ż·3‘X;[›Xy3oKÁĠx{˙âë€y¤èž_Ç^fhΟĥu9Q†<Ü(rKRğ$/DáşSì|ÖóĈ endstream endobj 37 0 obj <>stream +RÖïÁêáü…ŝ>hóf´ ­4X?Àq#Àĝ+Ö3ĵğĉ,ΐ;ĦŝF@ĵ\а ÖúGï?Çż×€+ĝbîGœvœxû4XxM•žBsàĝ™Q˜·a‰Lv£6—ÁcBBèë‹ S°žcZâĥ§€ÓO‰9à1×&ŭËcÂÔnì°Nĉó­÷+Dğ°Ö#EœzžnY‹ħż‹Îj6£Êö0ĦyÀ~ô”Y߇ĞɘšàC5ĴŸ´úUxp7Âë°f9Jâĉ7ʙ›ĊÚvàĞll…×ÜÀSD˜Ñ¤AWf·Ċz´(äĜ€½'ÎϜġž„û=₣—GéñMGhŞÒó”mê„홀}|4wi4çÁ úI°gpxB‚ßp"è1 ×GƒV0p ĵĈŭK„ݘ¸Ş½"ż'ëħŸşgt|Ù2£U™ŒŻĜĊOkÙ8 z—úoëŞk` âê|êŸ +`íJWOBh‹p|ÂßÂ^Q—4½ˆ{3°vħ‰y5èkż8zX"à÷(ß@´÷€‡€ž­Ä;{è°âµòÓ½.ɕŒċX˙úrĴaŬâ‹c1@s <‡ ˙):‹âĊäĴçdÜ?ƒÚx{Ğàŭıá½,ä)GAµúÎĜGŭ²˙tòˆùHĜ‚=(Îğŝ‡ÇDJŠ(­Vƒĥ‘˙ËcB ½ ‹cúĥ³ßƒÇŒĜé_=&܆=&P(n¤Vˆ³Ë=7÷œ“wÄ>hA˙_÷›Kqܝġ™ yĵWɔ%:K™}µ ÷û-=§PWğx˙à9°>|¸eá7ò"ĝ‘R§‰ƒğµˆûàÉ +½Vŝ ‹‘`è›Áü;€ħV-WT3Ħ_>xĜÓzÀËÁ<PÍLu8/è_Â}Á:Ħm*‚[ŭhNmm˜Ó}qpi–OGà˙ i=&4iB[‹"Ĝvcàċò5îOż<ĈŻk˜œ…żšš‚{%:…êĝ➵›@ğˆóĈa·‰b_íĊy0'ô:Áó+ìéf&êċvÀ™ ğc +ıŽzĵyXż4h6^Gu‹W€uTĴ÷–·‰ÍlÔ]ÈÛ°†"µBıÜ+eİ(­ê$³‰/ÚİGgtİ‘ñĠ;ħÇš'Ĵύċd\ö˜ cËva ğaż…–!Ħ+:+>Kà;}(ì³íżĵ[°Ç„˰DŽĝ_=&Ì˙ò˜°MD'e0Ŝ…5aTçéĜò=ltÉ.áNÜ3½ħòĉœ6‘òbÛ+˜”΃ìĠ^M*uPúÒ"×ëK„ö óèĴ.5oœ´´/Áŝ0t`ïÍsîSñëYÀËĦ\ĝ/x‚ŝƒšĜôòXÉYŻ)àkŸ WK‡żÛĈ:\OžöœşÔ…àİŸ<ñ uU=BYEP7 ôĜ“x=p'\Ğúµ ‡=,>~F£1Ÿ|¸ö|AŒÒÇ-G³ˆKµ‹SÊĠ™°ÂmbTÛpïŬ:`&^˙ƒ½N ›Ĥ@&×ìcÓ;5°ÇDpîZˆòŸV?=&.Œ•`‰[ëA£_|ÁkôÖĝh>Q°÷aM‰}Ì< ì…ÜxìòèµñH Á>5R|)xÖĥ‡=îK!WAĵâ<zŞÑùğ„a;¤Î) +0ž/ +È)bϤĊ ‘,ˆy²‘ıÑŞ'ĵÚ˘ ^U8×Ĉ•+J²+yÂ䪃lTŝvÈ Lvƒ&h:Cïï}TߜUÀ€šŬ_ ö˜¨ß/ÌèÑeµëQÙêäĠf%öJÖRXĦŽ;Œ·Mžt÷—ÇßĵWŒxä) ĝAŜZ/q ™ë;ŞeÂà›k…ĦÏĥŠ}oŻÁ8ŞxoÊ÷0VtBÉ^ab• +›RB§T(ÁĝBï™+Ü k7"Ëö¸µœLhÜC…mdä.§Ÿ­Ċ9Êïŝ*°d|Ż/L‡ħ9ĴCŜ˙·ÌlLù^6ĦZ 8m%ĵÖë÷àùXöíĦ˜F½Ĝ)J;ÄdwhIîĠKnĥ +逧khëyÚ2d:yÎo2ĴAMÌG0F# Pœa@óe1ä5!šß‹‚ġ"=MŠ€ß>-J|Ĵ—z\]†ñÌyßi°_|)D‰*Âà‚-x?Ĵفoéϵ^ê˙U2ĤpŝxxLˆ­£qz°çHê³Hr%m™Ä?wìéĈ4É pïú@½Ĥáğ}Ô\งšğ<Ĥà5+Żé‡ŜŠ$FUSşo˜³£úmû;îĴ–xĤ/ƒž=öĞÄë~ÓĦžl`Î*ĉzŽEÍé“r3„ÔR×&ÀSïeK-;(ɨÓ^­Ġ$“ +vbOHàŽ(ÙZû }×#ÀŻ +aè˙ûb Îf"ë˘d âĤ‡‹o4QäĠe˜_sĈ=máúDúê|T^g|žŻĈÖ30òÏ\ =/ħ[üBì1á>ì1!Šz´|$°?ÂŝKÄ\R°ŸâİX£½Ï&W+³İuޘŸ¤´(š ĝOöĝäÍ˙§O^Z·*ìûÑċÑZäxŸAâBìk€żZëħ•J˘Ôfu:¤h܈ĵ&^=°– +ziPGŬŞ£ŒŸĵ:+yTs„—óAĉ”żžħJ’-}àšÀ—:ù€İ8;%.mv:µMâ]áA̓ÚĜŻ”'BġĠyñû R¨#àIjf9òğäœ?ŜW,r ›ġ•aíö–ÁžT… Í웷Fâœħք˙b_7X£„ġ4–°W rà[¸MÁ½ŝD–áˆG__* +~²òöns{ CüĠ?k?Cì²Ö¸Ż}iB!ğ:$ÌN½(Ĝïcx9XŜÈÂyŠĜÖOkê˙ô„„ħ%³ZJ–5*,ĥfîµ `JGS@@mÂ| z;à p5ĝÜÒiŞàÛI'7)²á…ÛEŜwW‰<²–`^Xó· “‡sÖ}^ƒŭ +ñWĵ.䞸üOâÊv€OuÚmàú*ì%…ê?ì;O#ìğäqc ì?BÖ.BÇÀ³ġBûäy€›1­êĴßġĜÒŭĈbŸĤĴ"gRöa³ ×{ah›ÈYü£–£`ÍLˆj9à(Qz³–aEè=‘Âc2°pö€DuüÑÀ+ú™Ĵ‡˜´ŜІ{àà%ôpîS |ĞB‡°á=ÀS³#ž÷èÂ^F˙Üuàa€÷ÁzĴ£4 +Öİ`}ֆ G{ÄnÉ +x_9ĝAÀxù u9p}úÂĵGĠCà5X÷rpF8ìĉ—ôj%. Ä×Wŝ^žĞàS’·|—Eİ×䒈 ½·žLĞÙOĈ—í ½o.£­#gÁžˆa#ô3öÊߊ½ˆìCäA‹˙ÛàÏŭßğؘ—ÛȨüM¸ožTg½'CûVú=X ŝâŸĞñž>Ĝ{aîxŬ^F÷föë=ĴÀûkÀ p™Wö2Ä6/ Ö߇Œxš‹Ûżàıë¨À)wÛFˁ÷ô‡"|XÔRŽ’£-L/pàIàYJžDXÚ9KATşp‡>m>Íg]'áġxÉ)YŒÎĜN£zˆġċñ~ 7ÜïĊx+ôR½n­À|# w öBq}àhü½aŻ޳ÀoÀ›Ċ‡80o“È/wŒ-ĴYZ=ö˘€>&Ĵ_BżöĝBŸß-s1î Áš)ʽx-zX˙!œÁ^2 çQ\‚µfˆÑà‡ħ˙ôÓaË=u ö;ƒ|òdĞ(ôÁ&àqŭĸ…à+Ïdż×$ÓZÁRx1p:sÖaœ3Â1ûÀGV5íbÈL|­p=ˆ@ìB~Ŝ6…ò)™R­}|MNèÜÀO>ĊOĜ‹­ĜW;ÁZôÚ*àl°? ünèŒĥƒdV› +ôB÷Ğ Y·tĜg½2Ħb—0àċ&ܗFsöëßĈ8×˙ĉJX+Ĉ~ï owAn€Ĝ†ç=`żú7Ö +½nâŭ²°ëĵӀŭ8tdÑV:ğWCX·Kx!`erž"Ĵ]|zŬY)²Kœ‡½^lÂgCŻ́exÈ>?7‚×ŝ/‡ÎÄŜ(ż‰}­Âµóĝùĝ}3· ìI|à=ê'œÇ^è£ Oïİ79;zK|³²3&Ï8Œ'Y_r=aS0!›éèŠ0ÀÏ ñz>Êħ€‹ao.ö´ƒġ2ğ 9Š‚})lpŝĤá{9j*>gĜƒä˙t=Qıĵh1ŸGıâö‰ş%/Áĵ?ĝˆ N,òÎ[kŠŭ€ĞKÁcK웷Ž /ڎ1+à0ë0y|à}rÖ`}aT/q^pNúâ… ÉßŜ^¸‰âŬוà7 +>=àqžetĝ“Íx î·ú2Ü„5!Xw„žħGÊBŒŸP=£R*öÓ1/ĥáuгž“Á; ÖùEA÷6@? Íß­Ĝ>ĥh;ö ÏŬy™ŠCy×:T½³PÍħ +cZ­˙!ß;ĞpíÏì:$ÈhVdd.‚ß…ŝĦ İu/ĴIÑÁE›€żñ5ğ„™mştfï!*ħi/Žû ‡à!·JĴ܃jÖvȰŽŠĝñVèy‹<-…ü5Gìs úpoġġ&}*Ħr7íı{G@Żêä™Q¸Ŝ'LZ÷*µW‰ -Û÷ò#ìaeBßlĦ/GÎdlg³ž×—İD-:෎û\pXó< ŭ×Ğ +°ÈwŸUqħXì˜öa/!ü€=ɐƒsŽxĥc× +ĴÛÍĊŒî*2 +ŭ]ÀĴÖħr¤eè4Ê>i6풳Œ(ßB^˙tˆÙŻËżŝUUûC—zġ͐*ĝx˜Î`ékŸ´ÈĴOİÌAUöv_ü´ċ˜äUƒ…ĝuóĉQ—˜ÉèUgcŜî1ĵ’´LzÚvô%ŜUtÏÀCÍÓÂÀgٔféµÊ8ğRt8­’4N-ç‰bKħßħeLİCÇÀ+İÄÚ½Ÿ½Ĝû2¨¤Ú½à%„9'ÂölÖ{m&ûƒ“ÖŻÊ$w€u8À˙çı´VE_=Ŭñš–÷µPqżó¨ġhàƒlhÉv¨Ħ‡D•íù§*xöC@½ü&!‹7Ĥ ż™ +Ŝŭí0ż’3ĦÛżĜ {ß{1mŸèŞlQ˙)¸wÒÊrWqUƒEŸ)ŭdPD?‹_4ž’>­?mxŻÖDšQǓÄרJ’1)-QîÙJ?]Ë$µ+‰Żĥ]m DIj"ż§ë+ı&,–ĜÍ1:ï9Ŭ-s™0 ֎óħ˙ĝ‚Â:ÔGĉF§ssÀ€Íí`ÙÜ6!ûĴó°èi1a~‡İèz'Ee ŞQ‰{ŬJìN{݃a’÷ġÈğ_u™› ¨ğƒìŬNš×gµ‰D÷[Ċ’ĵş#FùçEЍ˜ôN5AJŭ^2½GJsL덗côĠn5aFğ&Ĵ× +³;!6u×ê(éÍ*!“Q§Fĥ(AîcÓPŝKjQ„5 2í½"™ùá?gè }­_ƒÙ£CŜÔĤn}ÔĦî|ÔcHÙg}(ô²Ô‹öĠ‡˘ĵî˘ÛèïvPÂĵFİĝaëaöa›˜×̓3˙ÁWAîW]òÉgš-ĝxLPüw#òĊWĦ°ĵŬR\^mgôêíE£§oÏHîVK™k­:LÖ 876Ĵ`+Ô\W>˘ò?J„ı½6u@EıàġR#6İC…wĝ´Ĵ‰ċH´„µPÂb+éóJsѽ^CanŸT|ĞS$Én§$×iaZĞĤ(ĞW—ÍìĠd}Ż,ÖûŜ +:˘t;ö% +ĜĝEä…ĉyHé6Qz§Ĥ(í½ÚĞÂÏŝ˘,ˆĜĊK˙ĥ—ŭCQż˜#y-œ™àŸ—Ċġno²îËYŞġ‹Ó˙эî˙ĉ"* :òá~ÄɎ›1âÁ†@Qï{?iWcQwEÄñŽüICµşbúġׂŜ“âÒFéËĤs˘ğmé:#ĵŠÓ‡_X?*µ߯•’Y_T‰íğ…×ğùÒĵşì­>’Š­Ŭŭ?è ³ÚtQҗ^­ß>jx³V +|“NëTe!2şÔé;mŸ Šŝ8J½ŝf(xùEH}2f*zÌ%ċŜ’Îw>˘ê +;ĉù{cúî=¤A&wì#3>„ùÀÜï˘Ù‡bq^‹1{ż‰e²ÛµÈÌ.aVğžôQĠ1ˆoéÓ +3á6†Ŭc@_ïÒŜé Ċš…Ï:Œİ›_5ÉğuĜ[$•ÛÉ'ġPT~ż”.ĝz”}ÛkÎVtgŜġœeŞŜ_`ŞğÎQ/ĊL^µ‰zÑ'˘îżúÂû­Bş°ċÓĜf)ìnñ4x&j +´rĉĵ:Δjú|‘iì²a^÷r>iĦ¨†ÚFÏ^kš8—#\ +ġúUĵÚuĵëWĉvI$Ċ•—Lç_’Ä×Ğ1AÖòo}W'oÓĵü̐Oi~öoʂ˜íüÄoğEÉCÒĴ6Òĝ^ÍIiq‰µay‰ËáwĊnFeĥâu§$·[D˘ìNŒUöİO£QcÓ4&Ü.ĥğş@W·C÷Ğ>Yú̈́îûì$ŝô.@=2ôÍF:ĝĠ*²~;uŭ£ĵ&zŜdjĝ²ò˘4żÂ\š[uTr·ÉPú ĈÄn1ó¨CÌ>y/%Ÿġ°ìË6SQaÓYq~ñ“ö˘Ç&äŬï:äAƒê/û²ŬT\Ue'ŞŻu–ĥT{÷”„Ÿ|7ñtûġÄŬâŽöżŒ ÖúˆÛŞ›|xaׁc2ğÌ9ò^™Sdú;·(ó֔h ŠÛ£=ı‘':nĊHރÄ­ŝGş_F1MƒÖĵ×°Á%[ğ2Ù½Z¸ĉŜo“o üw½4ÌlH’;4لŞŭTôÛíÔµêâ—í§ ĞÊ]%ċUŽÂ'ŒYż„—n ƒŠ×ñ"Ŝm Ÿ‘’úr·ïŸ%ëy/í*½Żó4*żĜœ˜èQä^˜\ëY*i+ġ˘:.ĵpi +IñjôŽkrÎĴqŠÈsğYċŽ7ÒĞÒ7Ê˙o¤•wÔċĈ˜è†³>¸Óeg™çƒĈ’gM§$/›Ì%Ċµ—ÄϚN°÷ZiöFЁèc³/ˆ³fżv{n͉?×z5ÙĵġZÒéÖ[ɒZ_şô³ŻìoAŬdġßOê½áôuò95½´žmúW?î½mżxĝCiԑŜü(ĤíƒSÚ}†)ë´@ĝù„8£EŸÉyŻ-zP'­ê3)_UĊ׺iĉŝ7ZXŜuQÒ×(ìnódğßğKêCğ*CèÁÂϝҁ²P£êĤ­Ûž˙üw>ùì=)*Ĵ;%myç%¨ 6xáZ”ìßèzĦ5ëê‘îçQ’Ÿ£½ÏcŽ÷܍;Ös+Úş-<&¸Ö=ê^}DI½uhQ“UÈĞfАbôµ Á:¤ Ŝ:äY]x.šwİĠ.Qé.QɕQžĠŝ1ÒO…AzċœP?´l˙§,ĵ?(ç –Üï1·ž3*+u3j* 0î, ½iĥdސŭ*âìĝQÇQIqóEqŞÉ/ż˜Hêê=üĞüRj#RÛK"„ífäß5ù‰;ר1OúD–fWËĉä”Sí·’ŒúJP.,ˆ6ê/ m >қeÓ•˜PïSï–hŜ–•,xÌv5¸œèşï֐àŜèWïq³Ĉ> ŽğĠöáÑ8½Ĵ°‹È/uŠ}Vêu·Ì1"ĥÜ=òdgN¤èc›ż°³ĊSZ[sEXĜqZ\Vo%z×d%ĴµƒıQzĊµ_”oo´[eHĴsMHlRİ{Œ_"ŬŭÁÙà5Çç5s'£üXá[â^âe߉â+))¤Ê;é$:7jpÈIç §£÷šÓ´~·€ûtóÔàš€œ€ÚÀóö[ĤŬıÑlS°²â‚[}H&Œ/ĞmoÖ:„§W:‡ßг /i² +Mmrˆ>Ö{7†úµ×E˙w ˙§yßıKä÷ONFO‚jÂcŭнcâËÜ"3KÜ#íŞ#£-“#Ï5ĤDŸl͎~(2é}!ù,yß im÷>úġuóïZÂçż5i)<ג•zĥ5;áĜûğ1‡û^Dù,Zĝħӛü›5Ó×ë*úVxĴëv”I˙£ƒNÎÌ uèŭÖöX×ŭX—Ĉk† Wô^qZşYßĥéú=Y¨k4]Ï!iĤnrË&ƒÊ?DT_·ƒY÷µĜf·Ĝ¸Z×(Ӟ[żqtş9CíœXk€“hġsBÍŽÑâL rç ~p–ì·ö{ùċ‹£N'֎lYĦ˙€S§Ŝü8".mµ1Ş­ñ9Ùv/ÑĦ62%²Ò+1³Â5ÖĤ96UÒ[í/llvf:mE Ġ.’Ĥ sMIN5á‰6Ġħ 7‹Ü˘½q +·jŒC9ûyĴt 2̤·(Ú´'7ĉbkRŞ_ƒoŞs]XâݎĴĉ÷ž+tW—ƒ°·ċÎÊ0ÓŜĵ˜ÓÙq[ccc]c=ü„ŸZ}ݞÏvT×7[^=g˘[ÂéjŬÚ;[+(gF)§Ìëŝ~Fôku W•_LZİkŞ{7K\#<ËŭO·d„›vŬgŬÙĈ6ÌĞOGQ?Ĉ6w9žèĵï^˜xŻĜ9âċ;ûÜb—¨;o\˙ëñôSDú[÷è£Ŭ¨Ĉö—„A}ġ­ò‹}úÖ1˘°Ô>4ċĴ²jëàĦ–KÑQ‚r{ƒ_ŒàNmÏà;gyĴûVÔĠ&ǘ’–Ë!Ošl#r›l#ƒZ<“Eß+DßĞŭĦG~ğ¨ġœSÒµš˘~Ü\ö Ñ™}|1ħó€&ħu÷~bûÄĉíÊÄĈ­ûˆuەˆÛġEÒa„ŞŬ“iŞY[ÖÀİQ_:ËCÓ_zEŬ|íVä[à•VäRè}a‡³ÍYħÂ>†=UaÇ;îĈ"\RúĈ36ŭkT ѕħ€óĝÍ73üXš^ċġċ·gÍVĦwÚ­BîtZ…ħ?šĵur>mÓ³Š˜Ş˘%"ÖÌW ”#rÄ|b1 +èûĠcçĉ.#b;uİĞìî½4ħ|Ú|b1ŭÖb’Ĵ1Uf.1{¤1ìrBaĈzbñü­ÄŞUŠÄ6}sâ€wĠĴC/¸=:5œPŭ§%ġ†;"|óÙܨëmDö÷˜˘7aoJ +ËmCŸuOŞtŽ.÷ŒġŞöOt­NHzsİkDÜÛ+1aïĵ˘÷= ğ~½L÷÷ıĜ5‡ĈÔµ\nlğ„ĉP<ù£ßU³‰Ó;”óëúC7ĤkZgLĠqĵ'§VA3çËFÜżoÓ|Èí֌iXÄ;A,UĜ@,ž½„P[Ša1‰˜@L$ĈÑ1ŭ$OÌ$dgKg(vûBe•.?Ÿ¨?´@­…S×˙áŭÊYĵġġĝ ›‡ÜD-½žâŜN˙ïoĊ\İ ˆ‹™Vèq½Ĝ-ċĊÈÌ"¨ÇŽŻßه]-uDù8âyħSÄë"§°˘waİQ‘Užq­­¸ó/ÖIżöŸ÷?Ġ•Ĥû;gv°˜ÛĤâŝzĈ>ħġˆMğUˆËˆµëVŞĈ2×ä4Ŭ2gޞ°‘]ĥP˜JL&ĈcˆQÄHü9 +]—,úAÈüüy$ze"şêñè·F£ŸdñkÑç/“V7‹ˆ=”ŸÌÁ;Üa‰[DDìsżÈˆBŸˆèBŸÈè·W"c‹ĵ˘Ò‹<"ŻşGŜ+p|Qè‘Wèŝĝ•Kĝ]47ï”:G<(qŠ|Snĉ]íÏ~íò~nô!ŭärİ-:ĉU+ŞÁí—B˘[œ˘ġpşû O+çĴDq8?œÛtV2ĝ*`l& ÎtñŝŝÁWż w`1fÄ4ôu21Zf2úi1{ÚZbŭĥ#ÄAÏ9Ŝ ŞCœ#ÊQGĊŭ­ŝfm×c³ Ü#‹ +Â2߸EfżuD9&,żÄ!Ô½*0Öĝ“Š 8ˆÍGĊŽáwß:EĖzDšudE +mógoöulŠĞyoÖê÷;wú`Ôëù[öi +gĦk‹Ï4:Cĝ~şĤ™(âĤ£ïàû˙ċjŝóÇ|u˙zŬ#'ŒŬxôïÍBsqÍŝS„’oû,Ġ›ÜjŬAî8ÛġÁSÚYhÒö<üD[NÔċşĜXĞú¨˜WŻ–E1 c[ì˜ûÊ=êe‘7ȏ #›J£ğ*ìĊKŭżgŞŬĊħúŭÜ)ŝwÎZ§ĥ[ה˜†Fè˙ġ\£ÌÏ;˙ġóžÉYF,^ĴKĴWğLìwİ™˘Ú˘>UĜZ–%%ĵôşóÚ=úiĦsԓט'%NqŜ:EçşDżt~UàüÖ'Â*$&¨Ü':°Ò+*³ +ñJ‡ˆ›ċNáIċîQĵݜÚ+nğŞçí™ÊĤ62Öo'fËLÁ18ŸĊ˙s2ĝŝËâ8…Ż˙ù†#q4z ž{ópŝ^‹>' Ĵ:‰˜MLµ”˜'XınjĜnœ&£ÖÈİ‘ŸğŒ{䔸„–úFjˌ>lŜ”¸ x%Â^‘>èĞM]dô‰Žœx=çsx%ÂìuVĦX×*$ħŜ%Ö¤?7á ħòċ1 ĉÌŝ˙½÷#ÑñŻ×ú×kp½²?ßîÑĝΌGwh<úœ‚gïpFÎA²?ŻužrS7Ğw™ğOŜv“['èċĴŽĥŬ9WñĈÇáÙĤÔÈşׄwEÎÑ h KœZŠ]“[Ŝ9%ÔU8Dżzâ3êI‘KTB‰g”Ö'Ù¤(!fMšçÖ—ŝ·]ç÷×4î瘎FŸcñġOAŸ¨&NßJ,Z! V)]"ĥˆGìËäè|ĉL6ŬòJzáu;ß#:˙µkì›B—„ŠBהòR§¤çE.ħyEΑ)E•á‘p¸VF˘ú]íq¤çv°f9§µfĊĉ˙ġu gCY|β˙2Ĥ#~7½;}N1›˜%ğ€˜2BÓ ”“ĉĦż˜1j1eäRb²ìbÚ¸µÄlıCÄjEgb÷ñ×£” ı l_Ħ#Â-¨@Mˆt ‰,÷7Ì<Ġ’rLäS”+SP\˜ü*Ê­Eö­-—o"ÎiĠó;Ş–ö~ùM 1[vò˙elˆ˙’+áçżêÌÓI(+Á5ɏ]F̞ĵ…˜;s71gĈNB~ÖBnú6bĉ¤ÄÌ1ˆéÖÓáûñ›ı‰è÷䔉›; ³eĉp+ġş¸ĤÍ·N×\ lvï…GdŞ}íĊn魅o]RûŜş_ŭPá’1PíœŜWç˜ÒZmŸP^î˜ĵë@%·}Šì˙›üĝW„ëœ%?J˜6Rŭ4"T~T?eĉĦ\²˜5r%1cÌZbĈ¸uÄ̉›‰Ùó‹V"ì§ĉDlf“GlĤÊìñïĤó…3övŒ}éy˙ٕ¸·.ħEÎħ•Ċ. •eŽħo‹œb‹‹cï½uŽ,Dùôċ[Ç(x=êG„J§ĵzƒò˙úZŝʛ#ĈÌ>ĉç÷cq÷óûİhċG-&ĉ˘qš7c+1_n+1gŝ~bŜ2UbÁ}bÎ>1gİ>!?O•˜µHƒ˜ż‚!Öi…{Ú&)½á6ˆßżp {‰qKħwä"ç„͢bJŬ#Όîq§á„ĊŜ½sˆĴ/vŠ,.qŒD×Ħŭ;ĵË,HfɖŬ¨ĥNŭ·Ż òäXœFâï‡sàÑÈb–ÌlbÎĝ•Äœiˆy³÷ËÖIˆ;Ï‹·š˘Œ˜·ZDÌ[L³—“Äì…zÄ,yUbîÜCĝ½ ĵhbŻcŭ$Ġ÷œşn?wÔ¤ùŜóÊԀ„g~‘eÏŬ_ğ%”ş& ûşÄ!â}™cÌ`•}Ì@mì`½}b]™c`RÍœdÉ6ƒ˙Ġ˜ÁùOÁmÊOô8\ó`î ż7 ½;=‡˜7a1gâjB~úz”›WrÓÖĦù·‹˜3}/!?c/1sĈ~|móW󗈉ĊNĞ4}ˆ­GîÉî +ê™Ĥ”Ë­•QLês7 ĥ›‹8ËtŭˆUl<ħŠJ"6™<•ÙüÛ,ĊrnŬWzùRQr°{qX˜oq@ĝ;„½jµ=|çġĠ¸òR‡¨Žr‡˜žJ‡ĜŽ*ûĜ‚b§è µñáŞo¸=sĤÌŭ·ÇíŻùù*ĠLYyB~ô"tMsQ<ÎDŻOB{ò{2ó ùq+Q>Dc7aʛ[‰yrû‰…‹IbÉ3bù~+bİš ħLĊ™X¨hM,Pµ!~Qµ%Vò‰†2ğ|Ú§(=áVé pDž=ĊŽçK“Ü +ÂCŸ=ôNĴyî‘ÜÚ#½ À9 +8CP…OĴes|l⠍v¸)úĝòŠÒnٜ9ŝíZ>c-Àˆ¨zDµl‚ÊŭKù‘‹Qž_ˆ"rŽÍèsĤŒşEÄì KˆĦ܈ŽİĞ ı™(˙/Ñ$Ö +ëM‰E›NK÷9Ku‰EšŝÄ:ÓÛ2;<ë'ìżÍ-Viâ”>-é|áqĥ6-(äU@äíîUŻ\˘ѵ•8…=-³_còİŜ6~ Ġ6ı˘Ö>1İÌ-ÜàGïĊu"Ğ˙ë˜ cà˙ĝùŻ\2Œ…ÇĦњ€ĉÚL4†s1SöB~Ê&"~Q&)h ëP"ĉ,TAıB‘›òÇì(g˘y†ĉÚü9{‰ys÷ 䕈ù‹ġˆ+hbñĉÄJUb½ …Ĝp<µ˘Â&¸żÊ:$Ô=òP?GmÒĥĝŻm4žI¸6O%äqŝ˜€1˙ü0ä˙£ 2ÍGybú(8ˆ™“×siK>ĥx1r_H˙Ĵ}×ı…ŠÏ¸•€'s+ö&˙mÎîˆ;ƒ{Ĥír˜¸ëòħû|+§)çqĞÖsÊŸ¸súŸ¸³Â/%žĈŭ‚Î5ÇGŸNXó1p×"ç¨çoÂËËìÂZŜÙGV9%Ġ½sŒ#ż´ĜĞ8½›9òûż›~ÖrˆO@Ĉòcĉó§­'ŻÑ"Öİ[+)kb…i(ħÖ>oä:Ÿ7£7û·ĊŭÍĜ —ŸŒÜà?j›gĊĝm~­·ù4NÜĉvìvĞ‚1ğŬĞ&xÌ­;PÏíUĵÉ-Q +l•SÉáV¨×sêZœ@ğƒi·pBŝwùRmL8`¸l„ŞCcôh}BCçz’-B*÷‹@Ïŭö\EáKVìûâRäġYòÏV"äŞò+ġ‰,ˆġ¤'ħ–ĵBl…[ÌËîĴ›ĵ÷·@1O5·í@5· òß˙†iÛOdÉnù[‘#v>jŸsùäŭ>m3”cÎ?ĝ˜ÛŒÉ!­_9#ŜĦ‹ì—7­^NxÈżlvdËJŭà’•Ô½?ġ…e½DÏż§n˙İ+H˙›2›óÑïĈìÓÏĈÂÜ>‰ôqí qaÛ9Ĝï¤[Â(‰ŭegÊŝÏuú!0ÓĤ]„°ŝfâħhħdÇ)bıš5ħŽçAĴ=dIĴßw‚X³•"VĴU%VT#ÖnÛI˙;/<³ËĤdü´ż/VĞáT48>ΘüòŬÑ´óf¨èóÛ+üoßĴŸĜjµqìĦĴßÖj&÷ĴĠşÁmĠ)çôġÊ8šWĊ šϲÍġöìûZ—#}Ï˘Mz^F‰>vúÓġƒVĵwœDPŭ$ÛŬîîVœXUnì^­’4´hħÂö#.e€µ!ìĉşÎ–óĉm'–m1 6ĞŸ&vîÄ.ʞĜs*qä°·Ó‹ıĠj?8ž>7t^ôéİ3ù[•­Á?žüQkÍû³ĊJ÷î¤ÚwNOŭ3ÇÓúÎI´żrG˜O=î:=œÑĦ€ÂùZ§Çİ›ŽÖ.â4ùÜŬœ?wê;]ŸÍÈ]Îf7âŽuŬ‰½œ–lÖy'QW_‡`Ž˜bB_lç4RÌÓ>ħ~Ú§mj–‰–ÚƒyÚ÷1Û/ò;ˆċëĝçz;NżµÓ·sòîNĊŜÎCŸ9Jû7îˆöî¨ĉwN| …Û­\ÁmQíċTuŝàŽ[ׇGäT8…ÇVıF8׆‹†^şBEĊžÚKn‡úCnëĦ +NMŻ…3ĉġp‚Á?íÄßjÙ/ï½trJş†f2Ê[všjŞD?bù1e›ÈkÉÄüíô½:QŜ[ħ¤˘Äθħ_ĝ¤Û˜M:ȄUí`Š70y-ŒqËKIoE€^9ÇlÚCŭ·×5ċĊ)²ó‰İcÓ'/BÖ˙á:]mħcÑ\b÷ÒyÄ^8VÍ%Ôì ÈĜ‚­˘W 'é§],?şpuÁo +ŜžÓŻ÷D›9Œ£MĴFƒ–Ĵ0ıKU˜Ò£Ĉ„ĉoĤS{TÄ7[XĤĤÇRTÒrŽÌüŭ új˙ŜWMŞhè(ŬĜwQŻ›;˘VĊ)+z—Mßu,]vçñì‘{gR6Ë£vùáU—'3e]G şÂ^§Ú²ïНÎNQ?Ĥg£~ú—z8Uƒk?ö\Š›ĥwŻħAa.ħyŜ¤ +ÏUvá3ġ.zMt˚ĉ?gż‰§ìÚ=$1k’1c,∇ܨG(;MUmáj~àêËGWjà7'ŜkŽ1¸Á)ë;ĈÍ48ŽîċEI‚§Ğ)÷”(Œ¤ÏxLMA%UBmÛBWQ•2fĝY!Ĵ皽ÄÈ*lĥPOBï ĵAğĊÏ'cË·‘y+ißğ+Ż{+D魚&Y56ş|7k4 žÁ ŭo­ Òşñu{ݐ§ë™U$9´ĝC­ż´ÂÏàĉߕ)óĝñċ[ȧCŒaKݏÑà›ö{“/˙gÍûğˆêٍ.ŽÔÈċvj\Ιޤw˜PĦß´–iîµVt]˘Ÿ|c˘§TÔ ôyĈ~FçÙJÒïÉJM„Ĝıl ħġB÷€2a$6‘=rÑqşéLJ-œĤJmgSIĊ{`ŸŻq£™×É#s>Ğó²{ö ¤- ŭr–·şô`_­àĈ75^LÇAÜÇԍżkó˘Ğ6Q6Iòäğq´mĝ,~jÓúĈ 6™3¨ĈKŞÚĈ }½J/­wğ~§Ĥ;¨›óc—öżo×ÎmU+ävĞpşšżrbġ!NG³‘ÓÖ~Ëiéä´ J9V/ŸÓÒzŞ sÖi´‰ıĴÁá³²šêÄĠ ‰;všzşuäÒhĉœÓDá0òcŸ:D÷–òÉX„ġ@|ҖKü䙳ĞèY‚”ú=drÛ>ÚóŞí7‡vŽš#@ıP’_yêpÙ OêE·XpċÎbmtÊÁRñ“ĥ#’êJWĜ)}û֖3Àç§´î˘=o,Ĥ-Ĥ üŸŻÔ/âxäÀEOı½jöOĤİšgWż”;EíBöDÜ6ŜGî2ìċUs&şÎYr‡´ U%tMŞ„Ê.EâÀ=„ÀÜvs½CW˜Ó¤O·( ,œĈëó<“Σ„„ôĴŭ$xıÚ ax³TŒŸuKU AF‹"Ì9Ò˙ú2ê‚÷dÒ:h:˜ğž?‘¤6é³lN³žäYĊ1Q^³D’Ûp˜Í¤;ö ’:÷2iCްçSôĥŝïöïjĵ´ŽŬd“Ġ‚°Gkĝıß´ Šŝ$uŞĤêäëvqĈhÜt4ns[t‚—j›¸ŽRTÔ#Ôġ%„ä²,ïbäTU-ħo‡ +ĦuHB¨+iJk·êû{ÑÏʨİëÊ{Şş_"DRYsĥ“\S—ğ_[ÏI\Cç3ŽìµmğĠÇE÷Ŝ‹ù×>Ğ˘ċ(÷ĞżÒ?* "J7‘—˘gÏúO\ŭSIRzıÛGg]läáyfÒûĈbÒ5a.ċ’2_àsw‰~JVŭğ?T U4ˆ+ߨ—1¸]÷Ú×]şı˖pzU“”üÑ~Ç=Ğsôœ˘fèg|ÛEċ Pħí[ôíbflf .…LÓĦ´}ħcÙJbßĈí„6šwÔ Çħ,héI.ùÌ-v2ìĊ*§GCtżN$|P/dïĥÒÂ[Í|:ğ_ƒ {¸ŽvŽŸÇZ‡ÍbRĉÑvñ(ßĈÏ!½ÒÂ<ä]P! ğŒDĊugɇŸyĵëßTĝYù× ~ Ù’v aAû)ŝġï|'Ӗ“IçŒùĵÄĈô‹RIk͕ŬĜîŭ|NO÷§ŞĠżVÇ1Oŝ€î B“ĥÑ½œ4Ġ —Sç<]+ĥá™ĜŽ]İO”QŜ­ŒĉßBáê˘ïTAV·2Ì]Öphf€n1sĜ|¤ô˘˙Lqà³-´ŞCTjı’ ­f?“Ñv4 ¤·k$üœ^êJĥí=›qO_ÏzÁóñĴwĈç1)~aĤéZĵEsfÒáÒWQfż.˙|-íŭbyuP™~Ü%ä§ĥïÜüĴNŜíĠĦî ì˙?öŜ2:ÊĴÛ÷­($!Bp îîN@ˆTĠOUbą¸ğw î†;tC7öĥÒhÓhğ½÷>gì{ÇŬwŭg5½ß3Î8cÜ/÷5F5tH%UÏ3×´µĉ˙WçÄċ´LÒfvŽ÷.ğ0ÓĞŝÓ^)ƒÜŒÉĉ\”™‡šnáĊ'š4Ó'wÔİspÙáİ™=bœf<Ğ›V8ÎìŜ²G³{óVÍA/Ò!öÒû™q†p ââĖŽQ‚"ĴxöYÁ1F;@wË—ç ÇfŽÂ̰4ôè€áÚŭġÂK#W˙ŝr}zçéUÚĦßvòEçgƒĠċ­F˜sÌV•kßR/4ۋëÈ5|°BÈïÎ§ÖŽKOͅv wŭ7Żk˙ħ×çâ?÷ú\ú÷=>§ŝħ]Wq~ĥĥìt]FÛx}tħî‹ĝcŜгùÌÖ'e×ĉs °{ĝÂl̕ê§Y{°<ÌŬË Ñ+IBnï4ġëÍbۋÍ†žé ]|ÎëÏüĉŠÙ.Ħíŝnà™ 7ôb7ĉĊyĉS„ÜÎibrí8>ız,ŸÖä¤?ĈâüŸwê:mô9ŭÛNŭ•ßĵı÷~4 +ïŝhàïüâ'}mwí7öüşò7S´gŝÇ..²Èî äoĉíkù-~ĝïn†›OÂ|ï}œgüün–pûƒ÷Ġ˙ÇU÷ÖyzU}ġV/éǵyƒSĵ+oÏÑĊ·ŒŬ½—Ġ k·hĥß­qÙĵ_sPh†9KmDħÍÚùË4sl4síÇi–Ž™ĤÙĈòäWı]³”ÚK+0“g8z}™Ôò`›oñİE²_´V/kDc¸%i‚…_4FÉo˜*ğFèŝxğûŝ–K/ŭ×µ>XĞğĝw7éÂÏĵnàċ6p„¸òÑà.ġ7—síOĥpOĥˆŭżì§µ^}aĦPÚ?‹;qwxpù•÷Vxï{ñWAüÛ? +,&nĉ +†§ë" +lĵĝpó}‚Ĉu§—Ĉ :÷Ħı#ù¸Ú1|fßèFñÁÙ#ĵ„Pĉ;˘Ìù# c™-Ì +Ĝ³úċ˜[NŝÙC,𸀋Èĥáâ +G ı=,ž_`ùàñ Bj“ÉGV_]Âu~ıEè~ħK8ó½‡xö;/~ĝ§½¤·}ŝGOáòO:ÌièğŸoĠ7ŜZĤ=ġÛNÌĦ–Ċ™oáŬߌşŝżlÓ6~ĵLÛûÏ-x˙|JÑh}tĤPqi~èÏ.ÜÀ_vA7“Ğĵ0Ÿ+ğO͚+5˜fk6Ì]ĦÙ²rµfϞ=·žš=ûYlcùħğ¤q÷4û]½4ûŬ½5ŜÑú”GhÂż`FZ‹úùsNË|dNü¸ïŻ—zžïá{_¸@³›‹Éµ*†çЧŸ{ÎŬW`ğbÙ)§e +4ħä3_é•kO òĠ—Şpîg/nèŻ{ıáìLßúhĦœW7™Ż˜£k˙t­pŝùĉ7şs˙sŸĥêÎB}ĠŬŜ=żléùu³ĝÌLïÀL+o9ÖÜ]hĉ}(ْ‹İu†eXoZµA³bĈ|͖uğ4ûv`~S§#Újé酆ÎO]•ĉ/·ƒğ:èjġF— !fNdÌúC÷E.9RfYM…‚ŽéúÎç[ĝ³ñàNŭĠ•Ż{g™˜Ö:Q`OèĊ‹I•Ž4“—Ġ2…ò›Ĉ?­"]ÁŠĞ‹¸c·Vò 7— Ċ§fñeççêßÎ]üÙS¸ĝ“7×˙Ŭ\é9Ë,ĵ„ĉZżTK.ĵÌÎÜ™ùç˜;hêéüR­ ³ŭGŝpŜH1ĞkŞXvu!wâĞġ°/hŝ²ĵb†W9š-sà#slıˆŒ‘Ž ÏÍÑ·?ŬD3Èuo-Ów}ħ ³•,ŝù=”Ż>5oߏ–ßr˜żĝ³ùó5"‹ŭúš·a6ókÂûßhOŭÓE—Ġ9Qß0FŸß7M7ôo;u'ۅ|‡Ùĉ.Ŭ?vA Lg…ž†—hN:--w×hğżÚÀg÷NññKħܵĠC³ué&͞-û™]j5ž:^£SÌġAĴĥŒÉĊǤÛjCâ,Á $—À$+>ÑI޸ħš>u5&5LPCRFú†¤Ú(R ı!$ĊĈ˜×;[l½ğZOĈ೚'òe³ıŜ§Û…îÇ;Ċá—î˜s•*O/„ž ßûÌE9óX'\xĠ ˙â˘=û÷]üÛż +ÊGÏ˘”[Ï‹g~ôÒ ?Ŭ)–Ís'qu—ëÏŭĊf—ßŝIĠ_üżXŬñxµ.İa,—ÔèÈġüĥ]ß÷ëŝĜ§kġċ—ĉñÙ“u%Wf듛Çı¸xj6,_ĞqŬv@Ž'X_:û“Ċ1Ȝ4?ŠI£SˆHÍT²Kĉ7Ċ†‹Ë„Ħo÷q½w·ÉI…c¤˜t;ı°y:ßxs…X{c9ßÄ~ßÉżîĠ ŝ°CÊm™*¤Ġ9IEç炵Á§×;‰éÇ'"NŠ9͓IS'ĠƒÉ,/˜)f7O&-ÉÔĈñ|tş ]`Gz;ċo-¤?kÇr!# 5×`Uşé֘“†ŜžT~m‘\ùÎr>Ĥ`”hĉİóĠÀžı¨|;)ğs*֋îÔ_wëÎŭĥüi7ôç½úîÛ¤ÒóóĦíĦï›ŬXƒößlÒ°ĉN~żOzuPĵĝR/ŭÊ ĵġRÒ ŝĉ"Ôĵµşsˆúĉ?­á.üz;÷77ŭħÏVsY=“ÑWÓ§ÇW2ŸÙóbríÑ&̏CÏڑ:•­µC‘\Zí8ôô½ßl›>Y…Œtß'³:ÈUsÀCÖHñċc¤ÒÙĤ” +úf²k9AJntÂ5ÖEdŽÔù&Xj˘,ÀìàÛîoĞš@JċÉĊRŬ;ĞĦ­½OÒ¸Îí íQÒÒfħB×úÑ]ï³­l=nŽż½Jlùp#ßqw‹Ü˙ÈŬpò+Ô÷ċ>Ħ˙Á^aĝçŭüù<ßúÊ_~VaüêBÌßûp;EşöTÏ²ŽObkw­pĉ—˜ĊċÏŝ§‡.ëää½ûxÍö ;4úȊQB÷ğÄĦÜ /ĈċöLї]ĞO<áˆ\Ôu˜­èېndñ|â1eސc+Çë!­i4ċÁUħÎxíÓùÜcta„C!ìëĊc ‰ÎŸŝĠ]7ĝ‹ ´Í¸ĉ'pĦEfÁêÊĜ!·kސÏâ,Ğ/Dĉ+„ŒĤ Rj“ql—Ëê£ÄšħBb­£P7VŽÊĊÇÙó,ƒ‹ nq@Ġ(s1Ŝ ó­\ßo.\ß7;Ħ!ċwÍ VQ5ĞsZ>Ŭĝxàò‚͍!1ħp44\„³ßŻ?SĠK_¤³_éP#@3½ÒŞ8³P,ér†ÖßôŜjhπ ³:‰?ġg7îÔ_öéz^nÁš†™ŝL\Î()żm:ònà§=bÑı9àîú°Z5@bÙàlĜ(44¸¨,O­>Ášïú°$k}xöH>ïÔ ĥĥwJ—xzhönß§9à#k¸€D+ı }tÄĦ$Dċځ}B!ĤÄ^œhµÏCÒCÍĜµ˜í!hşòŝq–’I?{piİàÏғóċ²yrċ…%¤•R~awìö*bŠôżO=ópùàë·âŭ/}$ġ=u#= +vŻ+Ïġ£Żc ß|Qê˙Íu˜•ƒV‰zŝ‘ˆı|ôMï,׳Dßŝù]ïÏÛô•ï.†Üíâ­Ùşd£ĈĠt˘¸[8êxĆhsïCñ–^ÌohĀkhOĥĵïîÛúÁÒN /°ƒV¸%Sêœĝ°ÄˆÛ†Ë÷Œ‡|.Ġż½ştTâZŜ[#\ü³V¸ô÷À?6 Eç@^¨d9e;+ĊÄşq>jr=ħĝìÄYÔĠşCQ–ö玔ÚC#K¨£‹Êf>3ßNŒd.İÜQ†ŜdjË$}H’ĠÁƒ,ê% t’‰ħĈì +ô9h ħ8dbœĥNÇ@JÊ-§•ƒ.#>8¨â–ËÎ,€^‹a.&ĴÙş·ˆ4£Ğœ c­}ï×ÛÁ ,xލwÖ ï’.½¤ûÀÇċÒû…Zp~&n#4–YĴÔ·ßß(&pòR"Í}Dĉ… 318ubˆ˜Ġ2™O,ííI i]`$]0Ï|üÂÌIg#żg:brOoYеżˆĠ)äœúÉ`b!žƒÊGfĜ Oĉ-‡›³ÁL˜n-$TBÒGè¤pÒ)’ •ŸĠ0Q*˜ËêöMûżÚ/tßÛ)5\_Ešw5——Ù vŸzúħŝğï'Ŭz'Ċ÷ì}#iC6·kTßòŝZÄrùŬ‡äO^FcN5Û!eĥ²ëÔàĤŒé&nĝïœuĜėžœ%g·MĊ{sÛÊ֓¨‹츰\%ʜ Nħĉ"p-’ĴÜĵ$VóìÖl˜żN³iÙzÍ^èr2óö°à“ê…£gç +‰UcĦ-Uâ'•9Ş™u`÷ÏÜËSÑ@÷‰ĝl§bŝçQó -$u?Ü -fòMq™£ô_n&ŭŸ[żĝ o˙MáÚÙ ĉ˜SáÀֆıнúĜ ß÷r·ñÎrĝÉ}ûôšŭû½4à]Ñ=HŞvwŠ8N`2ŭÍĦwìݝ|ÈZŜ¤1JŠIĥáüĴHSžùCİí£­†Ž÷vɵo­€] ÁñVO|²Iìültż¤Ĵê ”k5´‘ïŝ|+8 †Üúİja×,p —Bëoŭh“:üHËŭ°O8Râ ?aIœóâöÙJÍÉ%àŠCż¸ 'ñ Xß÷܅´˜ŠOÏC‹mĊl[Ž­?-ğ•–Şn,۞n•ëïn€V8j¸gèA›Hün1O™ż3;ĤˆÙŬS)_Ż~wıÔŝr§ÜŭÍ>C÷ó†î'„{ÛÁBTRŞœ¤‚ž™2„ŽÎ3@ßXÈí›N9GùµĊâħÏÖ˝ßí‘{żq7ô>òòë{ Uúz@?‘­ċċJ~ë CNŬŝêjħû³]rÇŬŬÌ67PNĈrĦx`‹u‹HO/ŞÌLLóé6qè7éä/Ñ·@ŸzBqÏLŠûqÌO—žž‡ŝŒ}j†>ŞÔŽOlpäb*íıİÖ^˘ż™Ëĥ=š­[vh°'äɅ˜ċ-0ĦëÙNèĝÒ5bu­·VÔA‘V`T¨ġ·7-ĦґĜ´lZ¨}÷ˆÇ?Ŝ(çŸy)úí,ïÊuP˘SmÙßg^߅_½„+żÚÓß-¤×:A“ÑK cħÍÄ9*Ç@'],½¸ìDèÒKÁQVYÇĤs:9ǧ£Áûšy8¨ÑK~fcD܄Ŝ´¸Ħ7ÌĊZ‘ŝdéÉyʉ÷·H-Ÿm—š£Ä€‡ö+˲î9ÒÔuĵ·NşŒS‡{Ëâ6†[ӆŬż“_ˆJßwĉW7 }OöHgòk-á ìĦá/Ĉ8€uŒ?Ċèl;äĉè=HŭÎ|F<Î˜Pxj–˜Ö;Eœf Ĉ‹c ËÇ÷üì"ĵ‰Ù3j?9½s*i×ġ=Ù­ïz°5/˜Yè‹QhhlŜñ•+´ŜĞğÄĥ{ÛÁ>gŒ×ĴĦëËúŻĥA'=òż¸Î%§ç/ĥşvzÛ^żşĈ´Ş‰RÀ+Ĵ{ôœÔÚĞĞ„žû.êCoßĦG‚Òù`/ßúù&0[úKË u'ž™CÜĞ’Ë‹”<ä“ßy ŭÛËġ|³]*0úÇ%'çŬİW^ĈĞ÷‚ÔËÏ|ùÚ–Ó>F\Ŭ.Ĥtj]V‚ğî%6ƒ˘”4Nf?Ÿt$ÁŒav§CÌìבŜ1Ĝ*/4T^]i,˜/%TŒUbÊÇ(-“ĊŽÇ;Ôî‡ûĊú×ŞéµI ñz×GòÀ8“~ggq'X^vŝoġú“@ÒTËëšŝš…<ŠW0i!Ċ@S´u">Ż!Ğs†!ı~"4PY'ĤCħ–˜,ŜBŸXxİĊcċ†7¨í]}Ûş+-wwË;ĥĜÁ˜~lŠĦüêr0|ÁĜHĥ!6{_†“·X{r‘tî+oċ½ûĦĈ۟EC‹ÛÍĊ]y€7iq÷Ŝu5 ŜóQäz>ÙBZܨ)ğŸï`5ôjh˘Qä:p‡XnĊò_b/²:ƒgñÚô†ÂŜıˆġ Ž^šÏG–Ò$YĦîżDÉ?5KÉ==‹—%§ W€fċ5—ÂĥtR”9¸|°µŭÑ^cÇ37µìÚRäżz)È̇÷77ÀĵЁĊeĦŝ*Ġ=r|#4.Ùġĥ×Pí`×Ğŭ™‡Zvc9tÔħ‡„8ĈÉĦĉ˘Ĵ•_0š48ß\gè|ìĉÛ}ßšğyïˆëcŝìĜgk‰‹Ù9ÚÁ|ÇĞm|ŭÇĞ„â+ó…ê;ĴĤş¸P,ż´ˆxşÓpnpÀ­[‰†›wkÏüe7_wkıPóÑ +1­ƒ|,˜sĜ§ó:§£Ż>ôïÀî{_í÷ÄmŻğfß^ĉWµËCŭÌ^óĉ 1ùBp´â"q³b+ǂ•‚ŝ;1 B3l°îÔĝÜÑr‹ƒX….7ħ³˜˙êy¸O9ùX >qè;w}7ËcÀÎ:\`Ğ H´[V/EXèĊpsèq˘  Ħıv`œĤìĦ$k‰4msG‘ĤòÑĦı2ôıÁ€H*783ĈŻ‚ħBl˜bâ ÎġMĴï•íĤŠr´wîk-nlp>wòĠ>۟†ĝ}ö^–tċ•›qß­1qšš' DZÜċç~ ˙Ċ>ùÔ3o߁ŻuRÏw{E£‰Ċb6q†2ZĤ€7;Kŭv–ŝÔ_w£>Äŝ–çŽr%;ЈXÄĥ‰Ïĥ›‚Ĝ¤KÛ7úϰ½×ì,µíë=r׋=dÇlkĊHs=³-°ĉñĴ†´êñȧ•üî™xORHĥ”1|yCë=r÷+Wpĝĵ>Â\'šż̲áù1¤ƒXuj‰Ôxs­Òùp/tuŜWû ñ(t<ÛÁbéÎsġ˙‹îüÔ?tçû~p5\}ѝu‰—Xunġ Áy(œÉ'Ö;R_ħêêRáĝ{ë ×%XBëXfy9âşĦ÷‰î9Î[!ç$^18¸`"ŞÁĉ:5r=Òĉ>k .ñjÀƒŒ·V"™Ŭ$W;Aû\|qĜYEìÚfgU€Ċòğ˜\{5ïÄ4hĈÒYÜû%FÙiY|p^Kĉ˘ŭ.ßCR@¤´–E#³Í0Ĝk#ññX£žH|ñh.4Ì|&hz“îġñÛëH‹œ-§ñô.^oFŬġèɅr%hq—Ÿ\ŝ•:ĝÈ 92ö²„ –3EÚÉĦ&-nâµŜßL:³`>CçïğúÂ2hÖâ<ñ{#ÓlL}àTb|sFFgĜ™ĜY ÓĊá'èJI`g5Ŝ^à™$§ ûnà…!İ‘Éĥż³³&EzŻÙYA#™]3”ş[kù§ĉĞ,ž‘Xž-qğÒ[§C1½Ü KCnÓthé2˜/d÷U -°#ûğ½Żgñp´éġıĤ×göL‡f5ì[Œfĥš\2Öp´ooç]w˙ö‡žT7ġ>üCwž­;úıöם˙ztçoìĊ+1 M5³}š’Û7S’lž„>,m„”Píˆn–'wÈ̋÷3Ӄ£VpzŽ\˙ċFäırz÷Ä?°ŭĝÀ4kàgĤĠ*f'–Äa=R8šXìIEcĠœĉ醤:Ż kŝèĊBï³=àĦż¨cyĜ2àœ{yè5öî'v–NRÍôÂìĴYè!&zy5ž{µ,›#>‚RGBÒm Ħ)6JPÂ98u$|4XÜħÎnœ˘ĉ6O‡˙£Smï‰wÁ­tâÎ0~HŸ>ĦÜyĞÊr}ĉĞM76(5ç—)ç³­¨uĤ0go+…·”Xí(°Ÿ ™Ôñ9)z€JhŽ­‘m‡s#ÄĈ*읅~ ħ³{§ GGsіÄrb1“bäkvV×]rï£ŭèĵfg!Ŝ* µ`Ïrzxe`g—ŒÚìżÙYù&v–‘Ġû~–ˆ/ĈÄêñr`˘5Ö.4üĠ#UŽÈàs ùÍ3ˆg–Ö4٘Y;™ùÀIˆr@êboħ×û&ĠLÀëĦ·ŝŻŻGŻu͆ĉ61ûk4½żÉùŝnߒӋ•ŒŞ }ï™X°çç żşÊC?{AGìX°ñèġ,v˘ ´ĵ³V9:0ßÄ]³+üôħçu“5^rùA˘ñ–‚ÍP;˘ŸíİS5`bKÌgˆuĴB.)G—Ĝûxûk4<µÁbaHݘ`,lŸ:êrb›"[ˆŜħ`KÎ΃†=ΠfċÎüì&5ÜYŜ<ĜYž8+)ùšƒ$v³qĝ'bgıħßǞ`ż*Ĉ݉ùc|#RìüB ìÁh”cĴĊÀh+%ŠĊO°ğ˜O–Ëúĉ‚†ġÎÁ5kğż]jûlĝJrcN3r÷—{‘çcŸ9´ı‰Ox´cĥ}ßħ… %,ïÈmŸ&%³Ï.Gï=–oŬŬeÌjšfÏħóKiœì›ÁêúòĦ…†Ħ{zéNJ2ĝқ‡vrëƒ ÄÎ"~ûéù\ë‡ÄÎ[ĜLìĴĴ°³,<°Ġhs)g`:´ş‰M}t˜ĜY“ÁÎÊ7ħ³ ˙ÊΊ~ÍÎJ!ĝ†Zp"Ğ-U–·#ç;>§}:ô½Áß@N˜!İ„­ÏĈİ`+ëYŬ!‡°×û…Yp| ¸TȈûƒ×W^]BO05X^bÒ9œĞ²kİDĉĜŸ,4a˜ßJFódŝĜ‡kÄS?zèğžm˙ó ħÀùrž=QĞQ™0’÷°8àĤh´<ĞɃ2Gà{<½9ÎxÈ\NĞrBñġ~.zàNs,˙É<1YŞşĵĵ +°ı=\ġ7½ùĥšÄüqŭdµ|x!X”W²¸-Ÿ”2ŸËj9Ž˜8oĊġ?w‘^ v4Ò#Rlt°³’gg%Ĝ‰uvıRws­_2F§÷7{o{†ô†Ijġé…Ŭs}ó‰oMġxúħI¤ÇŜúÉfâ°8. iكW@lòĈIrZ-˽NÍE[?Ŭ*wŬß+t|şoyo=Ô ùŞeşœñı¤†wVCKçĠ²+KÁ%U{ÊMïĴóM*'DXÒmY½6Mjŝl+r0‰Ġ²&¤‰%;ëñvı˙{ċä œAF}@,Œ˜ÜQ|pÖmH²š?ò5; ŭ%0ˆŻTÚ=O­:·LÍНJñ=ŻĠYŞ=³Dixw­ĦìâR°+•˜ĴQ8+†5މ!·ÓYÚCfb@šµ!²Äġ­!½v˜'ÉRͅ%jïWI{‡3GÂçKq%ˆ…œ!ÚÂ[wÈÌg~XìA.…8fÈê˜A1’Ċ5âì˘çÉê6œOCżÔÄ/š#Ô mŭ ¨ı„Ĉ·W‚C`H=6‰ĝ`Ù­Ów|‹[É?¨•WV(ĴVŭMS¸ÊÑÄĦb1yjŭµ`ż! & +<,—€@‰s'`0cf07uÈCÄĤĞ+ċcmBˆ}°ÁEçGĴż‚ll™ ŠEóċĥ/wÂ>Ŝ÷cżNí}ìá?ô@–˜˙—Îë ĝ‰Áĉā.ìš))=}Ü!:ÓûRBğĞĝĉÏփe8ġT÷żÚ v–Xsvf>¤˘áÙRvÏ4hY ÔsµˆĜY`… ŸUÁ쳤—}&öyÁÎ*0ħ³äco­[Ŝ߈AŭVó Ù-Ó)×d~Ì䉛kċ:öıKşgÉE=³ˆ5_44OmĵħN:ñŜFâÚbÏ%xĴ1›Ġ`ĝ•\(uŜu‘ğìċğïnÛÙÏŞş<;p>À{RËŻ/7¤6O‚#­äê³KÓPÏ<â‘Qo£ïùNíġÄwb5ĠċW–Ê­Ÿn—´y’—Ö_-%˙dkô|ÔĜ<pPĠ[CRı“ÔġĊnߞ{ŜĒIĞ›€\€gġ7Ğ×ġÌĥƒ #ôÁ£A_ƒr0âœfĜ²ZĤŬ…šOÎéœĉ†\483&ÔgÊ?9G„½˘e+ÇĉŒBF fKJċù%ĜÏ Ĉ{Tž½˜Lù>r0ĝâñħ›ÑQŠzgƒùĝ-2ĥ+êQò‹ù'ĤYMs.ġ­#^Pj%1P )‰ÁÌî òPıžĊmV£!ß'Ž ò˘˘ng‘]{ލÀMeŸ“ÙéïLw{İĉÒRô4ԋ_І‹÷bσ]’o”^+k°EŒšœ†)Äĝç yXdÁ(ê'ü ;Klĵ½†êĥĵ–irŬġUÈÇġ7Ħ~×§ZëYŽ/&·N+M)ùĊÉê>ĥŽgJŻÙY…³À6’°Ĥšoc]-˜cúı=3`T ‚C]9ĵ@Şğ´Llı³ÙĜ&İñ6ċ,Ô³Ş<ı?ƒĜpĊÌîÙïC.@ Ü)ĥFĊ*VË÷<ÜĦœ{Èóçóà:ïnĈ;ìıĞחÓıɔœÑòıG:˙럄_ğpŝ`à}ĦïŜ.Vıà=İYÓÙ½dŸ]ûÒŜy8ë&…dTŠÏͧšıċÎf%µa‚Îf.°œšÖy}Îàn‰Ì~`z1Ô\Ż÷eıĦN£Ó5BpêäÇĝ\‰?­C_‚Ġ“#tœÁŒXžìw)½sÀ·Âù%bUŜXÎ˙|˜#`ÊќĞeыC"ĴÀÚÂġTŞßZ!V]^‚^>b´šeb-ÁQĈşR|~ñQhŻLŞĥ™àĴĦ·Y2ıîöZìYó=LĜEÉġĊjáéyàPrğœqŝFjşcÊ-i Í7T\^ğ§{~x\ù­3ğ–{ğ3˙½\ŠËµ—CÓmÄCqVJRŭxœëÏ|i8˙µ˘ |í%ĥÜßBÌôˆ;}uĜñù6İíóíjébšƒyËr>ÊY+Ï/ÂùBĝ%÷ÄT0°Äc7×Ïws-Żŝ.ö›iÖ1˘ŽbRĊÙĊóȔ”Âħ”§d›b(èpĤ=!ĉßù–;ë¸coŻÀġgġĵN‰4ż‚˜*,Ï+îÀ–Ä Âçfù#ĊĥîĊ޳ E–Ÿ³şe ò ­ÄüËC…Œxß8{&Ĝ uû½­bÓ{k°żÄò9b×Ó]8ëݞŭZëß_K:£vrVü\ò1ì^âì%xO8@q½+ÔŭŸ¸À§ÒŜ´ê^ÄXü|!(Ú +g2 §Hô;bÓúš˜ˆéÇ'İ‚Ï„½1!8Ìò ğËi|„Ùö˜“kĈ™xĉo-W*Î,B{È•¸|bbħ ïÍP|rÒxk=ú3J1³?öŝԒK‹¤”†ñ8!FfÙ*)àX²Ÿ˙•Ù6qRË>:ÓŭKıáŬu`?Ĵ-°áÒOLBMûÈYìŝ‚A^^Ŭ…eÈGˆ[ f{Q˙V£Ÿ{çċÄâéĝl3ĜEx Ġ{¨U™Ŭ"‚ï|o¸>Oİ`ı¸Jˆµ5—ñ=Ï\Ôá‡:pb°WOĴŻÄ2G:{‚^#ŝ](³ĵ|cü?ü¸Ë=·é;>ßÈ7ŬYM{:É,vÀvĜ3ñ[§Ò> ú8;œql²)Gns\Çǔ;É%Csı€+½áˆj pАs€ 'Ĥײ8Ó4Qfù§ŒóVeóÔĵĤİ´WÖtm•ĜùÙvİé½ Ĝ§2­½¤03î0‹e…ŭÎ\ëÇóiż&“ÙCNÇTĴ1ݨϙŻ=ğëüt3×òÑzîÄk1‹*FdĜ€)FĤĜ(ŭóˆ‡3$y³ċ0C#óìԔÁ*TÀÒfù¨TÙÏ|èı%°IVsÂŜü xSJLޝx¤ÄAIŞ'ç÷2Ġ1ú|Ĵf˘zƒ½×|i/­ĈGÇiG£6A½‹ëŽ< û­³Y)*Ġ†lŒiv͔üÎ8Ë#GeĜވçoŻCžêAœÙR‹úĉàìÖŜö‹•äP;#$nzBı#9 >ıĈ‰Ċ1'Šóà½2Ÿ"6NәxÂ8ݘĠJÌnı8·èÑĤ•#Vùà·Vç=–‡bKµ×MŝìSĉˆsV,úìl)IìÚċ3;cġ ò"Ĝ ЁÖïÂ}DN(´ğ^f?ƒ}N≁ +ŝ0ú<è“'—Œ½R–ÏĤô?9ˆ9:!™ċÛ8K[ÌÛÑSóÁ˘#^öéÒ˝P']‡µM×ŝĦĉÊ:\~f.Îğ‚›!Î b}QŽÀ-ü•!§cĊʋˈ Î>³t´k6ÙiÙàĉĈòú"1ıÑ ù}6œ{iû|3Ö1ĥBbĴÀ מüvğŝòwžÒÉïJC/=ĝê³ „$k̇ ˙c÷n8=,,˘ġö`t‰½oZ××VüכǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛǛÇ˙ϏyóöFîñ÷·÷ÛÏsq[çËŝ_ë$>(ÎŜÓ~žï +—¸ĝ=ĦñĦÑQŝq)Λñ%ñàÎmófç…üS‚â|WúZéğÈy‹óB7ö7ö +öϋœ—²ï]ı|ġZçÚ ˙ç…ĤŸêÌŝÙÙ+.4$4Š}QàdúÖ-ìiżlú Ğ–Ż^µró†×,_ğzçH|yÓĈċkVnX˙/_ŽÀ—M˙ƒ/›á÷/˙÷ù?|ùżÈa{Á>ÊŜÇ~“óÂE΢`żÒÙ%È>Öt-\C#‚6›ŝş+ˆ½ß/ ûĈUÎâ>û{‚C‚v”<œEO{Ċy3}`Óœ˙x{Ĝ/ܰrùúÎçUìżëW³˙{û–×/úŭÎkÙï_µ‘ŭg%û+^ıÒ~Ŝf½‚Íö{È×=Zğ‡˘Ñê›é‚²­1ĉ¨δÖgXk­ĵĠXó½.^š[÷kÜ\%'nĉiŒ5÷ԇ›ğş‹š=.>šŭŜH y›kƒŽXùĝÇXp‘yĥú°"[Ż T+­Żĉ ×! dŸtñ–ú ‚ZżdK_úŬî>ö3tš½;ÜĜŸZbŽħQ?pÀÇG +5ƒSĴ!ebH­É"cNë ŒÒcԕdz#rí0òL£-G*ĈbĵÁ8zŒqLCAËLŒš`’?kİ`<’'éĥ†ËêK+1–‰292Ӗ$(ĜŸJXލ‰’ú‰“"i|?F'”ƒX£ + qì÷'”;B’DˆÉ´#i„ TkFŠy£§˜CŽÒB`ĴF +16,ĊYC*[ËIÎ?ÂBŠĞ‹q>4Áš‰# HpIá6—„„ŞNïgĤ“™‰ÇgŸ?:ĠVͨž¨–ZdÈ陉Qd5ÔLH°‚´}ö’ÁyŒÙf?cĦ¸žqGǒ„QVÇt%p–”Ġ:EH(vĞÙ×ëĈI)uNBHÎHC”d[˜ìQ$™‘yb2'ɚ˘ħtM0:sb +F™p|žŽĞCށŭŜ7܂—üÌ!èm1‡Œ6d˜½|‚ÍĵµŝfŜŞ’K:Œ&H$çx€˘9œÁ~½£:%ÒBÏ>À)ûHaîŬs@ƒñRÈş +ĦEĥ\h‰­ŝP²¤ğ½ _êċŻÑ, }éîİÓ`|Z(ÉÌ6‹ÇbdŜPvv‰Ruiı!éĜ92ËNŒÎ´…cŒrDĦ1½”Ĉ 4ĉQ0 +ĥİĉtÏ$ÙĞcn”[înĊ£”e’ŠbóGé ì^0{ ÑxfÏż-ê )ÂıEeĜÒ¨IjĦ£!·cĤ”P2F +KI£${e÷Ĉñ‚#Ĵ¤ŒİRd·dîşÓùHWV`ë͐hİ•c,ôr8ğ—ñ–{jċ0󃞲ĈÓC4!lŒQ$”ÄÖ|€™7gÔ@nïr­b`֌ߑĊ£ Á‡ŸÍšù!f$£Ì>F–ĆqRHžÎgßY +Œ +áıv… û†Q=Óh5ä&;SF*a…vz5ĈB§2?êmİ„ċÙİɵ qŽjd†žbƒQTcjĠ)£İÖs•2jhT ’•g÷ǖì>‰ˆ³Ò‚ÍáHv $yìYïfÁEZbôÙKŻñͅ 4k!4Û²ĥĝŬ—‡ñ~ÉVġĊÚˆ5Eç³÷\1ZÄç‹.$VŽƒÜdu yĦÄW9BÖÏmÏ> §F˜+› ɵċüb-!ÏA2¨,ö’ ó…jxŞ-$”¸‚э2l0’¨–tÍÁĜ2ülKgöÉî'=e7O…,Ĉiô‘$–TK#~Ĉ˘Áù4*Í~|²)/èœİ÷ÍeùÁtH +İ}óԊ‹Ká›ÔÒ3 ዠIސƒcĴhl‹­ärè‘MUÓÊÇ+GÊÇÊ)u!B2d2@<ÌhÂĜÙ|Œ.ò™-a,c…lŭôÉĴħ÷{Hm˜I'|&Ĵ%Œ*—–ÒÈm5ÇÂĝĈœÏTNvûtülȇcäTŒĊè_Î(%›ÙĈĠ`‹ŭs!Íl(žgÈ蜎q{öğ&b-aÄIŽ)r€|<ĵCz÷H‘Ċô”Ĥ‰X+BğöÑiĥĠ#ŸÊ|-d8˙v˙“,0|½oÜöŒ‰z@ŝ\'̀XCY\˲…ĵĴào)Jµ†Ĵ$ñxĉ95Ôù F!‹&HÎBŝOÊuŒÌ~cŠG‘ @fÓ$1İl,FŸ9– pAÉVBTÉ(HOIG/.PŠ/-$Ù·€x+‰ùR ekÒy$aż '&`|] 41Ȝ¤˜Ÿŭb­xCI–›}ÄeŒqÓè~D2ċjdĥ‰Òçn˜@9 |d2‹ċY,'ÌižFö iöï¸÷ƒô½IM AR„|Tê‰É4Èâ7r;ÜC’PÉdy\JŬ’dJ(£&–#ù#fQ˜Í`,>k(óĜdÁ†üTJ‰£!żk–šßéŒñ]cdëë2“ÛşüŠBrm3>I&òÔÌ!wG£‹ıÍ4ĤÛĝcDµìüBÈ&C‚J,ż´²ĜŝÀ"ŝ„Ϥ‘JŒ"ĉöLǘ)O2[ƒt¤!ıb’4cœ] f_àû!+ĈĜ£ĝäH°`ıüž“gñB²8f³‰•Ž$™ˆŻĊçÛsa™#…ĉû Y‹‘ú<ĥĈ˜?ĤQ{H†EĜCgŝO?2×OĝvMÇ£Xĵ`ñU ^x²i”½‡Ş›+hmħ‘Öû7ĝä6rĊÛ˅ĉÏ7‰µïĴ iáÊk‹i|1şÔAJk$}kħĜúd›T÷éZ)²ÊÁK ?nĦ¤ÖOPŞ/.“ëÀh8]ğÂŝYż‡ŒI?ÉòËv_XübëQM?1Ċ˜?0 +~Gô;l $ʗJ óp{Â|lS…ĴkòÑq=¤ÑKv‘Ñ*ğß°HL85ĈfqMĜú Ù– ÉQ9v?%)ĝ(ÜŻ¸²1¸– +|ɍ—8`IÉżÇXäŭ…Í@òKÌN_ċ½è2Ë!%˙vż(ĉ#ö'—9˘Î‚4ÉGÖ\Y +YlYe6ŞĤÔ’Ż¤gR…£”^1H ĝQHžÔù…@ˆyÓHž#>_lñhŠÏ…'gC^ŝ²Żeĉ‚cİĈRò;gJĠזbüXŒc÷/$k$îŜdm0š +ܤAĠÂá9RL™|*d;hä<×ĥa˘żÉjĜ-¤ĥ…ÁIV•ˆ2[˙dŸĊ}s|Ä`3-‹ċ^*û“Ġ*ĝğieġ—^5a?HáġjéµĊĉñÖҋ -€$2'ħü˜ŝ^3N.93OĴzk $ĞĊÌĉIÀzC#Ĥ48‰ÙíSä3;'…Ys tĴ ’íbl‰=Zc´9rRzòĴ&32˙œ69¤v”ĝÚqd,V >ŞĴŜ  ż¨l;9­Ú‰¤:_¸PŭšjC1‘Ŭ_ŭÑfHéóµ7–BĉöI> °Û>y5¤Ŝ[ħš`| ‹[£aŸÈéŝGÁbr~ä oQÙ}€„ĊY_d_à‡)ç`ĥLˆ’Ìú 4ÊÍòŠC,‡ )ÌV7„§ÙR.Âb§ôû×IVRIlŭÂ&á‡hdĝ÷×`½`MÁ?ËEŬ³HŠŭ½·âŝÙÀP@֜Ż:żñdXïĝ=X;(€LŽÈlâä²Ĵ°ÎHJŭNÈòëYÍìašQdñŽV£ġäC['£–ċ|cİÖ£tĥ>qŭ””RG°+…²šƒĊ$!œ­ƒ kžĊc`µ`ŸÒ‘Ê1@Gà:ctŬ[ÏjŜÏ ½$ä…xo‚/êös­Âê0sÈÛóC}äg¸ÏÌg!&³\ĜF)ğ´ë ħ°R\ùh’'eùĦànÉÇXêc-))ͅĤXCò2†ZV—›dŭ,ћ˘ +ìxżKoÔëJ”…—hŽz ġ›Ŝ7ĈŽ$Ëêt)4c$$ġ ˜\V°{„<­ĝÔ< ¸Ž§[i}ÁeĠLâşn‡~uןú{ußn‚&ÉġSÇëƒâ,}$Ġ 7ĦéŭµRíĞ„*G.0Î +=ÈR` ÈħY£à7İÎŞG…ĠÒ'ĤAF˜Är‚˜ŒQjt²-òO5­tê S oŽ5EµеYŽd 9ÈN’Xn ) ”Ú ‘–„ä*“Ĉ“Że1 ˆÊ `÷Ìg›äĝ†ĉJµ×VÈ$Ċ\8š¤àêïĴûĜ/zċĵ$YP’v‰)üšddäÛÑ@מÙìy|'â5¨-„öŭ•è Ċ–:‡ÓFP‚œ ĦŜxÊ 2;Ĥ“Ô4Ëq •B>ßÇòj  HŽ5h´•k‹µÛ$ËւŠz²¸àĉêĦÁ}×ûXĦ~VÖ´~­€€¤´^ +6—Âslá·%ĉS˙€äċŒÌȐq€ŒDÊñ l-€4Ÿp8s$ÇêjVÓxë|5>r€ÉJ²Ż÷‰‡™í[C:ġ:¤Ŝ9%ÎÒ|ƒS­ħġ~G,i1‹%|'Ğ÷,)ŝQœ/´2}äȨ;XĴž|¤(ïĴ#™#H| fd5.$„ÓŻŠ~ÓqçŝßċZ`5°ŽQÇy錄1޲oBÍ[KĊĝ’шE| ûŬHAŜ +{ÌívzJeñ½'cNÛLä˘ß +fġú5–ċ[AŜ‰iĉËɇBÚ¸TŻ;BŞ–Pe§Rŭ›Ŭ6]ÍoŸ‰<=C5­z‚!µŜ$ИY7™òċÒŜ9|ç½m„>J*‹~&É?·ÌRÊMŻû^íĉûżÛExǖO7JµwVCÒP/…X Ä š1X"äЉO7Hu•2š'!?BÓGBv\hŝbßŭl;IŞħ•Ġ9UÌì0ċGŻ/ßŬ$µ?Ù)w>Ŝ-·ßs\‰I²Ċ•ÜÖi¨KIş’•ˆK@ ô9S~̞JùĠ%RġÍċâħOÖğ{ê5èeÀ.zèMġ:³+Ĵ)Âp°şŸ$ä’F"ßPPs²ú Òg´6™Ŭ£Ïƒ~‚Sê ³ş²äèÛ!ïċ1˙fš’N ’(·–c*ÇÀ/#ßAO²í°IȸËħUc€>׉ĉRh–wtŒ˜5ĥ yGäĦ†#EÔЃT3zğÔį̈Ÿ¤–7Éy Œd9\bÁäz$]Ÿ?šd| ;fpmŸlàÎüĠ?˙OŭàŻ;…Œşñ°?o5Ü}YHr#µ" wĴsĉ'(?‡LTnÓ4ê飇tôô"ê'Q˙çĜH‚˘/İe½ôRXÁêuÈĦ7nH`1ùcÚñI&ı!–ż2?I5T)d˙Î-nù>IÜĦ^ÎĥS ñX00‡äÉH’¨g6ä!Ÿ c1­ÖIJaġKÒÑħèŻŠIEc Nx›òK‹€3Ĥú rÓ5חı'§uOA.ˆû…8!U\["t}·S<ö`£˜ß?qQNo›,6µ’ëŝz]Rqß,1ħڑc1/ċ9E½ÎXJë}ĦŭñVóñ6İé£ $·û(²W²k'Éu–wY!’OƒtdôQU½³×[ü‹µúîç[HR,<ËV8m…z]D½Ž8Éò&ô_ËÛS.•R?žÖğ7ȵàC#cËG+i-Ĥz=ħl ġ™ÏEĵ€”´\raPûÎrıìêb9éĝ18yŝ°ì½ÓZLşìÚ¨‰'&@ÊVˆš( ÈÉÌߢGĤg5<֋’fƒ=!Cißïġz†ú5Ô+dL*šC=BÔn! # Ċ ۔ÑÇû Á7Ŭ\)œùö€rċİ‘úy$o_#!¤à쑂?ËAŽX˘Ĥ“Ô8"n2N@–f"êsìMİÌI +²ÊŸùŬ³ ÁJRœèàzċµ“ĵĉïÒ{J*ĞëXŝK2VĤzŬ5ŜI8ĉĥN—K‡çħÚyĠÍYìŝ™$¨ĈQ5|MĊÙĊ¨éċÊĞKáù–O6ˆµï­+‘ûĤ ĈĴ~§Ž ÙĈÂŜYÈO¤Äù³ùZĴŒXviSċ€˜†ŜµĊjïĵS³äœSΈÓTK²˜3à΄VW²˜ é4½kD0Rjëƒ]JǓŬ@… ǀ.Òĉ´Y\Xìj~½xì’ú£ü6­e"î0 @QêŝşKÛ˙íÖ×ġ:r#ğĤ¨× -ÎÖ|dš-Éh2+×]_İt:Ğy]3Y<ҊÈA!ÇNŭ`‰ïĴĞŜ^ +,"°ÎT·ħZ R…@ Oĥ³z}]3šúûJôġşT{y9Gèż!OÇZEdŞ×ħ^²í OOûkì>ÂN|sûfĞ9'ĤQ½îÏêu`!Ĝ½sñ\Ş—ñµĝLıüäB’7BŸ‰óäîû{•áŻĵċóÏ9q7}ÇǛ Êy ËĊƒYž£ÄXjœ…Iú”Ġŝ̇amâ=@âġ:r*ԏˆ$‘ı*ô3Obö W½µL)?³HÍ;>MĦz½šêuHâ=R½Ž"ê ÔyĦ̃(ż³ĝ2ôÖѧ¤ZċTĞCR½†ĵÖi"GÌò÷6-Çw½ĜÁr‚ċdX§Ô³ÈħŒA„„Pŝ $ş”30‡cµ²§ücGBÛ+ ̧×NB‰I³Ú!ÜHNï äÄĵüš Ħ´=v‘;ŸïĈçƒD8b¨Ì~B…#dÇ ż +ĵßÊjìŞ+Ôs% ı£§ĉs·rCżîĤXh9Yá™ùĈügCLlı I˙xƒĜyo‡Ĝúé’ĦÄ焌e[k$ÂAv:“”g×W{ÔĦŻ}pm„ï­%û,;ğ{4ÒÑó Hj­êÖ2)wĜ™.ċƒŭQ.ÔŝUÍëuĈ}DLB_CË IYÎ?Ġ +{ &LGŬÚïzk½7ôâYÎ|—Ê|;ü"IŻ1û#ä!úFğc6Œ¤h QÚéü˘Hˆ*“jû°4ZOÔCÏi™&Ÿ™+U\Ylò_ì÷CJ9czĠH›a˙€jhV!' ?I~âĴYòˆ˙ÈX]ndı Ió³C}NßO{‰mÓ!™*UßZAŭˆÈl;äó„Uˆ-cŒ`kàp”Ġm„„hœ.}€âG2··Ş!›Â~N8¤żÓm§·ô;b2ĝlĈ×HˆàŒ‘&YËw× +Ï,PXî"˘GÊj"ô< †fŽòÔb È„ö/ĥˆġ×VY‚ï…üħT~}1×üp°Q&ıëÎéèWÑòn–ŻcÏ >ÊPÄÖ7ó™è͒0Èŝ)´çˆÜ˙ԍïùÎEdµ-ÉDz|²)@bàĴúD¨ùĊè£öÔÀßY=ĴJĥòÒ›ıïó4›M,ÎèĜÚĜšşŭ$œY@„#¨‰c`_·†´/j Ú@˙’ċTbëŭ­JĊċ„`×Lhûb ×˙…kûr“÷ù6äiè]z³|ÛsŸ!!ôĴV×ñ !œá°wċéeĝPÈ>ñğí„dp"ġf°wÛ¤şr˜‡G ‡ gŝ}HċĦüĴáèÈĤÒ^y¤İ×e(éŸOrĠɵM2‰#)`k ˆ ô?•hfżÌ. ÑĊÔ?Cl­L(êÛǙÎVHSÀ™°X3aϓ+ıÀKœ !dđü˙FBt?Ü­ô>rқ'FBèñd3èCĤWG~$óŻHˆ‚Ċ8B:0ğ1Ĥ°($m¤gMŭ…Ü™¨ ;ÀÖúï”˙žKv]ĉ?T*×ŭNĦû{Ħŝ½UÔïO(Íü°ëTJȵÇŝÖŻJ~¨a"áiXlGâ jj Ĝ€ş‚<8ßûh'I CÒµĜÜËÛKyÀ[ê~3Ô9Ĝ@=ŒÚ­p€_>t˙>A³g³‡f×ĥŭ TÑkĠ…ċĠ<Ĝ^ôͰ‡…Ÿƒ˜¤eQż²˜‰~!°u„à@/u9°@2°˜‰œq5/ä*q]HÖ³˙ċnŭı_ŬĜšZ$6^n÷5S'H Q˙C‚šî‚ĉ€Ż‘gŒ4½Áü5ġ''ÄŭĤ}€(+ú38Ĉ +×J‰`ñÛè ;>$‘üċ oŻSZŜÛJ~9'z@t5Ü\-ż³y&dqOá„oŻ6ɍÖL˘}Ԃ6g죒UúŜ¸5Şy!}z çĜ“P™q…cè\DjŭxÔċèĦVGŭ „'ò?ôÔà䑆èÒÑ@Vaïò²Bçë¤Ĵi\dħdÜùĝÚ1°O­joŻ—Ĉe÷>Û>—FûĦÈ;…G; 7 ùrô°tħáu*‹mÔ{O­r˘ŭ?œċȁlkŻ3×ġp›Ô÷­!!jŻ.…Íp !R~GBď4âÜrHêĞñcÑ[ÓħġÄì Ë5 ™ÍS 8 …ĵ1$yzmZΠEXŞIµIŠg. +ûçÂWÁ^ÉAŝôÄíMrŒıŬθŸèżŸ˘wΆ¤ħùĈJñÌ /yàıî/Räk[ïî0 ßÓÊ]÷÷HÇo݇o‡Ÿ¸C‚½K:9ÓòS‹P ŝĈžŬk$„HHˆŻĥËŭ?ş+CŻĵĝáßöqÏvJ%CsħÇÎĦ?œbͅĜĵFBmÏĥŞĴ.ƒŸ2ßP}nı!żnĊwËäÚ³KċúwÖŞċç—PŒ|€Ċ:Ûü=î•ŝÉVıŝnİûînĦû˝¸żè= ĈŜĵuÑıù\û×[ĝúVŠ%Wç Ġï,%Uqy“bùéùÈé(7Ç>ò}à +çJÍw·Jív˘ĉҎO@Ŭ€ŭzÔ=´>Ëܳ ùĝ­J×ŭâ7†Kü g_ÈBĠÍ%BjûD!ĦΑ‹ĞpÀ„. ĈÒGô3óavŠDdy[/³á×dĥыÂ~‘—;ŻÁ÷V…ċ…†²+ˍEó(Ÿ9R>ç5€‘P:Ü-×~°†Î3`ϘÑß÷zÖ.÷‡kŝpĜĝö* !ÔÔԃ@gŽŒ…ͳ %½ó •WWàL‡)§éšN½wôKÇR=óĝÔԀDn|ÑhÚI)uD½Cë½JógÛL5;‹ßi8ßqaħĦ¸ozö„—¤}è +Gô€p”ŞO-O?>(ßzhĵq7G}4@ÓYĥž/öú{ʏÜıÎ6ÂÈìĤOÖCRĠ´ĵË˙7a,X͖V7û˘\3ĞMYžyÊs߸  ıXĜ;Ó´?Ñ7?R3¨tħìŬĊ„„H­GuTċàBôĵԂĥ™„„(4!!”o­ö$óYîoH`ġ@^·3á×XJ’Âìß.RϽTŸt?wÁž °=ÀÚñ ˙ ÖnÚXğŜöâ܏§V0I‡Ó9ƒŽ™ +Î5à÷C½ċŜNçÙ>Ħî£U¸°ÚZ{ݨÑÑKCR5†|qNÇtHİ =/wŜŬY>èçáEµ +‹ï,ÎĞQ™vFÄ DFÀżâ*é\ħR0äħw„³e8ó⢠)ċòkK ıŭ³°'„ü—0lĜ£Äŝ +ğ—8+Ÿƒüĝ<5ĥ`4ġúgÙ( ĴŽ>=WݽħŝP @’gĈê×ÊĞ$Ġ ەRËİŻŽ‰ħŭëŭÀÓËYíSQ“ …ó>ɵŭbsGĞéH˙w„#î-7ô|ñúA~ŝ)UĵôR}ރîz bĠkèíáXuy1°´Bï7{Ùşžî?\ݽ¸H)šCH]ìù§5LDNŒ.´§=ĜABĴ~}ĦŽ™À—£ž·~ħX9>²À–‹(ħc62M,ş08hBË´³ZċÄ ù5qçñjÏ/NÜZ‡˜m(ž‡Üïu•jÚ²Áùbûç;ԎJçƒ=BßW`í„×XğSÏ}ŝwĴŬ`íp“ÖúGÌIêô"B?ħĝs‡@&İèÌœ>PÊhšHö_ġÎr9³k*ìŝµ™Ĝ˙bŸTqz! ÏÌ.šO9ĉÄg6ŒGŻga„´cuA VĜ3“Y,Gô=óYˆŜ'‡˜<,ò>B6²8œĈègJá,÷@?6™`:ĞF=p ?k/£>ó@˘ÊY Ĥ3¨S³³:ƒÎèâ,cċĠe@ù ì7`ċP’öݰż‡½!ô(pVA-èrĤsċÀ7`¨°2–G%W"GQאL9|jF<3[§ŭ†^­!ŻişZ~z1Î÷Š@8"g†­ö=tŝTß˙í:£U0 +g qF…úŽm÷7£g zòí¨‰ħJÎ, 3û¨gĞ€`µÎä4O£µ +ĴdŬµċÀ$+ù=Ĥϔ×7KĴż´œë}¸kûbƒpôìŭlàtŸ)ż¸ˆo³Ž;~{ġM€Š>ê€>2a&+,ÜPvf1é9pœ]ÄÚ)=?ïûi<ĝëAıèÊ:_|ò²ÒáyĴfXŒ Éċ³ş‚­ĊuÈ_hm`5%êîôñ¤3ŭġ,żA NvûTì{bÏO I£¸{,D$¤³­Y]Ó°G‹Ú‡úĝĝ!ĥÄènÔI@Œra,—Îr–k>[‹ĵCÎìFħ9:ߞö ”‡EÛİ,’<—( ~/ŭԭ薞[@ġFĠĠ%„.É9pv˙âĴ‹³¨o€ÒaöĦV_[T\]†{‹=kìĠ:}Lì_˘_ˆ3èó ÎĤöL™ï½|ô°:–gHÉ%cɏ‘„½fĜhíġ•„ @?û\…=sO]wc­Reê8S?ħu&0âwî\ïó@8ʉĠŽbt–Ŝ3Ëcĥû*#Ĥ%Ö9ÑgĊçaµlŝ½mžùSûÁôUè3ċ°÷ü{ ³Ÿ†[k ƒ]}e)ûÚ"Ôl8<˙r7ôr7zĦbáÀLİ ÏçĴëáÚżÜ$WŬYE}iĥ6p^ġ6ċı•gbݘìíŸn‚o€mcŜçEĜÏX*—žó²Ĝ_À>/z8#ûh­0ü“›ñ&9j,Jg%ÑSÄŜ5Öğ\zaĦ’Ñ1•,i“+bk`íeÖÓÜíŭ'×;ʙù7µìä"ŠŭT´M£/°“ŠèIgÔCsmq}4½o˜éL}@´%zK:ßh ôŒı¨,[.$Ġq`J¤ÜîébŬĞ…_nÀZ~ŒĠġĉ:ĉc‘l.!è°_–Q3h'œK‘joŻ2]ƒc“Sé= RċÍċBÓ½ @ÇR=Ï|+ìçD} şĉP]ŠüĜV+GŻ-Áž˘İ00H,µüÚ2İñ£ġ”³"Km˜HO:'we ċAè ³xI~!·sìEŞğ½(.ê_2ğg×u! ÀêIĘxc5íĦàzWöÍ£ž ö„°ïˆžqQ÷LʟX<ğżÜ.4ßZGûVÑĊ@aŸ_İı´ŭ4ħŝö U IßòÑzÂ÷5^] żÌ·2?MħŽĊÀ£C,fŸYD9-0À•_XDħûŭúŝg;ĒÁYĝ^ôġ/ĥbOJ¨ŭhêíá&y§0ĝÓ~éV²ûšë@­ç;îma1k=ü0öQY}ĵ=oèä\ĝĵìòİŝú +ê3}úİ7ß~o³ptp6ĦĞ +‹²˘x„KïğĝžŸvŠġ_Ĵu„ÄVħŝ5Bò1'1½c’T|zŽóÍ.˙ùAàÑİ߈ı.Ô ĜóD>Œ~Aŝ€3öĊĥ4Ğ’{fĥšŬ7gÈŭDÎ$W_eyÄ;+)çÈ?,œ-V^]Ägż9kjË.Ħ~,ŸÙ9IÈ;5“kşğ†;ŭ·ŭÂÙ_=u§˙ıWġ?=ù÷ŝ͗˙àŻ‡„kżIÂÉżypCÛŝyŻtŝGzóyˆá½'ħêûÏ˘Ä·WĊŝŸöI͟nñ-éœgŒL·C_‚βkä#[§ äêwVJŬÏvO>áŭ‡ï)‡zïqŝ=wµJË';OœPdÌj§kŒş’ïx´ŭĉÖœËà;mú‡jN–ÛKC߇ö{Ŭ+v}³ û&xWD~÷ĊHžçÛıĉğԗ–jŜ^˙É~ğEì|ħ˜G`r`gjÙıĊÔKó˘ÁáOİĝÌ<Ħŝĉ +áĝçëıŝïvñ½Ïw ƒÏ÷+ϽäÁ§€yäşŜ†÷ˆŝ Ŝ;×ŝ`3ìvÍ÷|ğgG„“?ğ‹ç^hŠ/}ÇézÙo{µ™ŝwWñŸ|•O;"ŭéûHġ!â•W˘|Ž=Ù÷.>ö•.<×+ž³×½â”ĞÏü¤+?ˆ|ŬĞĝşOWrÍO7j‡˙C¸öƒdxçq¸áÚ£ä2†S9ag7ŭ+ÔJ@!áĴxü“Mjûŭ=ò•W²tá'½Ĝò`³ 3:4_ìzıKßôñJ>ö¨=ênĦëĊßË}/> +ú˙é*Ôŝi%0¸JùğË ÁÖŝdíi}{)â1ġ;ƒR­QJġŸĴG <äĝ•²ËpŝĊĜûÄ[éŭÉ =(ħäò|V?Mr‡Ĥ ù'grE×f{·>Yċ}ùżöêßùO=çß ÜŸŝ§żáżë?˙żéîŭW€êòOߕŠ/˙–%Ü˙9Vúè×\;½ğùêŭÇYò­_‚…V„w~SĠ[_Go~é{éQ€ħ˙ħÖöpŻĦóÉ~ħûùĉ{ĥàòµ7—ŠŻvŞ/|üžJç7JĊÍċ¨ŭòÛg2k&û)vô-œ'7`ïĝ6 ñÄ>â£xĉ[/ñìo>ÒĠo$éêKYzçÛCÊÍ'!òío‚•ÓßòüŸ]ùŽŻ·èûĜ)ùV+]úFÙ=ä.ŭًğĝOOñì_}ĝ‹ö‘.~+—~ÔIo½T”Ë/TµÇ~·?;˘\à'ö}ëŞïŝj+×÷£ {î„͉µïŻ„]ÂĈ„\ċŝWîĜŻ•‡ż…mzO>ĉgïËb˙cWçùNĝ>İ—ùżÎç;°gÁġ~·ƒüù˙eí-À›jÖ½ïİáÚĊŬŬ]*ÔÛ$M²4R/(kiİ;P×TR ‚(îPw7¨ ŝÏŜ{}3‹ç9gżçœïĵ{_כ\‹¤ISÖÌÜsËdÍïŻ%È9Hä 7zM°ÛĈĝ͏&ĝí\òѐ”z:ŭ@…?˙(Ħ^ġŬïħŬ‚m,èÂéûÍRñƒvKêA‡˜¸ÓGk̂{_M„…_9ĜÏUôñíßÍħç_iş²óĴ¸²ÖÍüUİ£ù“Ò’‚Z)™×nBĉô s£bŠĥ˘XÀĈ˜á/>JèÂ> •9¤KA_`y­ÌœJëÒĉ[Ú+™ZUF”èğP³7oÏŞDwúÌèÂİĝĉ{‘$·—ä5tVğĦ(§C]í3¤‚­A’VÔ;+YÙvVF4ĤhÊ_Dá<*Û&Ê~o(Êú`@döi rżh +“‡vñ³żíçŝ8À{Ë`ü6ĉ¨°˙sâĦĈ0z¨çÖċŜŝĊ™üèG ~󑌔EX÷ߕ麑(n +ġ}‘v7G˜÷TÉw½H‘4ĠÀ~ŻżZÒE}GÄeÍç/[N‰ +:$ÒÛ ĉ÷Ğì-_9[<,;)[/ĊrèS;wÓ×zÒû ‡İ›.Żß…Ö˙š1ÓÁ~ˆ'½R/´¸Ukcv£^ŠêM"ë½…lár·qğƒ/.l3½h<"yÑb/,ĝŬ{ĝEH<’ÒoğNÒE½GȧRâá E?{oE½é:B}²!Ŝ"+úN’ċäğÏvxñï6ĝëof—_hĵĝ“YĠë éŞĵ$y_$Ş­r#Ÿ}° +ú…DŜµğüé šäŬn‚z^,ßfAŬmĦÈÜN#ìj·6Óɕ>Ĵ9„ì[ú¤ê(}ğƒ$nġš׺MèÛ]„ĝ^Ğŭ´ËżñĠ+ĝhBŬìÂÂ÷ìa/Žż”E_m¨Ò>ŞŞû4YŜ{‚Ĵùp†Ĵí>…?“÷{I›ç"üî!öpPHßm§‰7mÖdsÇYş§-l¨O°Áó?Ñ0†ş&ÌDuúN“ġċ0/Eñ­Wñ£ë×ñŻŭ]›.ì–HŜV;Ù>zá$InÔ%#Üü‡Ŭúf$|ù™Ä‚Ü_5…‰Ûİßv‹ÒG ¤9˜Ċş#Ò·%.f•%>–ċoŭ̋*\ĊÏŽInµ‰DıïMÙ\ċʀŞÓç¨ì!˜nğ]™'LjĜ!ĵ˙ +ûfE |ö*T„ÑŸ>SżôџZ‚İ݃ÉáAñpeđÎ\ىöĴĝÀê°¤˜Ş ‰‡ğoĈży‹Û"}¸'7ï+—‰û;Â$ïÛBˆĈn'ĜŸäë[êċˆ0çğ–5Ĵ!yÑê`^\ċ)}Ôq„~Ġˆ¸7‚“OzĊâòVgó޲pqeğŭşŬ^TÖyZRRë"ݨó0Ż{sATŜ~Vò²ÑAôÑA\ÔzŠzÙmKĵîħżh†öXc/ySqR\\{ú<3Ó˽ğ!÷–ñċ ›ù·˙Ħ˜â%ƒ‡D]́ÒŜŞHé`]¤¨·ġ=Ĝ~IÜ×Jt~pTüÍBPñ‡9Vñ‹­°ĉ‹ñá£=Ò$ùTeÛû Qüİ-œ¨ùpŠxÙ'%Żpħèw‰ÈW¸ĈíĝµFè5ѳ[³—ĠŽÒUÒÂIA‹™ô^•YAù°KL=ŝ ĊžöRÔË[ћ–âMÇĊ;íDŜ[aßM°|Ĉ_êe§­¸ĤĈMÔXï-mнdÑ[{äCAŞ}çµÔ=÷’l_&ІëƒÄ5˘ÊgâĠ 9UŜy’jŻ÷6ï{k="áh×͇öĴ¤³ÍİIŽIñ§ZÓċG;s͆‹"ɑ~a/Çĝ~7Aë?âÓQj"ŻĞ ŒˆĵaCêʐ!òm(v ½Ÿ-àe|ÜN6˙.ÒŞĞHfÑXbÓŭ4ÁşûU]×ĉ*,ùnÁıÇh +ž-ĉ[ğŽ214aĞ(òĵħH\ĜdeĠŭ*ŜëVÚÙÖìlğŽİfÍeA(Q·ÚqQ^ĞݨöÓërGóĤ˘`éĞšÓÔµ6žäV‡ùê}ĞïħÜDhs‰)ċñÁ! Èmúîęĵ‰–|ziĠ˙@ĉÖ$cm2·Â;îN…W\vı_ĵC{F‚Ú­Moaœ]×ÍDÉPm„x¨=Ôşçe<Ù2ìÂżÏıßġ„ݽ{H˙Çˉ+_ô͟4œ‘<îĥŝq‹(_Ϗ­[/|ö”vÖÛv?K:üŝq²Ù@] ŬÑâ+îidÙW'éİ %Ëşí…ĊŸÌ~ç Ÿöádiç1²ĤóĴ°áÛa²·É‰uÏxQ}›iáŻzÜËġ[x9ğ8wà1FüĥߏĜw\•gVû&ĤÔĝ%…6\JñkˆH=Ӟ‘jÛ{/Qò&Züı3œŝÔ*úÖjŬ÷ îtkFò‘Îüx‹ÁG1‚ú‡y·×&Żአ;aœÖ£ƒĴĦ"Kĥ Ü•Ìí3bcîŬ }ĉ×:0³ĞMBIz—!•R³O(ŬŽç}Ôżì´7Ğİô•TÖxҏû-„9żj cË6`o×ñeċ°'#˜¤ħÒ)‡zŸ%Kğ+DÍF*c[SSÒüRÓë|䁍a™’޲‹DS׋ĦR™OKTĈĊĉK 1- Wëĵdı 17jĠ~%ŬĦ=/Íŭfş¤ğ>˜(û|”_ñ7‰°á‡Vû÷#Üw Ïä£ËÍêŬĈğòq·¨´ÓѲż,ŜşïE<ÙÑïF–ġ'+ŜŸ„ù³ĝrÌ˙`,ş× KĞO™·ĵĥ뺝dŭŝqܑ{İgÛ²²][eòÀú8÷ĉˆĜÚÀĜĞĠŜ²ÛîħEÎQ•­N%u磋k\£+œ#kë#+áÏĠµ.Ñn1÷+=bŻVúąWÉZ²͆^EІBĴz˰Ĥ?N +3|üŜ?äíoòÁ€Hô°Û’ÎûÈ#3êˆózòî7‚ìv” ´…Ó=TÏÉPc”ĝSu1ÜïK~,ވ6¨•‘=î‚gż °§0ћ†cÒĥò‹’ĦşHóĦw2߆ˆôĉK™gÚsX÷<‹— ”Ùô=K<Ü[t¨÷f‚KGlbd½ü:wYI£Ktq‹sÔĞV稷ħ¨É%ިÑ%êi[l!œw™µ>ñÙU>ñéĠñµĦ‰ÒOo"¸• ͋X%Èc4éğ"ñŭ!KÉŬ^+ñÛöSĉe~ĉ-%aïËbEïZO +s‡µħ˃ÚâÜ6Ħĝa—ämĞ£¸Ĉä—_Ĵ$ Ħ5!™^ġ²L‹Î]Ôyğŝ›Ħ µy‡0ï‹.ùx@D·µúžmMÏ8Öy3Í| ú¢óÁ²Xñ×ĉHëÂĝómñİ)ŜòÄFżT‡ŽœtÉPy$ĠŬäc×]ì×–âß"Ojô–Ŭ¨sAGA­{ì#8N/ĞÜd/ÊĵäOË< *ÙÀ8~ˆjíö´{_ì_žzç­·ìeı{lá[ŸĝÛï|àg}dOŜyɲKŭlz`Œ,‰Añ5¸&Dŝ¤ÔSöĤÌ=:úĴŠZ—È‘6§(Îż)$QĝûG/ƒ†oú9{¨çfü•ÏĒĥsQ[\e…-qmé˘ïUa˘ïµĦ(ZŒĵ• †~u4zĈhpÜ#&ëvP:h~FqŸ@ vj‚­ğ÷ƒíğ´Àĉíš`Ö}`Ŭv °q;À<tÜOĠÉùÛ*Ŭ&F˙òŜ˳2:6ûċĊĝŻŭbŠƒċEAñYĊŝ²¨7Ħ `îp˘5GNô™ġÖÄî*ĵ(9Ş2(%ó] <ğÜ7>ĉ Ġr”ç Z˙~ÔìcQtvwüKèߞĥ:GßîtŽşŭŜ9†úÑrÉ$˙Ó6³lŠĥ‘Ĵ™ğ,Vž€`.P³áħ>_=f6Ĝ0{Òħ›˘žÔWi÷^,Ÿ:̳àoÍ•f€)гÁLċ…`î˜ċ`ĦÚz°xîV°jĠ°ç´.ĠL×Îì1İchaÏgñwŒ5ŭywİ,÷bñ;˜we1o*]£Ÿ”zÄĤUû&$TÊ/ֆĤúÖFĤ¤½ LĵĊŽİŻ,İôBbLùĊˁ'2Ĵû—sÄà€[ktbCÛıÈĉ§8‡’ħƒ†- W?˙—ġú×U ].O1ñĵ3(ĴtĦaŝ—…ßfĝ€Ùm˜Ĝ´\ƒo–.ÜÏ\ÎX +Û0LÁ0ŒƒÇdĝ“:˜*MKĠ‚ ;LÁ~óh%sÏ&h&ÌÓmcôx_˜ü_³Ħ瑢ŜşuÄOÔÖ(î{j÷áfⅺ°¤äwqYoüe×ŜúÉ _ŒğZ˙¨ÌSöşÜ=ĉJ™oôDzgo½dŻ‹½bŠË=b2Ğ|j“ÚÛ˜^‡¨/].iż ž=֝ù9z-³MÛ˙µÚ>ħ‹ÂĤŬÚ`Ċò…`íş•@Ç⤢A@Ŝ CżĞÓtìÎ+-[°L“À0¨eöÛï +@ñϟ•á+`ĞÇÁßRb_›ïó'7‹Àzċ[çĉí2oÙ½ݏw•n1—jC“İŻŬAôçĉ ì—O>N ‰ŻÚa îtŠJhóJïe8û̎€•³VB;T…çÎm4<+EĥhlĈİĝÏz˙żŜÙÖ ßD=0ŒV˜ +'QŠ“àOÓÁÌİkÁúmÖà``Ŭ ŝ0Œ#Œ'ôQ6âÁö£×äıEŝqĊoĵbó‹Ë-ġƒ>&ĉE‰G´M¸Ü˘˙qT@UD²Í‡o=c J½dò²€¸£]9qô/ĦÔo­Áž­IuÎFÄ´{ĊrcìĈżžğeŸ1X8a:löüGÁ3DÏ'Â6Mƒ§ +ŸĦç +˙­5˙ġĤÀĥîŸÛ­ïhìĈÁż7ÎĊ5ûàÎé:7˜Ġœaĉ0ĠŬ(}_nĠñ,Ö#?ŝ\ƒ\îÜŸĝêÌeĦM˘1”ż½Ĉħ•üËb/vܐ/}ôĈ;Ì3ĦğÊ=Vüħ,ŝ=[n†â 2Ç߃rFw7ÇL…#ô˙ú†Ú¨ĝg Uŝì³£—Ċ‹9`½î9°ß§n²N/£Şr=[‘‘ò28ŝök˙„'oĵù&>.ñJşWê•âOÂۗ ݊|â"Kƒd>5Q‰•A áĠŻÖÀşĞÚCv£Ò+6­Ò?ž˙•9ĞûŠÙxkšĤíyĊ 뷃™Š“Y˞Ċ˙isŠl˙+ħvŠ˙k~Zâ(ĝŝhvîŭœ‡ +ìsôÚx½êD0LUY +ĉ¨+÷Û-²u›]ìs‡Eß°üŸĜ²àĝcWP=쒏ò2TWÂÜ+.>žoˆK°ëʗĦ×ó˽cĞaÎŜÜàŭ3×uŽJmô‘[ Ê`~!Ö<5zŜĴ™˙ż}Ż në_ŻĦö*ŭùŜÏvb{fìĦq>™½?=êO¤ôg[DzóoĈ”Í`ġ£`÷‘[*ş7˜uÂ>ĈÙĤnÔİÚìÙğKĴžhɌk(òM)/öNh‚cĜ\âÒöÖ7½­Ü+ĦÊ#áĠ;ïhŸñ‹}âSJFÉĤ0}˘;·ŝ'żïŜŝjç˙tCmû瘎‚÷1lû';Œ‰Ş[Á˘B°J l§*ìğÊÌ3ùÌĜÚ´Üĵ˜ö<(ŝ֋€„Ż}ċïŜĝ¤T½ñͨ,óJ{Vì#ż_ì—Q 󨎍C‡oMxŒï²„Z?™uï­HJĈh͊Í˙v;~zC%öœ•ŝiLŝ|o|w<ĵOU˜ Ĥ+Í“fÀqRƒ>iŒñ €šÊ20Yy)˜¤´Lğ̜ĦVğżVÑ|l ŜxÂĵEŠ qŜĠQ ⏕Ħf/µ]–A÷úÊ FŻA9ùè[‹ËÜeímçboÀšÓı=6Ŝä;c£›ġaùC ˜İ4é˙26àżùJôó_ñÍӉ+Ħ6ݏYfNÚfOÛ fİíêÓw€ŞÛÀ´‰Á´Ñ€êĝġ@=· ̘o†&XşÙì0ËU:˜ÏĴäv3vĥ­·ÂìëDĦÜìÎó€¸û:ßúe·ż ¸üÔ's Ô˙J•ÏċĦZïìόöZ÷”ÊJÏTTwiU3Û'+ŭżñùAÔ>”§ ñRWYĤ*ĞŸ&QD‘ĈOĊ9—,ӕWµÑkÚĜu`ڄÍ`ĉ܃`ÑJ˜ûézÍTşÂ6:SqOhßT“/ŒŬ÷ÚSŝ28îîÓ IE>òŞboyġ[Ÿ”ê +Oyiħ—üí[oùRï¸7Ÿ,ġŒGŻÇ—È´ğÍĠ4˙íĥüċ7‘ÇzöÑ>ú‘ħ>ŸÇQ]e1˜ ÇiŽÚV0wĈV0kî~0g™˜·„f-€YKy@}Ž˜ÈÌ]A‚uFQ`GÇDwÌñ‡çž1ÏĜĵċí¸GĊŜ2˜›Ċ'–ùË`ž™€jÛo`ŝsħòr¸Ĉ·^qoK<`eĈßË]G#—lÙ cë”ı]ÈOŽa=ƒ2ûü§ü9ÇħÙÈd0]q&˜5n%˜5u˜3s?XĥNVì<oµ…ÇQ0gµÌYŒƒ™Ë10sLW׳gë³ïmà'€½žu>0zœAĈĈŞġ·ḛ̂”§!qÏü“š_û”½ñM1^ŝşÄCöĦÂ3q¸Ĉ=q¨ÁU>ÜèžÚPᙂrRŒdÉ6ÓkÌùOfs´Éf?cš{?ߛߝ +fŒšĉŒ_fMX ÔU×Cßĵ +̘şÎż]`–ê^ ĥLSÛÏĥmîJs0w‰,Ŝ`V­Öw”vEôNĠ(dVj•1Û9™C‡šò‚Púì…żĵŝOb3§úJ÷¸JÏd4çŜ7zduĠyft5ğżĞô„µDP´v#³oÙƒÛ6ĥ°‡â™Şâ, Ş+$8ŻÔàœ›Ĥ´ĥL‚c8j£—€éÖÂĥm3fm‡öİ m’fo6óĥ;€EZ`'Ĵ˘’Á*< l²z˘¸7ò×é*™MÄ@Ù9§âôH˙·11ÁobËaîUÛö Ü3ŝŒq•eñ]•‰½ĠòwyÑ[Ż„3ġÉħ:ï˜=³&Ïŝ—ÇíŻù†ü=ŠTӔԁú¨E°M³Ħ=NƒŻO„{ÒÏ÷çġħ+Ħ?„c7~ô›[ÁœûÁ‚ĊX²ċ(Xß,ĠġË´½Á‚.`žÎy0_ÇĴäǂf—wuNÖxÌĴâ1‡éŜ·ž§ËÒüŠb£Ÿ>¸”Z÷, ½éu@vQ‘w<Ş"Ş‚äg[“ċĊ°Nhrc×!E_^¸Í,›5kż˕Ù\ ċˆ0z)X6~!ôŭK€şòbèç@‹œÎÚĤĵOSœÛ·Ìż¨_}#<ĤĴ3ĤA˙żÄ,\g·‹6K÷yœX°È0Ĵ³½¸#°qüŝ[ÌbíFĉÁö’÷ÏNÔgED½ +‹ğġÜ_VóÊ'ĥ­˘È+ĉI…{ì‡:—¨OÉCíéUġîİi~ħĤ?ú׉œ˙Żcö3ŝϟ˙ò%?sáħp´Ĉı6 Žá,ö˜Ĥ4¨OŜÀŽ•ú0úË9ŞëàbŜ0wöN˜SrÁ˘µX´Q–kžë9a`=![?UÚĠ=açCfĥĉs@û£ĊalıÌQŞ0àPûÍhûĤœëž{ħö­ıòÌWċiŻ/ɏ·ċXô—Ċy7ĈfVUĴq‰J.óÓdMĈ'˙×ĥbÛ3‘ÍS€:ë?Ĉ³9˙xöċ È_NS™sıp>ŞUt,Ó&­³%`~|òıò¨Áéû1 ³ê`#£iú‰9ĊûĜ ż”Z >Œ8Ġš,CġŞÉQùĠĊŜñÏJ=b++ÜbÚÊŬ†kĵÒÊ=“°/mîÚ^ċjÈG ˙ŝŻĜĉĜ?c9²O”ЏžĉN]Ż1ëôN‚•¸ Xa ÖşßW^ônÔĉàòħ[üߍÙpîħò*ÛĞĈm iŸ°-¨yÂ6Ò1۝‹FïöŻ™¨ġˆY§ĠÈì=pƒY˘Ŝ>C;ŸYĦ×Èè53B.FdÜĈ‚ĉœS}b,ÊYPğraîìUÈ%xÀÀD ž†äz~rŭoÍ>@;),YħïħKEv̐_Ÿóá™`Ĉ ’Vhëħ@°ğ6ˆ˘À–£×”v„7LڛÇÌ;ŽO-³MĞ–Ù…üߞĤİÛír”6ˆBÀViœÂ.ûk*ûĵ+'íêPÓLü:÷à#f3ÌOô~aÌù?Fİ/%~F} ­Z1Ï8m%/²d%~ç]ÑwFôìÛaüÖaöß4İü˜Š|· ž|ĥ  $ÒGġvâ7§ġNœĈTCŞ4Mé{h=Í4Ġ1‹`żÌ_ȋ֘ƒ%;ށċş.`?ĴĠ? Öï³kĥâ`ĊZ°r.XğÛħP…gŜudœVÖßëÖ1چMŒİÉc}ùîiûŝF´èséÁ·oÎÂÏ?\:J?ç×µ†é½k3[M*·‚!ĝ5Œ…°eĝĠÚèN}¨÷ħxš`Ġû2^ôñ}(Ñ8ìÌ/g$ÂÚG¨žNżşÈԚÊó‘ŝ5á Úi#‹/Üŝ/Ĝ"ŞÚ`îçl§Úĝ`Μí`ÙS°YÏìÀüÁ.Üì9–Şĵ+ĤtꁷÌjŬ ŸÇŒœ}zâŭZjúŻ§…ż×ğ˙hsĉüÎÑŭÎpġ>3|£ïŒÄĝ+cM~êġ7éeÌġŜÌ5²Ğg>ʸ˜1T1֜ü?vòĵÍ<`L‰î!ï£]דuߖŸiÍJ?úŝv*‡gHë£*dôóMâüfœ|2 ĉe}ÚĤ{6uüÒU{Ĝ:íşM‚6_}XNó܋`‡ŭ+•Áï'íÎ`ÔĦííÔ˙ÌàĈż2ÖĈ?ïŒXЍ٭YĊlÑéctL~gğ4ĈÊòĞĵbċ52ïúXÑÈK_´†bmO÷%³Cï³UżŠÑċĥ1ü^ĉ¤pĝ7ñ·úpêˇ‹& ŽÙQEÍ-;Ħ@û(ÑuŒXVĞój“Èġò\ññèİ´×ŭ%DîïFôŭa3<ç³áws‘À5GŬÈ6lôÚÍ<0gâÒ˙ĥôŸĥİó,˜cM^ –n£ÁV³4Ċ½á]jÈ˙üÌÎKŜwĈž÷ ÀùÄĜµ@_È`œ*3.gLx͌•p˜q5íaŽqĞŠóœÑçÉşÖñü ĉq3ûĥ +j~·!û½g~sÔ8˙íĵ Â…ü”ĈmxŜg}âá%HĴĜ„E=_‹ĜNÜi0Ŭ/KŞJÜ,šß„ҏ{,¨´‘ƒdLÍ2ìíò~iÑö2TÒWĈ­dÈM{˙ħ] _œĴ4L3¨NZëèm`Ñj#°ÁÄì8vSyÇĊê {oŝ}v-³Î'ŝKfŸ~Àsu}ûÌqĈŜ÷ԍ_1şd[µëÑד#o"ÈáV?áàÀyN1ċÇİsOVĉž>;Šë0É8ŝŝĈîm  Z;Üy +ĉE€céĴÌğö·ŭĜµB‡IBKW2Ĥi'}§G$~ĠfO½è²˘Jڏ‰Ë+Ls‡÷ Ż}ÓÁrşµñ+uèÇ,ñ˘/–Fύƒ§sÇ/ZħŸ­³˙ùĤ +cĈÚ B°‹ +Vôx1ù`-£aô‘‘š~fN1f_‹y0îâ_ùâßFüŒĦo08Ÿ7u§†Ĝkà8œQ1½7 /j-ġ:ّ“éÜ&O·¸öáÖ0´áĠë‚^Ï3yÈhp_1Nf÷f^̓ċĵ‡?ôñ§ïIìî İöo˜S˘šÀ씒‘İ`ÒcJ,' ñ÷½3ĉÉ-{Èkß8Ò×­NÒâ'AĈÈቋM“TOĊMĜkr +,šµ•ÑJìzşÂŸvİĤ(Á¸6s XħCvJC4âûfk>gÖj73û e¤ÂÜ?şü¨ßšƒ-†_Ģïŝ¨Ħ˘q ÷Í{ġ›˜,9.nlġ“Tĥ{Q÷‡ĊĜù´FšFÀ`÷.@ +H€ç'Wnċ=ŝ‡/ıt˙\$´Z˜X´ËÒ%î +„‰ġۄžI3İ€ôùâàĴċ”ĵrŻYN!}[áb^Y }Ŝxœ.|/Ĥó;ùXNÏAL^ħMrcħљ¸ èûĥiÊÙµƒĦħœ1e˜żZĴ5r{nŽ>x—Ycϰ<ŒÖè ‡ʸ—Ħy ŒıÉ­żí6ĥñP106úÚ`Ê7fhyÔu‚•OĈr:Ħbú`ǘv,š v/ö˘cĠl Ğµ`ò˘­˘WMGˆ'Ŭ” áÍ&üLÈdöúóüAcöšè£c +çQˆ%K§wë½şdô‹ÍDfŻĥĝFEÖġž•´Âŝv‹~µNpçĞ!^Wf˜Fĉ-2 ͜Nj½µ”›Ġ¸•›×ż[ŝbĉš9wLT£\Òf×ĉ×çÇC&êk½ûßĈ+>ˆ%ŠBİ…"á›4GXĵI ³Yòf+žĝp‹0ċġ6ìê€6yŻ‹ÂŸ½§Ùë*/%/"}Òçáyz’'ġGÌ*k|ĴŞ_‡šU”yIŠêÏ +è }˜[ì4Ċñ†~9Óu/½˜µß*Pií LŸ¸¨ġĴCWnäMŻâ):mÌA~†Äż|ôĊ‡~ġâżfHÓëŒ&Ï3išéaĜ—Ž…ÑOVŝó P&ŽL@LA  ğmà4y”Ŭ+IJ|s—˜;Ç̤ı ß7…~ƒKž‹É+·aá÷WÁ+ȋwVˆ²Û ­rê$TBċnÊ-b:ڃA„Ŝ\gukÉ {ñ¨'ë…W?jKòßâŝúPi[Uˆéżk +}3ĉ’+·`OFH³ĥ² óáw2ê{K°àÂ˙•q„ñì¸A7ƒ2; ÎċOÑàZ=ña“ä–µdkßyşŞÛ‰xüžI˜z€àñ-ğG#èéJ,äñJCì\ĥì_½p´4ıĜJÉÚÑSĠöŒ§šċIŻ)RיxÚÛ=è:_úQ³9v˙=Ë˙ĴÇÏíŬ/ĵ5 É_BÜìĉ˘ëj…׿éòğĥ“>îÀŻ˙Ŭ˜ŸP³ ?ŸĤŽwK¸ĈNdĥì!cùşü´šmüè×иY}Ûy÷]Ŝĉ '˙Ç.ëßn|ÙŞû†Ù­7Äp aÄz#Œ‰a3cl\Êq^2FĤe Ċ}ÁGİÈ·rUšŸSĉáG5wkÂù·€ùîmüBîBÂ3a&韽íġBûİK—— >ĠÛçîÇ[ò’Oĥ^M³,+ò]äĦÏÖ—žŻÂ kşiAfç^áÏzXAŸ V°wš†yÉgòŬÓĤó‚n/àF—à:_U3žSÔĊŽ+‰]•¸¸£˘1ÏZAèŻÊ?5Ió,­Ĥşiƒê| ½ç Ŝ½˜qY1Wh€IŽ*ħş8'/NÙSÁa[‘ŝ‹ôxà$ÄŬ’œò™DŸtŸ€ö S9ġĈ’û5VâÛR,úġzĦkÚ Lön?gH¸µiuñÄÇ1hĞ˘û]–â‚ ~ċ“êG,Ĥhá›5w‰T#/ĉ/Eì@ìÁ)÷ŝ/:Ĥ_uLï|?hš˙eż äÖb˙y·äéѸ!ŭ1ž ½ùÖgàA÷—cgC&!ğÇo/FûJ‡Ï2‚y˜!W„"'%Â;k.žÔĵ›Ln×@ÜlÄ3byBm¸ú.ÚÛE$×ìÁ´jb9íÚhż8} +á6—<݆Ÿ ŸŠŸ—MĈÁ8Ÿ;Ĵ!HĞßizmHCxoˆ‡½ê•Ïz%ĝËsŞèŭ!ìŝ€ë‡.ŝdHÄżŝĞf0Ŝ„²Pà™ŸTBû·ÜÏ’'MGÌŞßùHË+=ˆ^á?t7ìŬR=Á!°V})X3q|œ tIÀ·;?Jpäü(SГʘÍıQéYe -°úÏŭÛw³zlĜ™I„ƒ×x…­"Šô §qbÇ ŞĴf”ËXÊê„2mï4ħèĵžĝv‹˜(è1Ċ“ĉâÎaŞ‚ìĤŬĕ^=Ä5$΅NŬ#Ġ‰ì&mÉR[Ğ’'>vuwc̟Wž! éĦ=h”ï­Ċ„Ĵavoy!s!ŭr#~{ÌVñóhË6˜şĈİò}Îĉ…X"8#ŸŞ­녭{ÀŜíÚ@s·>0á[+ }–ücc·._–Œ›–NTk§Ìû`ŝò+3ïôE˘È;ž<Éë(yí>³ÀüU´ù e¤ô¨2Ë"DZgĤˆ|cĉPqĥïö 3jöÀ\zARíVAÁgêv?.¸Òħé(§‚'#Ŭ<úÉz,i–Ö´‡ĵ< ÏÎġÛ+‰‹—a •ÛțĤÄŬN![âU·ùĤÓÔKÀ˜¸ó˝'8ĉ7–‹UÔÓ%€pçŜÎ{ ~*r +îž=q£p[ÏÑ\ÂúŽŠĝé˜İĉ~³í[!ò†È ‚Ĝ1ÏħĜ)˙ „w&Œç·a>?ƒp‘ŭô‘á…k°´Ş=DFğq½Ûˆĵñ‹çöé°ĵí[½ânŸíÓf´íĈ>_ÇÏÒ@û€P-‹ù&ž I—Göñcß­g}ŬƒÎw˜,<á>–ı³B˜3Ĵ‰]ÑBÜL,ôör,èî2ĦĴt#?Ğo7ïú÷'ıŞÇlYħĴ›ĥìXşìÙ¸ê`ı_ôž0<İ~êCÚ'jre‰ t+qkÀ”~Òe-¸ù›?ìċJaXċZ^ĉÀÓÌÁŬ‚Àë xÖî*<ú¤˘ĦZgyNsˆœÄ?â6j×Ĥ`üċ`Ï6- wÀúM@‘ˆ /xm$­TW”Xµé!âò…R`Ê%Їé3 íġGÜ:ĝòr´Ĉù„‡LK'Lkۃß1Âò?êâQOבç“Ô x ^<éŞÊîÉóÏfó›Ĝ·›X`Há*,îùF<ĉÉz"0tkİàJ÷~Ĵ ŸCôñ°Ë_´ħ‹w– ^_zJ‰KVä›ğ(cGƒĈ›"Ŭúgżñˆİ'0wQAœ=ÄÄûŒ!=ÒçA…+ħ„ĈíÈóĉó‰SĦ“ñ“A“p{ŻqĜ1·1ˆIúß\"LiÙĊîAŽz¸N˜^ħ í­„ñÏLrżÖš.l‘H_Ԝ _7Ĉ úM…‰ċ[Hû…WĦ½‰h˙ñú½?˙ĞĤÀ#M]p&fŠ7{ 盆 oH ċ;6µı_´ Lxè” +ZÓàŠ­YN‹ĵr ?£qî™5ÛÔÜYYkŻĜğv8¸GÚ%p8ˆ­…6°ĥt™€;¸Ž:Œ4(YĈ‹µ“ +î; +yĵ1}×Uê3C|ÈyŒÙ!—ħ"ÊZQrÈyĴÔ'k1™Tıħž÷HTǃrcY-û‰Œ 2·ísBŻ­DkᏠQqëqÑóĥäġ^ ·Eƒĵ˜³„ôŠ‰EŬY-ĵ9bÀî]~Ô'ü뎆ͧ˜İ˜SĴ*–9´_˜=x+Ŭ* ³ ÷L%¸poħ\˘šĤ&ìXżèî3HÇi} ĈÔF‘e~\eÄ1§Ñˆ™ÊÚ%ô›dLÁ:"ç½–UıvòŸB9¸Ž§ŭçáħO6‘×2ĝ˙ċ}Ô\í9@yËçç£ĤQ·–"­ Ü5z鯎â$é•8‹e꜇ġà9˜‹û]Y@z&ÎbY’.ħÓñcñ~YŜN•ì£cäTìÛhĚGŸAû£JpĜuÚ'x{TŭUtèÓġ¸ƒßSÌZ#0Ȟħ)Ï´9hò?j néaWû´°œaaFû>êâ­ċˆíŽ8Dv—6bĴ!öžĝ“aċuëQ9&dA‡|Ô)!vP‚ĞCšDÄ5ˆ;‡â†0ñíìö  vó“0l3ĉ‘9 ­Ğ ĠPè33Û÷ĦK߅ö#ž?bG +ÄpYÚ+aç#Ġڀ0Ğk.+قòc¨G:Hр:<…ş˜½ħ))żì°/gPçb§Ħ>s#0;ĞÌ·:„4;äšŬHĞ1DĦyĞݨ§›[ñ>YĈµwÖÄeYÚ0V’Š·²Z÷Âù¸›ˆ´‰”żÙ‰§VîĦ/×JòTv•qıV‡Èí×Çoġp¨ÇïÍèşzWiGYˆ´ñ?ÚoQô™şß"B>—ˆŸ çîVâú€1ڋ‹ßĝa$ț£‡ƒŭ;Ħ}È"£G‹Ìé1@|1Ì;sĥ0¨pİ1Aċ˘şZH³Ġ ˍ Ì]Îê1Ú¸ĤO†NaµÎËf Ĥ<ÒUBzx(ÖIï—˘o6†°<_œ‚˜èĝµACÁĠMÄ6›v ñE,:¤Y@ƒuċÉ “ïô9„/Œ³° ĦŻ Üd3(—ˆi„[Ü ÌÖGŽS ÇHUâlÔTú¸ïüdÀDĈ`¤‹‹tCXPñqEÒ9zÚߊeibÙ]ˆAùĤÏgµŠÂa#/ŬôĊ>ÒċEÚLˆ1D:úOF âĈ{cúAĞX|§YBŬh 1£ÑÚ Ë +ı’ĵħžpÙĞ͈=ƒ´ApX'áùXŝˆž ³cš3ˆaF!ŭ™S^(ßäy(oÁô$n.AşğĤ°–A5Ò"ƒ.F6ŠĜqħùEÄ|q%<ê9÷ɟçĥuñÎ +Ï +èì×ĈĤ4ÀĴUhż”ùˆ#Ž8@ÄqïñH ñ ‡ ĥŽ*zF0!í`_ÌCì!ÄtĊ-N)#– Éò³Ż.aY*èñbŜr:({z{ ËJ ½‹{ħ‰ĠıÜ­'ŜˆYŬ}cgûàù‹;ċ6Tv‹Ë£€cMŬk#ÄĊÍ’Š‹]EQhŻb•ˆoĠ“h_>ÒcʞÂD˜RCĠżOúl˙HÀmMĜğf'0€5b:ħqó¤˙c¤G,9Ħȳ<£lĵ‚~Ó +VΣ{ÊZŝÚ,İè ËN;ê7ħ˘n bè“ÎQÓ#Ž£Qܖܭ–ZŜ+?JE?ڈ¸tˆİ„É_m! +†ùĝ/Ŝ•/ğ‰€‚%ˆaO„œ2ĉéFÒ1JÍTl£€r=2ĈgQ]-°<ŒĜŝĜé‹#;>EpÜúLßñ¤=ôuNÁŞ4âMşÈg +9ݘ˜À(¤â$³kžŽZ{ÄKĈĦŸ§Is‘Žċä;™>¤†¸Œ¨]Hħ¸é ë+ŻĈ0͟ŒĴ+‹ëéħÌ(ǰiˆcˆXÂĴĉŭH_€Ġ‚EzŞħ/· ĵ‹şÓÁŽ~Êg‚ÜN 3?öS·1–aĴĤÔì$ĤqEöŠĤ$ô„ië2ĊÒC> w šÌ3³g5¤Ööl? Í3Só#Š,g7sŠ(Gáh€[žTAúE°N™A{EÏBšX(ž#VÜŜm,Z'ÑGaŽ  ´vEœ ›Jr- Ž²œ" +ħò=bÔİ +KaŬ~qÉˍúDFµó`Ëĵ‹¸ğiv"í>ñµĦċ³×gmž?u6ğQ#eِħŻĥ 9*”żŜŠb9ŭĴŬ’.é8öéĦq\ s èˎ(N10>ĤÏ%N…MFkU¸kâ T# ­4öƒ]+v&€o}NE qP2€µĞĥ>ĉÒ0‡ÙħúÛ<Ħ…br#ŝ4â—"ö?nuFE€RÄ-OĞÎáӈ›+DÜ&;|FĊ˜ÇHwíĞGpüC£ô ĝùEV§ ĉ¤[Œéž6'nsLq1Y½Jh_ˆ Ċ€°<ŞLŸ‚6ĉè?…<ç’gÒ¤G€ĜE˘ˆ‚u,—ĉ¤ƒ +ËĞ +/Ü ğµqıfiwbâԑòwğè°kß§Ħçñİ‹S^7Ò×ÀSËv“YµÚ(7CÌPV7Û+aâ`Šn·ˆ¤ëŽˆn5‘xRéN4‡‘6ûéĤ"f*á3°/´>Ğ‚´2(ÇVcÙš—<ÊR;â<ŠĠòÏXHœœÄ7‡ù ôwˆŭKÀZċNQjˆġ.öÍ[ÂêÍĝÉç"Ŭ'VÓµÖ-ˆ•Ž´ş0F ½-âôÉÄı5VÀ;mžĝÂ͕,O +­sĈŜß@gĠèŠŻ6Déġş¤ìÉfd—4‘€80;â=ÖTt\³u…C}á¤bÀ`Í£ v,ßv­Ût4—ÓRgqL wŠV%.ŬXJ8†MEœxÄReu„‚TĊîQHğo*Ò3çrDqŸX}6ħ‚ŝ]‚bb QuڈĊÌúĤSî„iUğYŝÏó âÑ'–ܵiŽ!“àÜP4‚µ—‰) âÙÚÂĜ—둟ÔÓ}}.@zWì8…OCşSĴŽÒd–Z("Ŝħ)&ÚRħĵYFô · ”ıħ˜ĊY–)ŭ!•\ĵW’úJ‹Ž|¸Ù5a{FñÁȄ’]dZÙÄŭ˘<Âg°ıVbñN<£|/ÒaxGÏû§/B:’‚µˆuˆ'ïçÖóñœ=âô…IBËcÊĴÎy`ÊbQDŜ¤;Hĉ yFlĴÏnÓdYL×–’vÈ£ž08˙ĝp<Wš +{ĵOnÙKGWî@Ĵ8¤£†Ĉ ­!6yġƒĞy +ŭ éž:›ô̘ĉëáÏÖS)tF—ž$£ÍX’ÑdL¤WïGZˆ"ç°i”_ĉÄ2D=t=âŜÙóĜœ#ĝŝj2l;öá Ġe(ÉŞçšg×òE—ëŒ?Îċġ"ߤùŻ¨Ù˘èÂÍdF™Zİ ms›“Á܆ĵ²ĈşU,Oïx$¤‰‰§µì#s†Œ¨ĵ´nÖIšÌ\ÀĈŭSO_ĵĥ ­Ïžùó…Ç/ŽÇcT1‡‰Ĝa—Q\ÒBAsßA°wÏ€â`‡–;bé­ˆËöĴky|à6ö*H£BŭbЁv6T•ĠĤ…óġ…8ğĈ˜Œ·“öŠŸ8òÔ˙Iìz§_ +Ìğĵ'‰N¸ŒƒÏç³ĵۃ\âŜÎżöY›pœ†˜Œ\ÑÛ~êgC§ N:yħ`ò H;qé)Û*fqs^i ^ñóP †["?nĤ`dl„”ıâ1˘¸‰x[ˆĊx¸ÍI–?y1o™(áġJ^ĥé²"ĉ(ЏĜŻ0¤‚2– –Ĥ ġĠ6êv+&ÎiàшĊ-=ŞÄjÚÀq1ÏĞ EÙµ†Żî&²›R×ydÄŭ5¸£ßDÄ'ÏĝMBZÇè‘<á9ċĉhíòğĵ1ŸQkĥöü(¤ħcĈÄċ3û5Éĝ†]†˘ÚvM›²ë²›´…éµğQ͋4³şğ³Ùĵ$µQħŜÈÌv-2ız?Ò> ğAş~Hk†HŻ: Ìn܇8ĦhM„ġż¨Ÿ/\[B¤ĥ7™ÂÏk#îƒô|˜:euZÍ{´ĉ$Ž,ÜDdÖhŠsêxf9ġ„(­VO*߅4[İè;ëëŽòż„Ġ½şpw•(ğLjÎûÀ#.ÒÁ2ğöS·—ħëÇò–°|ğüN´°ÚF|·Ġ ,ZÏ~q*j +ĉpqŞuMa ˆt×ıÔaÄA¤ÎÊÔhĝ÷YŽ$ҌvÇ')ë XŜ1ÒVAüBIháFiÀ•ċÔِİ"‡à)"7ù,2µá€8£NŸŒ~·UìİβQ|EĵëÓ>“Ĉġ§v–ó²[]<ñƒ&k–İĉ“>ï/í,”GáâÓÚ+Qˆ)š¤ŽÚ+ñH›/9­Ž¨R„yˆ‹b-Ğı-ââ³Zx.Sé˜w;Ä) şfÉu†"yĞċ}2p’Ô5nĥ$¸p=Òĝ2;ƒ46΍eu°áyIœ²¸ÉÈĵUÔÍFžèUôEÙ Äâ64cü'‹;ĞRWrµÚTtÁË,Ù²¸QM™Ñv֛sĠ#âÓŜ“0K˜[Áü—Ġ^„u bÓKü³–˘XxÄ;Ëqûà +'T÷ ŭ‘oŝ"‘÷µEĴĈċ…k+P€˜Elqg5êCd[ê¸"ÒċCö/NİבĤĥˆƒîŻEùݐ²Q0Ċ-7ĉÒj€q™ˆ.dëúL„*b\Âŝ…t ĊݰżRZÄA×#Ž:ú Ċ1ŒĥS$-NވÏĝMfœñOĥIÒ Ì2j8ˆı‹8ÏHïˆŝ,l+Ğ‹àž6ħƒñÔÎ}xôğMDà½ċDĝKXSĴ$ƒïĴ´hHWÚZ=î(yRy˜}Dzžˆ(Ŝ@žOe},ҜCßӑ>ióşÒG@ü;¤ŬAfuDş':†@OúU>óPs…żôĉ$“Û*(.²şY'C§"­´ŝÎjĜıEóN|Ĉ{2 bĴ".7НŭWfž(݁|dÎCaÌcvÖażq+Ge¤-+¤Ž) É£ŠˆÇ-9á?Ibç=iœ°LYK§QË´ġžÀ2•/ċ,Ÿi@8NA:ÜHgFšŜh‚4VXmc‡ÀIĴnĦßĠfŽĦÓ͏{NBš*˘KYK˙bq‹‚.Çò:ġ¤J™—½ò îuÈf òÀOĤęHˆeqß\Áêa#?pı]Îoċ™]iP™tH£Yí,³Y!7ùl¤%”X³ÚYâÒÎĉÔFġ!ú~‹cŒħıÒOíĴV+€Ġĥ99iS°Ú,—6{>â?#ÛûK;KœÜ|No?ÈÚ1œ|Ò^Qm iͣψ‘Vùé(Ÿùf,@çDòKÙ¸Fúò’¤†ƒtF§.Ò=ÀĦÏSÖ +Ĵ~ Ò Ê]Ž| ËA Ë_CĊ>Ù*JĞÓA\]*ĞS1‰ÔÖ0ĉħÜy,ú˙àÎÏùî|v¤°ŬÊŞĝ—ĝj— ğıŠ]7D:ŝWàŽÑŞìşbXáZ"ŝĠ6´η9ĞŒXÇ4ÌËQ\—d5qј£ë­PÎÉê#\¤‰(ĥUˆ­Ù\es>9 +é"ħz5HÚúÌ(‘=´›sáÓû\tµŬ„ĠÎ +€}û—vVÒ΂ùƒ÷DħOÂ\ȕ¸Â¸÷§vy,`<ĉÁ&…§ĴI üżÌ,•(+{ÄZ&6 { Ueġñ`c×DÎNĈìŽ(#}&Äôfı×ñ/ĥħ,n¤³4:ÌN\˜‚ôêÌܢf‹/ċ­¤c‹vRˆĊœ·é_‰ŻÖsQŽŒË"Ü`ÎtÜá6ŝ§vVÌ<2·É­RNH;K +x\¤gâ4étĦïŬ^ŠCbûsŝÔΚ‰´³X^é_ÚY6nc¤îéóEQÏ·J}ó—‹axë˙üyTNjÒ#ĉ6Ğهr Ùë]’´×Úf­ı…Í@Üg¤÷ÌjÁ^ĵµœ¸2¨KçôsGiÇ"m<öó0v˘5BŝtĞèҕċ?u×O)#­D¤?€ÖÑw^& ¸´˘‰@x”­ŞÑz6G H›‚>ƒŒ*ڄrIúą‰Ĥ< `bLcÒCJאR˙”EHĠċĴĥ)Š;nDkĴì…Ë]S€jVìzżór қGÚYt­$eĤˆ´³„¤mù'V;Ëŝ@Ú!jbGß)fǜǛÛùMD´µ(Òú„Šè8ŒŸHğ úd:({)Ò@DjìÚ9Ò5KÙO%—íCú˘sħ3¤^™ ‘FQƒò|ô=Êİ››Ġ'ĵ”ş˜È¨ÑDħ…ĠH¸óï”ıÔ9ĜF¤Ë‘U ó­J-݇lä¨×ĝ˙½÷ŽŠ*ëĥG fÌ˘ĥÚbÀœckÛmN ıŞNĴD@’EÉ9KŽEΈ€9çœE‚(QÌَ_¸÷ŝx{îÒï~7ĵñî÷ŝó8J (ŞÎ9{íµĉZ{Ż9­}2GZĵ>jвŞNĤ:$Š•f +p'ç7,ĤÚYTżŭÀ$yŝMޝĊċ=XJµ³‚ò m„ı(ıiñ!{ǀЛjSïĤÚYJè'C;+\£ügí,·ŻÚY;{²VŽÚrŽä–ÁíÀĵŽ)~oèo“@ Lı+†ÌÏÌQV OòÁü½µ“ĥ\ħtİ€¨îŝ>ñÔtú€ĤÁ%žÊ‰ı—˘kH_ŞOĉèĠšßb@îHEÖÍùÜŝWF²’ÖĦ(·vĈŝry W£y‚ĞW/…­öĤ"cĦ 9ı]`OĵĈÄLÎXŞ6k ~ICQGDüAŝ†÷E şÓò-˙ĉŒä“NLƒ^´ıÖÉ£2x›sÜEüqúH)z +´|)$q[€?‰%>—ä2‚OĠü~+yEÛJaoû&ޝŽtŸŜ–˙Îòŝ˘ċĠ[Eµ³ÍÓ.,vÄ ´”ÙtıCokJ˙ŒRòV‘­v„S}kšûg |ìùw—R½‡ KCıìĦW@µÉ3G~İ{퟈8Èċß[&”ÔŻe‹îŭĴÈğĥ´†ŭ94—)ÑÇuñçKû¸“3 K*ím2ÔZíŠÂÙştW9ù÷!ùÚh>·f0OrY¤F;‹ÚYM? /ŒÄ}íĉĜƒŒü€ja¸‡öSĜġ´p֑;†÷úޝ…ú4¨Rl݁”txĤ–:ŠĈ÷°|}>ġàt1ÒeÜħŬƒúaŻĉ8ê&Êb}.ëÌ<>ÇT7&ş@ŻEìĦǕtjŽr÷ÑiRpêHĝbżÙħ;ô· sÏç]XÌ?^ú]s‡–`hñ½êҎ´ĦTÙ%ŒjŬĞŠô…¸² Xż`‘ği–žrÑeúœ³oKÎNKfµE ħ“â_púû& 5ZÇ1ĉ›ğqĥ~=”1ŭ‘ß*ŭSG@ó>™O9:]*lLyħVħ5°|>ïÓħPtÓ6³ÜÜÍ {~Hì–BS}Oc$‰kTg5O’·aêŭ’Ş lê9pë/FÎĊfž›oÖŞœ?qÇ*:Ÿú)ñäl‘äŞÀA}S£)œ4X£CEb(pjúù~ š(à!XŝXûN  ûB4ƒqżĦQÂİOͲn-VÄş +´Ħ‹.ŭÌlj›–  ħh’Ppì“/µëuRy“‘MUƒÀ˙ ]:Scè'ÚkQèȒħÂö˜XÓǘ°n}°.Ċf\šĞÈ­Yí,ċŝVVñt´³¸”CSÑóÁGUçƒËFƒËš5çËSİv´BPÏJ öSN‰\/´³"4ÚYBÖم\Ŝġ#h½•Ä|epŜŠ5‰ß‡f 0›saF;ĤtœU6ŽjÍGUH™çò9×~ şĥXsÙ=HLòhĝĊí›Â×JÖ*JkR’÷J>5zvù€Ŝ“f–Ò7w$kïŞ#$šŽš†t‘¸ˆÖ6ö´­Ü\DġHŽEsĝ“3„ü{? Ù·–'™ZĜ0 +ĠÎîĵwÔ|$°ŝA•œ}ú(wĊċKĴĥ*Ğ3£Z2~izÀ +’™›‘|]Fl›U20BŬz4¨kP FuNú(ƒòFCğ 9ŸR<šBTċxô˜:Sĝ ìġK· >‚GH?à0ŞClIL<2ëT}[˜.·Ċ›â}`01úĜd.çŜRÔDĨòñüFüĉˆƒĥî+òQêsFC³šöı¤ßZHġ‚|İŞÒ'aĠ`&c*¤“¸Mr4à}Şc\UŞÏ‘{Os#èáú’ë$vúEÓ]—O9>5 éX³¤çŻ­41ĉ‹'ÉûÈ<ËĠΊ,m#s*÷2ĠX—"öNĵoÙ÷°š B‡:ħz2Ÿv|&—wu1ħħ%|ĉŠYhÍ*qßTĵĠ†‹&vO>X€ú6èN‘9Ê%‘\Ĵqıx¸QĦ8üÜH^\ğ{ì°ĉ.%œ™E÷Mú„ ?²´9s×ÉŝôywÛ#wìU•ġĉìžşU$Z‰s†/’‚ŠĈħ$×@î}lıöşñÁ½Äè“hΜwuİè›ĦgİrÒb ĤĤÖa{ôĦğĊûË8G-™ÌŠ`CKĈÒBĊ°ö=q]lÎ텨K|²§\ٍjy’ÏcË'@ß +û—¨&QâùYŠìû Ħ9M9Úç@rYÔ˘8hmá~ŠÉggsI'Ĥ£–Í9ġ–+=şCGkèbô‘ÉT…ġB“Ş`,tÖPÛF/™veÖĴ¨ĉ!j˜°‹˜3Ó¤ÈĦV†–èc˙ ŻŞÁ–tUMR&œ˜ ğ§czô¸ÂóżGíZ(o2$ŝ{ïŞ+8ú÷ĉ6{êˆğ҇a_w°ÓDy¤Y÷6›ryġ?RÍÔ¨îôİ9\ÑŭŸĝ‚û?KħĠ“İĤ94o ĉ£˜5ñÈTì/„CsFA‹Ëş0_ħ·mµ<ïÎBĴïb½™ö:şDö1)á4ĝy`)Ñ'rĊ)Yß)#ŠôéšñïŠĵĞ ċYçfŝ@gùĵèŞŭ +ŞİBâ +ġyÑEĜ2™êáş ~¤1‚Ì{.éŽàs’·Ìž°à‰"8”uè‰óĈŜ3²}4¨[Ö-Ô×ĉc. ~qñ{&p%-а×S:ÔÌré×P_Ş̊÷>†Œ%ö^Bï ûhÜCí +yÑŬ•İtmÚĈNy/b,ŜŸµsÓÁž ÔÂĦSÄYo×ħ´°Òh"úg€Ĥ + kcĴ½SwcӊŒ°Ĝ֘½S†hôÌÏÎNE kÀŒ˘gxމEb40ÎM½o²˜yyê3b4ħ?r~RÌñİĵOĈ0ì‰à\ƒúˆ>ħ$ï˙Xâ¤-{·À¨_ +—BóˆêAk Úpŝ9#gÓuä 2 ƒ^^ÚљÀ#T·šíQHŽBġ9°v_NµxŠj–BğCó=äŞÄn Ħ(nûYQĜĝ#|ž˜@°t•kSŽÍT”µ”Ş-ĦƒµzŞġµ3n0Ŭ{‚Z#öĊšÂG\ }cü ˙Ŭċ²ĈŸdE÷P¨ŻÎ£k:Ŝ$vÀvÈÓè珢뀨G`ïp@ÖH FÎ˙ûäEw(vbŞ&Êm}tdÊíÚÈ% [ÌM8Î?•ÄġpàOû­âŞ ¤0ġ(şVĤ>=—+ù™W_[ŒuzÖ6°‡)ïÔM•Ä²È +}yŝĊxş^Hì!¤hĉµG_‘zhŠĵĝŜRyŜ­Eòœ ‹Êıô†>&çêÓ[Œ­0 úpĜCV=^p"1Ô5ĴŻä“=Z…"´´ ċ+ˆ=<6Ir~X{ƒŜ”èîۗÛÓ_ܕ8D/'>Şh4­ó‘œ‰ĉäïp /mjdÁ˜[Êàhä&Èwq߁“°ŜÊ›ċ·ùöĤĥ irÏÄâïħ—GĜGB<Ï<·xzZÈħgKŠÚ3{70ŻpX/½sô;GRŬtŻĝÁtÏ´à½S†’86”Ĉy轟ÂûfêAәê cżbP>Ġ얀} s‹­_ÜŞĠD}ÙıTç5‚C1ÇùÔ3íSâ¨Î´bQg'sLÜEî]8ħ3’ŸÁI4ŸÍĵ4LÈĉ_Z$$“÷ ×IġÄ  +ŭaÔyP'÷ŽD×J &‚>›XñÄ}tĴ7ÁÛĜKMîÛîŭ“ EGġʰNç?y´ë0·é}€H99îŽ?8û]Ħ› BìÄü˘Ü[ĝ+eHÑ÷4.%›I5ÁÉ5óğKĈS;Ğœ H9?]‘xf*ç9xŽ^ö½Ü_ŠùD5ĥÜu nħïÙϲÏMĝ}ύùŞ#EòĦÉĴèŝ#cgĤÒùíA·˜ŝôĵéĵ>=ğëÛñíĝv|;ߎoÇ·Ûñíĝv|;ߎoÇ·Ûñíĝv|;ߎoÇ·Ûñíĝv|;ߎoÇ·Ûñíĝv|;ߎoÇ·˙çÀ`íĥ-klvĜèrt Vn\hE~ĥ°ÙÎS×D×ÀjöJÏkmw8şm³ñôÑ_Ч8Mòkô—êOÙdcçi5Çj‰ĠTŭġ§ĴÜ8wŽùòÛİú3ÈKç̚·@ĥ…‹ŝ͛ê“_ë›z::8n#OZÚÚ¸Ĝi^ú#yèÎ\ĵhɳĉÏYĵHñ’ısf-œ·`ħëxú‡ĉÏZ0oñb}<­ùOk^ŸŸŝǛ¸ü÷ïí˘ğU—ĠŬĤkğDÊT}ŽĠ•˙Ówä~ü€ûħÊÓkûV3›äü·iž\eG.à?<=Em›ĞŬ}úĴ>yZÑTŬ9ú+Ƀۅoìt½È—ıúsè?·ü`Hq"Oíҟ;GßX_TÎÑ߂×[³]Fİ?—|ò˘y¸ĥ­˙£×6|ù›/_~_@>}îô.-ǟÍÑ50 ç#]Şż`î˘E‹uı}6ld™µĞ™Ĉ,clı›렅‡ħ°YËTnÓÍÄÜĥ›ħİ}· F³nch$2²­Ŭ,í‚{ SfĜCfbËN3ÉCkíJSfù² ÌĈu ½Í£ÉÇç áÍq‚k`JAŠN½EwŻ¤Q%]ÁëÑ\µĠğ—`ż½‡j[d'ù|ŻĝÁ [aŬûRÒ;ß–h–V¨şÉE[--4ŬâĦƒfI4Dóvž=@n!çı‹6ï™2B +GŻ +OJŽr1Ŝ9 7AAk)³îf)lîĈhÀ™\ż›o) y¸·Ş2¤l,šĴÍ%ÇnĴ­—H#èµÇT(Ñ@ĵ•ĵ^q?=w˘äLAEcÄÊq|PŝwĴWtnG2y>mï“6”uéeÜĤ BZŜ=¸% ÌI7¸S2ž¨Aôž )"$ç;4iĦ1€nÄ ù…•³ĥ‚·Öñ£™ÒA á ˜65·ïffaÓÍÈLb@&e‰Ĥ Ŝ…Uoc5l1hŒµ]µeäzĥ䞒ŸAòıvÍ&³ Ĵe£úÈcúÈ6{뀔ÜÄĴĤ6ŒLċ¤ ROCKáÜöäAĉĥچĈ³j½)cŒĈ]ŸÂĥ¤üŽ”Aœkd?çĤñ sĠíäuWƒtĜşH˜p [²´ÚٝUşwgí½{HN!}•ÁŭDŻèVAi°ıħ˘š6ÒËÈġ’s½S‡J…£”Ħú iPîJ +âIJÔċ7öğìê­pÜĠCòË˙ŽÜßQ"7‚rFKêĞKÄ´ó ”AI#ñžĜżÍğ7š%(éJx%-䏅Í[ùĤTyè*=½û*½‡‚Œ’Mlë2 ÖfğˆAp£°rÔfm·éPÂKçà>œgP?4ŠŞ³G£YĜŜ_´ìMɏB²FĦ™LòN*¸öa·nïÂ1ÚdDl_á°­;gçĦ2 ћĜĈÎèA PĈš.&ŸÜ•'¸ġċÜûÀÎÑ ˘%4ıDŸL=ÚÀáÑĥ)…”Ž„^Y7òj—ĦA“Ґ`°áŭ,•d,ˆ=ĤêĞÑXU>$T¨n[@ÚD9XZ4–÷ŠÈ;íêE›dKĈ6Úğè%£x×f‚Öş†ÄGc,X2ߔ;ğ[îÚ2Á™ŒċŽîrò°œ´ŒMĈĈӈó¨ĥiS2ğ]dÎÛv3“ĞÉâü@DËm ê‰Ĉ"Ö5şÈñ>fò-ŬÌY‡n” š\šħùCx‡°Ŝ–JOm|7\-:‡öá'4!jšĈA¤ !'ÎÙ§—èÙW&ık[JďZıuÂúJŜİ”ž ƒ%׀’³Oo4ÙŞ|“ôx[4qĝö@/B›à@2>}¨èJ<ä0TÚ7M•”$pgĉ0:NêBÒıÙhâD“9šlEr_AA|/a”ÑĤ(SÎÌSî>0U˘$“”höéG} ñŸš†dⓉÏDìŠ6ܒħâœ}{ĦĦ6£Ü1Mı´ħM3áÑ´Do½˘Q{#~Yı3aˆ´#fè˘ ?‡÷˘„_s˙$ÚKĜwï5PFî3À\“˘*&‚ĵKÓ¸X56E–•‚ FƒDHV9~<‚û !ù£ÑDGı£ËNjhVDKPĉHÁ/m%61ıKP*ˆCI” Ĉ  OL.z… Àüa-ü*HÍp +KĜ#‘ˆÏ€}‚xƒspĠA/`W†ëLM ÈİdħĊ +Ĉx“Š‘ äï‰ORĜzêȔöZ?”PÁÁğ'ìYf¤­°síŽĤn#ScÎmÑbíüz°ŽÁ½AĜ‹Ïq>lLaí­ƒ&fÌ-4ц-·prÎ 8\Ÿ[d?qgâ)0d⎤Á ,ܸf=#—\´D49„ö‘[{tñ%x%ħ—\_!9ûöùƒè1$ŞœS@o4[J1% ˙Ûœ‰}’ñ¤ ]Áı£@8„FaŜÁż%FەJ›UQ•“h87É?{¤•˘÷L$ĝ` Ȓ¤Ĝ=RÂħMRìÁ)EÊ]ħƒAòĊÙğë†42€-Çí=Ñt+ùĊ·Ç|҆à„Ĵ¤ñ0@†şIhÊT†[B/&ÉüĦ¤v”@Žœ ìÁ7CdU¸&Ì%4܊ ÇgfâŒĞóÑh†Ĉ84pÏP àÂ1xo££™–ó@ScH?1˜Ĝñ`‹ħA:­Œ6P‘ùĴá˜KhŜÜ£úƒŸ6óƒTx{TÓ}Ô1WĜmäŜğùġA"ġİÄׂBnNĈo+%<†Ż£çñ ƒxÜğ[rŞnàI\p +êâ\ÖjGw~³oFìOAü˘\rÔ~AS&?@02];àAħŽŠĜŻ{t?Jp¨Á튄Ĥn9Ár;ov[L?jñğM£OĦ„vĥ;txâKiÓ+™“VÀu —„ŭzċèĦ1ßoœ%M ~’³öQ(í4„äZ—Ñ NI \ĵ)”\ƒûÒXzŬzÂGz“XD0aHîhjÏ ½!żÇĜÒ×îRë ,…ú(ߜ‘´ı‘Äo`;Œ!%‡ $8Î'M’MyE”vĈ ĦÄNÄ6à£hüġ$6ƒ†GĝXÌĦÀĴ‘´ıÄZ>1ƒ•á%¤b}4&ÓM2_1/A ‰†DÌˈ”¨˘à{œ'%@ñ6ħCùÑĤÌ\ڀ ÛĝGómܑ) „ı| +żAj‚K|…Ï¤Í˘h² -ƒZÚJl ¤ E™Œ†Ĵĝrr/ˆ} ïı-çĦKĊ>˘÷Mı =-à÷÷0]4NR$6ğ3q0%ƒÄs;ÂuċN½X[âû@Ĉ ²€02Lj?Ĥ$ Cs‹ıŸ‚ĝ?Öy{OÜ<àKÈ=¤ÚF≯"ŝœ½{kš[É9$]˜MçÉàé|#żƒ/ĥÎÍbsï/áR/ÎĤ¤É‰§§ÑĈL·Ĝŝĵ_ŝ~÷Ùi\ŝ“Ÿĝ´{ xפŝĤÓÎÚ˘oşž˜|lĤvj6šŜ齋ĴbäQGkş|éEĈĠ‹Ä/2%˙œïTá{'ÂWÁïpÖ[µAîDñR ,̉ƒmJ ĴġŜ=„Ž´İ”Œ#pm% ymGC0î ™”†`!a[H_4ÖR’ĝ(Œ—gÜ@ÜK>İÇôÇ<â½żÄXà~4Âf@úb)b§_ p.´)›`HžÄ–ŒùˆŭŜqƒ‘gtcĤœœÂoڌKlTòI’>v% ĉŭ†@Ĵ~d.TÄ ŝèdˆ4paĊ£)ñˆgdz}Ñh|ŽÜ7Ä9 ´E“ĥÜŜƒĉXbxñX>ùô 4Vsždü‚za p~ ìAÓ-„T@z*EVOàŬú§‚àŸA›éCpo3†ó›$€Ŭ‚Dœu ém Ñ û]:•ˆ™˙Ô>£÷L0çìğYXn*‘Ż$WÁ÷ĉĵĞ–Éżd’F„’=|m°== ¤´q7öĜ2€ìŽ6iï"ĝ˜~Ÿ2Dˆ9hÀ%2n.0wË °ùd ċ‚ żCX<"O l‡h‚%É p2zÎ#Fb$*7-`RúPœLEü·½_O`‰;R‡P; ħñQ"ùġ— 'ÜÜWKJI*ŠÛWÒüÛÑ·7‰d|ċ…–B$@‘z~ìaŸÔD–ê‡WƒÄĜŠäßא¸5ö œHÇB$fó7€˜F"r<gI|H|Ĥ˜ƒĜ2_ L×£Mê·8D0%ùt!yƒ³_ŠEHìäż4$rYı•Íġhs=™Ÿ¸˘Oì`*À@b,ïHr“Xg2ì|z(H<†`ì“ßž8˘¸ÏhÊ7“‘\EaŬ µ$àBœk…ĵŬE˂w yˆ“ˆû `DëÀggⳓ î-ĈŸ†ù…Ĝ r[Ŝ3~%^%ĝµqî.·wï.ÛâѝĈƒíqäŽ>=@ĉ ‚F ’—k ½ş£6Án‹èаöên†|]ÜĤmÊnÑB>†| +÷Mfċ rJJ†KòtŜ1 ÈİĜnBIŽAĈ8-zżÄäE-Ëèü‚ J!/i\ĈU½3”í˙ËZˢgK@òI…`ƒ™dvžŬÍyİÄéXġġ|êyĵWÒ`ùOÔp@¸9 xġƒß¤ùpP:j($—Î ‚DĠ.‚ ÜúInŜ}€?%żĜ!Èg âvÌ)š+\›`¤ jĦĥrÁ– 9òIĠAW(§wĈ0êkÎĝ +Ċ°{â³5DƒUùÔÓ³J29€’À_]ÀUĵÜÀïjĜÛA O)i{ôàkJğ=\âôŜۃ]wÁw"^CtıëB^_‰şGlĊVżž‡x†pĊEc(‰6Á8 Ħ>Ż#¸˘ ”hvGÔv[hÌ5Ĝ&ġħd.HÈ÷ñ•Ä…ëŒŒğÌÚGù3s5óg§@–-íµxç>Û<ñ)¨€ÌbFâ?T€ '[Ìž d·ö’“ĵڜä4f–VŒı`ۍf’çáû¸­Ävíü{€ù:Hìċ˘§6HAN¨°÷íy(³ŜŜÎ1âcQ·„ï$ù^w˙hœÔ… êÀÈÈ;HĴŝú*ld^]H œ@^‚œ‘ä¸ —`<5ĉŽ·”ŝs“"á†`#3µTQV̀ŽM9;ƒÛ3ħHħ…|6È_€[aĦúĠ’HĵEíIR0Xŝ$È$_ï)y<"à~gˆXN}(Hk@îKóġèÁ á" qĤü7¸`Œ^885CÉ/YOé›!Œ LIñrlùEqŬOTÔiWü Ô3)ħEtŜ81r2гPħçéjEĊóUT¸2ïŜ|êĠy kœ£û!ÖBĵGî‚KÀĞlνĊ|ÚÍ|@îàCÖÑżĠÙÜK­?S²Xˆ‡â‹4a÷™i\víÉ +Ħ¸iµPX·D,2FWBóG#/¤D D\‚¸KÄ}ŠÉCŒ?5O0‹ËşğÈDĈ –ğ06’iòubW˜ST`„äŭ”ßiW/à 9'ɟ@êFç&ħ{ÔyPOàŬcû $oá:êvÀ½òÍÄÚúġ@N²*+ñ^[ î‰ᗁwP!=lġ‚GÒ@ˆş[rĥZĵcPoÁs÷@qKP/Ĝ&ˆ+C•Û£h­$Ô¨íÒzg@ú)¨y +Áp;#ëQR–á(AqdÑ÷ò‚ğ‹ċ?*Ž|4‘U[Á¤ ƒŭ™IÎZ¨Ë‚l8÷Š’Ócž?Añ9°BĠ£iM5¤ŬĤÒz­˙d}²SÔe@"- Öç…Z +Á$_ÁjJ/Sŭ²Ghˆ”~%~’ĉPħ 4<<BBÀû”ĵùş[p_ä•{'Pâ5JĥT6D” †93ç—:”÷!ùËŬƒP_ċvE Á9î‰?>BÍ4‘vʙYüJżÄx!N §§³%ÏWpY ?páß#. +ŝ#ı̳säÍË!LĈGïÇíLĴp"1Ï‹àœ¨r}Ì1ż~%[Ĝ´LQÜôݵ˜Élƒ}DéŠÁİ#„´£³ äÂ$J R: ‡Kş8 ÷[–ŭ`Ĵ´íGJ–ĉԇŬìĤƒ|CŽ8Ipjĝ_‰û)–òIFç`-ĝ```aÎ#~€è—§É×wĈ ¤5Fâs/@’-ĝÌĤ^œ%ĝš&ìÊÖì½{â÷T0ƒœ›Ê/OCL3G$½²ÍßÙĤ â#ĝ[ÔÈd$‡Ç|üzcMHğçKġZ+$Œš@k„ÈŬĵz‚dĥ) Ž÷EìBĦ0‡=ĝl“x²E¨z³d_Ċ.xûà^Ĵ Á ĥÛğ#§ĥ§ FÜRä€pg8òsĴMIÄ)9£á?Kǁ\–’Œ˘V€ûVH‰Cż +ö}I^Gü-%èÒäëşÈħpn”œ24Œ[m@rçİ4o"§!×Bk ÈùàkMCN/$žšŸ¨Èğğ˜K½6›Kö‡MG TüÛêۓRF–>ávö´ +/ŻÈı½‚9\ÜñÉĴ{RÄ4ÔĊm$÷Û?NÙŻ8MsIÓA!76…ä•$fƒN&yhCü +YR~*ħèÉjˆ cÀ@¤ít^“¸ĈeĜ•{}—uƒ’R|ë—7cˆlÊö~ZeQñlÙ×|˜GEî)òu*šáLĉĵĞ_JJü­vfŽQĴ/…•Œ%yFƒ‚hžÖk ¸”yu>—tn!XMó6’+„"GlѓŸIwK@ëû˘Û?òu>ġÄ,ˆ7ĦŝœŽı + ¤É×1_‚û‚xŸŻ‘q„X…î/…äŒĤùş É×!xAĈ–֝£Ğ&Ò|Ïíì/Äï›B‰›Pg˘bĠBiŭZħúħ™p¤MÎUÜ(+ş³„Š]8’{…`q{‚sDwm…äİ­!u%ı?ña˜›8ˆ _ĤBŝˆ@É endstream endobj 38 0 obj <>stream +Ÿ@ązêIÄ„¤³3ĊĝƒS°ìÑ"Íדi2[œ#Í×QCD><>”ĝa<²ÙW@˜ µuÔ)iFp)ÍĠAˆZCXŝhbNÄ*Šê–B4OQҜ`ĜÁd˜§´fëÒW²£bâ?‰]@ìÙû½ıœäÊĤr†µñĝ"v­+z?ìŸ:b˘ğ__Ì*¤Rŝ=0ħÂ~M#v!4­ŠÛVú@~ŽÊٓÏ÷J B5{ÁŻB8E‘Or줓´ĉJÉñvïŸ$/j\&Żz·Äĵ–€‰pÏ"NR…é+Ŭ#ú6m(ùböĊ\qŬr.˙Ŝ”`× ‚Î̳óy*tYĴOIJKŻ‘ŞšÍqoĜìk ¨}ĈšŒ5~÷‘É”D.éòL>´Z_áĠÏë£rG-ĝW)Ĵ\ˆ˜„şë dır_Ĵ-hHÒôèzwÒÙıôÜPĜAp8ñ]ñ틔TŽĜsDŬD~ÄĤ P’]*v[Ĵ˙ħ‹xˆ]$i„˙á_ü hŝħ žä˘Àĉĉ&*Ёg08’{‚ĝĥFŭäΤ!tı½“O´†’7š>8‘O89MżÈçƒ$˜Ñ?I¤mX? 94ɍ€ èWJĴxl:ĉ,ġˆ˙À$/WlCEÈÓ×ӵĂ1 ƒċ“/ÏĤġ×àÀóT0Â#v Ê…́­ÛthŜFĊ.2ÇpĠ͛hü†Ĝ…’13“jSXÏqİıoàI}ğ ħ \›êĞĜ…}@/ açÊȃ“E‚]x_ÔHIN„šgDĠx*4“¸DÖĜÂ?ré§gCŒŻħ3fš<·q1ħ4DŜĊcPŻ˘k ÀŬŻcÍ >JEĉ7ñ™¨ÍR’=<Ûĝ57ˆ›-eÏWr$·Ä¸>bĜ+:r~Îm·.­?à{’ËìĵuL-íğeQóԂĜ·ÂÑż'/°À’Ì]–ÌyˆR˘ž„= ÀQ§„r"ÔÈó=@ZŒˆq ~I0—_żLL8?‹ ++{Ĉ<ĝQ^ÑR^p‰eyÛOÀi¨]šĵm²~#ğ‘\ŬRñħ }ĝĴ]™˜*óM"µO|­B]Ò~'­Í`íĥIój}nŬÙ5,ù=ñ7¨£€yˆu•ğĞ'ƒ–•ğjj]ʘŠI”ˆÛ;u˜†@yg/ŠÈƒĝêŸ˘ħ_b—J·èŝ´~†Ĝš|‚Šĵş½§fo?ĦëQwĤ‚îŜ‰ƒċ[ÜğcoĜŝïbĞĊòGY˙Üá_Ċ.dŞÚÔfP‡ôO|ħ ŒòÏbħ ¨Xħ•Ɂüzqvž=h}!´d,rG*¨@ĉêï˙FšHíÎ-?üD`ċŻV°/V²é×ĉÒzżWôĊŜ—k0OyŻP]Ĵ?aŝJÔe §Â;$ĥrÎ;{arjˆÌAÄ ÄçŠòG+(ı;ÈZ‘ )ĥj™š™2&›Ì’÷wCžƒġäÈŭ ŭá!Œşa=ËĴYjÄĴúiqXÔZ-!R–ĞAbÔͰ†…÷Ĥ¤ıÈ_IÌD½‚|T\µ@äċ$…Ĝ‰™ÀäˆÈyAĉûB K+:VËżÛHĉÔBˆ}CìÂt#ˆÎ­şáaÉò Ä%‘˙ƒ\›Š]²Ì&#o 肨ñ×´>ıĠğĈ›kĜnÓĦ_íŬupŻD ëWᰓú!Š-2Î-ó-£~˜µNˆe\˜Çe_]œ HŒ)|›}nž†H5e]G(Ç:*%žÌ8=—Żl6„Àü6ÖPT>ėǖNËë7(+[,½ÏLيëä ?Pħ 2Oĝ¸ƒ“äù7¨Ĝ›÷` ğ ù3ö[™X1&˘›Ÿ €ˆ:üŽ**vĤğŝYìÂŭĞĜ…WÖÚQ[!:iQĵ‹5açÙĵÚùœğKx‚;iÍ ŝàĝšsúe —˘ŽLĉJŸ­á÷6T”}X‰ş´~`‚X8Š­zħBr4çİ7ò%ì#*ê9î‹M†ĵġ#äêÈ!N +ü‡šdïŬKé;b\Xûq.›y!´w´Ü5ş/ê;RÂ>-$G­ġkM™•Ğ×3כ3Ĥĵ]îdK-‘.ˆÙQ²T@XÉ£Í'’Ï̞/Ĝ(ğĠĞOri\ğTZğžË¸ıP"ħÖŜ}“†Òġ?ìċ!mıĵ¤ñ'~ϳTì"ġÔ ĜŒüb>_Ä.vôRRħ‹³  툄ښ%™O +ì=!XS˜;J‰½PÀŜ=Qk³+n³KwiWê0J²=‘áĞ`ŻÔĜ5çÊ!ĈbUhİ>ĈġwˆbÀ§HÑĊAÖ,Ë=?‡;Ĝn*ìm3ÂĝB4‹úÚüÚċÊê: Ħ¤~ Ÿ}e|WŭÄäÒ¨]Òŭ jß?yòoĴÙ}ğà¨ĜĊŸ…ŠW†bĠSSEġûġò½­+ĝ˜Ş‰XQl ê)ÛêÓCîÑûĞĜ[şL"yü”Âɇg)ÓFÓĝNb™zh†~qd:ĊÁÀ$v½=ÄßcĴĜÂğ˄˘úĠ|iíjĥôá +Œ/jÏlĈÍyXğ!Üux’ĵ°ùGEú­9\ÌİIlòĊÔG%œ˜ +1M.ŝÀ$`:ŠÍħĵ!ˆˆÊ‰|ní2°arÖ/[yÖë‘÷ù,}{Ä&„ìË?ˆ%M¸êN#ċñG6ÊCí›ta:ë[8œġJ,÷Lè5K[÷îĉœu7sb§ÈA8‚È|ż&ùZ֋L  ^Gc.TĈœŠÚk@ñÌöĝAĜ݁ ħèáj!ġĈ|şŸkvPŭ²Ö ÑPÁb|äı7r™çĉBìBòÍĦ5Ô°çH™;NSn L<5{:4˜Ĥd ­½£´3v­ħf‡|œÖ0@ŝğ#j]ñ‰Œ:8j+ÊüĈµbnÍOšœÄo?ìï8:M½Ç5{*œI×Ħ£qJ>y˙Tî@“ħpıq‹ê|­3Ä)Öob nL÷²•=X£Ĵh2ö>2”ßĝŠSB \}wH˙AÂM×# œE0ê˙’³ùéa]TžKrS‚ƒ- +ùŜΕğ€À:Y>V³>ħgŒb{Ê@ˆÀsq—ĤQħ ߤ!4JĴœ‚š—Q0–Š]DjÄ.Ä쳋 hAĊöWz‘| ĴTŸ +ˑ<•’%“ßó% +ù²Ĥµ4?)m[‰5A°O‘ñûF˙C°ŻüċZìû1ħ`5¤ètŸAÑXûù }ÏĞ[!–µgÓnÍĊ}€í5!ˆa-9:jiˆ‡$G7)lÎ_sSžmÜbħ˙ÍJÌ6ċÊ,Χx8Hŭ‘k"_˘ëÀۓR_R4$ñlYÇjĜğ!Áƒ†k6QáT ‘Äwçm}Uˆ#Guöê ˙ôL¤ûŠĊˆŒÑ”èkGĜ[†=?$. + ‰Ž?=]Z1kBÀżT`k”X_!c‰½b9À”<"Z˙Ö Ŝ˘W&É£LSÏχ˙£"[„É_OQjĜ.ïOëꨛ¨ +›7pd<„ ÂQÈIP‹Â~+ïÔáÖĦ$˙=Jî˙Eœc+Żj[£:óÀÎúĉm_îx‡ ëTĈ†2ħ‰ĉk¨í@œ2éÄ4î²ċk! ʖ´,ç3o.w›*FUM bÁXó÷ËŽçİK×`˙IìBAòWş.Y4ÂìÈ'dùC0OáÑGîӗĜÈh.ꨄ‘ƒ€Œ[ŠÌù^ĝ*v8ŭxİGf²9—"f+£Ş €ŭÖWiNW9‰+ĵż\*jX'7Ĵa÷<ŝ‡`ûU°o›ùì{²‚}Ĝ‡IçêGÄ)ñ}ҁİTԊÄì;„¸€Š:8{ ŒÈ¨‡SûOş8K,ğ€?@nĈU´ŻçLĤ┑ÇC[á“5T˜1 µì…aŭ²†YÚyé`ÍL ħ8JÜÓj$ĴˆÚ“\pÂ~Xà>*FIâ„Ú ڌz&ïL°êñ°I/Í^5Z‡¨iʙ™´NAüÄ^…  ͞ä)Àì$Ï {tħ—1ñÔLˆ)ŭAXoÀ:Êĉ]:X§ÂúֆP£À^)˘DŸî+‡0Öà ‚Gp”wòÖuGOşG†ÄCä5”€>9#ù£ j‡Z­2L=FŠ?0 û{9ˆS3V÷4BĜUVñl9Ŭ£°-˘öb +­;Ô/EÍäúÔ·#'ĈüŠ98™îùƒßG>›Q’{`ïJHîh:W!˜™vz Ċ2Í5…íÇŸ%/oüY^`1ğûë›5 {"4BKäg*DueE +LQúŜ +B}&ŝĜTEîĠ…òì+siŬâXnğû£ŽL4N΀ı2îà4ş§ûÀħws'öˆbÏë5Bċ;c!êädşżÂ`ÀeħĠ$g˜ *Lò +2żıuTä”Èğŭs†A÷ô§|Ĵ qŸàÂQX÷ĚçàG>Ĉ˜uñîE÷ĥ•ŒĈ-rĊˆ:gëħ1ş%GžñTıÁÒĦUúBJÍà!°|4Ínáşt=^é˘MqĜ6˙‰‡”èžî—ˆ ġ^ú9È[QK=<™ĉI§ĤSQ–0ì'ż{­HœE~‘ bRòéıbÂİ™[ĴYc­žŠb Ž‰ġKÔ ħÇuŝˆÊñ´.„5Sâ{éZ>jXĝ;‚3xï˜AԏBü kͰÑÔ3s¨êéXçŠ,›@…×àŻÓÎ/ÓOÎE§İ'ĉ…À=WŭÜP^Ŝĥâ”ÂÎäÁœ[P_œ3Á1?AV@Lۙ6”^+‡ä°]ĝÔĥğÊK–£BŻ)„œ„íSˆŭd\^@“OÎ ÏMEΆŭaŜa+:ÖÈĞ:V£ÊEîËGìÑÇ>+Ôzä…—IWçÒş4™Ĝ݇|›âÜÄCS°VL…ç ï-o€m£ßûEÈ{ÌbÑŭ²X_À:/jĜfŬZÀVżŜ(+jZ"ìH¤°u¤{%QSÄÚ5ĉğ{tŠP4ŠŠÎĝeŽ@­ˆÌş˜NûFèÚżwúP*RMü›·o*ŭ4˙(MïїwŠ˘şGŬ1´ö˘ Ž&³rÒìİ·uëŽÚ’•›6jĈòmA}ä= >´t —vc›óp1ĉ„ĠH^ŻeI|,p1öĉRq=Ĵ—¤èA´ +ûRĝÔ+s5÷ k$b*=gìAJĵ0‹U×-†(.Íç‰o…]cŸ¨UDÉš—˙C„äÄâîÓÓħĤ¨İìħ/)ŝôL>óÖ"ŠY|3†ÓŬ'wr:ĊA¨ “xIŭBhñ÷°>íÊ|ˆŒÑú%ħ{r_§@ĝ‚A[x›y~]CÁŭNÜc@k‚XÂş#jĈQc)~"ñLQúg6÷òBşnċŬ"nXçSŽÏF=Kż2bħˆŭŠĵ[‹¨0aĉİ9ˊ|â§iĴ#1pw‰Ù§RL  !ĊJcċ‹ ²ŠÖċ\Lċ8ĵġCYqû2ĴIħİ·ĉ"‘4.*;LĜÊ×E-˨Ŭ§œ˜Ŭ"EQŬ$f-‚Ĉ:*ɏ ĉ-Fí›˙ƒ˜#Ċ˜Î§Ÿ™Mk >bĤ(Ĵ[ÊîOE,PĞrÚĤCÄiÊ_R”½^Á?Xˆû˙ˆ=Ĵ\úùĴwÖPÎżh}`[ÖıJĴh3†;­7˘Ż 9Ö<‡Q/ßЏu@nkDÚĞzpĵĵg,öQQ#ˆ`O2|pò)‚#.ÎĦ˜#ü >qh<—xjŞ<›|.0ĞožžÜ+}"°xĥĴ\];_~àóö;Ëż­•úğ‰âÚïVŠŸ6³§ßóìÏFòŞÏk•ÖòG^YJÚ”מxH×[·qg_H\Ċëġ|î½­bŠ Tŝ}Q— {WÉ=ƒ˜%™§“…ä‹sĝÒÖĠŞ}O6Ġuâĉò:ıMY­…˜ww9^öJŞ +*¤÷y˘èÑ2ÔgĔËóħ/CQühDhÎI°=_ġ|WŭĈˆ+·–+é\…u< ÄDŭ\yûrb§em?Ëski]šO97ŝSQùl-| WÜ–‚Iq‡§ÑZ*Ŭ/zl*üòÑ Ĝô ³Ùìû‹äÏW)ÊÛVħ•mÄê6SĦ²e,ċ%Í?áQżÁıË –ÂN`׊²g+°w„Ŭ÷Ĉ;Ünlîĝsıeù۟eO—ÊĞ˙XÇ]|m%Ŝ}żŭÂUşĜîÀ|Ê ‡ÉƒĵVyĴɊ?Ú&ĥ‘ż{*OµZó'_rŠ´si÷ĉÈs[~°¨ŝe9{ú%ŻĵĜäĴ<ŭÈXFıżIÎVÙ(ĞzşıDž°×€ËğD*Ĵ_#œ|*G_˸ĵ†ĠŞI\IÇ*™úÎ…Çn]äŬlIûrĞ [ĴŽ=²c+~[ÇĤŜž_1ŝÒ,*.Wĝd9]ÓÚ}nâ1­wÚùö@>ȧß]„JqHöƒĸó3ħ˙EUŝÄL,½5(.ĉÄ$’?`CĞĈ°áûĈÊ£N7Ë2×ìD×ZÙĊżËWWÊo˙Ġ†½ùğ½ìŝżnĥĴë²eŸŝ ĵ~Ëu|bëßx·ŜıàŜİêjúĤ áò[{öü‘½ĝ^’.7ğ¨.ĈÄW>R\ù¤N½Vòeï×ñÄl>PcÍwĥĜìŞmnëĠâšX µşyÛGuİÎ]<ŝÚJ8ġV%~&*ĞŸ*”ûšYĦĵŬPĴzmÂW6äÏM‡XżûĝdV]³ˆ +¤fÜXü"Ĉ’yžV³PÜóÌP,‘-{½Ú²úו²‚÷K,öüŝ“Eġߗ›Ŭî’[´u9ËŜü‹·ôŝq’ŝċnyÓŻnŠö_}¸wŸ"Ĝwż‡)?Ö¤lysBíÔy(Wú$Y|ŭJìġß6 7^;I5Í~ŞĞ-žâħêh“µÍ釛ŻŜħ9[!x¤’WŭşVVôtİpàêtÓVŝ[ı"ïÑÔ˙P3Ş:Lˆ2Sí}$³9Ò`guè‘ +ù&[ŝl-[¨xħž=Úa!j³ŻÛħ·ß;p^{p÷ßşsw~qTÜú›âúïV²Ğż +Š[Ÿm¸‡ŻÜ•µğ•Ïîlj ¸KÏmĜcodlġǍò’ΟäŸ×`>p'^°ü™g’tşÍ†?ÑÂsĠOä•/V UOMUgë`ߪ …£{ä•9{à…ħp´“•NĥÚ;m‡~3”ûdÌî”+N=³”Ÿ}P\y§boüfÇß{íÎ?|ħğ˙ʍЃkxáݸüAâNżâ›—ߊŠÏeò³ïd‰v½Ùĥ…kî^ĥE[½żŸ!}lI–µwı[4uÙ+Z~ÙÉ5żżµSì˙ĵ‘M'1Ô?gò2ĴiR_Np)âêUéfZĝ·ĠÂİJċíş]öçìR<^ǜayĝġò#żÉŝÂÉÏ`-Ğ˙²R–ûv‘eÑïKĊ’UUr›NŞÛw}­jï†m;ÂúĈér“‹òH›(V?3§XeïÛġÈÓXçĝ=ï7L¸H +Ĝ;F–ß´XvúO3yÍïĥìÛ_B¤Ï÷“¤’„ÏÏù?_Ċ Ÿ[âùßŜĊrŜEJjSœžVĞŬÚ˳£ë’ò3Ĉän}q8[ñáŻĦÒğĥ‡ç'óĴ_ßWKo:’”ÏÚĜÇ/v‘ûéÎ]˙hÏ_ŭh'Ğúc•ĵü +ċ•Vwë[ƒUç:œ„koĜ“܅W’tżĠÇş£&YŞm·ğŠ5O·+ï6ĝ*4Y7ŜŒï·{)Ż>vïÏÊĵâĠR˄“yMó,ŽŝŸµşÌwß9ˆÍÑŞWSUïSĊW­ğ…wíğ×­‰ìÓçŝ–ŝĠĈòÁżXËüi/Ğ˙Ġ‘}ŝ)@ĝĜ§üܘf˙êLôı-™­îÉ^}­â5•§ß™Ĥ^›­ÈzĵHqà“ž/µĜ[]­Ûİşò]uŞŜNyĴĊJu²ÑÖêX£ wĥSâÏ?WÉ/âùĞöâÍ7éʓmÒù§ŽâıgĥòcËÏ|°àHüċŻ>µ—êëÄǏBUm ğm^ŬÍtz~ĴÈġ遢­/OĉÛ½ğš+~x'uÔG‹µM>ìµwÖüŭ§|û£Pë×w2·ĵ½’Üy¸½½<ßĞı(çülÏ֒<ç§ĠÙVn¤rßDʚŝtħ8ó7cÔ¤íiCĐÊħŠÒçËÙ} ù½ï áÛğdĦ—Ĉš•~ZÄŬú¸ĠúٝTÛÎj›Ç·ì^\ÌÙòâZŽĜĉ/ğû‡Éɕ–Q—Ĉ[lñïalhĊ°Ĵ½–|hœtꉭí‹kٝGнZ÷ìqì8SdĠ\‡¸ĈiWˆûZÍĊSä>]żżÓúɍxĠµúíü63ċ‘~†ÖîÒYKl.·~Tvüƒ„Ĝ ŬëYVoĤ+?ßNµ}sFDMm²úAhÖñ!Y{îGdğ·—ĉ(‰ŬÚ½:•ċĜy8Wù!Ezߞ¸ċċĠlċƒŻĊéMŠê?Öˊ^ŭÈEžŸÄîŭuƒġ…ĤÊó/ċ•˙²Fžr–Ef,Ùß9ĠÓĈxû—ò·>;_`ġĥ1Cèh —^6ïŜüú^–òec"WóÂUv볕ċıż™É.Vp÷žşpġO½dMżoċ^= Ċ˜lyy>[|T`~ê/ëM+Í7Ğú°ÄäÄߗ›Üè2²hû›“kGe^Y]xna}D~bÓîˆĤ”˘íEöŻNĉ*­O—~yš,|îLš¸ċġ™Ĵí­NO÷gÛĵ;—aùèï[͎ŝm5wWSéÔSç?ĴâÎLçSïÎvċŞ_ј{˘C)$ĝï@‡ÜŞò‰LYÒiÈÖ˙ĴÈı·HħïÓzéêSWĞúÚpem}°pŝĴê/Ğd™5³ċ)·gZ¨ïϖ_ĝ(W>ĜúübĦĞK޵IâóĤhЏµ™;[‹Š˘'G>N**i ˋ~œTĤ쨉eŸtî°yO֒VÛĵ;'£%<§²1D]Ŭ”q¨>8“\oVl]|vâŭĝĴÄúŬÙŜÍı9›ßœÉäßĵ‰dĵw.}°Q^lqQ^mqWŜ~´KşĜâÈogùƒíĉâ§Öxˏ]üo/c]Û÷xĥï-qoßWìÚ~¸DùâQ<[ó‹³ĊƒUʚŝî(oĝ7'Ó;]fĈWşÖ™–żZhĥ÷ÓRñŜӝ›ßÔdoy}%›ëxÀĠĵÜĈ=xĉA³£TÑfĈíI<Ù¤îĠyZ·\wì<šżċÙù,§Î“E^mċ{ü[Ġyя²›S2“˘3+ëBĠGfŜxì“VÛş+ċn£_ú­z˙ôM>İ |RkÉÏu édœ ÊĴĴ ËJËso)ϵz-Uü”`ûêĵZŝä_<,ÏwY(NŝKîèï–Ü™·˘xöĊfaß'3ô·µÒ—,wâwV¨}ħSùĥ-YxÙÍż|İ|˙8Mú\—Ĉ~x.üò,^ġŝAşġÛ5×ñ2òÒ_-ċŸËĊ›M.ŞĥûħÊ÷İÖï福RJ›w—íhŻÚğċċlċÛğqvŻ/ċn}u,ßáĠáߎÌÜÔG‘ÙÇĠwûĤßjñIğÖê“v›|½ñÄ7íĈcß´‹™§Èĵ+kËŜó0,ğ¤.<;ş!1WġùfŠim—`–ŝ`Şċ•‰˘túŭfċ‰WĥÒívOë5Ö-w“lžĠdŠwZ=dĠVË+Ŝ­–ŞÛdÒÙN;ċí֝Ò-“ŻŝjĞlz•XŸPòH]fóôZ¸ñÔY~݆–E͋eû~]ǝ+ +m­á^­%.O[ż½K|áëw5™ÒoÍİ[^ŸÊökË.*|š—û8˘È½£ŞDùŝ~*˙âI˜‹cmI…‘Í yùCĠ‡38Ö˜yŽŒÓĠ‡ê+5!yk‚³=VçĠFf9=۟%~êHžµEĞ5Ĉ7;]}Äû->RŬ£Ì uM ħë„ìĝşĝœˆş´ĵĈ´ĵâšÈÜÄş„"öċ›Póë]–­]N[‰J~Ww7:gÏŬÈìÀ'YĊ‹Óêw;‘sS|ĝb|§ËĜôz—ħĴŭĵ·këѲÔĈ¤ŭI’÷ğ?=\a˙òTßRç'Ô=Üñ8­„ÇĠ˙ÌC‚2÷ԅfo +ÈĵÛâ“^Ö”úXâÏ×afoşÍßŭW‹?şvÉ˙ĝbŭŝ|JPcf^bî܂Y•w#³²r<šK²<›KsœÚĞĠŞ7·Sl__T+ß´Ĥ*Ÿ·&)۟Ĉ g˙ܢ8ôoFÂ?ílÛj³<ÛŞÊÜÚĞ žËŬüör֖7s„OÏvËßüĊ—{û:\ü½1ÙáĊ‘lÛwgĠĉÏşœÍÛ?:°Ïù;ĵ8‘֜ıÏêɍÓk]F&Uż/4I8?ÖÄ·x°iPñP“’ĥıĉuo_9żÜ——Ö‘—˙(<ÛŝĠaµù_şvżì²ÚôĤK2zß4z×%ïâŒ?vٚ˙Öċiŝ÷./ŝ÷Ĉ(ŝĈ(ùŻżwtI›²Ú&›ìZݏó÷-RMğŸġ£Ĉ8§ŽEA²J³êb‹*†çùµĉ•)_7$ +Í­Ħü“gŝⓆ0ċۖϖŠâĈÌ"ż†ĵÂC·"²ÏŜ ÉôiÎ'>ûRžê}]†íë[9öŻNċîl/.Kx_ڔQäÒY•ËŭġU ûâEş•ĝÎş û×§s];Ğówĥçċċ6‡çE?I(>·Ç+^ŭ xñğżĊ.[“ğ]&F'>.ٔ–7Â(e˙è5]+-^ŝħMü³!9ĥ>!·ĵ&\MâžúŬputmbĤk[EĤŭ‹ƒ™Üû‘|ó?îÚg;ÇĝÖÁŽÏŽD>J.:~;T}ġ~`ĉİÛaÙGż S_¸˘Ŝs/2Çî%‰ħïîf Ĉ×'ä]¸ĴY˜^M|փßԏmğ’?‘Ç]âë"Ÿ$äÊŝö)dcG—…ù]^/gïm νÛĉvĊ_}ŞĊ?+-şDüa’ĝGC"âĦÍÇÛjË÷Ùitİk…I`ʀġ[Ŭµ×XïúÉRb~XeÈ,Xú3³hÉ*fŜ˘•Ìœ?13­`ĉ,2e–˃ş­ 8?hmĠżN]÷¤kâ×g!Áµé™{Ĉfş™•q+>;ïF\vù­HuÚÍĜ‚ÜZĞò„·oâĴ^Ġglí<–GpQAZm\aٝèĵ=÷³÷ܐS•œgÙúoÎVŸn¤ïİÍJüÛĊVŸô£O}Ҏ>óÉà˙Ŝ²Ûx˙ç…Ĥ>êĞDfúh}f|w=f,£ÇŒf†0ߑ‡>ù~ZŻï˜Ùß0ĞV‰ÌF)@k½*\{é2–™4h43ŠI^5’ÑĠÖcj}njèόî5‰Ñ2‹?z3uêrfĦ™;³jwŭ° —ğ~4nìd/˙ĊKq§k‹pçwë÷ÔĠw"soŬ ʸS”q³Ö?ŭ½ Ì⺜œÚèĵĜ†Ä˘†ÔÂâ;ÑıG蘆ĞóïĊäf܏ÍÙüö‚ZŝâOoöŬÛ°€ÖôÜĤ6ïÔĉŽ])dÈ˙ŝ.ܰËtŝ?gm:8Ĝ·b qq=£¤{ú†û³ñÔż-4<ÓµÔ0÷ɤŽÌDŭÙÌĝ}½‰ä†1şL_ĤӛéCÈO™ĦŒö0fâ}föbsĉgëtíŜ—ú­,ĝ8f][×z³_ğĥYüÙċkġŝrŞĝöU‚ú1Bl{-½~–èĝüpnLcR~ÁèĴò›‘ê·#ÔÄ/fUŜŠÊ>WĴ~?0coMxñÇêK·CÔ×o…dÜş”Qö0<;Ğ>:ż½}gR×+÷´_;}‹˙|·=ÑċEi†É_ğœ×ÜîZ¸:òúŸ$ßns—f&OÒgf̜ÂĴµñÚµOÏ0˘rèZG?mƒħúÌ@Ĥ?ӋéÉè0Ŭé?r]Úä_7FëËÏŬÉ3ŭÈU÷!ŻêA~ÒĤÏġ#˙םÊ̙'2?*´Öíš.ĵğĦ’¨Î𔐧Îı—•s/&+ïVlöž[QY{oFfżžuùf¨úôÍÌs×Â2‘ıy´&T}ònH֝ڀŒŬ ‰üo/â„_šä~ÛĠ‘“{­Äà§ğÒrÚBr6ĵê2ùÉʉ™2r +ħÁäüqn=ÉYiÑĞÀĜô%œi7ĉßüŝ?ZôjJÜ]Ĥg·AäkĤ‡VòÓ0fÄ ÌĴ…[˜5эzHÜĝĜL|”ô=Ñı@^ġÈĴ[7C2*ïDdUß Ï">&ÊŬ ôÈúä<›7çÓ˘Ĥä6ÏŜθ5%żñıWJF{HĤé_ğ\×d_=˙§MŒ~żaäzÑóïAÎßë’kJ,n0ùßwû/WóŸnôêŝùşğ‘ğ>äŭ†‘ı8ŭgfEüÓakuM3ùµ•ñ&ZġĴ!ÙĥRĤcÇŝlïĤĵ<ŸÇÙı×,Klc˜w;6xêZdöĠ[!tÜàKÏŬ Íjİ Îyñ00SúT“@ŜÏ~Ӌ.Ŝì]—‹ċ]ïw­[jbÏ "#ôûÀ5j}ı#ĝ_çË=ÓëiÀŒoÂÌZçÍüÖ8`íĞ ŠÏŭ½§^Ï>z=2çÂÍìó7ÂsÏß É?y/$çÊͰœÛWsŬËJ½§ĞOËMݍËI‹ÍĴ'yW]úPmHfqmdĥĊo]^ëu-Z}dèJ{?­Ù³1#´PìMÏâ?ڜ½˙ÚÔNñġ?_ƒĈ{ß÷¤sO3ğÑïñ\/òŻ/ñŞşÌfÎDfÔ5̔™E6ċZëšğÖÉydóúlÒŝğa™É5ñÙ.•YȇŬ[ʲËWì•Gú5eċ8vîWùŭ÷C3ëfonòI×`]Ÿ´˘ÇayĥïNİ Vz§ġ3rÄ˙ë½ïN˙|­_Ÿġjùĉş{;ӇÜĦ>äß:{5Uƒ´ż\ko:˙ôÎcĤ-qf–:ÑYw¨kĤìu—]lj4φ=9ê;ğİşµ”e5Ŭ/ĵ+4ç ĉğĦ…m·KÚî‡6= Êıv'4‡Ĝgöù[aمw£³>v)ç.W2t‡ıġßù…˙íñġ:˙ğ×Ôû˘ö ˙zÑë@ŝ‘˜8x3n²Œ™şb3_*êöSe×_şìíZÇ_ŽË>r%*çÊġĵ;7 +Ŝ /­­ )t+,ïô­ĴÒ[Qê şÌ,<Â듳H|Wç4D¨·ĵ:’jXÛe4}òĵ˙ġuhĵĦ6=gíÓn_~ׇüĥ/ù7¨Ûf˜öf@7=2NCˆOEbüXfˆŽ3 ûDĤżöfPï̽ Ì´ċĦÌÒ­×uVŜìšÍż½Lp‹šÄĄĴş´éSm˘Ġ‡+É.mjâc²._YJÂ| 0ù^â[oĠŞÛÛĵ3‘œÓ§=3Ûĝ.ğuċÏ'ŭh¨dFh÷˙˙ĉżĝJüü5^`žêŻ„kŜˀÑ>óŬÌÈ!?0‡-fô/d†êÎa†öœÍ î;‹ŒïûÌeôú‘×é­d&ÎÛÂ,ĥŞÖ^³żkŠé‹.GûÖ#I{Ӏ͎_ŽÊ*$ħïéíˆ=í7£*žŬ +{{/raïB÷ĵm +.mo,Ĵ­ .BŜµŞkÑí˙;ŝñĞÄġ§`ĵ†ëè3ƒş'? £ˆÈOâ§Ö(âKĈ2şOa†ôœÁ é=“Úo3bôfÜ‚ŭօ0óĝ’n …2­_2ŝµËVx}=8ïj|։‹1ù÷n„ċ=ĵšWw;Ĵ°îApŜ½[!y·o‡ĉżšu“ĝÓĞ÷‚³ñ|öŭ(ġêΕÓfŻü__ËWż чzöž_ïEŭHï/ß$8\g<ó§QC0£ġ0#G˙̌2Xˌ™`ĈŒœ`ɌœhĈ µ–6n#3z2ÇÌ4Jc~ ê]q§kĥôürpĈċä,Š[nïÎ:w+TM°YvnM¤šàÌäGoüB°ĜŭûAYo‡dŬœEQ½é÷ÍKœS´&Ì_JbëÀ˙ñuÁOö˘žĦ;ŭ^5s°E#˜aZ#˜‘}Ĥ0#ÍfFĝ™1˜İd&˙°żÀž<œ™QÓDfÔx3b’œ1֔6|-óŬwèïf[ä0˂ë}ŜµŜä]—mëñ÷ş²¤Â‹ Y.Eĉ7_(Ĵı^Hb|ŜġğAêç‚s?ÔĉoòÏû8°¨éAp!0İáßğ”š˙ŻĈ ç?€b´_£&ĉaîi~§K~;ˆÑë1’Ġ׀Ùo3|,⛧2zƒf’ù·„9x3|È2f萟鵍žb͌ž 1gğ2S ˜[Žk/Iy5hĊİ)Ğjş™|êrpx²/ôҕÈĵG7r›É8=Ş ÌêĴ .Àœ{ö8¨ĵ³1¸´³9 äNm0É%âÒW?îúÉ`úĈ˙µmj•Ħ‡x6Xk$3X›dHd^ !sn¨öXòÜXĤ?ä1¤çfXżäÚĉ1z#û\Il҄ùnž53f‘;3nUc`’ÀLċ ˜İŠbfí­eİĥĵĥk.ûĥĈ{×­’ÔÈÛñ·“2ïìĠHíÌŭàìs$ĈĠÖewÖċŞ ÊëĴÌğq;$gÇ£‚̵wş~9àğ˙ñ¸}o÷ˆTCµ‡3{Œ#×ôħÇĦäy]ħ˙öŜ3ĴŞkŬûžTŞ€]ĊŜ;vA¤—µXköUè ґŜAş¨(HQğĈ5ħĈ5ÑĜğĤ˜5;m—ì}Îzǐ쳟÷9×yϗ÷›3× +ŠĞÍ9îq—1ÇŭûÛöŝ›ñf°ĊDâÉĜYÍ ~s.3|2fÔŽqžˌ_–ĊŒġ\ˌs/fF-Ïf=r˜‘ıÌDU33x·ñÂêŭ\Ï&)ŜVÉŻŝT¸ĉĈşÒ+M ^×z÷ò]/—w]ıRĵ5Ĉ[ĠÍiOv4_%u£[ytRóĊJ×£†qC‡Îĝ_ÇrSšk!G$Ñ˔Ä2+'âû™ÁĤcˆŸE,r µM{òŸƒñ r~£™!VΌ½ĠhâÉ£˙dfñ˙ΌӴPĈiz3zV3vi36°‰í[ËL‹:bìRñÀjÙ÷ÇW’Çë<_žxŻscŭş-GΗm}iíÖGäÜ>żRÔxîóüĤŻîf×˙ùAîŽ7ÏrwŬş—ßÚöyiSoßĤOÓdŭŽYoü_˙—ôĉÂd´ĴÈ\s c8”>LF2ƒûÍ c5ĜѝĜ 3ŒĜáÈÙ:fäL‘ĝ”@fĝX_f07fhOfÌfÔ"2ç‚ê˜ÙħÇLĉmzl³¨Ç0tùml·ÛċÏ˙ˆ‹zÒ³úZMŽO*·ßıŭɉn{v·`ç7÷óÛ^?Ìßġĵĥoïµ}ğkI›}žÎN ŝWfòoŝħ×Ĝ’s!هġ$Ĉi¤3Úɇœ‡+3t”;ñ˙ACˆ˙âB|&™gdş„>l8Ĝ•1FÁ8N˜1³c˜‰k™él;3cĠ)Ù%·úÎŞfıèŒaä’Î߆­¸j˜íġÊ `|–üòtEùċĈĈ6lŝâJy×µĞEÛÎ^.ÙŞùk˜âcƒo R_\ŭ5LúòEI׆xÏÏ Ë\ĞÙĥó?žWol³ Ù!ĵ¤%ͲĦ‡1È8 ê7•Nâñ¸YQÌdÏ,fœK83n’Š3j)Hüċpği䁘7‡1lÉ)Ìèİ3zĤ†ï–ÂLĴcĤ ÍÌÜU™Ì˙ÚzÁ‡†ano ËŬż2Ĵ|gˆRĵ6ÄJß}_ŭìpCüîmߜhвŻıRUsÛċuÍ O{v†~wcKñƒĤŽ[·r6};ğ~Ǎ²-ŜßĝYŝÉ˙ı™ÓóħĦħı?3˜ú+šó[џÈAà/ÌI2‚ÌÇÁŒNŒƒí4fèh?Ĉy9ɏ“Ï›.­˙~àÒ†QË?2LD>ıüŒa’]˙şhókû›^ XX|Ëzaĉ™K×1Àí”aÒÊ· ?R”6$Ê?]Ğŭŝ)OvlF=‡šıĉÔW‹·~|½ éĉçyO?ËßòövQÛŭÏ +[¸Ÿžĉğ}f˙ŝżħM‹ßc9ì™ñà>™Ĥ3cĤĝ1Óĵ’™‰|63!ށ™šÊtZġ§ĉ³×f1§ìÓ32ϚÎ(¸`6Żâ–ċĵšgÖóŞYÏ+¸Ŝw~֕>‹ÊnÛĴ8c˜ĥâaÉòCg× Ïıï7Lz`ò{d`ŭ_4ŝO ²ú!3Ŝö&ä,8Ż}$w.şÓ°]!(Ÿ€ xşƒOeŝäOĴ˘ìȰċr†‘ó„˙ƒ]Ó1ƒ_8˜äC\™A£<˜Á•Ì„ÉÌt‚™ÊU234ġ̜Ĝ&.îÛ.é18.ż@ĈçŽaŜŠ;†…‹k˜Óm2CSÌĠo1ZÀliñMÛeĠÏíŬĥ˙ùZ§?s/FûÉóìw +ĵfrĠ֚8˜üÏqë!˜iv}G“\63ÒIĊŒžÂ8ğÄ1=³™iŞrfŞw3}i 3e.ÏL˜êÁLœèÉL/3óıZ£İgú,Ìıfı˘ó?ĈxŜ5¸û>4ĵ6„r?ŭZġċĦ͏×+Ġżü’Ċŝĝ[ßsƒäŬŭ×İğ^Mġ;h˜pÓ T|nT· Ħ췉ғùÒW÷ÖFĵŝh[ĝĞ‹[5?|Y+|>3nN3Û+žqáʘ…|>³8ĠtaġË˙d˜ìù›A4ĵ[£ùóıbsƒŝóç5ìßïeĞŝñ4+ï†Ġžż^?T~żtŝ?"Ä?ż* xeñûd„_|“…WÔs˙Ğ_ġ-CDàŝ,P˘>m~Sûò`Kô×G›SŸtîŠŭòhk 2€#bÍĆó³´ûñâı×ZeçŸçyĤµZ´˜Öi˙ŬaKĈmä`fü45ÉsĞ—ĝKf Öiğ¨Ŭ0˜ĜŜï ĵ˙_ ŝż"}5hW<5,rğe˜ñ­Á#àï†UÙš6ïżUÔÔ|ğdsñ½ MšwK°†âKlÏó˘ÁĊë´a÷-ƒ§âİ!TġʐÌŭGžö—{¤ŸŞ +8mp Ž5v›³€ñġô`G‰}Œ\çWĦñÒ,Mîîڄ†rÑ)gaßßŭäSoƒùңĠıŬƒŭ˘êúL­d†ÛŒŭżÖ‚ŝË6MHžErĴ~™ħódfnp›ñ’ /íá˙VŝHçK˜òWCĵò/†¤À?"ŭ_ÀÀŜ2pŝŸ” áì[Cn7†8Ċ-ƒxŜà­Üürš²ì˜£˘Ûıêۏ˙Xŭƒ!KġÒëż˙ó•Ġ'T;Ì{~ô>|'İ·>‹Ğ??•k½0_8~?HsêşVwëZ^è£Ojċ³ß„JmïVŠ·]Äş?ÍO=CŸ^ĴĠ}{ĞNqÓ ÎZÌ˙·çeIüb?“L˙ŽŒíhRGÏcFOöcfd3.q‡M]ް^rĝ?Fşß1,&óIá}ѰÔğüü`ïĝK˙âƒŭ/<Ċ§_äĈ~up‡ŝŬ'Ċ·OJÙï_ç^5(ë· V$2UĴI3W•Ûúo=ċìÍà+żzR.=yžŻĴ<6ÒGa²L•ŝıŒ;››´Á– Ë5.£Ñ^z/]x.]{§ŭìfF·ËĜżxpŬ_ğó{~Ï~Ĉ_ù)ÌïĵÁuċš}V£',£uöżv$fLÁ2 ġFnú­ĵcpġûÁ úѐâ˙ĈLüµVIâ.˙Ó/%ü/ïJŭ‰oÉé°ÀĠ‹™żp˜”jtâµ·ĉÉġ˘äçŬYO›wEĵ>µ•˙áíZĊmƒìğ÷‡é~Ġ—>4¸*.;ž­l<7^ùáoŜüG_ŠÜßħG˙ĉel·W§˜ĝħ §3Ħœ$÷‹Û…‹~ Ô_~’Ħżz?CŬŝn1›Xe”Ġb矲ĊzI@ +3zè\£MèzşÑïviĈô7!qmÈf‚ Ë,×ınŭv˜ÛyT÷G†e5èÙßÊ˙ñ²TúÛ£ġĦo/4áŜŸôĉy™àû ŝÓ_"ıKӊ×Ŝ%h<)ĠŬ|V$zĞċrÚùıù1>‹2˘Zd°˙]µĉ\ċÙ˙ôRî¸>C•ıŜ}ìö+³ı}o<…ßĞÙí÷ĉħ…-C¤ò]#µë;ÇKÍ7—w?ôú<;äĉµrŭù òÉ/µòŝ*û›•\óçóÔ5‡ĈĝnħĈŭ6SşvïĈrP˙IÌÈÉîÌTż$fIÒá>+?0LñùÎ úrÖè|ß$˙WYyßp䟋ü# Ì|üCow5¤ +a$.Ä8,6×:|mûxyÛçKÚÓÓŭUŒËèaÌ˘ħ™%xLĈxpa¸ĉ+s5—Î}-İ·}2‹O­éG÷Ÿï˙ŜŸî‰Ž-°³ÌÁ’•w}í!·żò.Ì:^ık=•ÄğŻÒ4מĤp{˙ĥ’k¸4M}üg_ŝêğHáÑëtĊ7†ÏÛ·ċë>·[Ŭe²`Ġ>Ó%Ğö™ıĊîï™yşŸÇÚ³öŜû~ž&ĵ{[‚½8E÷vrŻÎ 8aXÜŝjĤ²ë§Š žß–e´ X²Ä•™á4Œ™=|8z{1a ɖQ9#ò+‡ĦO,èĝO§/c´·oçĞ?ü‹J}ü/êCġ`kOŒgókì¸ú½ù£OtĉùŝC]sq<ŸÓ5„ /0W‡§›ħ1)f´ïeß+EÈÙ/’ƒŻ<ÌàÎżU[?›İŞ=3NÑùn~`ë÷3}‹O ZĦ-2žéŞgĈ“ĜAÓġÌ7ĵûNÚvs‘”·q z0„ÚĝÎŻW;î/áëÏMg÷ŝàÛ˙ ŭî^­ŝ魚 C˙áĈ–´Wï¸9‡;÷N ~z£:äí§›_ŻW˙fÈVŭĠNâY‚Ï×Îç¤aOĉŝŝŠ0ĈKğÊ(`Çİâ“osä[_gg‘ĜÔmV.÷a”ŞP†öhT4‘Ğ9;ÑW­cŒ›Â,›<‡ \áĈ„hM"Ò í˘R 풋úës7 áÛŝ´û|ċ3B¸S_޸ŭ?zİö½ZĈVv:r5û…_+°Ż–=ĝ‹§jûË9lË.üÁ˙Wmğ=‹ÏiÌ%äYıMĠ ßúsûßzŞÚnÏS5\ž¤èüvò”ÁSyܰ2p˙o ŭŝÇ|˙†ıžŸy½1úŝĊ ġzg}d÷żn ĵh şa ~ŝÏ9$™†'™…%šĝúx1 'bV¸¸0Š@†È0SŠĴÁ„ŽôETaİĤb~ÇpŽ\[z÷hÊİîŻ+¨,&–X‹YÛ²ísğž/*ö8 E-C…â­CYâ uˆ ûü|ŝ-[ytŒ:w“_~bĴöìóŬ/J°RŭzpôZŬŝlĦPqpŒÖhÇÖ~Ĥ°/zÙÀÒÓeTۃĊÎ5žŸÁïċ£ùàF>ñ@–Ž=äOÔÂï}¸ĈÓӄâìĈRAûp!oñ·;†rU]£0UŜ¸sŸ|˘ùÓŭDîô*Ġ_ÜĠŬ?,W÷ü´B8ŭ ]{‘,_y§>ë +6u½­VnËïĦj}ä"œ˙NŻ{v·2ĉ›Ó;oU^0(?2xnŭ~j@áİÁ+c_!Ù80³­Iƒ—şîÜĝ@m²ħ*<׌ É4UòЍŬı‘ù7ƒYNò>}}ĥû7̛@)ĜÌ p‹Ċ°$S}z­ƒvGsäÎÛŜ|ÇMWĥóî2q÷so0 ôGîêÔûżuç+÷9 …Û†ˆe]£ë…ŝxiŬngyÂ˙t>?áqώä'{ÛÂn\)Ñìŭ>PĴŭxްîü$nÏ[7áÌײşĊö^Üħoĝşcĝüz¨yˆ*żm ²úè(Eġ ŠĴ½ö>úLcO.ÁÈO›k˘àӍŭ•FlúV;Ġšz[·ċÌ˜>öÌ@R7Ͱɸ/^ɸ/ZÂĝ)(‡XÁ†qşXŞ‹“\Ġ_gĈ“s…ŝ‹>ĦÂÜ-]ÊZ[99ß=R÷=ŬİÛáÚ£Ïġ\ċélnÛ nó§³TŬo\ùò#c ĠÔĈsÄV5§^†i=×ñ{ŝìëÈ5^™!”t:òٛìĊŞŭcÁäNż Rœú‹GħŸ=‚Ž˙ş2h˙OËÔ5GĈ¨Ê9Şóv d+Ĵ0.~Sjôĉ[ÄWŸÏĠĜÂîıŠ£cWŞ^•cîGò0_…Ža5&BqçċÑ"qÇ3Wp³Á3˘<ĦcOyöàOôv ;n/ĉöE(n!fn²ç37 às6;°[Hœß÷ÖUŬvoA7ì‰7JîÒ+½ñ+ñuˆtċËhîÔµêÈožüı7ĠÁżàâË­¤P#eH² ú·ĝ}?úèÎ=\üĊ§kġŸŬ,.ĵÖ)Oŝ§§úCC ˘îÓħ^êhfêàħÌ›QäçĈÓ_dT19ĉêĠ9ĉAáÉĤ\dĤıZŸfêşÂƒYFüç²ù‹¨—Zc+$YİB£Œ+äÄ KmzĠŒŠÉĥÂMċĝ °äžÇJíÑÇZáĜ7A\EË>ĞÎNŬġp‘°ç•¸†Bfí9Ó`ĦëĦğîìġ¨kçÖĈÜŭ 1äüÍTaÏ/ô I%GĈ›ïğu'&‰•N|Ċ™Â†£“Hž0IĠó“ĞjëAı[ìTk÷SÖ^pV§6p÷ ġÂÜĊ̒ùîŒÛ"o&@a„>KU\…ĊÜñÓgKfĴ=3µ˙f)É?_ï­Ùt|zòtëNO“šï, Ĝ?II4Uħ2#êcM)‹Zİċŭ5%-§çíŸ.cÛo/&ıô4ŒżşċÎ\ġħ}¤£ßñê=ϗBGAHYßş |ıéÜ·‹ıĥ‡‹ĊŬݽé\ßpt˘Pµ{4·íĉ<ñ‹ áƒ,ĈV¸ôu¨ĝɋHŝÌ+ÄÄE\é>Gu\İ…‚5öòOW£ç>Ĥ¸/Ÿ²İ?Ÿß5 Ü(>ްBˆ!#Á˜_Ó8€ĜÂHĦ”<6|2}+BÏ[?ħúĜ.‚K)³Š;HrÉ)\Û­ĊBû³ÂÁŻŭÄC_)ĝ}ßzPŜö‘WÂßŞÑ§Áĥ?]Â6ŸĤÚ˙Ĉ}@¨eħç[ĝĝ^½ûŬRUÓ§ÓT?/Ĉ÷ç³Êûħ‰ùBÍñ l÷[7nÏğàfrµGÇsĠŒc7_Ÿİêüv‘òàŻËĠÍv^Ħ̜ 3™ic—ħ3˜Ċ3g3+Wd|ü™•Ŝ$ĥ‘üĜ7Hb|ĈÛSÁxû*ex˘ ›Ġhö ü z´ÁZëOä9ñ=\¤1ĠÛvyÔñt%ßùÌ Ìn.İĜJ¨Ù7V<4Pwĝĥĥ+Vw;KEÍÀĒ>`5§êä“ϵÂáï\÷ܟĵĈ·Ü[ˆk(Ż­Ê×ìqVïĵ>W8ò:H>÷2B}ĝo^Şş‹Ùş›S•Ż]‚:_¤88J‘oĤ”“}Ù#eXĤ)—´ÉVµ:Ï|á,fĈÈñÌây+ŻċŝÄoŞhD‚ Ż­:0Q×vŬS³ŭÖ2èC^ĦŠĠ3A +Ħz˜ECÑëî‹ĵ~÷xô‘’80R(Ĝıږ/²äâòú‚)–vfw>^H{ë?œĈîú|!z+Iü ֝ş!Ÿ|ĴÓ_¸(_~¸Š?ö]ğŭ³9"‰ŭìĈ'Ħ7ŭkÂċ/UûvS´ V§6ögKşF¨ğqU÷ĵY|‡Ĝĉ +ġŸV€ĈF§˜aMCĦ0Ĥœ–ĉ›sTí\ĝÂÎaA!YĤ+–ĝ1KĤ.dV.ö&vİbĠ<£Ö†³‘¤ĥLZkÍ'ċZŞ˘SLĦAI/f|V“ƒTsv*˜>àşê3i£³úGg[h¤c]t–…~mçħċĉb°žÀĈà ĥĉĞ÷á:/ÚïğŠûžû˘ÏUŞ=0´wùÌ·ZöĜ?HŬqĥ:£q—ÑdÇuĵYĈv}żœßr}.ğŝĝ8°u¨şòÄ6sğ½›[ 2}.ıԟŽ'´Ôjò“ĵ>Ҙ2?Ê÷RF§—ÑÌTj—ÄoŠÇĤ Ŭ_zq7—Êeŭ¤\+ılğ#ßtn†¸éìt~3ùĵž<Ô{żY.7rê¤ò#cĦµÁç68ˆı[#NŠEۇRĤNİ3I.^şg”X¸}(eIf7 äs-ĝÄR+ÊÛY˙áDú3}Ó.:ŻXóx úÁ¨RŻÊ5GŸ4x{ÒúS“äڏĤóIÖA\„Q :˜=s %VRaÛpÌġŝÜĠ‡ßxq{ż]Áużġ`۟-•ŞŽŒÛœĦë;k`ñÛ{Ö\Ï×^R÷‹ñĜsV<óB'|ĝ\Rï}&lüp +¸sˆìö?ÍáŽ~Àŝ³ğċĈl c(ÖĠĜĴ­ö|-ñ™ϖ"‡àvÜ[ˆŝqüÁŽTkÉ\ ‹7ár6Ùcm€í|ı”ß|m]Ú××K&u'ï'3RêúŝRU×°)ÒQäZ’2›pĠqù}ĠÁiĤŞhv;n/‚V˜@šÚžÉRŭG³ÁÖï“2‹;G=JYÚ$V¨[ÎQw>YBĉ"aë™Ybó' ĝ֛‹ċŬ÷|u=ÔR×-/a÷aßwŜü‘o³_ËwïċêŸß¨Ñ?ĝ´ ŭ÷ĦW.dI§kàs…‚­CÈܝ+|í^\ŝo~ꂞĦ^<³Ìe9Ĉ×X íßĴğżñ_Œ+îĈVŸËĤo³C.êıš­Á ĝ6”Yħo<ĠcŒÌï#'×ö§Z9›)]%èá!ÖéO]–ßWƒ #„E“ßWô?½Żzïk7°Í¸í]0`ÑA³@ˆ#uer­Pĵk¸PBâ,İ/Dâ+„ĵ̓¤ìBŜ–A\1ݏÒ7Ò7Ù iġä„k>ı܆'1ş¸ Ħ: Úc1ĞÁŭ­\×7ë+8RɑTĞhİsšŻğ@_ úxċ…6CbzY?0\„C_ú˧ŸhµÇé¤CÔ¨ÀŒĈÚ eĠœ(Vîrë‰ß|i6Ĝ3áIÄïëíçîxs 3 ú3)EÖRÉGä-ܞoWŠċ‡ĦğDjÔdĞ÷ށ‚ĦÁ%XŞt Ĉ`³Ğ3ÌÙĜÂüÚŭ#ÉÜv•ŞŽOT†3Ëĵ˙ ™áÂÓÍäҝ#ÁHH(ĥ‚ĝ„BR:*ŬÌËObÄ#r-ÁӕM1KF¤üì½Î”‚ŸU=ċêqríÑ)”•²ŝèn˅YTSd÷×^ڃ¸>‰‰:}>5ôĝg‘R×cÊ£ c-x*hŻ>JÒ½üĵ*ôċ•zôʁU˘=rOD_>ôĜÍMgI ÂîüÌEŬùŬRĥö ŞĠċ}ŬŬ”Ì’) R€éDfr™µ?ôˆu‰ĈʰTS?E8ñ›áŒžeöTDóeßà–++);-ĥÔ +Ĵ(薀Ħ/fĠ;ĞÓû në>ĝBvâ³XİáÌLpéÀTâš/Í޽U ÇR+÷ü´H(?ĉ †½PKrÊĈfŠéġöAÚH#äzbĊ!gÄYÔĠê°S°ŭı5U6`riúĞ +‰Ï,ħ‰ŻËXo'ƒ7™Ŭ<„Î0  1•p’İĈħ'èXaí‘KˆÄĦ^Ó–12JúÉ9Ġöà2âĵ ƒ +·\}pxu$†ıġ2²öŒëşE”•^çŽ!Xlç£e Z°Smş8y—tü9>e­5c…Äġê6‚ħLb%ğóö1c›ƒBo$ß(D‰QÙ}CĂĉĦ|zu?ep<ĠVGÄÓëͳ ĠĈ”³QÒሁ%P)3|X²ô‹H2H.j +M,Äsè°òñyX'SÊħĈ$G0b#rͅ´şBtnµK9EXùƒê=cIŬÜDq÷oĦŭ Wİñô,ÊĵÛĝÁ4hvBğO{à>öñċ´Èóeş­§lÈĤKs0GÙĉËsËċŸ…Éמ'˘O5<8BH(ñeĞM„ŒFwRêúa­ŠÏŬ>5‚?näşÄŸY8aħ<€QEdšİuI&>¤vu÷V’\šäšŞż­dCÀäüR°˙ùT35ṁ­1“³685‡'À‚ÛÄoı1OwèĴ;Lë>˜Jمe;Fñö“ÏĵĉÏŭE +:jäĞNŒ£qúdıÍC¸UİfŝJŬYôĠCNkîċ£bàİNÉÄĵzÓ -ĦÍÉGĈ™‚‹Iġ*‰} Pˌk*§K/ë/ĤıTĜ2z`i6›FıÌ$‡’Ì(ŻjÉÚş#ÓÀċ‚f•“hNĜüéBıî {ġ ­µ)UŭĦ× } ġĈ"ħóŽ;r30CİnvÑĥáà`jŽ>ÖèÏŜ]­9òPä[/À†6G%tSÁL²„ĝ ++6"Í ZRz#ĠĜ„a^*0#nu–9Ġ*kwÖTĜŞBH~BüĜżİġh,Ϩ·ë][ÒLġfJ›G@÷‰jşâüIŬV:´şÔ$F@oKX³ŸÙhO5 ŠÛµ•‡'RžÖ9›N͐;o{j÷ŜWjvŬó7Ÿ› ğ”É÷ÌυíWˆğ>wC=¨é~Èu>Y.ċ·ëÔèMĥġñBnߏž`N¨Ûž-äĞzF˅;†ğùĴô$óId„Ĝr+nuħE&Á˜‹Ê2çâp-2Ì|İyÜ—ñó˜…Óĉ3nàr†)CLĝŒ;aŬĦħBzŬpâÁR:ÂĠvÚüzh÷ €žı"P€ûDġÙÀ§"ŝûQóÀ’ÚïşƒĊL}SJ5Ûvkċ˙œ*œù³†Ûñr4Dޤ[27ŒŭHíÄ3°Aëı;Ûtq:ü¤—Ëx{+è]Ñ1ÈĜàŬ)ŞMf}¨1xÇAœ–QËaĈ`ySFtbžµ””iÁ…Ĥ™QĤ<ñ‡ÒŽĞKt­—Vț>œğ˘RÍÀ·][(ĥŬXî—T°a͵ĥ_]À·ĥ: şâ†áÚ²]£Ħ Ğ96ĴCċêBí{*û/aM-gJuÎ+vŽÑlì™ŬAħûµŻóڏĈú§n”ĊTq`ĴSa)ĈZrdŝİÈx€+-ĠĈïxĵDn¸éVtÔ0fXK›HÜû•Ġ<%ŝFÌo&ĥ§ùú†§K;ŸğÊí/½tíOŭuíŭ…]_,ƒ˘&ĞÎA*í–!8zĜÏħPÜċHsŽġ§&‹[n̗ÛZ)wôĠuŜS„tŬQivßġ?‘Ìċ隒–‘ş˘úaš†“³Ċö+ä֛îÄ6]hNFrĦbÏhë&Qž^Bµ-41ùĥÇKĊî7~RÏëĴ[`քjڐq éù\ÔtŬñ%~u‘ġptRÜxj +Ÿ^j†ż˜Zj ­cü ­›cíA*Ŭíĉ3â 8cBÙŝÑbNç06*Ç{$fô—ïĝÎMÜz!ħ!'Ô~rnÛpÊëzèÎîş³5/4³°.F×áÊğGĉu­<Áz;ž­w|ħ ÚòŞĵġƒÖŒ°ëÖrĥëÁRpBħ&Bŭ/sċgĦġÙ2ŬG>BÇW+ÉëŬÁ}çÔ –ÂטaŜcÍIğéä,Ħĥ›ĥû2¸ûž iğÁ·|ĥš­Rñi`ŬIeİîUċ“4]ßĝÉ=_)…Ŭöà:^.“*ŽŽ£ëǕ=Δo·˙…Bò‹HíO‚ùMWĤÓû)ġŭı¤*kÔşA¤„îşBZe˘”ĥÙ^&ïO9’Œ!v§£ŭ½Ġ”w m uµ'gêË÷Œ—Òjh’Ö÷×ä5[ï/×ĥßġ>ĞÍŬ4˜²_Áğ^³ÖgÒïÚYÜ6’—yİԞ~A™jkw9ŝĦ…<Š×!ŝ0ŜDJS´e0ÎWW6R—Ù0 T}Á6G`kİĉ‰·àâS-ĵìŠr§.ڝ÷=ƒwÜġĠ4ßtZŜÉĥúÜ-tëON‡ĈWp*462-¨6ù^şĴ^·¸İg’tĝRsévŒŝD°¸}Ü|™@—ĊŬyÓS·÷‹ ͞û\ǵĊ”Ċš²ŭérRCÏsġˆvMħ-Fr+’˙RíERg$Ŝ€MŻ+ë‹X^ °îĝx>~½µ:< uôK4%ûGkŠŒĤ—•& W³ˆĉOĈ5„mİcèòÁŝµ;ïyè[ŸĝhĞOMEŝËJ‘FA|¨‘€¸Í+h5¸,4œ¤uœşÑŒKr½ÍĦk¨m%×kç?mġÙéà¨â'Ç‹ĦÉfÚÔÒ~”ÁıġÜ<]Û}Ÿàöہ`î‚ó ½#‹ĝ³-7ĉR]„üĥá`ó­/–ò ŸÎ*NŒ6\$5Ġħ‰âú“¸=]ugoF…Ÿ?Ÿ;ws•êà;wŝütaĠbN+ġħœ}:qm›#Öġ ŝ´;ÄÎ+Ħ{âáËxyżŞ’Hbô‡Ŝœ.İÄVˆJ4C\¤şYɵ •‚ġwŞa“gy§M-î'ב8Ĉ*¸ÜT;‹ĝŻŽğ^šžû*0ĝÄîŻ|Ùv’Ç@;kUİ:<ŬÚ²ĴgŠħĈàqëËlu1ĊV8ĦLÙ° s‰2m‹­)Sy]÷X|nh@dTô‡7tfôğ@c…j'UĜRŬÂÒ½cƒÓk†$ÚBSE³sì,nMġŜñ\Ï /ŭ™ëÑ!7.H'^°ߕJĤW§iûèQ÷ú¨6üÀîg^òŝ'Êà=ÔRÇW"‰ÑT;‹ÄlŞ3”×< ÚYĴ.‚jgi˙M;‹Ŭ˙ƒ;êCÜß +ôçhÔНUNµ¨ĥMjĦ ´)¨6<ċÒv˙ĥ÷‡v–vÇ£•òg+İ“9Yb[šÇk´jÈÙ0ù´Ĥ¤}“]h!EĉġĵċŝJıŭ…'tĝhĵ>ÎX-FQŭh†WïC9ˆuû§HMçĉjÚîz€Ğ+uQh}²œÄ<ʝçŝîüqçğñԝ|~ġb‘vïC…Xwx]7„ÎCÙŜQ|zƒ]WĴ;9UĜziÖÂU‘iĤ`Ë$/G\×u>T`Ìħß +9'Ġ+†.4µQĈjmÍġ(›{U²9t‘¨^ ô #RÍ5ñÄn278€}Ùû,€jg•“kû‡vV ´³H~—Tl£]ğm˜ħş\÷~×ÎÊ­T$XÉ2ĵa,êÈg‡™Háñf`-‹zb›ĞaݵvTÄ1ş&’Zя‹Ym +}&0½)÷zë…y”Ċ -§ñNĴì½şàĵúaÚu=ċĤ+ $°¸×÷L€ŝ•vï=rdÜËòHΔPf%Çô²¸İŝPËíE”3 Ígpñ½7f-ö£QŭŜĝ‹ŜuàlŞñĦ-²†v”61ÏŞW;ĞÑQÜ÷ëƒR´³ôŒR=“Œ>éÂ}7è…!i3-×Îí,Ê+ŭC;+2ŻŻ>×HMŭùıú’ŭµ$žQ˙굖T·+·eĠPÌ]ïK]ñfG°ôuyÄ’qĠĔZQûż0Ż'ñ°_ïë‹{_Ÿßáf5ì[L$ĥšY9@·k|pÛMߝwiŬÔy÷_Üyŝîü§Ş˙›;˙h¸óú3Ĝ{ñBƒ˜ MmŝΚâQltĤ9Ö$ĜĠ9}¤´ vˆñÍ +äŒ|ˆ µÒÎr­ÈsċÜöaˆö#rÌĠBˆ‘Jaˆ˜RÖ5eŭ¨{FùmÑvG]F}Ż^ĉüş“…Î'+ĦK„ġE5É{ -s…Ëĝ{xSí,µ¤5b…igĈb˘"PÏz¨H|‰2F|ÒEf÷ĠEçZèb²,4‘i}ä¨ìÑâĤúԅM´ĊÛá?ĊÄl Ä{ŞwA­´í˘ 4~(Ÿ>m½òV-Éġ‰˜ĴŬ|ÖE³ñÈ4MÍáÉT³­ĵe”°ç'öŜ`­,n)}ƒ@ŜúfRë]7ä¤XÔÄYj +­°o„jc•uŽĈz Ġŝ-ìtÒÖġÂMİ–‰™4FŝĦµëî +ıóž7ÖRŝÎBĵĠ¤m²‡=Ëıµ+ƒvô’Q›ŭ—vVIŻv–žÔû!qĤˆ/úô ċˆtsÌ]0üµkêìÁçêJĥ¤zf9›‡êó7 %>pb‡žŬ‡jo‘×gl„׃·ŝïŻGŻ-ß5ÌmŞÙ‡\cóċ…şĥËîÁ•&kòêû ½gŞ[udĵ°ç{Oıû;8²Ž…6}=‰Xš?šĞY·g|ŻîzŠ)´Ħ?€ġ@Üó +àdF!G¨5ŒRŠ2Bíˆġì@µ–&ĥD|†XerI9ħÒ&HÊĝ Œ ŠôÑ&şÜšAú²£ĦƒŽşœj›"îTžˆµŞ[yhöĜS€š•;ĝÔxqôĉĦˆ½’R°1´³XAbhg‡˘ÚY>äóÈÚïş´{mzI˙à¸,А˜Rh4ÊIĉbD˘™&ÄOhwŸ,Ww…"4ÔèÚ9tÍvÜ^&í¸ħúšÌĤAú˘'hTÈí·<ç>r*°ıİ>áşÖ1Bûm7ÄŞ‘PIòŽâ#¤LrŽċèü‚ä[7Wè 6ĊY…d5 Î#uŭúî/XŭûÍŜçJìä–;.T;‹ê·ϵ|Bµ³ÄĉÏQíĴ‚fhg™ĝa.j˘=Ž`uSmêuû¨v–úÉÎ*éĠÎÒŭğvVâÚYé}„àN$µ–äíÈyĦ_´Ó|oèo '˜.£’ÌÏĤáV Ż'u‡M^²Ú„#Œ K…œêŝàġµ'§45H^ÒË9Ŝ;VK&Ȋê“Ċ¤ġĉ·&oûP~Ë'sÄŭŻüĜ]OC˙ ‰6Áŝrž­/nâï£aT<İÉ#óûà9JŽQëŒċœ:Ĵ#"ŝ ~ûb şÓ\Éò· •ê>˜ ½ +hsûy²ŒŸË ßc2ˆ?nŞ]żo"´|i^Iâĥ RE|.İeäĴzŞù‡ŭVÜî§nòžgŝT; Œô¸, ġż´³2×ÎJ³SíĴCÓ5ġçĉjS+ûĞÙP#|wèm^İ.·qˆvİÁeícƒSK¨5­Çs· Ħ<ö–k‹¨^‰CĦ,{èPmòĤ!rÎ&’{í‹8(ĥ\_"ïşí!´^_Ĉ7_š xş†ŭ9´–Ùċ„ó’?š –<ö=jĞOL….İvÏŭ@yóGó‚3ÊíĊ8Sŭê\KRŻĥßX‚L"µlŻdŻv–@µ³î/“wí§éy„=Ȩ¨FRħ5UGiĈĊ”ôŭC; ëK úJUí´u‡§i×nNûÚ'iÓÁ)šĈçêŞM…v&İÀ{Ċ0Çħn˘+ns·œžŬĞÏññ\ŞSħ ÏEì@ĞîäLŬş£“µ…›†Âkú°SèoAç^j>ç"ĥ=pĊú½ç-Áâzâ{7ÑĤÖ;P 縵Të^żĥĠIîpĈŭ µË‘GİXÑá$ĈĉZ¨ĊHc68Âħ“ĉż`úg×9ĝyŠL*ÌH Ï1×ĊWÚ˘ĠċnÍĝdiÑ)ÚΔƒŒ{ĞòûÂçK)•ĥˆ…œ.ÑDİ3Rbω=ÈÇt­#iŒ$qêìb͓ÔmĜŸ†ġÒ^ŭ’ngaÓ°ġ]Ps MgfB‡@—½eĠ+lqDÜ hĦŝA[{b††ÔŞÀÁúfŻĤp]݉ĦÈSÎ΅öòމ ’KÀ? ×ÄhcÍ`\ohÔ!7Ÿœ)oışı"îĞ@;ş(ùNÏ ĥ m™<‹ĈË;nıÂ>ÎWŜ¸_§íĵïÚ}G–ˆ˙„."ú‰QĈTşl×(yMe?ÜÓǘ‰ù–¸/%4~<‹ß~c>´³tû ìîÎ7š„žİ|ßݰcXÖ]s>?‰jgA+ëY5Ä>+;É9‘ó…vViŻv–ĵċybóċˆt½•Ä|]a³#Í5‰ß‡f òaaÛıır=9ïÊöÑryÇhŞ5_Ŝ=NÛtvž´íÒŞk‹{.İô…¤>€†_uÏDİíĤ›Ü~ǃożı”ßIŜkÉ)³ƒÎôž´ëOO×eo*DĊ›ÉMÁš†öà=y]ÛèzêÊíĝd>Ġw"5­5֟˜*·\_&o½şy’BÊútS)4Ók>ÚäµĥAĠĈfYê2Ö;Hğ>wîĝBIµdrê!àI=¤$ġ:Kl[10Âş1ôh°As0Şsšgİ+hí.Ô|rQ›#47äò½ccBיJzœEĜ+Ö/ ,ċä"käaT†Ĝ’ĤöÈÜÏ ï kmĈLšï#ÓT› nğk"šòÎ1üFü‰ƒĥ+êQêKĥ€f5ísi¸:êe×R T]VÍ@ŞÁLĈy¨Ü@â6İѐïSäEċíN"ıö´6‚n69Ob§żkşÛHOĊš†öĜ#­îĜm½Ĝqg…œ`ÊŞd÷ݍFMQ0Şñ7äañÖt=áß´³ÄĤ shŬĥĥy„\zòqĥġîBÔïlTĥ9Kr|1³e´Ò4•żkq’şÌQÒÚYem£Ħm$aNm?O5Öµ{œ{ß·c$ìÖ‚ĦŬ7AŞ?>MlèBllĦÔtĉ,tÍŞĥgŜƒjUğ'Ÿ‡\€ú6èN‘9*֑ZîrÍáğ<ĝ+?íĉ"ìħ=wmÍéétßdVQ?ù=uèékĞ£NM +?òi”~ïí Ħ다rw†/Ò´:’ħ$ç@}Uç8ìu“˘ ûj*§5sóĊEšìĈAjŭjcäÔTzm—t·Db?°qVŒ1fÙ`’޵JÏQÙ}ĵ„mš‡u ROöQs:#ŞċI>KSĠé }+ì_˘šDµg§ó[?›ÍhÊÑ>RËb-JŒŽ3ƒÖ§f‡3ÄşĤ`-1ZŒ)°àtÉĤQĈ=tMĊ‘ T…Ŝë…&ĠŽQYÚ6zÉäú sqϊjb vQyz²ĥìÀ8èPëŠw9a˙´ùbonIçQ÷x]ÍÓ`÷tĴħŜ=’–‘Xğ–;ïû˙=]J)ĥ‘cr-İ3MF@ìë Ôy¤Ñìy¤›o/Ĥš=XC şÓ'gŠ­Ÿ-•v|ĥL[µoĠ4‡ĉ-ÉùhÎZ{döÂhŠ· ‡–¸ċÜ~ÏSwùÓy¸ż‹ûÍ´×1̊Ĉ¤šC“áç‘Ki²Ê<%Ë0]iн'Dü;ß|q·ċÌ \èĴ£žWkâĦ_A5UH\Ħ>Ż˘{X&PŬ œ7ÉiŒ ó^Ĵ;4Q$ù9İ[ĉ ŸPIÄ?‘•Ŝ›4AŬ‹‹÷"Ͱ'ká)C֘İUÁ½šˆı[‡@Sç„{cBÔjÓ_’Ójy ħ ÜcÎÜhßĞgŝátMÍÁIXCĊ=H䌚”[މEb4r$|7]EÏMÓùùXŸÑTû#ßO[y|’”Ġ8{"ÄĝKMt,Éûċï†8݁–}bÖ/ċĈçAóˆêAk Úpıۆ ÎĤ÷‘ ÈĝBƒ zyġG§!ĦşĠl/ßíLjŞÏ{çċT‹§ġĈ"há5´ŜC­Jì94 ĝĥ§ËĝwçijH.]%ÄڍÇĤñOÜ´ûîŞĦƒ{ġTë+½ÚŽî=ÁZ#öUš(UĵúĈĝ;üt—;î.e[?[Ào8›ŜÓÉ$ħĥCĉXŻqËpzëĜ;œ·ehoŽÜ2û¸ÖOiî$Wvċ³ÌXŬÔ­BÎM81w‰3›Ë$˙”ħߪzß8íÚÍ齲ͧf‰m7–I›/ıà>½žoVqĞH,+Ûíĵ|ê‚÷§÷kò‰=µÇ“ÊğœĝM‡&rm×qÍWçsÛÌE/Ş—g}L1>ËBSµ{Ġ‡’µûĈÈĞI _kÍÚ:Z…hi“|TŞŬM|èá)°IRsYŜü ôĤ4IÙVâšJ[MF­½\ÒI|TëşÎGj&Zo×áA_Zá§b‚Ôƒ<µ ê]\wäI¸ß*›•²-¨mCcš\3MIÛHìċ‘ò,µˆçMgĉ!_žêAìÙҖw9cïĉîk2· Bí ˙<’êĤ§­·£{Ž ŸıсÄ1çĦ÷J|Š”Ŭ4šÎTOû Z¨f·ıtnħF›SmOµš¨ŝpĠyĊš ÉC1ÇM§{ŭ´O‰£:WŠĊ:;™cš ríJˆ‘úylÔ@s„Ĥga‘ +-ϗ7÷ çIġÄ  +ŭaĴó`<³r½WJr"è³iv? @Iòmì­ ×mŬŝñ˘£ze¸O—ğŜu´ë0·éu€Ĝxb +ŬĵŝàXìw…n"4ħ_ó‹ĉäÚÂ_éŠZGÒ¸T{lĠ'ç,­Û5†Úiġ^g~Ù)|íéIbf“ò9znĜ÷²³E˜OTc+:É :᪞/—ħ|(ġ| u?÷7š Dg˜£?ùğqé!q`LĴ´ß›ÎëS3 ï÷Çûŭñŝxĵ?Ŝï÷Çûŭñŝxĵ?Ŝï÷Çûŭñŝxĵ?Ŝï÷Çûŭñŝxĵ?Ŝï÷Çûŭñŝxĵ?Ŝ˙?Ĉy$DĴ M µ½mĈıùÌ &W…ILħ ´<-%ueLxjLbBhJ–Ó"üJ ç|V:-ršèš™<3xA$§ĊNŬ|fÍ &/ ˙:Éi*yêÌé³ç:ÍPE†Ĉ9Mì}S'òÏNŠ”˜è˜òKuxh\dïS“‡Í4—ù ĉLŸ2{ž“ËÂY3§Ïżp–Sü˙ñë LŸ=oö,§8üş÷/ĝuïŝßżŝכÄŭ÷ïg³ÊF°I° ²Yè4q’“(ĜÌtr‹´I1q‘‹z˙¸"’|߯ yâ,'ÑËfĈÊÈô˜H÷ÉÏI ´Ñ8ÑӝIŝ›F˙4ÍĊeÖĴ}µ9N:§Yó8͟Mž úß<˙öûK~˙ħÀi.ùìY È˙f’?җیGżFq‘ÓÜYóçğĜˆ>–Ŝ>áÀĝL€:ÂH)D ‡+¸P£À p£E”‘·ŸÌxT1~FĊ2RGš£‘Ê7g£òÌUéfJm²ħ‡›‚Yěññ”˜@>Ö(PŸlÈĈ{úŠÌJ· ĈÛSɀ~ĤÔ­2VE1 +M2áâ×Z²ĞË-‘Ùf~Ş`&@Ĉ€ĝ¤O5e#Kû¨B2Mŭ‚‚égûéÈ{¨ċ>䧊 ’˘Ññ€Ŭéŝŝ!ô9ARŒ•eЉ.ğv hEú˘–‘è˘G—+%ôĈ[ĦۙvµĴİ€ÎRtc×1:1uÍ£e‚NH>,ÙTƒÎhNâr-A…Ŭ•ŽÏDG&şÇäĝ|KJŸ ?5г-4I “4 IŠRI|t­Êì+G­1×'”ÙêRÈç§­·DHÊ·˘T„Èls5ş‰y½§ 7‰T!"Ù Ŭ„è–"SÌAÉVq…Ĉ™H) “†I3ç£S(=ô-)6ϝ’ §ŞÙ#µf$˘?–œbĥ6o`mġŝIş˘ŽQèBÒĈ áif *sŻÜ;N‡ÛUä}Šë™²n´:jJöŽ– +Z† iĥbêòûz{)ĞŜAˆ.ê¤K0ħUJ*´Ĥ´ŒümCépJĞ)@Ż şŠĥ CvÎӝê 4ÏáƒcMx)ÄdD.Úm˜AQFJU¨‘ŸRˀĥ¤FW‚GIŽŝ&JŜ,ƒÎQµ&Ŝ„%燓kJŝ +ĤÇJ ş +1ċ–\L%–ij·äRE(êW›€zé¨f9-Ù0 (<ÙÄ7@fVx)˜tĥ†f™Ë uŭ¤ÔÄĝ2kVL4†:C>Ġć<ÏÇTŜ#PŠ=@#R§› +ş$S!*Ó\ğşÈJ_h­IĞè\P›É­„ĉ,9_òŒ5™›´ù;‡ëŠÛ@1eÔ:€ÌHIVYĠ°).‚É0×ĉ´ #×w¸DŠ‚m#´›/.ÔԟĞ+¨ŠçHÄv¤„L tP*II+íï´Œ‚Íg7 Ġ'çÙèR2­t™ë@+ 4†5kmA‹Bט< c"„'˜Q"dlĦ˜R`NJ}ŝÖè•SKl5Qù”T´e8ş­´™ur\°j9ˆ\´ ‡Ĝ>`*F&›ö É$ĥ‘^1ŬòşêCS4uǧë2ĥ ’ ĴÄÄ|KĜ9:ĝ@"BíËjD;âJ­a›Ú˘öQ”xµċ“róÍ%è`” +z)Br‰µZGĈ‚Ĝí:N%öŒÎÛòÎ1 (P%·„Á„Òb"3Ȝ7Rrz¤U|?ZĊˆ‚>èĵâ+ĴAßû(ı£ !ڈ”É9 [YJo´—˘×Z¨u)&ĝ )}Ĵ‰-ĥ‚ŽÏjtéġvUƒ4 #16ĞŻfu™ĞM2Qk‰ N4ĠĴ^kÍÜ4P—Rc§Ï³ÒĈfY  UŸ]7H +G—Cĥ9:\ĵ´K ´ tɓñħ¤Şd(™'³ĈA›Zm‡CJÑKoHÇ)oóıîÌ t9˘ ]¨š,r]AŸ "şŠuOÏÖ­;0IK)ğÇëò _dM} ñŸ½ğÄ'Ÿ‰.ĜíH%c%Ĉf÷EÇ9lF—Q:]Ğ´ó]%%ğǠЇvĤĤU  öFü².½Ĉ^›Z9@“Rd?‡÷˘D,ŒyníŜëöŒÓ•ġŒ\Ӗï şUog_·3í +ë-Ü1”ŭÚ½Îô³@4H.´–‹ZF ËŒv:WtŽÑ ›!MCċœú”ü rw\%UŒĦ”áŽèR“óëkÒÖöüÑ~Ô/|W^OĈöˆNâ3`Ÿ SˆÑñfèrvċëİ`|ŭU èMĴHlћgüġ +“ןć§˜ħş(cĝJˆÎìûofCW›‘ñĤèzöS°La,Dĉ˜ 1… Úâ³A–‡ñ!™fèòĊÜBwíhJ,!ßıĤŸˆóK,³Ö¤×ڃ4˘hšÔ:;ŭ|Vz1œ6ÎXƒŽ™èbK.$ÙdJ@%ħ— ˆ/„Ĉf[‚Ž I)íßʨ¸:ÏŬˆÚÊ]ÎèX†€mÉħÄ>ÉxҎ§ÂíAäA'­Û—’26Ñî>}ùŜñ´KšŒ›6wëŜĵ m”ĥ˘k,ÉAÒVuÓÖ› +ߤ­:8H—Qe +–•dF;ĥÈ<@n!ÇĴéƒTmÎúš5ëÈYġAĦ2P ó6£l<şu%Ė‹ŽB2(ġÖÈw=d7Í ç„ı„ŽTMÍñİ´ÛĥñâtbĦs NÈg(%§p§#Ŝäpt›ŠÉèú+²ÖğC§lħj÷XP™uûĈéòÚÑiO>k0ĉş›ä¤r[i·;¨ğkÊmiLÏÚ<sEH ×>1Ç]zÔ§_ bšDĈo%×Ñïñ ŻA‡8ÈçjQou1†Ä…Ġ– Ë +ÁİĤRXĥ9ˆJ áñÄ/rÚcä/èZ&fA>Àƒĉ:zbżI֔żyˆ˜Q=]ÏɸÈL3!ĦÒÔ)iŬħ šŠ)ñ-<ĠL"”v…’9ŒĵôEĜoÚĥAè\W€&FSŞñ“bH²Ż‹ì%r“sA\F7íڏˤy 6ŠvˆÒónDs@ĝÈLË HNX´}µgPaÈżcìáés36B.šġQÙۆÒî?ż‘Ûa )=%ŸäqYġƒ()­Ĵż6½Úž’ˆmÀGÑĝ›Blħ˜Cù[†Òîk§²*ít%ğFkKڜıK;É|Ċĵa{˜7 Żh(ÉaÇH|OJ™šĜ!Hw´kħx;íP„müĞ;µúÈD“AŸ×Ÿ"6¨è@ÄOĝLÚM‰.ÄâGt˜ÒÎIbk F€ÚJ/͌ĝrr-ˆ}Ù÷ƒŝ*Ĥ”ÚP5ŒŠgW ‰Ü~ONZkƒÎBj)ÄfÓkí(-żK-ħáVç÷‰ï­ŬôkÉ#ŝ˜vك–XjúOüŸğĤ %äš'xAâĞĵĜL‹ŜîOòêÎÍ s‹Ôt‘ƒ/@n#ל™.l˙lĦ¸é£”*\{j2í\LĴ²•rZ†Hë>œ,ĥ<\*Ġ_Ÿ+Ċ×Ù*TÓħ&šì†Aš ÇĤÉġ'g +œ^ğ²Ŭ£Ñy‚By2žä—id\ÓHü"óQ›ğm˜dÏXĝ*ĝ1d• èG4_Şáá ñq°M-ˆ™ëìA<¤]—d‘ÑîS2Ŝ°%h'5:fqMÈü Ä’ É EVè<ĝ(ŒWJu\K |%WÚbI™żÇXäŭè …Í€ŠòħÓ?:òñ]h×2É!%˙2^4ĉ#ögVÛĦΕ€’#7ž˜ +"6íV%6ŞÍÚD}%}dÔĜIı5öP³€í„RŝםqmÛJĉH)³ç—\яĈ粞1 ËÀ€ĝŠ.f.*™ÖXš’ĥQ҆SSÑy,Ĥñ‹.è‹1À÷Ñ]İPT[ĥÏYJŞĥ…OŸAğ͋pmK›¤€Ŭ‚²-ÄY¨Ħ*•a_‰X!“ùOí³˘Ë9HŒ2R‘X’Ÿ¤VÁŸƒ¤xcİżXmŻâ!üсZuj2¨ĵ´³µêĜD(€Gğ˜3H~L˙ĵÑ^<8NĴûp +hĠbŝö!Pô‚˜Ġè ß6*H šCU@Mê0(€Ö.&WÚ@­CO4FNJ<İÉôÄGċôAʎ&u“=µ+µ¤Ŝ ŝô„B+9gƒ8´=s£ġwLĥ‰d|ı÷˘Ïo:;„wĜ'ġeíN!ÈĞAyCnEj‚‘5$nġƒ}"O¤% +³ó#oıEKĈô8gI|‘I|Ĥ9ħeŞN’ß0ˆvq“ĵ…Ĉ!’CP +fİbs,i.Bb§ôûï)Q”$2a“C´[ĝ÷×``NÁ?Ëċí£)İŠüŭnğÇ@DsîÈÄoÇ0ßñ9˜; €#[£q¤ìˆ43Ì3JQ Ÿ "?Ajĉà8Ԍ"‰w<UUO}hËPÔ²\p2­ġh÷9™Ÿ¸~šĴ*;ŞP@bĴCj“„X2"³ÌyĦ¨û”ÖÔö‡j3şÖ•,İUĝ#Ĵ%!/Äw‚Q·ÇФhR‡Ĵ6Ù +?tùĈ™ĝ,Äd’ [hޏOĈüBlŭUJYߏ’I‰ïG~(„ĈšrQIĤlD²)kŞûq1Yĉ Ŭ‚`¨"uy/Ñ/ÍkBBİ’fŞD½I0QĈ¨ÇPOáşħÁI& 7RZ,İӘĵ éQ5 `ŠI[JĈyZĊŝqPCàZ/Ħó ~Ĵ`n×Ŭ%b÷÷ìŝżz¨[ż\ +&%ġ³›²‘)ĤA’ÖêmÂĉËsMWfKiuv\DŠÖp@¤À“ Ĵá7i=\€5RKo‚ >ƒäIyÖÚÄLKäŸÚœ*{Ô3PKÙsŠÖ +¤Ö&9’9H Në2Hn +PÖĤA HA‘„’*3R_KbÔIhnğ'>ğ—Ä×=VÚtj†L)Ìeŭ(ŝ¨áâ\q÷7ŜÒŝAüžç”Jİ.Iŭ_S‚욨3kOlvĵ ñި-„8ò|ĝJĴ %WÙòĞrú<9AZƒ”h^ßêH)Ó$Ç%…úh<äĠP5 $ÖÔò~BBħ%ĉl“úX2´¨÷ñ“ÄO?Άd™Ħ~†˘lïüI7ƒhÒĴe,ĊYÂoKħ`ŭ´?š3˙!ƒà‚DÖÖAd.ġ•OX•ß—#uuİi”ê`&H7˘DIò{ĝ>qħŬÈ\sP#Q݃òÎiRL@ċ½Ê6ÇP$B*lğî"Ġ2WÊÛ>ùĦ“ÛÄqaûç ùö'Ë(MêZmĊüÖŜaŬéÉâ֛ ]ċĥûîòÎ/Ü@*é’¸RÜ2u)ö€V‰¸ġ“Ò.'š“‡fŭÉ)҆sÓĊ-×ĉû² Ö2`~lo½Nì +sŠ*pşŸÒWgôEĦAÍIê'PÏèÜ$vuĴ'HIUĥ2İ[@$Çşò^.ŒĝÏsÔt 9>$5ÒÜZNŞíżŒ|k ĥ&Ap—“ëúCġ\-†K1rÊşŝšˆ‚°M‘‡ê֔ӵ:PšħĥK×;ó†hЏô’Yj{"Ğĝ9€aÀO0žÙk¨¸*tHċÚ)yĝE‘uÔl:èéF"^”ğ·¤EôeŸİäqìó.aœš¨û@YĦJE×ì!ckö2ÁùÛıN+§a}¸NÛùÍù?XJQˆëœ]Û ƒ>p8ï—ëáy CKĥ +›vsŬÄNĜŽž|~&ˆá˙ĠٞR3¸}€ç°ĜÀÀ€…és“ÄVC|ŭ²ûd.Ĉˆm.ĝ è"-şŝ`ċ÷r½È=kµèJèLÚüê(xŸS”À÷&³ŠꞋŸärĜLèb+<ê4§ċĦ3Û[ˆ‘ 1‡‡ŭ">b5rBÒIòġk ^Ċ +ħ-cÜҖp1BànG.‚.ܰ6EÇûS ‚ ~ħ‘şÓ'~Ü #Óz4ĦÛí_jŒıŬhÊc³ Ó‰.ĝNż%½i€ŸCnJ‚×!×½ +:*ƒŭtŠ_ŬWı.œ+€çċÍuÖü³ëŜDħ%ĉu€½ċ:X ñġ ÀħàŜ¸î‘óE7җaîĵŠÍĥxŝ†şOMb ÀùÀÖxŜ] œ^䕵l"Q¸ö{ğöìkÚy2‰ù}Ôr×ħÑ%qàĉÈċQĈNħ‹É°%P”ĦŬ ÎzOŸħkñi̽3‰ì3ÁOs\ûtè`Jg”/ĉ•ĜgC×4Ħäœ<¨C‚”$²rż8ĤN TBc€èjÎíkì×è@ìğÂß)Ñ!ı\—?ßZE(Àœ¨P +S>íç'·ïù‹Żĉ‘ág +|S•8÷ü)Ğħ\MloEŝO6Šc%Žq 1^]ƒB'v.^ŠDAoĥŜÏւ""(:sĵ s%èR*@TLŬ>Ì×·1g|'qñ}ñ™òuĈïÑzP7‚ĝàtĜĞ€†ĝ:ìğq™žËŻáy„ub쐴Xb6ëĤ˜Żƒ"ž[.îì–ĥ”ËÚE›‰"[+ıÎFgâÔ Ò—‰â+ÔĊ鵆˘ûMÚİ-Œyż“Sƒ8†Ÿù!ŒĊÍ1Ο•'%çċ‡şžbîmìM¸èî|0G\w$èTñ ˆ'áġ ò~şNìqg•Ä1tž˜ë>_‡nŻp_‡" ày`CħD*ôÍVP.ƒĜ:Ä)9†q)ÇĠĦ›Ä#çÑ v„m!S TċȸfeŒI†Ô 0&ƒ}ÊĊlOڏ#d‡95ñż¨A€:cŸ²ÀˆÀ\™G Êôܟjnė°ĥöS5ñYĞq°w8ûÄ€‰I°kCjâ¨UQl“ŒşƒƒÍñżÉs*tƒîW`WAY„ŒÄÛû1sċşÇŬÌXNÄTí!Òú€B/(BKÁ3sı³\ĉ£(=ë<Ö&`;aèûítlı2ùa7ׁĈ ,ƒžna8%ÈXE‹g\íIZ½<*ôíVn}şß]9ĉĉŭ\—5ï×ë‡tEòŒëx#ȏÇäÀJaÁ'A\ƒ:~m4t“%L-G@naHĦ&—ïö~ş‰ğ7ˆ?\Ä8Û. ĥí`ıkxŭqj‡7‚NwxM‚tĦċÔ nÄ*ŝS ÂÔ ĵ‡:óƒ˙ûbĊñ?Pƒ`0lnd 0ĝĜàhÌ=Ħ3*Ĵ5ÎN^öžĈċé€Û·âöC·˜Ç¸ŬYÊx>^=dżż]ô3Z{τf?à84ĉF€ ¸Ż\çÁÌ5°g9[ +ĥü?`ÌËeÛp]ùñ{ÀÏıßçr‰QóĦ[*óz8e7<§¨pîĈdÙIĵŽžÁñ6N "h>^ŻÇùĞ !E††Ä­)È眀ßÖc§€Òҟj³A Ĉ&ûK ÂüÚèĦŽ–ŻĥJ]îĴcìÂXBŒs"ˆy:§-ĉ”Xĵ2Vƒ +]²›ÈŜj%ğù˜ñx²šŻÚŠQCcçCĵŠË1îĈxrf`£¤xc› ħY ( ›Zp97P˙%7h“ UiÌmıÎħAÇN°) †µ'ÎOŸı9‹?À÷˜ _Á˜ÓQ§ ĉ)jĜä1ëQ uĵw)ĵçAµâIP³8 +ÔA™8Äë#ĦĞ/p .ÇñKŒİèȊ=bÏçë9ċų̈¨’ŬDr³*UĥSĜ´pÄ. 1Ŝ6ÔĉÔ „˜Ğ ÈŞA(‚m€Ü•OŠŒôÄÜú„‹Su‚¸¤ùe.6ısX›݆N˜G/‚–ĝ=ĥ7G.yÀC óĴôfú +è˜ÊċÊO Ċş¤×“—sŞŻúÍê0|y4‡u ˆŠÏàġ‹×ôŒÛD.~Ġç§‚ÂĊíÏĠV0`§@Éûzˆ;sŠçW½Ĥ‡Î‡ÚN-â‚Ó¨AÄW݉е)ëp…żÔ „²‹òܚ8¤µ÷ À÷ s ħ˙W5ç!5ì85ĵnd˜ħM>?’‹/8Ä-îÈ)à}ñw˙şÜ]Ê­ğ3îÁŽ€J*ßBĊw¨Ro7qñŝKn“ȔΰO™K ˙ûWÂÙĦ@N™ûVúÄċÑPœTĜ@ċ +:ƒ“‰Ġ*\÷sèf +\ˆ<*Ç3ä!=C„y˙0à9> ܏<ç9ì"(‡jiRèÀ.]´ŻġTˆµ +ށŠWĝLP셸ä°àïĉşÊĊ>ⅠXÇİo@,x9(v‚ö™€ÉÁoç…N•\¸ŽžÉ-jÂ{}ÚxOm5lPƒàiC'pap (ú"è>ÍİAèPHO—DÌÑk£e şí5ŸÛ<ÔiÔw—GuŽR„<*י10{“ZŻĝÁnCEfmùĝâÄ +-ijƒ@’ÒΣ’;4ˆ¨ÊœŜ'ŒûċDd.§AE”ìäÔ 0†z ]cd >#ŠH q(NÛ5j¨ĴpjŽCj’Uƒ8û—đ”É1yR|\ŽğĈ~žŠ(Ŭ̈́îd0îäbwV‚á8§Uˆ‚Äġŝ +:ŭ“Ò­C& ¨B\Zìt{‰È&z.•ÖĦJkç…×À— > _œJĉy—É\]„eÀ àċ?üÔ;˙A Mb~u´ô̍I VıOè,KoclSĉ§ÜĈAwò˘ßdXŸ|É19MuRUÓDښFˆÇçòĦ€;ݸjeè4 Ë!†% AyèÜHŽOĝ<Ù 5_°Fİ£—F2˜KĜ%ñšt`Ŝ6 öm\ìŬÒ{:—˙ƒZ{èĜš¨HÄUíe’Úµ95żĴµ°fˆŞAXüİqq´”Sƒ¸·şéK.Ŝ˜ħ5ŜO$Ԟ`Ĵ)µ Ÿ+…Z(ÀGŽ‚XŸ"úàÉá’+~3¸.ôPsá’ĵlĴWÎAçÓ°œ˘ÀÜí2‡xE˜OˆżƒjĜ‰[ìbèf, ‘ÓÌ4éÂü‚Şgk#K•éċ|Q\Ċ&4G l^§Ŭ—!vÉĠƒ@'SŒUÀ€CÎî/5šSƒ¨Ŭ'JîÒ§µòÈô~M"Q…ıžĥr<äQÛQ£#‰ÎcŝRƒ ˘÷H0/;%ċŸ{ëNŝó8˙Ž}™ÈïîZQÀË­ûk8 xûĥÛ{˜+*şp(ĤB‰/U£âËT`~!öLĉm†Ü”­]ï-'˘ëw“ùéëYË)Ÿ—k9ċùh¨MÒ·—Ĥ°9ä!ïƒR‚sêR&ĵt]İœ‡² + ĵòġÀ{¸ŭXêöš…Ŝ!ŽĞÑ˘ÓÛtĞMw›E”÷‹5”e´uÉ*qŜs"ä fg‡Ñ&Œ:Bc€÷Ëb°k"ĵż!ù"ž‰à÷8EŒ î×Ë\S–qxĉ‚Ç¨× qL™šÈ/w WÏ9;Pŭ3× Şš ” +óC„çm£ƒžm5‰eƒ€ÔÉ\ÂIŻ'.“zem€šŽ!L7Ÿ‹½Cèò)\ŒŬ&tq.†Ŭq/şNâr<7ĤBb+ÒÈ*uqxÑŜ!Ύŭ·ÔwĞèÛ5ú˘×U‡dÏKO€z£Ĥġ_–-Ħä€4ıĈ@”R­CÄĉîàÔA-;¸P şâC—j.ÊR#@üHÁs6+˙™%Â17Ċ8\r§$RÚTA Èi—Ä…Cù‰¤ùäßÉ ’NğżZÍİAXzOx”WêJˆyIœ£rj.Cjâ§J ĝÀuËÇĜ_z óÇxENy óT›0~Ÿ‰ĞTejÔ9~ߤ +9PìE;2˙P´›÷OEğÄNu¨û1àSC]ı:ƒ˜…b¨k€ş˘G”Ј5)˙üM`íp9!PĠ\*ptˆ?ÄI|݆4}ŝöŒôiĠ!~F*ìÊ7g=mĞ]ïk_âòÀĵ'sĥĜ>f>tQ§ZÔ`½ë`<¨s@Sċ‹ħÇ~^rÚfœ ü¨‡ž¸4 +ìğôĵWW,vœÇuB†ÜԖAÍö‹"è˘ì‘½FêĵrB€96ÈQB~Ï%ԊÍ|Êy’sΓ¸X˙QÛ1âKA˜Gß^*ö{ì§²jä6 †ùĞW×Ö.céÁĊĠ!n"‹×ez‘mô\à$‹‚zĞ~ +&ç&IĴ=grŬï˙To„ı%ҚȞ”6É+°¤ĥ!OŻ#Dà›8ħPoô~´iİÄ6uPĜ¤â”™ <%ñÍÌUb×´%œš.äü­ FGŸq™Àċ`˙E ‚Äü•Ë ıÄ,ċràÂȒí (GžrKœĵ>Ż‘y´ëƒe ÍİÊ;Gcĥ@ô—ĝ ¨ÇóğżŽ +{½ |ĥÔ5}`żżâЧuO]NG+Kb*5Äħ•¨¤Ú*ÚQ)Úe4ŭWEğ:UP´ƒ:LnAüŻE3ĵ÷íUœêö˙PwêCœB’ë%P#ʁ̵`nŭ{ż\/²‰› ëìp3:ıY“ñĵ½‚Sotı³”˘I‹é¤Mà ˆµ@- e2CpĝÒș‰°/%NjÔaĴħ'BtDêa÷qjĜρ’¨C<“9ħÄaM^ŞUbà úéûd§ÀöÔPEĥC5ÀS³cžÁĠèB-£WÖ:Pàêƒ ßy”ƒWF@ž +ò{‚Ô*HœışrPn€¨„ıcuĠguêâ(FûCà5\‡r°!ÀᲉœ ŞoĞ•:ϗxÜ^ ġ½4¨7f†µšTʧÂäveFá´óx¨1„.îUħ b&}ž³íÀ‰a]ż³‚Ğùğ|ÖT+0÷€ÚûyÜ^EI˙ìġ ,vJ“cÒ":àáz"ħjU²şywe2j"†”ˆÏœRSÎVN5ÈĈ_şĉs”t >‘ıŠ ³ÍÙÄĊM@=êÌ͉Gĉ&=Ż%pİûĠ\MԁCí"ì÷—‘IŬDİ}ú"×Ç+¸úPÎ\v#}ĉ ›@Á…ë”6ó +ĵ·~áöäQSïĥS€‹ĞéÀĝ°.¨ßĜEυĵ'äüè#Vœß‡9ĤN^ÍĠĥÚĈ̓-pò"¨‡Î¤Î]ŸŞŬÀ“@]”8Žħ´Cš˘È·h+à‘Mâ<Î7ŸqšÀċ'ċ9vÚzœûC$>ٛĞYë`n!g ızN5☐ż„x!ÔĝBœß9u1‚œ)ĥ½\.bX˙aœÁ\½>…³£ ŽıfX£~O6rJO‡<—KÂN™ ìµ˙ó­â€Ç›€Ç Ċ#‚<ŝQ‡HlRġFÑeŸİôÛqpÏÇìĊWĝ´ËŝÓıħÂx07€µ öbÛ$ĥ§D|2ÄU¸1Ù{ċw_ĵ~_oċ°}ŻĊŻ­Îġa LC%· ÒZÔ Jğ¤,dœ“ĦÎ +b=DtÙN‘÷›M\\ï ¨×Íá\Żğ+!WÌ)³GĜ ĥÖ6œ÷€zü7֊nÜċêe!ży^ˆi@=’ż•JïÖĈÔì]ôžBšj%!ĤıkĜï˘VŠŻĊÌċTYĴ‚fAĴïe\È&€;7ÂċŝŻLçTœħ}“¸ßZĊù~ŽDÍŜ?á<Ž9îÊ]\ú1‡ħP‹q4ĦññĦšz³3!ĥ$0>#1câ´íXâˆċHP…Ĉ!~>íŸğ™ ++Û{”Ç0Ż—` ¸js9ġ9ȗ]ó ŞNP—Âĝċlz!³Á§r÷ 5H^/ÖSÁċÛA5–óĜĥÂş†:Qcç¸%/üŠ˜‹of݁œâP< e)¨aI<²×1AùJff¨À]\Ü5‚¸0ö—œ]pˆ]ë…ñÏÙ*\\üŻ{ü\W‚2((ê€ ¨‹QAÏ7s9xŜ^I˸˜ ä„ ï1c×ĝ…~ÂŝŒŒ/ÛG…żŜĈċ­Î¸M•3Èó‹}n€x³ÔT95úˆ|%Nı/(k#Ĝe2ÛiÎ×ax3 ûì;Ğ8L + äñ`çûS;´„ɍÊôġÔEğ?Ĉ6ċ—ż ĝ UµS”Úb@vk‘1 {¸uïûÔŜ”ȘòŬĜg)†<*ĉÇ[!ĉ-v½µìĝ‰û£5LÀ“ \ Ĥo7’Ñċğ¨›İ‹9•ˆU?=‚ów Ŝ’ĜıŸLèVĦJĥÁsû5ĴtÀû-ÔĠé´uÌ,Ĉíö*Ħmż8ıI”Ñıx#œë9OÀ/pJQ„< }Ôy,wVĊáÎb‰]ÒB¨!T@j’Áûdañr#‡9œî(2ÎwÓ^YЈPüïfµŒ˜I\ +˜BÚÄ΢3Á[ˆÛŸµ¨ğ}‚ÛßԅY? ȷߍÉÜOİì~†şġY—Hû|€LPgîw $/šŽHß֝“ĵkÛö“LmWÛBÇ6Ğ€Â#(äÀ:“¸ß[ÍĊRızÑÌU`Çà+vgbZĴD$ÜO&6í§R›´ÄéM Ĥ^öK$ŻëOÊ^Ԟ2~Xm&KáK£ŞÔħuZt|Ól{vĵ’~/ÖÒħ­*’”f#“”:RÛĤ!ö|ħ¸˘‰Sôbݍïl“ nSS—‰!wœ)5‚'äéÀ?ÒwÚyôŬ~#&Ѝa²ZDÌËöƒâuGD9mĉâÛí$™6 AĈÔï&wŞ0wÚùÌ6šĈsH<à™ß èğŸŒÈÌ#&³˘v ˜§-bñ£f‰4ğĉINÑñ“J:İ]C_ğ‡HêRĊ— +Ĵ9ÚïŬFX—°Ĉ¨”N QrĞäkEéí°6 d·jHÙŬ +\£A&4İ€ícħŭ‹mR†œ‘ĝQ™HíÙ/È<@ŬêÓĤîvéôÈ{ŸôÉŸxô³~ó²ہn†|ŭIÊĵí9*Îî<(Ç˜ÙFвëe’'Í™'-êa'b̂Çßô…Yß ˆç_(&÷ÓaÁßMˆ×ßD˘ÒÖK’ÒÊk&o?\6yñá´4³RFßjÖ§Óz´áŜ˜ÀÜ­à 8ż‚ñ™óI*Êê–2 ŭ ĥo™0ħmjüƒ§äÌ. ġIȅçXÈ^•Ÿ?ì6eġÊ$÷ÚĊÒôVRzО%6ëˆÓş ˜ÔnĈÙP³bn>\A)q +˘ıÛżˆoà}î_´MœÔ#Nü¨M%tĞ ÒżŞ +£úwò“ïċ§˙T6,` ~{BĜóÇUI­·¨żó&Qóġ ÙüĠ‚îûäLġ}w”ùêy|ĵín¸d ÎGÜŭÑSÖQïkÒY|´-'ZZW銟£„z÷í (·û¸¤¨ŜJöĤáĵ8³E*{Pcbš]vêà›\ Ó§Eç$ŞeDÚWuaLë.ÑíN,ğĉ(sŻ— #ŞwBübĈ˘´l‡ e)ĠBÓû•‡ïVˀoR‰íê Ĵ…äMêA _’Ġd"Îİ=.Íi8%Ìü]xúUH½è—‰ +ÚΉrğŽÓ/{eÔÓ>FôŞŬŒÉk;Nç~>LôĦKşÏÑĊ½gé÷_Ž‘ùż&ß}7ù*"ó?›Òe]gm7íĊîâʲkôЏĤTfJÔ&âÚöɟÀ~ uP̓v‰$ğɔyÔÀé­şDj‡š(­•'{ZqÖ·ìE٠уšşßeDŬî=h£$ME/ÛLÉğßtˆÌOú̽6‚ÌjOğH2§OFċ~;Ì|è>˔u\ ‹ğÎ/ҕçÉ×:ğ‹ßD> +‰§}BÑ£f•×tˆoı$êlr3î/” 6ĝ›Ù³ü֜lĝr™ï°˘ßġ&3>kSĜ‡Z‡Í^9MΖc\ +ŝâUü€êuüÛWeuHċW̟ċ\‘FĠjO× +îŭ$î×ùBÏ(AúŻŞÂ^%AÌ÷]â¸AmYZ aú°ê¸Ĵ Ò¸´ñ`q³In‰µäuÍIéŭ&ħ8½Ŭˆ*)½šÀÓ(ì瘤~mŒ •$×Rĉ #kĥ ³1$Š›Q½_ì%Ÿ‹½%ƒ%Ŝ˘Ï=˜_şÜEŸ<˜o}7è>É@İïñÖôà3͉ĦnċŜ‘e׏vÜ %~sô5ùùĝ8¤ğ8XÒÓâ-moò¤j;àçy–~7hÎĵ<,LûħŸHP‘ĉ4ž5É/³“=k9.zÛs„zŭ/óĤĠ\RQqM\[í kŞĵiÚUtücfÌİÖÛ1G;Gî{.¨v—´T¸‰Kk,¨·}&Lqë9ĤıÚÁ¤û}ĦŜœ°m÷˘Ï6'F^ޏ‰ĵ\z1.âDkz¨ñ@=Ĝ"Ĵùċ$˙Éïú˙‘\Ÿ&ĥO]HĈTĤn è0)ŭ:`ÛÀw ^-4Œ˙¤Dç5iïg֖lZ›ïy¸eĜĦŽ·a˘Ş&kaáSƒÇĴŞÀġĠbŝ!ë‘ú:Ĉˆ˘ÌċÄvwI²êÌÌ:Ŝ†žjğ{İ1)éX˓ú"wkÌŭfR|ĞÑHœ…ŸÓğâË&uı²·˜ÛM†Òû-b°3L{£ÓÉĥôpĵĉ£‹]C=J<` î~b<˜ ŭ\àgÖó$ĝZ]0·&ÓKB–Ĝ‡$;‡žmŽ“âu{¸++äXÛ½piݤżÙëPç›PşaÀ’ŸÍê‘é?4…1]ği—çËİ”ŻZ&/j.JŸw#R˙8@ĝŻçU­úNËZĞ<Ì;^EmeÜ[(jip’tÖß<Ĝŭ!DÚYċEuœĉ6<ûŬPĝ²›¤?´ž¤+Z/ kğê`Nu>W—^3ÊúU“—\½Ċ0m`§Á£ŸÊıĴ.żé÷§ZR#ʝ£+œ#½jnF;×ĝĈ\lŽ1ïz.ŭZ ùÒê#úÜĉ%ŝŜêu¨ûIȅĈĝ¨­ĦĤ}ÏĠ?>ĝ]ó•'ÉjĊ~~@Säŝd W¸°+Ŝ­ËùÜG-RÑŒ˙n·ĈİuBi\›]ħ û DŜú¤)yÓzʸ˘ÔIZZa'zŜc*Lûuż0¨há[°Ž\ĵx1HHkK~|}¤ëU”Ĵ£Ô[üħĈÍx°4èrcLŒk­wĴK­wL\•c„[­w‚´èU×vÑ´˙C°cƒüú›a NaİUöÁé5ĥw+ì‚xCn”{„z{„xUÜ ½Zv°çIÓÓB•ôŸĦ_ ˜J_6œ”i8+-¨"yÙpŒyĜL1wšÄŸ=ƒĴ%ó­óĈİĉŒ¨óÍ)qg›oĊžj'í¨ö Šœà—üM*ĴùyŒ¨üûqŜ{ÖP?‡Ġà%vm3Lù´KüĦġòÁž˘CŬ9ĦtKÏ5ş¨ó4]Ò~çc’ä&C:£žĝqLôĦüĵI;cm"µ?9Ŝö8ĉRSb’ucp„[µgˆM½oO[PjıCƒZ› ÜZ ˙ÒĈ+…UVùÖ%5~•Ġ~ĝçòJˀ’’kÙĥAݎ!>îgûßú‰j<ÍşžuœùÍW3iM­ĞW…g‚}up‚ika°(·ġqç7ALŭvá­Żôó^ħ¨İÑéRc\üÉÖ{ħ&½…Ĝĉ†™ôIĠûêÎ +µj +‰uˆŻuŽ9ے'í/öc:êudF97yGğÔ{FDÖ:ß­² „+³Ò&èž§7eׂsŠì#^مf–ĜG”ş„oÏjñµ7ıÉŞĞ‹òÚNIJj-ÄĊ ’òêk°7‚‹uíêQîĉ\îáPċ[äîUîCuö8½cüFöĝQlŸ|ÊÜ£" +Ŭ’ +]BmêBúŠġݏ{ß90hŻ˙žĠç½cġ…Í?ÎÁß>Ġĝ ÁŻÊ;ğÚ'lë½dóÎĴ0ĤĦÜJT^vÑıÖ?ĉ 7•ÖAwĞmƒ’Ê‚Ö\ *l°Hh° ;ҝNŝÒíhĜ3êûÇ)ŝö +ñ³½I˙s_ÛŞ ŻÊ›áQ%Î!İ….!×*CÂÎĠDžœŻ;Ŝœ,ë)5ë~,íiô“~lô–6·zˆžŝrˆĵûw]ÑĞ_›5•†œoJK8Ӝ}äcfĝÁŜ×!‡z^†‰>µß$z~µ¤{ğÄßĞ|ŽtÜ5ë{lÔΞ0jÒñ(Âħ>è–q]îuŜ[V× íû6Ïç ,c§òlc§Ä5m2*˙]LövڞèĵáßèYíjŜu/ĜèWö˘~'kĴ×JtûYİn+ÒégiŭAÖÌè{Ŝè'{‰ù^ċÊü¨r%~µÓoa%z!M+ ³šäûŸ‡$EÍV&ĠUîÇ[ĈĜV‡Ä‡”߈I-sаjŒHvWz‰ê˜şvkq]£´·Á÷|CrĴ}UPŒUeDôŬ|ç§ïíƒ,ê#ħÍ~!ë/4ëÎ3ïÊ +żÜ›àYç‘àPs²--œŝ­ë:ĠÑa+ênÄĥ³<ĵ;;üT[zäċĉˆˆz§·:ÏhÑçf²ëË5²ğ5ż–53(d t îÔó˜ë›1OğˆUċwŝ8-ŝÒçF…gxb‘S0ö{Áw ‚ŬJ½‚N5%™wÜ ˘û\˜ú+úíçĜa;쎵gFıTûÄ<,p~Sl”Uàúà½#ŝƒ_ĵ·Núàv¸ûĜÂ@Żž/>ĜçÙ¤c›URié7ĜtĊç +ħ­sİó ŝŝÉ^ğ…ċŭ`/éĵšÒ`^ĜtĠ˙yƒupVƒuˆo“[œĝG™·ĝGĝCÓÁ‚`A˙Ż—u_ħ*6“4ž•?`rQnŻ@‚vì×A[wíCJ;÷£ÍJŞhÖ½h’ +Ú¨ÄCʄí0ġkϧ¨§ŭm•FĞA~m··+ Jzs#ôî;—À|ˆ\÷Ä|—`˙<ݰë;œiL‹ġö¸wUmˌÀ¸(ÊżÔ=:á½[DRħShĈ aċ€ó?aü)7 İÂ!ô ĥo/-´Zĝ?h·d~6ÜÔÏĝĵg“y•ĞŻĈĞF Î×hb5 ż²§ùż°–ĈŭŻŭĽ]ž˘ĈAgqS·›¤ğŬëĜÇ{á×Ğĵ#£Ŝğ…$ĉıß.pĈv1$5ß5ôY‘]ğb›À”"§lƒ_ĜżË·Ì/ĥ L(s + İp‹lnìÍvġ˙ÚfûK߯“ñżħ'°ÛÔ\ŜMÛ+ħĥi—Zħ\­]·İ›ž“Óv½5SÇ9uşú1+ùe Ñd4F£4œûÇ%?‡!ı?Ž_G=˙ÖHü“<÷Úxüı`Â*´q³í&=ċ<`׈ú +ƒsĵ‚#^y†çı‡ċı‡„}¸‘#4)ß5$%Ï%äaSÈë<‡àì<‡ goƒ2ñŜ|Päü¸>ä}éµÀ›•^QÌ·wїzwâ—ÏŽWZÂÂß6cÜzĊ?ĴÉ>LĞ‹5Ĝk|­œ½ŻİĝŝáŜFáğ’Fs3_p§|Àû˙ùCŽ ü&< hÔ°)ĝëD4Rn"ŝiš5e-Zżí:àV5“?€ŭĈ k‡mÔaI_³×‰–Ûéı.!ùyöİïCÒ?8…`˜ShàRáaÚóÜßµÌ7ÖĉÓğ ÌöÁE!'ÚÒBDż´x1ż5zĜ5úFV}ĵäĜlÄû=u ôŬĵ-{ġâĝx £ıû‰ïŸ€Ç4ݏİĝ;ĝ~ĜÍŝĈî_Ç= Â܍ĊoŜ‹köD*­3Ôï²Ğ Ĝ£LG›Ĵ½ÒÇĴċUħ–ŒĞ5µĦáoßb,‹×$ÌaDÁP˜ÇĴ·.Ħoòíıy[ú,Ï!¤ĦÈ.Ĵ£Ì&HòİÈ˙=s½–1ìcO +~°–ÚĊĴĈ.s4Ï˙ë£ÜŸOŝ;âÏg6sÔ2´xħZŻqísĴš¤ŜĊj‘ŸËĴ/•ÄúFżñ}Î%ìEžCèó\§ç…ö‘?Ĝ‡ċä9†ĵq +{›ëâ÷Á=ĜħÂ?Ü·Ô=̧üFhjĉ]ċĥÁwKíƒbK]BùßĜKoY%u·ûÓUÍ­ä6ĴWB³ä&qkp w˙皓žż<·NáëJ‰ßĊí½Ħ}8Œû^?ÇaĞ:ÍBSF,Es •ğO %ÓD9zVƒĝÒikÚŭÔ;£1ȧÈ#ôdKjá³ Ħ€Ë€Wbì⎿ZĠ„„kˆ×3Š‚Ê1fŻŻħÂşŝ1µŽf}YÁ_HTŻúš?{Ö˙ﳎŻë_ŻÁxċ˙|ohÜ#ı'3?Ħħĝs·{‡,ê ’˙sĴc¸ŭ7sòf´zç ´ëĝŭwÙuÂnÖâpË#˙ó•IaÁïorëLCBHMStqCXžúB‡èĤ§¸Ĥbûèš2Û°·ïÂú }žï]èŞ;ÈJ7)Kь Ó¸½ġßم˙íÇ_üï>`LcŝœÓ‘ĝs47ŝIĝûÄİ[Ñ˘B´Jċ +Ú"‰ĥ7•Ż˙…5?ÜpïFìk÷û9a9ïœ"Ŝç9F—ċ9Ċ—ÙÇÊwŒÈÎw‰Ïw ĥ- +ËİÂ'û÷à°JçàC]÷ŭtJYŬ5+6˙ŻÇ1d ċı{–˙—9öç{cñğç”a³ ùùhÒ°™xžĤa›4ûĝ…hڈehÒh˘ü4eÌZ4kĤZ­ì€v}7B5ŬÀôĉÙaÜŒŭĝ„‡r˙0ɧR/Ÿ“MÉÁĜĈ„ĵÀĥ2ğ°5€ÉS°mÍ/² nnştsN‹ĉ PŭìaÄËwëHÑ,ù‰˙—ıA˙ĊVÂÏù Ĝ§°U‚1)Œ^†fM܂ĉL߅fOہflG3§nCÓ'lDÓGm@SÇ­GSáûħ›Ìñĝ÷fŞ˘›ĦíĈéò2Ĝ•ĵö˜y}ïSU)ŝ€Ív ‰ĈݵÀ9İ9Ï5ıŭƒcBï—”ž2ÇäŝJ‡¤ŜğĝĉJ›èÒRğà]ûËYIò˙oì_vĈ8ĉKa„"š2\˙4 Ï"x~ì?ċĉb[²ÍMµM³Mż͚w-Z‰ħŸ†=ÚÌÄ Û&JÛíĠ=E˙+k&ê~gñĈ#äÑËë‘r#Êò"Ê £ËKì">äÛG8D<üà’‡íé›vĦzhħk°ZĞşzƒê˙z,ÙM°c9Ë>êÏïGsvd̟ßOĈó¨0b1šƒçiî´­hŜÌ­höĵ}hî2u4‰!š½D€f/5D +sĠьEÚhŜ +­ÓġGğm[&¨ĵg7H>ĥ |íÂᖂ›!Ïò‚16 /r Ĉ83 ¸Çƒ<Œ_0+.ĥ İ-°)(´ Ác ÖûÎÜyÂWnɖ]Ĝ·Nŝ·Çvr4g†sßÙÀĦ=8–C#“ ıYhöĜ•hö” hîĴ}hÙ:)Zħ4ZĵĠ_'ÜĠb4w1‰f-'Ĵ…<4CA͙£Ċ½·†öĜĠNP˙Èjôħ‡Í^?[žàŭÒ3¤ä•Kdŭ;çè˘<§hì#ŜÚ,ħ ¨° ïŻħލµ‰İ)ħ‹LŞó“•.Ùfôżš3¸˙IF›ô'zòy°÷†Ŝ›€ß‚fŽœĉŽ[†f_ĤÇĥyš9eŜ;Ñìİ{Â´=hú´}ÜĜĉ­4Aó–Hâ §*w´ġCù]ST²Ĝ•û‹X%ƒOì‘#u·ÜƒÊq‰¨Îs ŻÇóT]jÒVj{½Ö6ħ­Ê.­ŝZÜûR;Ì%ÜÔjÙ½ËÖh˙Ż×ĉX7àÏĤÊÍFSċ1CÂûjŜsÓċâע‰x'ákÚ¨%hĈĝµxl›ÑÌÙJx}Şâ5i€ĉl6Aó•΢EûmÑ2O´Š‰BĞÈX´Éì…Üż_g(—²›¨Ŝ˘ĞWòü\ += +ĵƒŠ1öŞÂc{Rlú û¸Ò"ÛĥRÛrۈĥ +›ˆÜû°‹ĠQAêïÙŬ³'Íù·çíŻŭö<Ġty¤0rÓĵ§×'`=qè=ıyHaÌJlñ܍ۀíĉV4wĉ>´p1–l9–ï³@K5Ñ25´PÙÍW·B Ô­ÑJ~Úhœ,·Ó½u’Êsvݟ=*ê*°ğPçíœòÉ͘ŞWquï\“rsB3ĝ–ıG\jŒŠÈÇ<Ħì‡zs]ċğlöì ˙ĥ/Îa-ÀˆĜ{ Çlœ"ĥŭKÂĊĜÎ/Ä+r·6§áÏér3ñĝĦY– iaۈŻÉĞÑÌéĜŝ/ÑAŠëL‘âzs´hÓI´tŻ=Zj„éxĦuĉ÷ċĥğĠŽÛwŸ]ĴÖÀŞ`|JÚŝÚġLu˘Ż˙[ïûŻ]‚+Ŝ:†Öħ•äÚ(ħ úXeé˙ıÖ:ŞżÙ:ĴÚ&&ĥÄ9Èèg÷ċub‹˙ëœ aà˙ĝù/[2„…ÇàÙ‡÷Út<‡³ıkşü¤0i7W +óĠÔEs:\°YŠl¤ħM1@s—ê …9ŞHa‘RĜh‚îÂ{ÎÈm>‘)żÍŻaÂ[ìlċ +v³jğŬÛ'ÍoŬt/ô ŒÊğŠmgĝ[Œñ k²îĴħ‰í­³‰ûRw-ĥğÒ>£ÂbIÁÚ-,o‰âŽkŜä˙Ċ>ُ‰x,}Œ_…¨˘EŠÚx*höB5l+”ÑÌYĜ~Ìڎm&ŜgxŻÍ›½͝³ÍWPAóóüZĵùZİîˆÖ ц£Ùr›ÊFoòoğëğ`OâÏ9ûóÙ͚],OĝÙڸ퉛ëğÀ@ߟàò\פÂ|û°çïœB?ò^ħ:F1żÈ˙qiou2ê`Oi”°ûTnNS˜°ĝאoĦC°’c9”zš‚çiĉ¤µh.öÇË6™£ĠhÙv3´l-^¸ÍÇörîÔuĝŸ·͛³cJZ´–B‹6ŠÑrĠóh½7ZOE ­G_Êoöïż);GµŸUVûÈî7dÍy½ì Ĥ§ÏġHó½€Suia‡:jLHx{#"öŬ͈ÓM·˘M{ŠBjƒÊÊĴüú*,ŭ£Š\B´úXr“Ŝı˙ql#ıñLà|ód¤ÀُqĉÇ} örúˆùƒÌûQM—"š>qš½H-QĈĝĝÜëá{ŭûfì½Í.T~É<İüŒ]ħ'îo³w÷NÛá×5e§CÙĝWŸŜëQ>E5›]u –U5ú̞7ü̞}-t3í{ê{1*ĝprÀšÏ€ğĉ;„ú`TZr-°İĜ&d Â>ĥĤĜ.’ĝÚd£f_< lĜ÷gmŽùӗúdĴ0j.š7e=ZĵF­Ó<‡V’–h…yZk“=|ûû‘›=ŠÇlqy?zĠç7ĜĉŒĜĉV6v›góĝmîġ·Ù~­d‘;j—KĊ„ŭÏĜuûkÙ=ÊwÙ%*>Í3Ġ2ĜšµĴĤn=+ÔkcĊzMĴH0È^½R˜Ĉ•Žħ³}e@82DÚúûôӐŜi‘Y_…<—ûs”EW†-Yħ÷X—rܜ]ŸĦ€ñ,4sĦ:RXiˆVì?‡Önh-qmû£-'nËo÷İ™¸ç;_9ÏO%ğm%ğìßnŻş)JÇÒä7ˆ=ÑVYȰ§nĜëP:qŸ{Ë4ĠoóüPTÒ}QüêûQòŝ¤żİ2˙0?ùaÊĵĝb*Êê•ÊžU“䵜‡z'ƒBÖHEâ%?]ŝö{6uô"Œġ7£Š|´h Z²ŭ$Za‰Öñ]ÑZ­KhŭŜchÍV­XЎVÔ@k•DH‰ĥâ³Q;­ +ÇîOüûb*VM§Ž5ÒïeM‰Ż?ìÌÛïˆż|¸.ĝŝŬBĝċ§µn ËhŭşV'k­îvĞ~)kÈ+a)~k*l84ÖÚ0Ğġ 3ëz*ŝÔîEĠX‹YݰòçqĤ³ĠĊıÊ/Ĥ˘ÔÊÏÂ'L-vpÑbEc]ÊkĜï3<Îi–˘ıs•²-Fh³ĉ)´pA;I´ûd̝Ĥ(°Ğ5~²|Cv‚ĝó â× +k£|ğ ü½Ú’˙G“…Áïìq,Oó Ë×ŭÁJġħ‡èÏ].ú]Ĵ‰–wŜ<ŬSAc4Í}Fêċ³:‚2öAĈ; íoÏ˘AĵŜ$ɨ'é½ÄÏÛ4.ĊŒ[şj7ÇÓŝğ‰xŜ(lGË× 0νĥŸz;b‡GûÄ]ñĴ^{;´°¤ŜŻì!½ŸìaĴdğKµŒŬ˘ŜÍŞë˙εĴ +Î(³Ѝp +v¨ö q‚Š^{oĜíšOĜ­ZeĴ݉5ċwħç„\“|Żöa~ĵĦ˙„U10>!§şeÒÑPGpŽê‰ÄF*í&ħuò<Éé€)"ûì%Túïş˘ìc2í‹&ċ|o‘À:MA×Ü{ÔÚ͆hî„˙%ôkS,Œħ&­DK·‰VXı=>mÓÀŝĝÂ헃†?ĜS†ż°g >³‡u°-¨e ƒ2–+fġ ëY3ákmÔɞä•ħŒÁkVË0¸mĦKĉ|^B÷VAĊï‡İÁ'ւßĈžËĝCÉ=K‘]ğĵġE‹z:ÈÂK6ŝŻ×19JÔ#qö‰´Ĵši}ž—èy§);x€ĴĜN{l ³›hÓĤ7^Òî2o^)KoÚMŝ·‹íâ$ùyhòèùhêÄE˜GoC‹Vë˘ ú–hûÉ{·ß(żçŜߨU²ğñ~âi½a÷jıV:•0VÏáħ‚Ŝ[Vƒn*·>ññN”l0ϗhtöġZä³<žGˆïÌÑáĵ —Fòì]'ê…f/Ñ+duD]Lc‹áġÌÚ|128h1Üößö·j ÏúL´AÖí=ìKŜ6brÚ̘Âĉ“’âÒ+Féû„·żĞijdÊ'uÑóÉÜŻu_³*.¤[´bdz˙ġc*ök7ÑNĈc˜ŞmΤ•ĴŠî'Vfô…=Ż×Ïc{-1Ä~—üúŬ‰ü>èĴ‡mƒĥĠ­);T4‘ÒÎMÈàìĊF{µÄìϵ¤%X4EÄêÍ%? 8ò*X‘Nê§ġşîïĉë?eUxoYƒ„ŽÍ†/–>ŭİEl§‰G}FÂżiW§ ŒÏËë !;)ÏġI‚ŝûñóݨ†Ŭôíï²wWdù5Wñƒğ…gnŒ3²ˆœŞw>düŭóhÑ쭜–çâéŝ\—#dyì×fmA+ĥ Ñ™×0•î9ŞŻÙµjġì>_Y™çÇkämÎÌoġĤ9Aûcú[\¨Ú+äû·żIèÂÁӒÚFgii³=“= !ĴbgêŞê"í];- Ôżó£J·>˙‡Ĥaԇ üĞá´0€yèʍ<¤jŸ?Y½‰= ÓÒä×ONd˙Żöüw,mt‡U5´‹œnt?ËË„/V“.ñóħNv=ġUԑĈĥíÈ@Y‰èÜY!wœSú‹ÀY"žiá÷°Ŭ œ£ĉÛŸì•”Gĉ +úĈâ¤f³´*)Vş‹ıĉ;Î`P^÷V‰ûݨš=¤˙‹ġÂÔOjҌvJÒSí%k*ó4şûwUĦSü\ATéâĊ mÜTän2>˜ùÑà!ĝÉZòe/cvZğƒ%´³ĜÚW3&Ğ"MÉÑaúQ kéĈn+QYÇêùwFx1lÊemdÈ7EÜ ÷—+ Ïç+uR´cÙ´oġd°_™HÌä]ĥ›j~ÑnÚÁsö“eÖ>³ÈĜ‚ŬPç+zVoBd·ó‰Œ/šüô}Âë‰ó ό%Ô½ÔĠ +ï|×à‡·mF~ÚNŜùğ?ĴbiĞ@œ6†²š!HhĜMŬ#24ĝħÛĝïVñğ• ³Y ‡ìƒŒŸ;ġîü]Iï6ğU#ŬÙÏèüÂJ4Y}zVOïĞk†Ġ5*b^ĞĞçûBQ˙ŒŭH³³òFÏÈëhk˘Ğ˘ŭÛ·#ž"]IŸ·=4AGôEĝ/{AÛ$Ì%³%Ŭ“qŭ@Ü—Km=è3Ni‹°ÂĝÚŬD\Ë^Ê-E‘²œM9„Îb[(Í)?y°äµùşS"ĵŝ`ħÀÚo*éúxİäyË!ieıÔAÊ>|°Ĥô ñÍ;)·;‹İKS…^ŻVĉ³|bĞ-à"íì ›çSÔÏĤĠĵ’5IbúxíÇì6ŝ'ö*Ôòñ+Y3‡´™ZşĈH]EIİíTFûwîF³ÖcèÛm˘ŒC2İIExÎ~ĴĦ@†àL:Ÿ!Ù› pNİÓ6[$áÎá:'(B ar“2ì9Âëö2òâ͉„ïTÊ'k5œ?‘&4ÀÙ&£‘'}YvDœŬ(•fĠdRûu¨¨ĥ½ÂĜö=tâ :Ô|Š?Ô^äß˙MƒŸĜĥ‹{Zĝt ëğžQŝ„~%ĈTíìAƒÖϛö}v‹oŭR=3§ÊÊ<¤i(EÒĞòüË!“ĠuĊhïv5¤Ğ%Eš*ÚHeíV¤ı÷ÀèŒœ†ĤRŬ³iĞ Db™™ĵéyë‰&N KM]n­‚³AR§€ypĈ‘ıĠĤgšYyTü£Dp닚6l&钲@˜ôIE\´‰¸6MpĈkĵ0ċinóE:³—âÎşXE+ÀyfâĉĊ„SôÒ1~ž=s‰a|ŬV̟jF·ż)E–nä%(ÜúĥÓ cÙB–gTñ7İQáßh½ÇżïĉıĤÌĉهN3Lŝ“Ìî'"Z·^ Ÿ&´Šž!ĵâ?ĊPtx˜ŠÒN´}ÙJ´w£ÒûŽÚëĠZêĉëUDʀ*ġĴC$HhŬ#ĵûE“ÈìÖ'½3W6ŝÓ ûˆY|›Ĝ†îò>ĴàY¤NӖ]•Ó NӕXËóÈËrz†‡† /‡Nċ_Ÿ¨Şl€š†f`Ŝ´aê¤ĥûRÛµéëò¸>Ä<ĦÉ0BzBžÓĊ9wc²ĝÉ$+èżÈNğM„[ÒóŽEçlĈ™a&­ZOš]a&y"#Ŝ­ZÇÎ$‚ßoâ§ġА÷ƒV—Ħ䤁ת8ğí $³EJĤ|V‡çHĉn œ瓖~ÓèKĦw ñ¤ßˆ—ŭ‹şQĉ7u£‡?e|Ŭ'ĵż˜ïrwàZÔ á·q0/ş ?f(Fp6Żġ™¤{örâ’çDX÷„ÛƒĊpTpÔj¤.Ĉa:<)ŠŻÈS‰óÈÈú]tT³ +ô͆~F\?ĦÌ&Rx§_ÎvQQğ‰”FU"­Y ΋“ĜĤPħóèĞ~ÓÈĞ>SHĞàéÂìçÓTħĠ;Œn÷Ğ÷oğdÔĞ.)ùĤׄÉm?Bd÷ ĝ÷j/úĊü;żî'NıŽÓgL‡šœ“‡ó[dúm鋺ĈċïeĊĥTNŻÔ0ë‚§ĴÏûŭRMÁ´Va)Z3a!ŝ:ièшÌj¤à¸ĠH#³s‰WG +d—†ĞìWGû°ŭܧ´‹Óc#.zN¤Îڏ›šËŻı2VrùúTN3ê˜ċĈìÌpÑİ+c W‚èVƒĦäAƒ„Êì4"Ü"ç‘ŜSIuğ¨”.MèkH]ġš"²ñS ’êÔ¤Ï?˜›pa|ĊnŒ×Áü "+· +2żh3zHAJË^Q Î{LŬ2àĊz"şn7[·›NîĠâöşÏƒ•ԍäEDXé6ú^Ğġ¨UsK½í0óZ“Ïş(ìwÎéó'ÇÈršÒPá!ôı?ĉ0š<ï7™´Iš}£HsğQ<êĥ§ċÈ SZX@9Ë'o=œ[Ħn èÒî™+ˆ“vcˆó.)‡ìÏ`<:“² ²‘>YkˆĜ²ŬT|ó~êN‡.}÷#LïVçúmßï2 u àœ†0i0èġ:~Fż +œ. 5ßÔĞ~™ yp/?èŭ:~â·Ŭp˙¤…ë$á›1”ç´U"ep?ôÍ$ĵ,'Ü-ĜÈOìŜex燲àJÄTMS´eĊF´núb´}é´{ftàÀ¤­g€ha߆ñħŽƒt (¤ÁCZ:†ÈìŒĵ"p*ôûg´Ħ×"ôú£I39‚mqXŽÓ {§Ä$4 ›UĦg7qÖaċ™”Ŭd ½W!†µKğ§-aì#ĉ@O,ѝZĦ8ğN*Êj‘P÷zxDÚ'u"ŭĞ&œ ##ĞwÂ39úÏ&=S–˘?lî÷‰^´ÜûM“ïŭfğt­aBïv£„]·; ٌ0“ÓfxêpâĴßDŝñk#wnڎ6,XŽvoۏ4•ġ°Ŭ ˆ„Ŝ’·WJc?hˆËöîôĦƒ~…|Ħ ñ(ÄéaÚΆ³ŝ÷Eä‘ĵΑb?°€² V œcĉ c›v“wu‰ŒO¤˙Ëu´U¤…/èO_ñšÊÉ³˜á› ‚M\_AÏĴUDÈëdà‹ġ”[Ĉ"ÒŭŝRAJÇ>"³Ç€Êì6$’żŞ7.~|ÙyyuTŽob9œ8á>ÎtDĜ>Ÿu=ġ&–# Ïô$:ŽĤmĉÒîY+‰°Z%X_óŠÔyŻIä9÷‰ä)ûħÄÉk£Ħw$íro‰0şa'wÙ˙é:a\ÉN8[‰ŭŸħ4ğò(ĞA*Ëİ8#zWw”Ìì1†oĦħïú>]gáüġ˙ħ÷ĉñmUר³Sʌ `ċÌCÂd;!Nl,k–c[vDdËÈr‡„ „  aJ 3 -‘öòµ—–2´”ŜŜŜ{ÛŜé{ï÷ßï½?î[kQ’9Ž-™#ˆuÎÖÙûìµöÚkĜ{íµ~òO­/ŭ_ĠU{żéË>vvÓşC—ĝ˙ß·úŽü½ġ Íߋ˙ğc5ud&àšF}Ĵm<ĊiÙġ߸˙s9°úàEwÜÙwb͍s+nĵA­˜1ŭ6 ËĈŠù@…/Ö:)ĥe÷}gşWœÖĜ‘9sPRŒ—ĥ};'†zïŒéƒq],}ìüXGß)-ËO†ÛĈ7wôşàƒW†v4c=alŒÀާżĜüâ•ŝƒżż9¸˙³[C/ŝñv<çŜúòdŒ'8ĝEuô•Ï|Á7ŝè{ñŻĠŻŝwMàŬż£|Ñŭá…^ù—zߋżż5ôÀáĞBkv^àßŝÖuMŻŭÇ:ğüîżĈšŜü˙ÀîĝŒó-}ì˙ҝçúüŭĉĤCğ%Ä/„Ĥ-oM +ĴŜsĦoÓ·ŻlZöôyĠĠó+dŻP1ëĤş +̉ı|>ĝÙ[O1?6ĵ@1:ƒİ'cÌT˘Kà›ĦÇŜĴ +ŝ§ÙŝƒŬYşŝìp÷ŠÓ#ëŸ4°ó{SCç <ï;òŸ3}/üċ–Ú]ïÙ>1ĵáġĞ1×F`ĊމĦO~ċdhÍÓRL{À\şĝŭÏ_Zŭô…KrùÎoÒ+N ¤ï?âílùîdú^òè9ŝŽ•'cĴyĴƒç1F•oъ“œ4ĈÛ oùΔÈÖï{Ŭ÷Ÿq‡żmÜ|_KÒ³żkŬéáĠ{/Ĉùâ{é?k}Żŭ}ĥ˙…­ñŝ÷™Mûżĵ)üÀë×`lwŒS<ô§ZŒħ†ħ‡Ok1ĴŭGŝyvĝWóBoŝħ)ôîWÍÁïŝ1ì{áïĠÁG{=ĈCıÑôô˙âŭoümž˙µ˙šÓôćœĠ q]­İïÉó[gĝò&Ô!üÏ|ŞâùqŒçħ#}1˜k ;Oßóèy¸6tO7˙9ïï¸˙”ÛgGÀšUQ77RÎn9;üÀĦ+16eĝŝC—.Ï/Û9qìKŬ{ŠŻ÷ÄĈÖ0gGà™§aŒ Ŭzäşöïs[}RŒëµ/ÇĜ£Kd…o÷ĵïà7Â|œ|ò]6´ë”ÀžĤGžûôöĉ#Ÿû‡~5;ĝÜof_ü·ÛŻ˙e~ĝ½j‰|òéŠüĦŸ˙l=žż˙ôG}áïü>Š<7¸êÉ `î +ÁWŝZ‡gqŻŝżs}Ў\8sv âfù–ŠĤ·Îî˙KMè_ĉ`|1˙Ú5m~ûêĤ%O‹şèĴÌÙÚRñm(näĈŻĦ|Œ‰{OŽÜ½ġlÊġpÏçcLyÌĞ„ùPÖ-ĝÎ/:"Ż}ĉ¸0Á…PñlŒ‰xùo·û^ĝk5Ĉ6ó?ŭ[ÇcÑa΂` +ìÊğ7\ğïâà:³`_„€WW>~~xù#ƒ+Ÿ8ßżì£%œ\òèıÁŜíçDşÖ¸{Ced0ĉĊĊĵ!”4Ö5>Ô·c"žoġú{µ˙ŸnĊ8áuû.£\Eƒ³ë2ĉüx˜—s3aŒĦ’ġga —àĞ˙Tyç‹Xì­ß5‡_ŭ܇6ĈŒĈµŠ!ô+“C›öy0ÖSàñ÷9Œ=ƒıA`'^ú÷9ŝ—ŝcĥïÀ§œÁfaÌ?“YsFxŬ3—˘Ŝâŝ_g„6ĵvĉŬ½l´É0Phó W"b תSç76#O1ߛîZzRÓâĠ§î{é2˜Û·†xëÚù ­3ož]QwG¤ÂßşdBäŝg/8â(Ĝµöt́…ñ ƒŬ›*}íK&̞˜JŽ\\Šħ‡0Ĥk ž9cɄ(~ö WQ,ü~àÈ5‘͇&Eĥq=ĊJÙòĈµŝ'~ÄRN‘çŝyvì•Ïŭ­ßú‡dû;?ÌĈßúe"|è÷s(ŒuĝÛĈ>ĝ]wóŸŝñĝŸ~şÏÊaĴ’Ĝ럆\>ĉchzüûŜ&°Ašžŭì;ĝo75mŭÁµwm8ĥşĦâĈ땊9``L'’›wŻ?£ó7§Ç7,̞8·ĝfkE¨µï$Œ=Ġĥë'··ìŝé ŠĥĝŝÓ1Vĉ-ÁúĦíw-9ċvó·~½`á·ı8ĵ]ÒaL%˙÷ùà›˙Ŝ|ëûž˙ßӂŜĵ +cĜ·‚NùĜ÷™’íçŬKŒC]/´ñĠĞP΢]í[Ĝu"Ĉö÷÷s´i×O”ċ‘|ı0òó?ĤñœÚÇ5xgxÙ]'—>òqß%ÁÌĥ³p­*°âéóÑF¨kjwëuêµJĊÌ[ĉU4ĥ-›àkî>aĜµ·5€. :d4Iù·šâ0&7ĈŸĈĝû?šà tŒ,ì™é{xbĦ×Eˆq›O|(6żúy¤ùċ/ƒ‘mßşbĉòÀË˙<7òîW-ïŭ?á;ŜĝŸY=‰äĉ'[ħë˙˘ì„ş†Ĉ +Ì;‹çê1\cNJ“fÏiĴ@HyÊ@­Ü2}ġi˜›3Hˆq1)_%Ĉ„Ş÷E*‚ Ÿɍ-Yv(siġî‹1Ĉ.Š>òfĊe:´°{ĊĞzĝíİħmŻWa\.ÌYJĤOÂ8uĦ]?S#Û^½jù WŸ˝zü{Òeŝáž9ÊóàÓ?UBûŝħíÁèáŻĉû~qKĝŜŬ€§Ç&bN™Ĥ=żWŭ/ŝ÷,Œ9áÛûxàÈ‘ĠÏ\Œ}›3çPEpñ†Óŭw­=ġŽh×x{ßIŝâbé„9ġa°yj+äkÄ +µJޘYq9Žkˆ§N,ŬqnÁWŻ.ÙvĈ‰ÇXŞ”Gxéĉsc÷nÇÜ}ç`>óúùÑ +ŒûDùÙ0>WôGA™‡ħ…Âû?İĊXÌě2÷žÑ´÷WÓ(ŝÏ˙û_Q˙3š†9ǂŬ scü\°½ĉŬ¨@ úcmÓÎ{‘OΞŬTqÛmġ˜ïŠĈ`é1ïċqÂœÌ â1ŜñŝX…/²p<ĈòĤÑé•g„ğ—ê÷N ˜òÀÏ|pcóž÷k"~w*Òu°=;ƒ…žúıÚûá-÷+ĵêáóI×zú%°˙—7b†ĉµ;.Ž­ßwĉh~èÍ0Öa`÷jìĊO‡˙2;Ĝ³éÌĤ…İ)ÏùĈg݌>räzÌ;:ü×ۃGŝ:—dŭĦ?TS,Ĥ/_Jn<-´xġi~˜0W:ĵí½ŞÀ3żż1²#cĊa53\KĜDĦŝ<›ržż Ŭğç˘êŭ“ŝĵág˙xkd˙Ÿf7ï˙C]óŝßÖ÷ŭúf̅íÛ61|˙Ë1–!ĈÑCŒo\{èRÒ9ĥ|çşJ‘½ž9ĝ§Û›~ZçĦß4FŸûd.ĈO„ıìÛ}YóšíEwĵͅöXÙóQ-ĤL:è6ÁÏ_²n +ĊÓëÚ|&ĉÄ ìŭŭMĦŸ>ò×y¸në¤:¸ñÀċ$÷3À§xyÏWżtYS×§–ĵó²bÌQʏħ_A oŜĈÒôíy_ żñ…?vĝ³†Ĉâ^°ĝÊirç‘ EŭĉvàĞӂ‡~;#üÊç ĦGs}`Éŭ•?”½˙LÌuŒßĦôêÓQ7ǵ‡ŭÏy0ĉ3ÊŒ3\˙ÒĦ{^ÔÔ~ÏI˜cdĈÙ—/pàߪCO~Ĥ yö‹ĴĜ{1Ċ;ôÛÚĤ}ż™†6/ĉÌÂu1Z‡Ûpĝ +¤ùĉ=ŸÏÂXoĦ_քžùġ͘û ²hċ)˜×sÍ÷ŭê–ĤCŸß„qBqM„ĝ/âyÓËW÷|ysóßÍ ĝó ¨_‹qܳí›á֞ 8ïqÍ)öèÛlÀÇĠħŸ4´ŝ4Ŭû›™ŬżT1gkxÇ[Uë.ĵŝ•Ğ(ïĠĤoM‰úËÜȑ?7ŸûŻ™ŝş9ĵñI´~ĵéÈUßîŻêĵŭëDì[_´ŭİ—ö12ÛÏöw?pÚşw€ ˆy×ë‹ĈaÄpïçE }Š#‰9c€îCënóQĵcÌ­‚ñ ›·Í,Ĝü5áŜ‡Î‰vo9;şrׅĦ=ŸŬÛ˙ÉmĦ?b+ŭ&ĊBFùŠñ{î;sœ…ġÜYŝ§@/{ŭO ħw~ÛF1ĠîÛwİ‘; ġ¨@Ĵĝaç ánŒ)şû›oóŞ½—5/ÛñMŒş`ĠS—boˆ˙qrÁ>Lc,î9Ġ·WÌŻ hħ¸~4Ğù…_ß}ŝ³yŝ?ŸNħ¸ÑĤÜ˙‡[À†ĉ0ĉ Ú#ħžµgú‚nú/ċ^;#òcÓ7Ż?x5ÊzŒ|­k[ε.€vĉ/‰{éŠèÚ—Ż —›^uŒYDzÄ#o]‡8DÚò…ğĈc^>¤˙Ĝ³ŸÎ\°ç‹9ħÍßıġßĤpb܁ĝ¸ Ê Ìy…ı@.wĵMvO$ûÈı}ĉ5Œí|=ûĊÜĜĉ÷ĵG÷PŽù#ÉñĦĝŬbÙûÏ˘œO~OlŜûٜ–ŭÏǘğçóù?{âCò"Üğ÷bŒĜóĠM?cƒż}MáƒMġĉ䖷ĤĝŸ˙ŭ­Íï}ÔŜú.iŝŜG‹_ùÚÀözƒ|05tÏâħ˜s÷éB÷í½×ġ0?ĈżÜĦƒ_ÍÀĵ'sfŜ^1{&ĠĈ0èĦwŽ3òÍ5wŻ;3Ĝžž€r‘òfŬ½ġ̕‚ëï” ıòTœwħìÚ³"Û@bŒUŒËMı³€ĝdvôÈgƒ/tĝÏ·7í=sg-ş˙4_ë’1·lS8uBShñxŒÇŬœ^fsrí阄bÊ.\zR˜bÚ=ƒb*?xĝêĈçĈK7žy¸1Ï̂}ŸÏ+”Û¸{™”·ŝnY²ġwv­>sŞD ó"QÌŬ–=)Ú t³ìá‰û<ú—ó(wÖÀ­‘;ë!̝ú]÷ÚÊĜ}O]‚1c›W€ÜÓsg…RNo=xŜŒĤŠ@¸m|¨ŜĠ²„pk猵Z´yÒëÖs)?È1ZÉn<˟ĵëDÌτ1½)îġ“?)7ĉÙ9˙ZқÎĈ|u-+·_{ÈäÈΟ*aŒĊ½ċȵ˜˙*ö§ġ¨#^Vp%èL]ëO$µXܔh÷ÇÓ(Î,ĉ|Ĉ8×Ĝï‡ß¨Â˜µèFù{;ï9U[^N9>,^sĉŽŠWžċÎzìҋż‹ëƒá˜;kAEC=ĉ3Yz2ĉéÂ}7̆r(Öıì4=wÖ˜;‹â•ı³+OYpïˢÛ(,X÷Ò51g‡˙ûN£ĵ]+v_D9Wl™ˆy,›×>~)ĈÒo^ ĵĈ5šĵ˙t˘ïí?’°>ȳ´úkµú÷¸cV#}‡Ò@ĞË6ÓüàĦkZö~t{üÙOĉ“Ŭt3î|Àˆ;˙ò Î˙Î/x}/Š˘Lšħ{Ÿ½$şöċMËNÂ5‰Ĥğî99Üûı(1oÖ|˙Âqġ;Ç5aµû_*²W +êı‘û/Bù‡ıŭm÷œä Ŝ9ħ1Ztr"ċaíYċb_şáœĜš§/m^ş]Ë׆sŝÁ· übĉ%ÂġEè=˜[óœ×Ïmި›yċÎò…cš‚fîĴ+pebŭüóg6‚|iòİ9ħü”ĉާ6'ûN&zOŽ´/?y4ĉâĤüÔĞw^[ûôÈ?Céċ§˘ĵ§|€ÛS?–1ÇĊ§ïŬr.ê­1ġ\{ü=9úÈëUч^ğŽrĥmĜ}yùOfĦï •b,î’‡Ï B›˜ß,ĵç“jÔIq 0š\sZ,µútôĦÜXë^ë-”ûwġÁKƒ½žċoMŸHıœ@f’Œ4rgíû¤&rÓÛp-Ċȝ…ò6ÚûèyHϑ['b2̝…ù’Ñ6³rg­Órg-{˙Îԉ(_,yĝ‘ĥ%'áÜĊŝħžm碄<·yŬӗQ>³{żpÁ½^<”‘Öċ'Sî-¨ß²ô‘óħ>Ĉ[·×G;>ĥaߕs›röĦñĝOÔĉ½?İmÙôòuѕÛÎǸϘï™rÁ>ú5Áç˙6+rĝßê1Ž,ĉŽĊÜxTd'w}_ˆ>ĝü5ZŜġ̉˜+óàz îyÍóG*ê#‰ñó|ъ†pû8´q={/V9ħÀ3BÛÊ˘.IoŞĵ£!^1Ż.XQ7żħ"¸ „ĉż`ŭ³W`t´Ë)·)ʝMŻMĈµÊğéĠI} +fġżòosŭ˜Ç|ó˜;k>úJ†[ĈcîĴĤ`¸"ˆı³€Ĉ‘?QîĴ9>ĝ‡ıߛ{:/ĥdŬÙ-İÓïLŜ_‰9#mŬ'…ÚÒ˘] ?1wäÈĉCWcDÌĦFkç˜×왏o?óáM˜ß5şlçù Ö`ŽŠÈŝ_ÍD=÷9P§ÂĜܔŸÁ=W÷\²…r$l½cí³—„—Œ˜—àŻAßú¨fÁŞÇ/i^ĵĉô;ûv^Ĝ²ìú-‡'7ŝuӂ—?‹F_ĝcCc'ïŝLı³(ûË×ĝw˙ċÎ +íúÇi”;kĠ.̝uÂ\œ‹ħôĝšç/ĊXŬ”›úÁ)wV3ĉOĈÜYë´ÜYÍöÜYi#w֒“ƒ-Éü!°-c ·£Î‹ı×<{)Ĉ÷Ĉü¨“`.°ĉ›`~îĵs+P}°;"P˙ÎğNÚĈa^*Ô(ïÖßúöġôsj€^˘Ċ9~áêà2ÚıĉtÊO–ì=s~GW>}aà‰àC/ŭËÜĤ}_LÇü‡ŝ;;N@˙òüC[ì„ÎŜSñÖêĉD+`“'î=Ÿ™ßàŻ-X8>rÏĥ‰¸Žˆòí7l×00ï´ż ôŸ{Ÿş0ĵí[×a +ÌÍ=wVSĊÜ9M¨o‡’Kï¸0ĥċĊɘ˗ôJÛä'Ï[&Ò·rŝĦż•˙ı?TGž˙²ŽrgaŒôTßİ>3wÖ2=wVïİ (wÖĞŜèöï ħìĤ³}MñqĜwÌ·{Í+ğ öË7´ĴßuKvċ·&{|ĊP<öŬ?ŸFù +@a^Šeù +(7ùÎ "÷< +ş×KW£ íŝĊ‘}Ï îùĊ́]ïK˜žÖÂ?‡l™}„+üĜ÷9Œ%~ħÍßó’Ĉž˙l~äñï‹-K7œjM¸à§½vIĝéoD, ĥĴ–_R˝¤ÜYŸŬyîŸçF|yú £}@ı0ş×žh_urcDz ŝäşSŒÜY¸„9(żÒû'Ċĥ½VğïыIß·Û~ô•룏ŭ@hŜüĉ ˜ğ2Ú½ê ô9Žë&Ík÷zBOĵiù9~ PŜ˜ÏxY”QÌǵímĤùÁ7‹­~ôBäĊQĴż0y"ĉßÂ<÷á]ߓC{?ż××hÏs Ŭĵ÷ñ bÙí)‡sê>Êużà=žÈĉWáŝEm—×çGœ†6„Ż8ĠJŒoji²“ô_Œéż|ÛÄı³Bw4.j½ç¤ĉÎMg˘}ÛĵâÑ 0ç òä#o\;ĝù<ŠƒŒ{‹î=y~8³éL”…ŝĉô …çdêR(ǚWíıŒd$È5ʳ‹kž`·Ħ—jùK_|ô]Œ­/£ÍÜù.ƒyš—?qċ[½ûR”;-wˆmŭöÔ(Ĝޘ×7µœÂÛÎĠòP E=uÇ{ĉ~C=€r˘`%? ‰~'˜ é ÏX`Î`Ä7ĉ¨C=$ôĝÛLä‰TÔq_sÇc^ÌóÚñÎT˘MÌ-³’dÑ5‘g~u+ÒgĝàżÜ†ûuħƒŸÍŝM$ üóÒĠÏü‰í)ôú}—Gz6…{ú8&Áô½§áTħ°§?”0wVóKż6=÷Ġ­˜;+ôÈĞSÌGx‹W†W¸cYiÍù‡S(wĉ +ÁġĴ‡€>7˜^̝uż–;+òÄwĊŸ((#h½d~óê]—’ |sĥ >|ê{Bd;À½i˙‘  \óOŠí|O ?ġBymqÏ%ğñœĞÁ>À~›Lïŭ¨:²˙73û?ş),´ġÛ×c>;Ìóùžb[Ŝñ6/úÂ`{ç„ÈŻ^kħW>  ^Dk‡ŝpĞ˙™(żĜXdklùö ‘Ŭż¸9òäÓPOŞoŒW,91_vùÄîïL̃[ÜwZóÒ-ûŝħĥċÀŻ(—Ì=ÛÏG] ö `Ż7m›+0‡c>\× Œòœ<­yĠK0wÚ|‘5{/Ċœ‘ /\‰gLhiŬ‘ĞBHݏ~™^uZäî5g F9`€–˘[_ż÷3(Ç{×}•Ħĥe¤ï£ŬĝĉµĦ§~1 ×D˘^‰9żQ~‡€Çan!Ä+Ú£Ä×=u ĉĴĤs.;>)_ò­”µıïĦoPfÔC#;@nƒ†ú>ċħA½h~OpOĥĉ]pê9Ŭ+ĵuiÄŜü]Ĵù͏„üĤ&ÜÒubSc¤÷Ż(G͚Ç.˘_˜ç ġ°ÎûÏ ġ[îĴÎñd·Ŭ·ë’ÈöwXÔǛö|˘˘ŭŜÔü¤&ñCËvŸıÒ˘›ô\œ`÷Á<v¸ç{è/ùMö­9+òÚ§ĝ;?żĞŭ;ïu·ŝ³ö/||GŻkÀŞĈ>#/Š­Ús)Œ%À¸àà$ôu wĴ>%şñµkÈfŜġiÑċï[p×ĝ èԔúCÌğúAo +%Ç75µ€nèĞ5.¨ĥ/?ġc„+ĝÔ˙q]ìɓ}ŝĉq”ËŜ}ààU˜ß +ŭ—('ÑÖ÷ĵ')bÎÌ)GçÀ–Ċµ¨PGjĉÚB|FŝîÔĥo]kù(£CÉU§ú›ï>ó(ztë×R~ÚëĊœTÏ\ŽyÖpmϒEĥ˙HÀ=+Êyˆk˜H›Ŝı.ĥŝċI˜‡şyí>ú߄˙ħĤ[Ò<:|MóCߪBş§ħĈġ&Ìǵn÷e¸v9ĝÙíÀż½áÌÚÊHrĊİĦ…™ Ñ;~=ĦWŝ4żùġßE£Ï˙>´ë锳×(ïôÛLhÏ/o +?ó˛cĵx-ċ4ǜ· ó‘Îşġġ)è_ˆ< şöİ‹1Vè‰ïñç˙Pëßġ3÷wqż™Î:Ĥ֟N2éĦWŻC>şT´oŭ9¤§ÜûÄEÍ÷ïñž÷À‹ŝ'ŜŠĝÁ<ëhÏû˘1ċTıBôÊ\CĊ=HÔ£™ugRN,Ñ¨#aߚ7ı6şó‡ÏD7ŭA˙b›Ŝšî{ìèê\uZ´óXBûÈżî}ĉ"”“QÌeŸ÷t\żŒ<ösQŝ ̵…ıáVByĞ1gû†ç…òsàŜ9òrÊĊ³çi˜ğ됽‡ĥ*-ê@˜"°÷7žŭd:òĵèC K`^%”µĵY8EuìĊO|˜'÷ê)×גÍç’ï 5˘ĉW'‡7‚^‹ùñùĉ]>ÉMM{~İ˙1G{:Ë@v íÀÓòï˜öq=}‡W>qĦĤ#ï ŭü{~FşSdÓáĞŭ­}šš{N@[óVĦ΁9áB+9óĝ7# Fßjó‹“b÷=~1í•=ŝ6´÷›ż/>}°ġŜ“êwó/Yĥŝ9÷ÏdlŸökîzX³çbœcá ‡<G_ìßû‹iŝ]Hŝ§~*àYÔPjċݘ3ÔÙwjôç&Q~8ô!ıïĊ+#w íĵïôXߓßÄ\…QÌ úhxësÀC_ğil3pï ù ĉ›Šv/?=Ô³éÌèÒ­çEÖµçZç›‰ì ¨‡8ÂüÒġs+îù+PFÛí]Ä;êI¸ßš w-?•hsL΢ëö^†<‘•§ĊPžï|WD}óiĦ=ˆ>[ħ ‡Bß œWĜÜ/Ž.{ê|´‘£IyÓ{·œK>G˜ ~Ù#AŽM$9ù^§„—ï<s:S>aôW\µ›rvÇP÷Á<·¸F{Ïĉó(Wñàﲔç×L@Ċ9~ôaîSàq”ç +sĊâ:;ÌħèRÀŬ: 3°OP/Bˆîü‹ˆ:ap÷¤ÈÀIùÄ0(ĉĈu\'_ĥéÚ+ó³EŸûí<ŬŠ-ÑNÂÜu8· Èùöġäĵċ•ĞÑßó&bBôÄùE:àùUóš=—‘\Úúfċ˜îğ’ètó WyïúÀÖwĤ„–휈úÁ†~/ÏürÎ'ÊħĠÑ=ó„7ù§››ġçùá#ž>üÇı‡_½6Ĝħô$<‚úŒŬ$ÌÓr` +ÍGÌ=˜Ŝt&ġ›ĉġwĤŝûq?îÇŭ¸÷~܏ûq?îÇŭ¸÷~܏ûq?îÇŭ¸÷~܏ûq?îÇŭ¸÷~܏ûq?îÇŭ¸÷~ÜÏqŝLš4³ĞmF<Ż ŬV9İzŽĜ÷ñžl"S9żrRËÔêLvF²5›LwĊ3}žiXšWçŸ33Í3ı.Ŝ—È´0-bËÏtÏäê9,Óà×)žàQĈË žİ‰xÊ3YkÔ?{ê3ɎdúZİ„öètĝWY%K2ëeEQȊŞx9‘c=XĴ^^ĉD[q +‹µ,Ö‹­F(ĥYTĴìŞĵ£RġLžâ +ŭĥ+À‡‚ĝ¨Éôö,jˆgĦ˙]&’Zĉ§ğ2Él²Ğ£ŞJ+I\ö*çw/€úɘ=+™BÜN5/§ˆÑùéĥ^ĉ {ÀÙË:S]St+“\Ĝ›Mô "aĵ2ñĵ'Z%Sm™DŝÎyĤÎéÊZżáŸl_7 Âd–a&MñLġw%[ĦĜívuä>ş$žêĠž]”Hv,Êŭéx'= }1żĦ”aZšlË.r ’ŝôˆCT=§:Ġ½(ŜÂ:…+ÙO >3â ¤Ŝ•hÍÖ¤{ğÚ o5éeN!j§İf{WNĠ9‚DËJŽ>Çpô½ğÂ&³½™…½İDWkÂ)*´Şħaĵg r +O&ÑӛrÎüÇGĤ´/›ÌĥÂÓ-¸zèéĤd*ᜭäÔq9§ uġvÖ·fKŠ€Ì^eäùŒ—Âĥ0Ŝ“˜•IÜŬ sÒ9×ÉĞċ„ {@úĵ6I–hrÈNĴe0Fx”|éŜLkbv&Ŝ½(ÙêXér…Òíí=‰ìà0†'R›sáĠ6ÒË9 ÎeWÛh×ġDsîĵÍyŸB½=%[ÓİtfÚÒEƒškvÉӗrrŞ?=âöt'Zë{!³òckŽ0zz3íñքîÒët°r*ÂΠcè`t{SñÌÌeŬéD—ó+Ĵ8òP dmşĞ'VĊr²TÀ\ƒS$-wŒ•ċ£azŠE€RâV4[̰ ğ}\T‘†t²+[W̒ÙñYĞLĝô[§ËċòӎŠ”· QġaHĞ@îvJ™m§” +O“[‘İdĥ!žL+?ÖP4/uĥàXWY<È‹ |´t †Ċĵs@ĝ’Ä9m-.mÒd; ì(Ï$³‹:Yçìùë.BËǎ.~mżhÑ;J9/‘éH &ËO%*V{Crüúá:ıŽGÁĎAÇ£Út:U“I$–;Ŝ)YŻ£ŻÑù“*Ñ1%–ĝÊp|bÌúWħ^Çgż3ñĥdŻs*5y (nâPI Ĥ2}ßR.ËOmÉTÜıB9ZĦóҙîEéTş1,³e r7ççIJœğž6ĉŽ:ş<­”yÚÂâÎh”0(âh\‰sÇCR., Êuß-‘é>Vc,tĴ™•<sΐK9ז˄ŭ¨ Ž=ĞË/jƒcjt£6Œš2:ˆë†ËĊGÇcR.\Ü1@=Ċó"E¨>%ï­VíxvQĵĞ+‘ò%R‰Öb– ++Ž8Ž7ĵ† +daĊQG3’=Ŭİxk˘3ѕï.?™Ô‡ĤoÀ–…­T\€ĈR–²Îġ…R—²ŽÇ¤\¤,1ŝó\²9—N!§+çĉ†ñĝ(:\ĤҙyĜG)²½…Ž-Á’gÎÙ]İ3 ÇcR.LÂù)à‘ ôR*³Ż½(?ĥöd*UŒğWj4ÄÁ ŒÛĥü‚Iİœ/ğhOüA!ÇiAf~>ġß!„yµFaѳË1%Ĉ[[{;{ß﵃gĞ2ò˝Žİ²Íy&íÙ‡%“ CËñPµµ%³É%E ”YĦtĊD{&ŬéœÒ£pt²+w|5žj—v~˘ÀVĦt7²iç6rz‰§–Ĉû³ž²ñLQږöü(Y&ñdgú8Q)ïw­ÛLİYG·¤\Ĵ£*Ċu›)é>VŬfZnjÛL ıÔù˜ë6Svn3Îcö•ŸßŒ›ò²ôċSë˜qœC||Ì9Î8VGËqĤċÇuœqgFXıŽ3g-Ǚ"ô…R—²cßq†ugÊˆíµŽǙ"Ĝ]İ3 ×qĉ8;ΔQù¸˙ÁCŠy£4”eĴ°OHw0Ê7ÌGùŒĊñëÇèöāŒĴžÓ2ƒ‚ž´·,ëH ,)ĉ|ŭ³L‚%ÉHŝnx—ż ™żI_gŝĉx—żıüÍċoeĊßff ÀUß\öVêì-„êr7—ğÏŬ\ċÍċn.wsıÛXnöm£–â\6Ĉ“s ü×o—DEL"ùë<‰ïN"wċN˘†ä²DŞ!ïk)î¸h)z}rR‰ŒGtì\§uµħ˙:[r⃙Dgz°pnLìÈhĊ¤qHŠn@š£ƒ7šiXç4éF¤Ċˆ4=ŬĈĊ)dċÄeÄbŸŒ0\ÉĥD{²kü×vĜşñìŒ"Ĥ™­ĈÈs;c<Ĵü›×=~ŒÍ“E²)Uja1éÈKü”ÀL+Y̔ˁwclq…ŸB­éÎîtÛúŜA&GùM!úòÁHŞĵ7Új ‚,?0”ıTNüaÌĊm’JTêìÁñ‚èâAvmà£{trñ pv@ĝ’Ä9m-.mÒd; ìhĴd’ÙE‰Ĵsµàë.JËgûcHË=…8„~¸ûÏż˙\\œÏR\gr÷Ÿžğ˙\ˆw˙ÙŬ>`şûÏô¨ğ˙<ŠûÏc7‰ˆğ˙\žûϤ´à4ÇL/Jq÷œKowÉŬs.ċá)—upwÏıäıB[²½½×yN“Rg ci ½ÈĦ)ĤàxíT‡ż6Ŭ*[—sÈ +ê8ˆ}‰T*½Ô)œİdǢ,ü^ĠŠaoƒ™_mä>Çܽ7Óf˜Ż¸¤9•J—JµyTl9uÜ%8w n8ל3w„×áÜÌÄî:œğç QùœŜ‘I$şĤƒ=”˜';Òӗ$ÓİDvz&Ñ6=‰w ĥÏî.tD"Ç+Ĥ‰ÜµVbĞ1ò˘Lq X|y²³7;HžH;7žµĠŸI22ëPíeߙšŬ[§k€ċ7ĈÒâMOw˘tÇÌ<ŝdĴ/m°c{m9t:Ï\Ö ĥVkp…GÁ“ĦX(‹^i,Ĵè.ĉ¸‹9îbŽğ˜.ĉ¸‹9îbŽğ˜3 áҍĥ˜£ŻìšŽğ˜SÚĥljòñŞpWĤܕİcéŠO·“ÊwijË9î +•{ŝŜ Ïñ5Ï1&/¤’Ù†xr°µ°òc Ċúğ–<[3a9œRâa9œRâa9œÇqr¸"t$MıHÏ1ÙjHv+BKŽa—¸u#[ı"´ÜEhù8-­Ü¨VCèÇèöa,Eµò-Š·—ş)•üÇÒŞ|Ĝ“{Ĝż,LÇĉÜŝƒġ0ÎööžDÇ!“h+Š9”Ë„rœĵµmıaw[VҀ8N‚LŽ¨'ÚûZÙCŸncĜX(•Á™Èò׈+q#Žċ™INétQ˘&óñ‘_³œ´4ÙV„/™ŝôˆCd™Únôè2Š]ĊŠŽ Ñıĉ8Šc18WjŽÂ+Ŭċ²°Ö$wù£ÔĠdwù£œ&”2V–?œâ.”Şv—?J˜ŻğËîòGY- aáKšĠe½ƒŬž‰·fİùé¤ó“Ze‡˜1Ŝ4Âpµ·.äÛŽ·?ß§’“r1şÒl2Û:ÈzİŬÀĈ§›’İ"ŽıçÔùcÇn˘]½ġÀJ–š½ÊÈûżzǚZïIÌÊ$îîMtµ:7„òj•“T{ñ—ŠB7\ÑÑÁÍpEn´˘"jô˘Á[Û3éNç̃…3Sc5ĝuœ)›vó§G7ŽÔ0Ċ‘•Ġ¤˘£)—•¤ĤŜÌÂŜ¨e¸ÔX„Ċ[âv˘#ċëp:Í]†=ŞÙ=½Š€İlĵ,‰Ñ2ÈÁewÉ<}´%ó‘V|“biûĦ9‡cÌzĦe*mċµPıËċċĥ\îĜĦĤüV˙Ò[.wmÀc`èZÌĴ=vS4ma*ŜşxşG+JwÇ[“ÙiE,:ödûRÎ×ôġ§G⢆oÈ\n”ĉÔ,ğò›R=O²v,MĴ⸄Ğ&Œ²šp,‘œÜï2[ñ.ĥWlÖÙgycÉ0*rhʅÍ9Žg£_›îêÉĈËÀi·(òë8ˆKq\7…[0{•qmƒ2żÚˆéĜÓ­§7ÓoMĝZĊ¨ĉ9•J—HµiTl9uÊiqhnÌD֒Ç6J¤àĤ¨5[[‘§]ŜñԌ/Ovöħıj>?jŞÖŒ$1ġşbĥıS´€šœİÓqùé~cIYBúçrQ˜\m˘ìµ ǒĈ ™ËşÓ]‰"”ŜŠĞ3}-Z³/ĴXvړĞ<ıʓĞ<µ'|úT._íi‡ĞDšċú‘ğĞê#MmcÌs/•Ì6ēƒİkċÇŠŬ)yĥàX5[<ˆ_… |´„$ĝ–¤qN[‹Gƒ´Ûx‹yÒ; +€Ä3Éì˘ÎD™N\ZÒÒĈ•ž£#=‡dı´äĝu‰KP瀔¸uNZc´|–ŞŬ¤’_gͨ|†äĝġ£üÈbĴF@ƒYĉ—)?k`ì‡vğñÜżeÀċ;”pċÀߋg†ÎŜgCĠžÁŭ“ʏğ³F˙Żż+³Ä)Ĝtċœ9˘-˜Jgĉ9˜€È8Ĉ 5–ş!EJ~FÈòÈT?ĉOÙV™hUŽĠu7G‰)|ÎpĠ™@ÓŒ>=tWúû–C`‰rˆĦL¨rbŽ…– —`§0w5pWî” +µ'2³’™żxT>ÛÑÙĝBçc\kžœÇñ.Á(n,§Îèëíjm,?Ĥ2ĉˆÍ+{Ï׃Üfğä6úäĈ~]˜[Í(;ސ=„‡½›2ñžvçÙ.J‡ú‡˘”ƒ§íĥŒˆWGÛܕwċdHCŜxĠİ”k#ƒqŬ@‡ÑíPRXMޞ2-3ğÚÌTVX$bIËütW4A~Ş´âšDG²ËŝCċünjC~òġu.L§*'W·µyfĊ—¤3ÈD*O5ü -Ċ‹DeŻġU_Éx%UfUUIaQñ0^VP™áN‰“4?/+1²",/s˘ B$3˘˘pĵÈİËbEE‘8YUax•<ĦxċqꃛÛáâ.(ZêaÏ>stream +V­Çê*/ jíÀ‹•á­ħÀesk%İ<Ó|F„ñS8 *STÎ:ĞÂ"ÛÀ|+’,[(ÄáyÎÂsmYd G *(ħ"GĠxQ˘FP*àplTè "ÚQßċċQ˘vT/İd/â‘èxhW‘UÏzyYĜe@Š$)X`ô‡ç8ğhAŻU…´v€œ5”Q˘…£U VÄÁƒGyF ÔÉŞ <Œ’(ÉZAÎH­•/FâEЈ\°2IĈQ=6€–XžC€ŝŠñ§20ËĴv,"´^†ÄKĥ=`YÙê4’Te ç +Ïr˘}âLâD AUÂà˘({8Ċ‹ HJ‚ÄI0cáLA=0Í^ࠂY00<ú “‚·•À|Fl ŠšéÏa³@3ĵ½#Ş­lŻôWójĞ”<“§xBÁÊI-ŭħ*("³‚šŭ°+,Òz2–…5‡Â´ìħħ­I-…ŒkRKÑĴkRː˜T +ûšÔÒÓ +‹faT-Ÿ‰Aa!›Ô2$FĠ +YµU<3| …Mj"C˘KÓÈ{LM›QCakP³Ĉ†C`m0ŝĊ2·I-…ì †Ğ€ÁMj +‹›ÔÒjïäêt—Gċ$âqvÚPU^šde˜I¤ÒijhxÔ4 ¨GRTä…F °*Ä €+Àübû+2êĠ‘. +¤÷W„S^%bÔ+,! ʤ)è=(,ħjѐâ`”XŻÏ‡­PˆĞÌ1ŒY!ĴBë%8¨°Z]ĥj÷Wfoġ§ż2{ŬB´Xeö΢ĈFH„?”€í™Í1ħ'µˆş‰F ߖj"ÓĠĤKO6CğëMşµEüĤšê`žHÀD&-uŒ8™Èojc"žÒ\ĵĦBN›Ş/•ÔBˆ‚•4;“l››èÓÚċ +;€a83YëĠrM:Ê}Ĥ W²g÷&Û4³zR Xo-•ŞAĤ!§™`ŭe5½ÙlşĞ%½ĴÄŝm²ëzƒ3ôy7€á$äÚMŒ§£8 °({qö)tyì‡Ó~ŻÒ$Ç((ĞFÖ7ĤĴqú[Ó*ĦF "ç̳¨šÑwñNşĈ'AšÀµQ_ôP‹ kÓê*×Ş‚ìÑÇîĜzŽÊÀó,TìÄ/w¤<0kID!Ϗ•ÖFSżÀeìô˜áğS +#j!eµÑŝ*r²ÇĴ + +G›ŝŠ*jÚì&£™!Ôĵ3ÁWh-×jÔUÖ,ÄÙàïB“żÍӑ‰·%@vüÔ*˜µÉ`=5•¨˜èà¸2I&Î,DÔ˘Ş$Ċz +´:Ùşq§‚ĥP%ƒĤc=Ĉ(Yµ·$+žP§íu,ËqĞi¨f[,ƒ()ŝu,Œ= ´y/‚ÀİiQàj†8 iJûé˘ ´êtH½55•×ù+qqf€9{mÔÓi§)ŭ˘Şß+;AĉŞAfU:ċPyÁ&G­5K +ż)•Ş´Í4kúéǘ7vŠ·Ï­Ñ>ç”öUV‘cpLyHÖS²,óöñ‚ÁĊS¤ñ² +#!y°6òòhŸáÁ6ÒĴkìylİĝ×ħD‚`?RcëˆBW3ÌÉñ³ĝ:†µ?o#ŝcù‚Gb[ç¸Jwö¸H÷ÚL˘-™ġÔĈ3m¤{İ,ğrh‡r¸ÖŞ_iĵ‡SiáÓTÖ( IWÔçÉäÔîàÌŭ–ìfş0Ó/ˆ%üŞ­ÔI¤żÙŞhÍh:„ĠzΛġéF+ĥŝëPʨ“x'}ËÀĵ`Òqú7Ğⷖpˆ +ëÇ*[*­|Rµ÷­àŽúÖ?ĤuşSż“4T“ñŞ7j\Û$ú&UQgì?Ûëé­ĠVÚ^R—óJìÈcWÈA÷€Éɲe¨}ψg³’‰Tۀ +8NK‘•™cA…aYQÀÙsOPQċ%ŽáûıgdQY˜‰ŒÊ‰`‡C ĞZ³VrTBsĤ²³Y+“Š\%i +“l|É4à˜,ò’ĵĝ…"QÏ8II#)0uÒô3À`Ŭ ğ£ë•­[ìeO‘<8@# 2–5Ŭ@24ŞKŒÖUê~£­(š_ÒÀ޲èT]`d*N=ĞDċ‰ìOċ¨wŒ$óT$b.oX?‰yê1ÁgYë8F°Ġ /l6ÂPY$ŒTˆ*^Ĵ.8X]`Öwif0ÁÖ'K´­k> ¸èô 9S5gíç8Ž~àİVxĠħàà5ÁÁj‚ƒĠ$o|•Œà°KAGr·(ĉš¨óôˆáƒÀ6¸NQ lvÒDpšà`5ÁÁztĤ •ˆàÈŬ2Dpô'uQġÊÛ1W£8‚cĜ×(ЁÍNGŒ&78M +d+Ğ"š~ögŠâħrN6{_‡›úƒ§fxá‘œÊ †DG#IÁèKE\äŒÍ â˘i •ÒÛ4³ÓĤ= ğ¸ ĥA5‰â`“œŠ †¤Gróhĵ@û[’ÂŽ·Á%Ebĥ(nškjĉ¨/)ƒmp˘(Ĝ$§’‚,‰ÎJŬÍ/r ÓF_RäÏĦ­ ;Ĝ˘è\ʝŸıìf0“B?àôφ +ïTNhĤ…HRA$ ÁëKFN9#1ˆœèGÂÇKó Á1 żœĥAµ‡â`Ê ÍŞ=ÚV•Ĉ ´ż%"'ì +ƒÊ‰~ä+²RÇË5ö·iĤĤĊŽƒœĥAu‡â`Ê żıçœëÓÁxUŽc6Eä9– /itgEÉôÑĵĤY:ó&˜û!v%ÄÜaµ\hŸ=:ecу58c‹ŸġTwSgkĞ7ġ3v²ħkkßĠ7q gÙñ.ĴeĠiùĥr9ë²Äs§Ħ=µHrŝú)Ll<GZÌQƒ*EĵÂŜ. ÚöğT9j‡ †ša†ÁĥP*pÇÊyŬ°9`ñ Í@×Ò˙^ħ=2éîĥôÒ£:Z[Y Θ"œYéšÖ DtÛé0QgAIY\H  [‘B‡kr³e:I$èĠġ'Œ‚ÚJŻáĞj6dzašeş–,Zm[%’Ġ–QfuóhEfSĈëTŭ³OFÂ£—¨f3pF‰½Ñj>ÊOĞ_ +žŒŠŞ4Ċ:‡]SSŬÚÚÛ٘ʁù ²½Ĥgêütĥ1њδSÓhŽöàKâÖ+ñä/ óÚê9³u6ĜԞÎtħä‰(hÛÒ -ĠsÔè/ۗJ´XŻĥ‘.1Ԇü•+Ŝ'µd +œ%(&Ùáh3"(.F„öŒì•è³ÀB³Yd#MĞ +Ґk …Na&*&=IA a=N£CAnĠ¨ +ùÓ˘ĥR)˜;F‰„Ѩd’’ S>nœı•…"h L?]]eÌU! g^ÛĥœîpËÙ%y×''• ŒZìğG†o 'GÙGGUP¨TNy6×#†ƒasĊÄQŜ†ŽğüӆX5÷uĴĉr2‚ÀĠ +p²Ĥ} +jŜÛÖĊğüd~rŬڂ‹›`ÁŽ|ŝÔYYÀÄ,–e²ı<6XÀ*í’ŬbŸŭ–òâ|n]ÀÑáò6a”"S†H™|nÛ/ÎçҖp0J +ù|Jàä4É Lœµb ĊŸ>Ç(,ŸËú@ÑV8Ċ“ğ>އÇI·ĝœ¨² qq–ƒŒŽrV0ŞÄïu’ÂW‹óıoÓXĝ‚V3Ĵ Éš)|1ñœ“%_/F5ÈA);£²­Gà]…%ì)<#Ħs:žáİ.ʂÂHFÀ_‘9VžcÈ)l^–•€ZÄ Œ—3˙%Ħe ƒĞ°:WéĴä ÖĈšŒ†Aû‘žKġSn`Mß Á•yÌGŽĵ +"k~‘ +˘•ß!¤YÉTçÑMŜ~ à£Ĝ½ùeyŒ[ÈB]ŽNÓàF>§àÁt½¨Î* +dQgVì§ÈŞĜNĈ8F_`T…L鴃Q„B`İ6ëU0úIa‰Qm@ @g˜ï ŻĴ ş§B‡q°W90XY…U +d!yeáDIbU•ĞEQ‘yV•Éw›<܀QJĴ¤à)J•GĦʲÈ($'„I–ĉ)ËSì ыË> +9^Ġbš8z•€’–çX˜Ĝ +ù{HiERYÔaM×Ç )`2+Q4Ñ+p²( ˆ ĞÎáb`ş¨xJĊ~#d  ó°bF’Y²W†à)‰…ÖxRAD–gN”e•ĊċzGï’T;É +§ +˘îÈšȲĥÖ6lX”T`òG™çYc\Ċv$d£ˆĊYĉ9_‹ġÀ„Ĥ΋÷,Ĥ+skF²çx[ŜXm*ÙŬ \$7Ô%ğφn˘ +0i'µôÂ?Šó=1͸!NïĦ r-31³Iĝ%–$)hŸ'4 +˘&­£ – §žfŽzĉ@™]° ħÑSÛ›à˜-ġĥíĈàŠ˘dğ ħ9´—i@ + ‘·!B@–$È9(½˘˘ÚÑUWIħKašĜjŠ^ŭĠ­ĈmÍ" ĥ"ÑlĜĂùzúÌnÚgcÖ´Ö·ĝ+ÀáIOÚñg/ÓIÛ ²T°ct!wŜàt!œƒ?ÙÊ6R…™K­Öí%­2 …ö2ÓlÜĄÙ;—1şjç2@—16¸Œ­Àä2ùĜBr6äè(´Œ¨\(˘ Ĵ×ݐıŒ×ñùœbä ŽWlS8§Dǟ­ÌÄ_N‚h5n`Áꂅ?³§úLhŒ" ^­eû½Žğ,!ê@äĞR.êìEž-ˆvL‰ +AÊá~HKtù³aŽPŜ†8Ŝ+ Ş` +ömV‘‰5{‚fĥkÀnÛB™ÙC e&F‘§Öŭ^GYve +pNÌö"‚LħħJ‚]&YIħ£LörĵÌÛ1&ƒ:!ÛEĦäU@Ù­ví:ĈĴ"cö"„Ìl×Ŭxµ…0³ÂLŒ" J­Yû½Ž°ܐ´eµ ı6„Ù‹0–µD·6=Ya•ñÀâür0†oĉíLğFÍ†m:ĈĴ"cö"Íl׀Ŭ|·mZ=´PfBaV3áÔÛµŬë(+ÀŽ&tµ…â’+²]SAyTt=€T"Ġ zb)xĈ½Mż3ŠlêUKWÒĴvġŬ6ċŽ LIĥëv,g˜­z-ÈşÀĦ—–bg”Ĝô:Ğ–ıÙU@ï-ÄĦÌPOl(3ŠL ÍÇ^׎l(3t(Ê EËĴe¨bfğF ef‘…2[‘šÑ° ĵñrÊôÚPfaÖ2!7Úµ(ËÇNŽîfC™Qd‚f(;&†Fd™Ħ8ÙpfhWf5]ŭ2ÛĠïm3J,„Y%\F£&äĈ‹mĝ2şgC˜‚Ÿ́ÛhĜV` ,79ʚ}ZêEÖôÑċĴ5Átġdž0CK²!ÌPÌj†²e6lĜPfY8³i° ›/·ÏK½‹ö‰İƒaMLvsbZĉÄ̏];³pĈ™Ò 3´tCáħfŞEÂLŬÉ(2µ+£Y³ÀB˜Ud"Ì^Dp™ ›/·fô—ƒQÂYè£Vm÷:²òñbWÇ,\%P†c@mh: uÈB•Ħ1%†Fe´iÜ[x2KL4ÙJ£M^­ŽŒžY82ún”˜êmÚîuċY82J x“íkʍ…#]²Pd¨HF‰ĦBM÷ŠÌEĥÇhÓWİ…!£_†‹qS‰ ĞŜ¤í^ÇP>6ì +—…!£ÄÇPŢë2† …ÇB‘Ħ™utÉlSż·Pd–˜(²•hËÚz›ĵĈ[m3M#£ïfZ£Më^ÇQ>>ŽZó¸n3ÚĥÁ°íS aÉӌEyĤ˙}`ó,ҞÓŝ:Ĝ†=Öm`}ĞÊĝ˙Ĵûcŭħ"÷Êŭ¸óÓ U ġ üP?Çk³•Ġâ<“µV{G{‹ĉĴ= ŞŽÇşĈöT-£íMĥ7Ú:j¤PU(†¨Oħdà7&„rû‡_†Q^e=\;áKK‰ÁW1(xÌ +ڏU +ÁQPçÍ_l ÊÑ˘—:Îh„ÉħòyEÉIQĴU{l=ı,Û‚k9™sByĉ…5ĠcâTÙCè‚À ċuxP°µS˜oúxV3Ĵ°IŞ-½GQlġr˘éÉÖekâĊhÉ&s¨°ŠÈ"6xŞ4êħLBµ‘o]Û˙ZÏX5×ÚÓİÜö^[wt?ÖTéŭ%áÒ×3Ÿ ²ŸµO˙PmĠ¨)p‘§¤‘ö‡Tléâ_§PB3[ît)?ïq‡f˜Ħc,Ò¸éöĴÒoi-fóHoâĵ +%MŬO[àpµŜĝ\Ne=Úo”~Ú¸‚_x o]WÔQC:ɀ[UqÒİÊhxA§ùŞ~úÓOŻ­‡ +š:J9<µÍŞÂħ„b‡ñ ŝG(½@ËÇWĞÄt˘ĤğŭŬšFx´`ÒCˆ"mÓâ)Ì!²Š˘wt “‹·.9ó²ÊöDpN™›*ucöĉ­vö/ɛŸèTè´ÊX—šd1\¤qUgvKğG1‡Üä´Ħ7][iĵÒÖ´ħôŠĜE; †*‰¨âUjSżÒBÒk—=·lyŒËx 0è÷Îé—:’XĈđ~İW¤zĜĤbèĥúkħ+fÌ'ÎC5iÎì:½Òjœs´n˜Ğ³ -£!‘Ú; :ìŠv­Ñ‘c×f ]ÊĤpñœĥEc‹Żpıxy…E1˜¤X‘êJġ`kHÌK,Á²`l³ĝ6ÑÖ”Ì ċm,ÊLÁŠŠ/ ùy%Ž7h5 š`èŒŞ¸4ĞqòQUY;ŭtÚ ËFn Zti#W‹ì Ş3¨Û ~kÎċ\m9v…ĠP–ì•–ûÀ^R˙:–$İĥ”ò’)lqŠ‚BġxÁ aˆŻc%´µDўĈ!ßÖ:ŜĠ ;tfE_gW˜sl-‹ïvVĉ1äË8ÊmŽcġPeè+À;pSr8UÔì) iŽÉ§i#xÀF„v´˜b€SZ…)!Jš/ oasµ•³heÄú×Nçt‚Nŭ“Ĵx;´†‘ğ{䄳I’È,—IkCMDzyòg„o‰jëç~Íĝ P… àL^@™Q`š!U€½t³Fñ*mM•‰"ú¨8Í£5–e9Ŝ +5F˘0Kp:H nħÈ€hÉ[TKl - …[˘hyjù ĠrÉ+ˆĵzžĤƒ“K&T"żíô›¨9Xku… sÔ£nàÇHK,z~ÍóGˆ´"IcŞÈXkD +­ĥpîâ‰~0P,F.wà PŜ<yŒ*#Ĝ¨†‚ċÊĞ@ž~µĠNdËQg\”ĤÀMžÚxĉ¨‹’ĥÉz5o~t ÔhVKÈÌpĈ :šk)œĴıa³¸Úΐgv^ĊÍB§jWRT–(´²H;>8aÌ"dZP9(A6€ŝÊH œŞß£c^ÌS ,£‘j3Jêl%´#!E,nIAƒ`1i+hވ[³J=ŞO¨26p׊Pc–àÌIW)2LpÀĦ´Œıl”Œ‘”i³z„œÇj†Œf´W÷Úò¨†`]/Âċ1ŭV;ċ+‘€‘t’u÷5–î5ݤµv èÖğĦèŬ„)†ĦdŜòôÒÖJŜއ=ÍÊċäQ­˘QċxbĝŒĤĵ 7&˜êxfÄ ,jÎÎZ ‘‘3™^ݰÄl ı›¤ûĈsÈµeEem5­/îiqŒġjZ2M‘³—™qĦÑĞ…GĈ, Rí+zk e™üèÍ"гF½Â£%#/É/ĞûfN+hĠFËıŭÛ'£Ġ|AK:ëŻRôÙI*²‘8O{Ĵ/Ĉ‹¸çÙ&K$¨ô{ĤšKzbĵAo€¨Ÿ4íú=­ÉȘüĊx€Eí5˜-Ö;Œ£zF'óÀÀċ)¨,‹6À ŞÊ3fÔúatŒ[Ĉ½Ŝ%£²Ŝe½m"Üĵh½€géFeÖhÛ¸×_mTÖ;–ÛïÖáXyĤ8PÉDP³d\ĉíAdh!XĊ¸ ĊhS|aMÔ0|?´ \ÍñNóÁ`[ĤċŒ;ĊSU99·ËµF›š€ +³RñĴñ<C} tQε‹â™Öt<ċİò4$şZ“)qj˘M{4§B<{m\wuô&ŒgġaÊožš€*u (ôĝñÎİS<^ ß0@9ĜĉQ+è:Œ‹½ïp‹Q ×ŝñèɊK%èLĉݞÓR“y‘JP uɅ0…Zj}¤Ô‚hm!èÒèé8B 0≝> †ŝ×ŝYs´éĠ|Ŝ›ÁöÎy/sœŜ+Ò{q$èµ`jӋTúßÁK‡s`ú›ZHnùs ʀz Xžê1ŝƒÎNAšêѝ˜-aĚW ÑêË#×óá°Ïé<°´çóyÄŝ + ,I Ì@˜f$¨Ú/0l_*ÑS9unWziŬ€àœ\êë鉷ÌöMñL½!4µ$뒄ñÈÔÚtg7΂YÉĈ]ŸFŸìòhhšĦ3UäP§’=InĜ`a lĵuq-ÔÄ{’­öê™ôâ„óúŭŞÏèĦEğŝ §³‰Ö4ˆı6üQ{LǀÇñΆe5uF˘Ŭ3ŬSé™lkĊût½Ö3½Ò3µ!žÉöYmşĞ­7™uÔQZA`‹ÀîQqmY˜¨7HfJá2ž(‹ĞÚt%Êĵì%Ĵ/ ñdĦÙÓí|ŻÌÁ¨Ùħı èïIÌ\’èŞoksˆĉ‰ ”¸Œ" Ï˘f2’ÂЌʋ’¨ +Z‰(³Ú˘ 1"ñxtÔyQÒC2ӕĦⓟĦÙӖœPÔÎÛpaó(ˆ­I%şÚ† ³ÔXѳÏŞ? •Sg.K´öbèŞ[À$ğpwş”ùħ÷!o59ݳËúööžDv + Àġġ +sRİ^²ıÒoĵÔġİš,A:ú&ç4êİTzfĥ·ƒ€ƒ§›’ÙRbĜ“ë{³=`œÙœf${şSñ>í6gÚhu5°ĉtiĠ1£r›3-ĵ†x+w§…^Ud•ĊµAŠÒl"z4¸ñ˜!§1“cħâQ9É-hqE‹+ZJĈCϕLdÒ=ôŸdêW*rЧ6éJdz†K*ä5jJ‚£ŽëeÑWOÏ9ˆ;ú½=‘ığ5fÖ·†Š w%Ĉ˘”ĥÊëÎĈ™¨1ĵÌŠÊpĵĉèûàe8‘QDŒ*ħèÔO é‚ʰŞİ(9*)ħĊTMÄÙáM Òsšı'û…³´Ŭ-§B=Ÿ@ 5ïM~Ĝ—ê²/—}••2QœDÁӋ.'Ñ9IMŞ7ᙟ(ġ}Qf%è ‰aöd‘YNäP9eeNVyVÀ€“Ĵ ŻGHÙò‚ÄĊ‘ŝöNó\#Y –\#%ħ-’=v†5ĝIĉq= RdNĉ‰Ċ¤h<è=ˆQòV$ö²Äëú“‡,†N(k+N¨4a4DĊĜĞFÜşšĝdÇ>% ­ œJ‘~D³`¸ Y’ ï\ŜŽ>žœñòWíd5·d üa Ĉħ‚>Y‘ß8{½‡é”[*ž +ÁÇCġv?fDŸ}‰SĤ.ċ,rˆ?Œċ1f¨È<Ż0 +G%ÄÀä•…Ĥ¨Êzĝ#šÁî$²5}‘D˜0<ĜöEÂQ™ïĵ$ò #°’ +œ%‡ZlQYâ8–“Ežĝ'È$•Ž*ÚüÏ#NJÏ`1iñÚs˙Ġh‡‚Á¸ŸV³Áz8RŠĵÂSĉşL›ƒ êĝ1îúĝ çż}äÌÇËù÷(Ŭ>`COtnTħT'0èócï" +ĉE?ĝ]<ˆž>…EĝŭA0ĵiŸ?€=fŜ3_˜ú/òL‹_şœe˙-&7ĥlD%J—ğVTŽ Km‡Ŝ#g-³%ÂşU]ÚÍŝĵïöV†L0‹}­ö\ġżf›aɋ-#Kqù€˙lÔ·‰+nĜgü—n˙YağFŒ$û@—„òuAèʙ˙ \Jx›ÓİäJT–;üßC$k"ÁÀ{˙ú%ŝżĉ‹IoכÛĈ´7\˙?Ê óßà­ż‹˙ç8G•X@Á×1Á„LĦÉóqjë°·£ıpÖ×£-ĥ¸‹ğQ­QN.Œî :j›Ŝ€mŠ•Üŝb5äìĥ§ÏvÂġ½éÍWżï§ÁğÁb+Àt½ŭ ς>šJxݘHğÛÌ?7=ĵÉÑx½ŬĥFÛk +ü_‘+‚lŝïÍ4˙•ךoĤA#y/ şéÄQYq҇JA+”Áï"I"ĝàZp¨êI Ż—É›R´Ġ°÷xŭ'9<‘{•L! CaÍ˙Ï˙[Áĝ_U“üĞs‹ġ?Ġ‡˙YLJ˙•ƒ˙Ġ[Ù£ŽŠŻvrÀëQc2Żv•”ݤg*è‚Ĉù_S“€}…_{‡Ċŝ'Z³ċfÁ‰VöĈN§ ™ġùwçKĦd½~ϛì1³žzT½/²Ö[Œöûža­ċ9Y^ù0ż[1Ÿ˙ş˙~Sœ£ĜҞÎö#ĉÙµÙ Èĥĥ#\ċ˜,ġ\òĥ>²#!hTʖôz޽„ß§}¤7à =ž Ğ—Œòy|ğ3Z IĊt€Â†½¨ú ċ#‚~˙íɳwz!·Vl{ +êĤĦß ¨Ĵ^|6ï")Œ˜öĝ`Ĥ{^Dz?ġgïĝz àĦ‘>ç%ĵÒçÇ!óA’&½02é½=aŝĝ:ÊLb_§hİïó£coœé€*uO c'|§ĦŸŜô&£ĠÇv +'` L’ ÒLĈ­Ŝġİ X…ÇžE“~/sY˘–0à÷Áè=~|ŽàS#$œ%÷˘èj<˘(ôÜĉ˘J2êġW`û|´…Ġúƒĉ&tT @˘˜ ƒ„~²ë#4DW5=èVKı EpOá\%Qĵ%3* +p‘‹R•‡ĉ(я^FŻ‚JNQĤ­€•ôó ZÚA&S‡ ) +臄yñ(„aŝ8ċ 7Ò£€™ĉ˘A‚7 +Ô? EÒ¨ +(“µËˀÊĦyĀöR´˙ÈêÑî¤p‰¸Q \†Aœ†A‘èŜC>|ïĝ<àC=QNŝĝIáI_ό" ı@rAàíÁqħĵDà8 +ÂJ+IF}Á(ĵ>¨ ÁC"ĤÂñ’¨`UœŞ²€˙fZ!­ĦRˆ<˜L‹Ĉà÷…(í ĝ$?lBXÔ 0  ÉGl"*( ”öÁ˜ĴD—Omƒ‰OtOO܋H>’,@B„-M2Y'^żX1…cŝaÛqŒ$ĴĤvІ§^Ĝñĵˆ™</!&Jtİ,o"ßQPúAxû‚"*#ˆ…”!†Û*‹w¤3r?Ç·8‰ +kzÄ7Ir`^/ìY0Xä…ÀK€ŭŬ‡‘c´|~Ÿíù>?tèeÈĤ² Ĝ’3òà<)”–Ÿ;6 ĜíŽ[ġżô..êe$š;Eċ/ìzڋÒ@¨Ê.""Àˆz:àEBáż.ov–ŬušéAs ŽÔÙ ‚Dxfö; `älù0vĵ߁ĥ |AXyàŒa\ŬÈ;@q +)L`BżÔ%Áìäi–cÜËÌkM@Á ‰i +@y)Ü!Êf@y–,ñ+N<#phĴœbív(Ôâ(_v h(DŒdġĦZ+°ç“ÌŜ³1Äĉ…ßx@v°:>Bë'^ ŭEŠÒ9G ™sCS?’<`Ġ ĵA`@zQI@ŒƒĴgT$%U< 0*‰(mWjÓ=SDi¨Géë?êI Ŝ²£ò ' rN|ÌúÀK¨8Ò Q5_ĵ Z˘Q{}¨À/ĉ1~^+#"<‚q‘G¨ÀWı(Z’ ·û‘Àŭ„4$²Qvm‡ ˆ½Afĉ?(˙ ŽÁRĝ1‰ĥu)²Ħâ¸ŭQGş'ĞÀĥ?2'*âCŠ!}P(<É*ç + HĊAÁ¤ÂôèÁÄH‘Gu›B™70iP‡Ĝ†êĦŞ…“Á°ċƒjzSHĉƒŞê§)ç?BZ †â_8}8ˆNË:nĦĴĤ÷cä vf^Š=îÑî÷ùÎ<ÌT @Ŝ-Ĵ1„úYK³`HRàÂZ ¨€†B8ôœ&´a`dP/½Œ’˘À?ÇÈ Ż¨Úìù}‚ıPXVĝ˘I;°­™t4'÷ƒTıLhü‰ôaìß ÊÊd}âK,¤<ìZ‚'&Àµ$w6z<½¤ˆ^yĥÛ󏅁´çq;üÛŝ$n8:òËñçb¨?)HüBĨ›˙Œè°ßŻWë?p]×fݟìmû^ŸûET­ĜR[ož6·ĴaĈÜ÷Zo5Z|¤ëŬˆiXeÛġö£ìl´fg T[ħŜ@SnŒz ¨"ÄlGÙŝ6ĠÛ˘‚›éz³AYwá(HĠi‡·ÙŜë->ĥàİZĊ…r™9ʊ]Ï4Lm9Zía|=TUĝĝŭ6„ż ğŸ+ċ‡ġp$ù0|kùçrħ‚ÇÎŜ~żġĜ‚îÄôÏKWèŸ× +Œ‡Ċp;Z1mŽa1ǧèϞĞml1­vôĥğ0ݜ żé=tŞÌ´EżïdÚĦLĤ;’àÛ(vVëĠHbëÁ|4Ԃ™cKÇß;Żŝl5„’ĉÄÑí$ÔçÇo}ċ˙%&HELhš˙ ĠúÖBĝŞĞú73:lûġò_Ċê˙IR,ô‡ĉÉĦĤÚIù_G‡Ħ]¸Ħ=XL+9ŝËù˘Š€ŭÊ˙.Ŭ˙ñ?x7ŝ›Ù`·˜ ŝÓe1E{\dì°îqĜ¨,7ç鈽„Luݏ-˙^qL{)—׃OhIµùŭc6ÄWɨNmĝ÷Ύ I—›N &Ô²<ïĞÛX+ZfvŝÎß;ɀÇE!×D_÷¨-á?5 ˘ż{VNŠöğ<qœ˜Ú´ŝÔ2­?˙GèX06ևí`”D Ağ‚ÛĜß=„ċhß‚ôÛq9uPh!'^c‡ƒx™Ök&cÄĝááÈxÓ²ĥ%—´ÛĴَüGŜnf.QĞ%,"ĝİ·˜”†Dá6qĜŻoë½Ŭ~´ŭ5â3€“‹Ñhˆ¤Wë4ë=HİízƒRLêÛı²!š +9żġIvר­gĞ=B²~XŒĥ|éxşh _îTaÓÚ߉íżîm‡·äùUP'۔ۗj‰:ğÎ4qëôÑt}´hë X<ŒÚz7CĊOİH´żBŠv‘Âî8ZÖ-ùpN•Çk˘uJUG’ıí֋Ŝ~tÛG‰6ì]W‚ĈÁÛMo3ÚŜîf˂ğ³Jĥżùj=˜ŻûÛ s<€·wşòšMS‚{GlAyğ=z8T[NpĈ„ĥĥ}޲PÜR@)ĊïVµíŬró˘x­öÛŜj·éĴü €gC@í_' +“é}N£xìc›£3Ġ[ŭÑÛ5ĝ½–ĤĥíFÛ?F·ÈÑ{›Îö½ŝl1Û˙)d +ܖó‹‚etĜܖ{ĞÉĦ7ŬÖ֛bò;÷ß6› ôżğĊ!·È ĵÁŽZA`à8Úhğی0Kç`Òˆù“*ñÙ£LËìb½ŜÖ9Tžî7ÌŻAÒĴWyžNKúä§F‹E +ö½Pe{ĊàĞ›Ŝ€C™—·Jèú¸ŭh…$ĊĦ‡z[ŭ1Zœ#‹¸3m™€A³Ġèv‡sR›ĜŜ(Ñ"ßÛèÑĥŜñx[Ĥey=è-tà·ċ7h"#AeĊ éu.‚·çÌ…ìaħ8’›HOÏe͛^oµŸŬ2zìÌ<²ÈEĞàoŠèÚ‹…¤>°eá3ÉÊz8R[NĴ2 VS–Dꈎ²½Áˆğː·˘€šZoËÜĜ·Ğ³(ŻÄ#Ÿµ”ˆ÷;‰„Ŭf–ŭѰĥ]g‹Qiô§ÚÔpŸ‚ıI 1-'ËUıïĨ”Ô8ùÓ³q× óÏ=§²JH:ÁĉK|ÉĤuħĵ·jòŒ²3}AܸÜ#İ·$ħíĊÓ\ĤŠÇĊŸĞWmk6ú°¨'ûŜjp4ĴÏşŻ6Ü}Ó”Ñ + +Îŝ„Qù|Â'M‘^…†7}`ŽìzµßĠ‘àd´œ~²9êŒë£BÇîä8˜]Ëâžp$^]˙IiÀÜbSÑùtÊ3pßIÊ s°˜m@=F§˙e{œş;żÓGރdo5ĈĴx q³“ä]Ëke4œ–·ġ˜W6+žÓޤTí,7)ĴŻïoyfçiÇGge´›rv5ù<0G}KFġ°ß€EĤüN½Á]Ü ÒFĊ÷:ˆmŒL­ `%­Á×iĠ1AŬ& +J³ê˜ÈŻ€”ËR.9s•?ܟäXÎZù¤Xòİ ÉGĤ&§òÉ7aën1ô›ÑŻ iUÄUZèĦX‰HÎÖC~v$ßş_­OL~;[avBîIô£~ñçW]…ô9ž˜) J…è¸HĴÛö¨ïn͆£µğ²ö½ŸûmÜ'§ŞLèĊ÷,ÀżŬnżp !#Öħ(w^c۟{Ì Ô#nˆ I ízğŝlżìm4ñzK°ç³^l]K΅ ×Ft˙)ò“+̵ääjŸÉÂGIĥŜ]ë-şZèa•l8Á~ĵ_›,’­6ĴY‰0ԉK‘ĝĜ6œi˜âV;d.ûRm÷‡òwƒÍb§ĵTbÚ V;%"†6{PÍxNm™ùÁ:-zu<°íĈ™,çÑ +ùĠ”ä.jµ;ŜjJı¸9#§OŒĦċ ù=ş4 *Ż(%íPSñHÁÊ"é÷‘ċĴÒf°=ŠcÙ&Ż³Ġx­ÒlËğBJ (òö{۝Â:žf2·½hhĵçMI­-oĦe[/{ÛùN8 ıahhˆW{×pĦ,ò˜6›íx½R’w¨ÙÌLšGjv0Qk\ŞE†”?……ŜıV£Iït2(Óh öqÊĥƒífÜׂ`çî™q%j·›ö†£íHK¨Ñh ĜcŜİ˘¨Ħ°•_JÎ˙sĜÉxhR­ĥ[‘µ‡mJİ–qK™vì.xnÇt(·\ÌD4@§ +=Ŭ!Óp½(HÜ`§°â¸Á Ż@ƒ{îġtìudH3NAJCOÊ*Év¸Ŭİï'¸Ġĝ°(Pӆ5 T²‰àwzĞĠ1"àd’žµR3#KžjeÙĦ ä +™ş?„vR.‰cwÑ˛-O)”Zhƒ °“/LşÍѳ5Xŝ9—G(Żáz?mċ["­’QB%Gm—à[¤9żı¤ĝt~ĜÒëvsó2‰0²ġÇoO'€„ĴWçäĝPħÑiĞì°áƒI1QÑ쑭ÎyÒ¤Ĥ‰íĉ³ hĠ+…5DÍĥ°ßlw#4:m–Â} —Œrx<Ĥ)zŜż­ÁlĈ_3ŸƒB} ŻIO |V™Ĉ͗A}àŻ‰À£g,zÔw$¨}á“5Š6oŒ9³+á€Ï6ÔH_Ïçĝäx@ogR³]ӍâúÒşsœ$~šMĥßèëúêÌ|Ĉ-èCŝ}IjÚßâŻx.Aí[žžgS÷è_ô ½™fúMBŸ¤ —§|oó$ŬÎZ˘ù½3f3I¸ĥĵgúwĦ×ôĜœ7ĤKO£ #ÓscÄÈ·' ş)•.x*Túî5D|ĥÈú_™6wÛ8MgşéìĵP3éž.cözÜÑ_ĵÄhñžĈìâÙĉ/̏ĵ§w[@Al˙À?ÂÛsĤi.uáçùìĜVBĞSŭ€'…úi´~L-ÉÇĈ}Àóöà"sÉÎK=QŜ›’·Á‹ĈcqMğötl͘ÖÏĥ\òŝLÎCCGüğ3KòHéÔkè ġ˛ŝ4˙N,דC6’-Tiş4hfÑ|Èžİ”Éĝ÷ŭÀoϔ³´çî0ĝë/÷ĵXÒÙcû­ŸĊŞJ4ñUj6îoŒŝċ[̕íîŭ™—q6=|ÍŬħŬë_’O˘ÑT…]šéŽC˘Ô1Œa%żìIgñ5]Ì7Ĉä"$>cßïwïĈžÄvP íóà;bŭc —׉ĈA7µ'3Ô8— ·N{=vyÒÉJ%&^Rf-˙Â4ü—Î`%:ìx:ŭ0˙ÓÛ^ ÙmJ§ğ/îÑ8ġìZYmïzġáù[g m˜ĈñşB –c-ïè›!kYˆżèĥsaïĴ“zäD´­3éôĤ÷ÎàH?èî({_gô뚢U9Dät–ûĊĞΚiĴuĥRĜ³?ê“:GĞÛÒ9ß2_:WßiĠı'³¨ŽXÖuäÎ?Òy û;çDë|ĤHQG; ]ŸüĜêñŠGÌzóş“Ğ °Bş¨İí×ĊbĊŞîèâ+ÒK†li]êĠĦ˘ĥwşlí;Ë7oşBuc•œ‡„Ü3~èîíV]ÍDtŭÄL×(Tĵş'âùI×:|éuÏkGF÷ò”·ç'żû¸xÓ}6}]żUoè†Ï›;Ŭx+ëĤëŜ^77yŬ2ÔùÖ­Ğœî{ŝÖíT^Ż+ôz&Yћ’“Ŝ2}~ÒÛS÷„Ŝı3~ê‰J/Ĵ÷•ċQïû +ġ³E­Ŝô1s/˘o;ßúÔ´Ŝgğ%Ż^XèËoùŞ:ĴxġġĊJ˙´o5ġúyK,ôú†îCß_äq¸@égOÁÒ°y×oj@ٛŸhƒħ½3˜ĵ÷SƒuÖoœ :o =€ÁgòĜ eogˆ|†Ç†xŭëĊ~(V ù‘5”Ûó¨Ħööè54ż˘NCÇ`5Ŝƒ½ĦWëm £Iciĝ˘J_7FޞšvĤÄäN_½ߙİɝ½››ŜáÒםO÷´ĵ }|ßĊJŬ]*Mšïòž„óboûîêŽ]ôí +ċîŜÜ­Ú]/dx½WJÓğùçîp·Ùç\F]ĝ½1MÏe£ŭ`~3’½•‘Ŝ'ìĈȃ)fL†17}œ+¨ĠĜğâĈŽ~˙lì.ĉßĈá׌6~}|֌›ñ`iÒ {^“y>|4ıLˍÉëׇMĦùjŠÏ–£)G·JĤÊó|ejšQÓËcoê3Żi2ò½šVéĥËtpZÛfÓí4;Gîg³·ġî2‡oĉdií5ލĦıöğ7·g–ı{˜VÌcşc7/˅ó~żùgŽEu×8ĝlĦƒtÈŭ +ì-™lĝÙRİhi&ËÛ[o`7eË"I–}²¤·š“£Ġ²×Ĵŝr9f½ïî\ÖÜwzg­ıĉCës1Ġĥ~u%ë,Ö(ÖïEÀg3Ĥżí6—éĠ`£ßÓßĥûĵwnË{îFĥGÓşgëĴG](coĥùìŭĠĥ_ĵÚ­ÖÉğ +Ĵ?ìáĵoOcûƒ#½°·+Ï[{Oż3Úż*—}ŻŻûoŒˇ!é ²…GÄı~udvٙ£:Ĝ÷šÇ1ĝôdËŝĵíÔŻšs§Ó³;ŭ!g™xĝn;K‹ñÚÙò½yœŸoíŠsîŞO‡É á²'_+.ÚÔ_¸âÓ @q•Z–ĥĞUŽÜız§ĵkQ\-Üú˘'âvÖë}w`hıS‡|×] í=b× „ès׺}ÂbIDϓaNÜûzY˘¸ŻˆÖ$Ŭ&úħ¸¤ħ`)ßIòÁê&£ ë”,ôˆ +ù´öSdŸL­ÉUÖ˘Œß³EEÍv*ĥÎ,¨RŞÛĦžmú¨Ÿú.Ìkşħò^ë§'ċû|òÔüɢç=x÷|•'Ż]%nŒ^÷>e÷F#~“·Ĝħë½Ïĥğ½wÔıÛywžğÏ>·í}Áĥ_ïËRFߓğjġ œÂ÷í°ùi›-yOÈÏ<Mşt³Ŝĝ û ˂ŝvL~ۛ—ö­,ìgınéÙߊQs˙pğĥùwC´·TŞí@$ŸßJݤ7 ?fĝWPSAjTŞ“ĤÖ&ĝ˜™F‚Ÿ£;à÷@IJÍ:ĦPVŻ™uŸ uFÓMh֌ĤoŒáğÒböĤrÙp:mŜ…›é÷rxĜ.šûюƒ/O}Í"µé éŜĴ‘ïñËgÔyßIEcĥĦ5ú›˘­ğRtSôybŽ\i‹Ĥûïħ‡’­ûxİÀêÇ6³éŜéLÍïcÛ÷ûêĤ\ğïeéûíĤŒğĞ9w<á÷˜ ‹Q.盄û>OxzݳDfĜ™$ړö8ñeîM“ĉÈü+|<,“ ħMv“9Cr³ĜoŒ)׃͓JPċXŞħßS~•{> Óŝê.]Ĵş\é÷ö4‘Ŝ|V·)6Ë$6kĉéM—ÈÌlËNÖÜŝÚeîi0û0š?eûĠŭ.§ Y£9Ÿ3ÍĴ%÷nTrßvë6OKİ|şĥçŸ§™X~i[L +Žf)VHX­_…§×AŞÌm‹ÖġPŒ öb£9}/N[£XÉR}Ŭ•˘/ŬV ,Ï ÈËÙl l;ċè•ĵ1–ĉ„­$èÌëCÛgxxXFŜÒUW%ĤğU}ĠĠïÌÜ\£Ĥ=C­p˙v¨}ìğûGŬûĝÈġĠ Ċxc|ÛikŬâġ{ϗżŜ +¸ï롧b=2=5rîzżÑ­Z7MŝÍŜ 4ï#ÍZÈRmNöŝ“m2<%_KĦ§—FüñiÛ Ï[n”lUĤħJklÊ|µ­É†÷ĈĜNLĈO헀QßŜŽc™g:˙ŝġ\µ[ÂϓyeħŜù;é÷§~çŭ• +ĵèz³ñKhZi:Bë—eĈZ~%Ç;ÛkÉ3éğŭĜ›5:½Œ³—··ŝ&ö{w™nŒïá‡P˙ŭéħQ~_7ŝ·GşUŬ˸;ó۞>\OO™‚…ô ž§öOĞ·pĝL­Èùg÷u?èŬúo½ûxĞŬ{‰×½CĦöĜ×kµ~kĜŞġ·ĥ~}xĜ·nŒƒĈŽ|ĴK…ŜvL†b;\ĥ^­#o‘jїäh‘ +×Ǟü÷`\m?ĈóqÜ3ñPžÂ¤Ú0}Lĉğµnêy\…§5÷²5]̷ۙ÷Íž=>…^gЇ2hŸ_tmPĝjĵٗ_›I!:šy+Ïw_›Ŝ"’y ,:r´Ô?/cËx¤ħ\vİlqeĥÍĞŒ™|[ ÜDtíğöëbŜÓ^OûħȆ"ކM­ññıYÛuĊwà3ĉûnzú­Îm÷ÖöĉÏíĴĈq˙‰qf2Ċ³oWm'ê`ż'é=ĊdK5=…ĞFÊÒÜòІ\!¸ ­–Î~0á8(Œ{µgˆ^Ĵ­³‘—´#™ï¨ƒÊzµàğeÒëĴ˜,oq8ÌûnjŜTQZL,ĠÛ0ɳ‘’ßY{ä–Ô9ÀqÓJ£F—ûĉ[šöHE\Bßpäë?ôÑ*€š°(‚¸tÙĠ|ڍ°§)C·ğ`ІWXq¤ĉİÚ +Hä£[OàgğÛjŽŞ'ş4+Gƒíl£rò-X(Í;‰­B˜ßħ1(wHŭQ +ŝŒ/GÔ[7•âÙ¸$~A1¤MĴĴŽ‚áWFuIqĉ¤úaĴ÷jzµGÚQs¸÷ì(zLUg2Í-§ĦÉJWÌêsjÖsíîè§|†6„âOıXĊ{*ż™+ñíaàÏf¨JÀĉ³ véŻôÄAÜĊ]—-qlvñ]‰rßá²n{lTÜ''ùÇr<â5R³hlvı̓3PċaàùÓYcÈ˙’Û§żŜ“Ŝ§#ħ\—w‰Bc?µÇh!›öŜµ“_ sûĈ˜ĊdgwŝàĜßz|}K4S–Ñ,îçSa–‡‡BMdßâL‘ÏH6 ÔasĜ“ë`WĵVBÌòö¸ ċÜOwŒ%˜ OĊr.ñQ$1ĊDì›gÖ2.ıD¤ùBYïşf Bt‡zp”µ˜6ÖԔÏ3ö²+{˘T`€ÎI˜Ffˆ(4Lµ4ÁÔ ÖÔdšÙùƒ§zÂ˙BµĊkPË/Z‚ġıŒÓÑJ-Ip>*nŒ‰feh  Ĥ“ċÎ\j´¸%Ż]Ód(‚Êy+申Że­µE8›ö½PöXîÓyc<Í f5g3iŸ?I;Ğ-,p\dċÀ@Óîύ-ùµ.“‹UkhNŸï ‹’ë`“qĴ¨ĴÉéMÔÇS3ĵönJÒöò”‘–VNBh×SF +fZÏù£÷Ĥ'ŸDŸ‘€˙L÷½ÓvâÉ8Ĝ ۙġĉë"µpF°D;mċô|]$"Éıe3ËFr¤…'Û_êĥ'°—„5IôKôğ}ÚiDO’-{˙†7jœ=|څŬ$öÀàK’‡Ċk˘ñYLħOƒ‰Ïx$ŸrA“ÏH²)I>CÓ{zŠƒƒ–ñí dbV‹ÏŸîNäšZù뉅ìwŸ“î.ƒh:EĉRċ8ú#Š92JŒúĦ{ÒaIŬsżĊNoÜO-ñŻèk‰Â~eê=2o¤oIĤ³Dęġûœé:ġñ²É &Ü}Mßıá%Q£‡S? OĜEœ|Œ{#Œ› ÑԐ¸é&@nŒxšÌ„Ñ üµ|‰~ ÎNPpb‡,Šżrŭ5X(ÜÛĝ0zާqB%nއÇ`q5 ?r(h`|rP"˘ƒĠ.”ÄÒŝ`!DËÀBaŜAÈ:ġ§ñ$DGÏêôwĈAÎIŒ!.9—˜ú’0CĈŸ¸ ÂŻ Y€ä—# Y²@ËÜĴN¤"‰,ü(ùYQf˜sŽèˆžĉŒW*âTQc˘ibœ„„]Ü G“â 34-ŠŸ¸(ù´Z‚U¨7G˜HH°J˜a ‘â,ïn/Gµ2½`”c,âžY“€xjk^F†Ì’p<ÄHK<Ĉ: ­Uü‰A?š<úó"Tŭl‰fĞ´ÊĈÍ£&húcŠża+Ĝ+'ċìgÊêl.ĜĊĵÇŬŜyšKzož&İY÷#žÌżMÌVĈS'|ûšĵ9W;ìml΀-&4h@Ó§ġžQŭjëÛiX[„!Ŝ2[‚İéĦŝ’.•“ü %?F‰ú*]7şÛ>=\’B(vl;„ˆĊGÄù™]‹ŸşġÖW0B[›ÌÀÑt'iċäٍd²?Il™üI·BšRñĈ_mÉGûĞHTĝ%Ä·E0ÙÇè’+]ĝò÷NhË!ŽEb•÷·ċf˘úTrîdˆó49£‚ÁgŒĤmä’ zòе˙I˙?訚Î͍#`ŻÇrj à“cŸÛèûÁ =ì}v[–1R"fFÂäEÜoOÉAŭJĊŸtAÖRmÚF€ĴıWĊè§^ĉ†ÔôM‚|W˙ŬÓuï'ç;"µħ—c2 şÉ9ĠpÄN„†Ë–İ(°‘éd6’ysq½ĝ³Ŭw›!›Y€+)cp`(Ëqç~ ĝċbòħ‡Ŭ˘³|`z菍²µÚ_ÇkáŸú5˘ĵq-rğêh+‚Ìröµ!ß9’ÌĈ·Ûé“7Tißcaâ>ü‰Ĵğ1Ĥ +ĵĞ›d>é=$ Òñ´Ó Ö൛†KNîAÓûíš%°-–qÄ·úb>k³:ĵ Ú`ß8†+ĜêÙì‡U7E3ġÄ#ŭî*Ŝ~´›BS{c›_ Ó9O:Ÿ90òÎtqkûdhìœbt™Ӓ_AgÚ¸—˘&ĵ"?Œ˙zNNGeîċ q/˜‚ëqjĥ›ÑÈĞà|­ĊÌwJÔ£+Ÿ×í£vî#÷z@})-p“ÎŸµvjûDİC™eŒ–†éá2è8ŸEvú=‘Nċ Ìfä\ëb.ĈÀxÏÚQ_hôiħxÊ×ÜɅĞNB§V;nŒ ć§À{ĉ£k|…ÁOtñïd×ÂíXSŽî@êÒwFÀD°€öœIĤï~™ u,ħ_ħíÎî×ċ hJŝveÓîŬLKēeşĠŝè&a$pĈÖÌÀNĵ%ĵ–à#ˆżv€ÑXC‘Xg‰Ĥ£Ùï|$½(ûNJ0ğˆ]ƒ.=n|S3ŭÛ[MĴb…µ ĦuADW]6ÁÊĜM&ŞĦL)Nnĝš7;²ˆ%uH&Çŝ÷áCzütg^F{“ŸÁŻ­ı û~·“XOĞ6À˜X8u }; u_àQI,J{¤$8Odš °ŽĠĈôĝq;2#*ĜÑĉ ÙTâ}’MĊ'ġü]”,$‚îyBşIÂöo5 ½l$½ç$ħAµG“x`³ŭÀ~És(`ÙZĠĤZgʨyÂ^"ıEeiùsyĜ__ÂnĦ< (3;äĤêĝ2Ċ[ĉ×wŒ.Òú‰ĥxÊ9üiÒúì*Ċ½pìú@Ökr ğŸŭĉ…{:ê~Q=òòёŻÒùîn—vô³™ˆġÎĝ´ĜùN.Ğ1ß9½<êaûšż M)LZ@Îy Ş5Ŭéqs Ĉ1^ò8°°{˙̳şR|kèîÓġÖ%A°AĜ5'VtĥóœMï='öaí¤ĝ‘#–Qħ²wÏ_3‚òͧé\Ì8#H3>ĜAëeÇuÎZ +62.ߐŒxN"]d*ì'xÊħYĴß6Ü­(÷•¨’I˜Ù÷óx$ĥ1yñ¨Á§Ħ›‡EbçxĦcOŜLÂç,="AAžCÁ@ğYŞ)ı'é³ċUfà[d§Ë*,sÂߨda :µÄ:1ĥHC̗r]X@{"&ĦŠŬ;iÓ¤ÓÄݲgÖEŽ9ç;ħ&nuŸ}˘ú$2ƒÎ֗Žç7ßÇĈŽ5Rèh†rĝ²Ú…=Z|)ò°ğÎ{ráßaS‚=ȤÑá‚ßv@ò˘rŽ#[nĤ|D%o%’‹ĊĉSdÀŸhŒ·m÷3}"bĉkl4ó ħèİ„Ö‰úşĵO;Şß£Ĥ4?p£ĉï/Š)3Óï`ÉèĥÙL ž+ßùzÊáñÒd³ŭ‹>éB@$vĈ… (èávĈ^5ہ]§RğXĜ°t³.)È7Fv;Yd­|\ÜYCžï §2ÁOĵĦĜcğ—àI8‚´DSŠZ­dĦ<¸g†P„Uh² 7 2’^ÄŭϓL"ÛíÑÑ·3k):[)òiı BĤ%ÌınċCŽ}/ħ‰dòŭ`$”–‡D ż™ĥ,p_{yġÖDx|mĊ˘wmKğyop˜hnŒô7l€ŬÈf òĈĦ9T§_½È¨ù´)G"•czŻmĊ‡‚‰338è?˜\[PiyÁv´%½óán=½·ŝûT>5}ꑅG=ŬtİÑs‡Ċâ×@ËöL™xĝŭ ÔN˙£ ßò/sĜsǛD}ák „pï9³>ëÓ˘ÈŜÜH Ôİ}íĊßü8ĴnŒ2MO|´>â8ĵÍèĜ·-Ví;ÉXjää'šŽ2‰•c;Ö¨¨™ìѸ_ŸĈħ0÷”ż1\G@ßÜu'çfh84CTÏVK.œd3÷üòĵ‚uÙ'OŜ<ĤÉC·È~Ĥ8)ÛFΕ£éĊ Á_lUve3ŸŬÎ6,ü“%ħêOvœlôĜ–xäĊXşmòÚ=;Fk‡ÓS†Ĉډĉ“żyÂ]p˙*̗mËaù³ [ԆĜ%ˆÈ†çĊÈJš#Í´mĉDR2pPĤÌó*§Éaŝ¸8Ĵ†—e*9HTKyt\:é +ĥħŒĞ)„Çġb‹żôCóhú}Ö1ë›ġ°ç,ċş<ĤĤñĦ3]X¤Ú˘-Ÿ ß YK)€uݽ8Öĵù üà4'fÈŝôeú͌ï$_âb‡ġÑCòÄ>d#{ˆĦçÊô>ż‰Ġ½–ŭ´ĵSˆŜÒEŬ˜8 ïĜ÷G7\¨ĉëtèùİseYH•EbĞjžĵñ}ġtÈ)´Èü°g*ö pŬ<ÔÜeħúŭÂ[xùÂ‹-§ÈL&ÂŬ‹·fš‰ï"ĉ÷pvâƒE×§lP%lmİe˙ß˙ĞO9[Íğ½k7ĜŽ·ßò!„l³ÁİvÉñ"™Âj~‹ +bK]ès†Äéúùïâ·M2Ŝ£ÊaħŸm£„ÂÁEÔÌMĈımoˆ­ĵí­†l†‡Ò]ÔÌKe/}—pUš³@g$ĉö›KA1oİ +Ÿ/U˜+É.,Žze +Š£žŽÏnpT'˙ÉXM{Ì÷é·ß·únÂmŻ8í÷Ó½}˘ĵ‘ǐ‡{È}žûĉ> šgnž7Ô£=d2Ĉ¸§”=Z§§:Ğ'Ġ9ŬĉúQgÍ#:ëKPç˜ÎàÑçĜ³B £òœÖ9‰ +E¸£ ïÓĴŜµ…Ç—ž{ïĞŸ1O2à €x[`)–C§§Dŝc”ş1n·ħh?áĜ<à.ÈGÚìúĊÛÊlß^ˆôKĥÓÌFÑ šéŠpWGOöXç"еzŠÈúÜÔ§._%ĉi‹?Ż£Ž>%áµ7ì‹°ħ`ŝîK4€îŬœĤÌ1}ZÔÄċŜrÔ½!߅Żı14uÒG|–wÛmx×Ú-%Âím0(À1´Çn9³'ŝhħÀ‹ä + zÂòö=e‹ğ<ċÀÁËéL'´a Ŝu½ħ’ÚŒ½L'° ÑOß·mCHíÒ/59 y˘ï~9ŒñÀFtŻ;CĞS“ú5ÇBİעP{xàÈġgğğ÷V¤çêí<YÂV‘ŞÏé;Ĝ¤€Ùf;} +ëÂKŒµF"!ô“È^ž¤ĉœqsĦïz– +ëòöĠ£Y°5³Y´Şž~1Ä@$ûáŞvĥïTñµžŻİëĠ­¤ìÔğ1ž‘R7’•ê[Tġ{9 ½m×dlI½1ÂğÙ½2Ó V t—x÷ÈÍ{ׯµ4ˆŜ²3ûM[ јìöI­–û×w) öH¸.7SÚ`ĝ>ĵĝ€" íĵÙR¤&‰`}v4zҏR@‰ìzV”jŞTG9 ôĈx6WogDä /ÒĞú&ŒswĞ@ŭ9÷qDoÇi9½1b°ïy£ÎÌ5ó6Ï +€Äˆr!èA@mg3ÍÏżŭŜä½W +(Q^ŽG(’–°h ’éöċ€v‰ê˘ÚZ2ż”\ġVyŠĜFĊ—š+ZÎyK^ Ż^˘YhXe€örîĠc”œk‹ĜÏd6GîİÑêšc" …[š[Ŭ½$ĥ³e’ÚNXÂ9 3âĊÉ/=ׇÂèK7°Y$÷ġY óÂ\EP°o÷D·›J­ÚġˆwI Ÿžg‹,P}§ksYbnğÍÖĉ¨ŭŒiŞTÜD4ô-–IrĠbÎƒ6 ”Ŭ÷1Ĝï˙r‹ÂnoÉ l­ÙCë}uœsjÓmĴÎ*u߉gšyĜÀ• Ĝŭ½]$ +ÄŬ4Ôû>TЇG"“yÊ" sAhԙG€f(ìb'Qu;Û {²äĠ7‹MFPjżÒQİŭ%ÎfÚòĵŬżžÓ€-êÄŜn3öZ[Šžê¨`a,˙Ô3(8OOÏv1{,ş^È ˘×´•}Jd"CÇñicu.aÊñüëñyëLÀ—ëÍ…§Ïüӊn1áV_êı÷Î%˙´z˜É?m´‚ÁÓÓ3Œi&)˙v³Ê>ŬîÔqSËu$drëÉ˙}|ŝ&f4˘5IäŸĥïjw +Oé7Ë cÏóÓ´üÓßĞ]ŝéûÜR===ÇX×â}–ğ;éŽdŸÂĉ‹I=e1Fz[ΞüÛQ×ĝIŝi2èġÊ?}ˆyÖ +#ĞßĦ°ìӐi³ŝ}Ş3ÙSӏíĈtw•Ĝüĝĵ/–}:ŠH/…O7" ‰™:g„šX+)ĥħF6 Ÿ*+VĝôêIöÓgñž³òÑfzNĤ’îb;mé{{£pêLĝ”ĞĊŬ{s*ûü–žĴ7èÀ`>íb<ĜàžEûVXF}$ú}] ûĥzÊ­9Ŭ Ù9ĵ™Ĉ 3ô]\bъìœ_sW+3XÁÏ´ òG¤€‚D‘²@ħ#”6Ü‘ó~+Úy“ +ŞíĈ#Ù9J‚E–Îä4·àèĴ| ŜĈ½5Ċ:4™ ' `Y ŭŸëġM‘öżêµËĠg{.>&‹µ `‚ö˙)´ó! ĉ˘ÏŬѲsĊÚż PP @§èÉ­Ÿ€2ZŸÁ–˘ßê'n¤úĴöäz÷ÀŒ>‘ß ƒ!‹€ŞÁW“ëüÛ£³xİ™6Ç&8ß÷B(úŒĈӟĜĈ2l²3î…ïS‚ĉ0ĝ7ÓHà×CNş§£´ŭ1pĜħIyĉ`Żi²wgÎs¤NŜ4äXĈÈŝqTÖRƒ )ğS’t<‘ôç•ĠùYŸ ;²*é÷–LIéìŸŜsúdU‹ĉû šĦç.\*Ÿf(=?ôGmŭÌzİġCĞ/XAğmM#1?¤ĵ^´~Ĵ‡Dj‰Ñרu ²ä‰ċ›ìĉmµÎ4ûšÌĵïrRxż1^JYa—Îᝇ1!ĉ?ĥ×ábœr)ùȉžÌ[Ì&=™“è9ò>7˙ W£Ĝ +È X€@´ú5—‰QÊÎq—AÖt÷ĥx43ÈöŠƒäyĉÊn†z?$K҂[’+œÄԜzİݝqÊÔîC…İ1£ì™ äÖ?£ŭ“ûld}U’`{ú +%;I÷tmžt°Ĉ–„ÑK’SÓ¢‡Ñ“%…4ĉH[ò++­pÊ˘ĴĈ(ĜĊĉ½òĈ¤a}qc|÷ µ-á8í3ŭIQ{ʉċô9²lüm—=“ÔH/·WĈıÑhRèd÷Êj*›^?e…NUçç5Ÿ?\?ቃĴ–ójÄbl½ŝ3·ò¸n.ꌸ&ĈÈëaŒş&Ĉ<żğ-³„ĉ87\'ybhîe”­’-Ú1•|JJ)…VNŽíïušliœä…–ĝo¸rwĦĦŒÏc%i,ùĵ7ŝ;h4&Ñh¤ġ1eì£ŜǓFSĦ.;—NÖ4‡´ ĠĦH D…qE‘Ò-a("ŬòGáq*{Ĉ§böôûœÄ•Çk ¤‚tK–ÒíaFl÷–ôXü5Ċíûn²×J‹Œ#éÖì|dkiÓúÈ "Â\Ŝwß²{ĵ”=,?$YÀÙûè +*Û²”ÑaŜ÷Óuĉçıo5+Ìşü +é€òİêŽ,ĤZ]€ġ~8?~4ž!16?_àϐħɁö÷'·âѲĝ9²ĵˆáF#²4ħ¸41ƒ ÎĊîÉâNÄâžğàĉ n¤İx—°‡dY²ĝ| žğċNv47ĈKŒŠ˘Ĝ%+í8sÉJIŝeQ¨Á˙lj^Ëij”spH Dĵ-+ş7¸ıˆÈ,„&ċ&üöˆ4Xi/˘ß§ˆw5ĝ}nŒ*ˆ‡,/| Êŝ¤v<6R˘@àiŞÒîsUzSB+ÓŞdTiÏŭ“Ŭ Â/êDµ))œIİnƒâ}èÑĴÁo+ ŸO-ô{~ٔ¨•ÎwdŠ‘Ô2+%:/ö=c?šx˓7Fy',“NxŒöhĦoŒ£Ë–Î6:9J6hÑeÑa•0~‘ùM‘ën4óÂöRÏo‰rĵʲOën‡ş +í´‹+ê,ş˙µL~nüB´jè”ç‚MOĥñIĦ°—£ĉ~4r T/ÇĜĤŸ_ŸTà^Î÷=.g䂝í,ċzĠş‰â}_Á-ŽŽy-"}ŭĉRĉ‘£ +ÍEĈï…:#³Ŭ ûÙÔ6BñŸ,*+)TJĴ _U”h­ġıDƒß$$Gchˆ7ħxÊMò´:uTñs‰]•7Fu1¤E˘ÁƒšîךÒóÓo$ډ÷aŬ ÑP/çMŠĈTûıX˘qš’¨ŸßK4ÔËQ˘q~KŝÑËéGZ.˜’Írqi-eg•OĞŭ\Ħni8€Ġs•ël~cF£`AU$£Öԕĝ¸Tĉ|_]Ì˘Îĥ5ì†Ê{ĦŒïÓê”Ĝ Ÿµ†#Éî…'Mécаò°4èÏÈQ—œ$òGĈGĉ‰!ċ<)ڗ×(Oĵj.¨r7t6ĠÀòĵÍ÷*@gsy/ú%bûYÄà"Œ]d\~l5éĵ\”š¤Ï 1ƒKÁu}Adĥ+aP +*ĞşŞ)Ŝ–ú;Ñĥ„Ħôw×q÷"“RÒÉj}˘Ĝ5Ġ%éçÌĊĝ”d‰sĊh[èìg§7’ş'KċëxHú;MŝäJ"(2Qˆh-Ŭš‚oqg2*Š' |°А> I–"p<Œ*{1ŒË²Zˆ²_Ú²dËùÇŻcú%ÛjÜî}²œÙv£żÉĦSΠŬŜ:ċ :ĉ„÷÷9tÊt8żò +9tÊtÂlÁŸç)gŬŻ“C§œAw–-ĝ:ċ :–WÉĦSΠ;ÏüYr Šà9tÊt“DöÓrèTÏ+ŸC' +H>߯1ĥDt£nöòġ:ù ĴŽ3'’pSÔqH)ċ|"ƒ@ĵû72Qħšiw`X OŻ:ždlÛ´x·.ŬÑ § O ċ831ždÎÄQf™p£?-‚ÑhKÂkĴ„g|żĦ'µ8,f~ê9#J™sZçÇĝ”ÒgžĞ .’TpŸdD3ÒUw/SùjdKg ˜]Ĥ µl9Qçbû{ÉğDĝ]ԞIüGE:'Ÿżï„§˘?6öòÊĈŜñ4AɅšŸaʛúrœG(Ĵ´lZ˜J‚ ^!öŒOŽNv +yâB•FšP‚›:ïĞ£C“ §pÊ#ʒSßŜäÎ$&yàJU>·iÔ#%Î:ż +X‹TÌħê‘ò™>jzĈ‰’UҏT҄RçLänŸ³dä÷óËôħ÷½QÌ<}ì"Ž/hàxáù‹,žövóotÊğ1^ĉŜùYf܍ñ˘A]ĉ‘á†$ô²ƒşÈ#£0$ñ*żÀ“&ŒŒ•$ôÈxî‚s·#SĵÈ#Ŭ8-™ó˙­ÛbYäY?HÏáŻY2ió]hHÏı ‘ĉNídW.‹żöÈ 44IÇe÷)è‘e¤˘4´ßzdpvž##wǝb|%çÜċ‚]ŠÊé9%ç ı„j{qêŭ“Q%šF‹² şœá÷9‰%­‘ ĵ˜+9ĞeSúġ½a܎z´ü> M.d{5RhèQ§)táœ>ù‘hÍ5+ċĠÍJjŞyu—ĈŸ[I1šRHTc1nüš(YcĜşEâµĦ~_Ÿĥ³2­ùp*÷ġ])Ž9KgÄ];îrûI>œT„*Êdğn>Üo"Tµç)e¤^/Y|×ÈW·JKıÎ~›ÇŬŞĦ1Ugùp21W·;·ÄUCú~§žYŻéX'uv_ñOóĊ~)Ò-QòÙµb"ŸNfôoxżµÖŞż+Ċô‚²˙Pġ‚*ŭòZ ܏r֍ö~~‘c´_P?òTï"ĊÉu&ŬĤuyÄsgsΆ› ˘´ħá%1 ²7N£ô£k„&”kħaK*4ùRmáû‡f´ vqÇïÙġ"bŸXŻL?—$BÊerĦ~~{ĠîEŬ£Mµg:“;v•ğ‰BÁ/m–¸x•UTiѝ²İoßWÉH%ġ*—¨hÏH%ġbğñݤŜĞĠUÊHíéG’n”Ġ…ö•2RÛWÊHm_)#µ}•ŒÔĥÔ5<‹OCŝšpÁD×@ $‚ŒÎ²9Dl(q 4ÊĊzRŜÀ´FÛ^7Ž™K^fğV*Üî‚ŝA*WżR²³kÂażşġŝËT8IğòêİpR^…ë§Â1{P5TO…ÓĤž.–Ì­ìFx¤ĞÜ/u°B–Ĝ/T“ZèìJ…'PöşĈ*:LÊċ×t–¤A£~•;dŻ ĉe£w7½Ë64$E#".‰A=q/Ş'IÎì +0Ġ~İŬDç\=~è­nFçLxş:g1˜AċÌSèSGç˜~5џ¸Î>puŽt=…ŝ ’šÁ;n9M˘³Ÿ>ĥzĴġ“{v¤qËçZA†’WO…‚Òyg½Iİ\œËݐagP“G ´Á´YĵÊ%ğ½(dĜíôÙ/ ğñCC¨‰,~ 䀅vâlĴdƒT”ìf˜ŽNBQœû[r3gĜy­Y €à¨|†‘ 2@q=ú’êÊċ)fĜíĵò@sŽÏÖ èy=‘Ċ?•ĞÇçRZ6Ë~Ù=Ċt²sĠĊߝMÁގ‚GĝğÖÔËp)Ûóŝħe÷°\İöHğ™çŞj;ߔ;îž^”tô–İ˘Ç#Ëù•†Ùƒ|•$ݐ۳ğԄĴÄÑkZíÚ˙óŭZŽU͜ċñçEż°|A̕|jPVışF%9)í—w–tJr1‰:r?ġµ‡H*Ç şh6Y“K"OıîÛĠŠÈÉOsÚ¸ĉ”Á°jE•óùIĊ'£bmʵ´É-:Gŝ1Ò5„Rjċ—°j‰ˆfî8Ġú˜M'!ò;˙Ús–M'e-‹ëeÓI9ĵµ8Ż’M'ċr–¸yò—ÙtR âĊßgÓIċÒÉŬuóól:í^ëßdÓItEŝî†İl:İ\:ċĊŸdÓIÓ0^ëkfÓIÙͽòÙtùTèîiJL™ğ_{5•ığцòÛ2w\,ûŽdĦğ_{0Z_Iì7ĝ1„ċ`ĉYxîŸü’_Ċ*·äıXI6ĝ’İYb.H¤jŜ?е†5]z żTĝŒï‡ê´dÀŞd•d/ +":?J3ĵ Â–Z>Qï,2”™ZiVċYkÛèPz  ×]^[^1 +:ğV4Tmİ1J9Í£÷Ħ6¤†ÌG믓{S8›jûu?s¤"-5öĝáhDu­ZŞ“iˆìB]ı4IK‰µÖó}ïıyĊ[Ħ3ù&72Nš…ï˘R°.CİNϐTLdàbĉC_CÊÇ{Ú\ı–èžÚŸeĤÀöĤ2gµ¨agšJËjĞ`¸›Ë‡ħjZ$÷ĝǙ¨òQO×8ÜĊ½\á–Üυ‰ RѸéâZ?Hd°%Ââjİ *lxW2ñRûE#ŞU¸Ó–_ùÛ +wâÜ7Mœsq…ğŸj—U¸SÌ|ü9 +zAıĠ×èG-ŸHkĵßċ*ċɳáï+ÜIJĴµW¸ûÁ­ĉ(ûİár 59Ö^bmĞ9~ùybm[ÙŞÖZëùíû7÷Sñ2WHĴ…^¤ĵYĈ\1ŭ\ìÁ<ó3ŭü>ħzQĵî²üvT.Oŝ š ­a"U4Ĥ1}lÏÙ~S÷kŬ5°!ÌêUĥş–$&á.²hĵ6]CÓÇVĵ.?xwĤnĥßh4Ü?ĥšÜÔ²~K!ĈèëĜ•°’-çvŒàz(‰‰…˘8¨ß_¤Ï³’ÌTòı縊/:ŝ‘bÈVÊğ^ŽkG*ġdY\šš|ž+ÍòNlĜu‘ÏqGmüèj*öž+èlŻA3Ó t¤2\\)OkıGĊÛPEşĞ”{|„ûyîg7žèzÎÜÑğtʜBقEĝ[ ĉ&ĝĝ–ı3ß­7üNP‡ÍÒżĞÏù–¸05íMİâ\×) ”È&éŞ#Sènċ Èáu€ĉt>y ıÜĥó\‰Ó ßôáM.5M!.Żó€rİi€1œċ^<ÉáùĤĥxÛĥ‘K“ÏüôNÁ.&Îŭ{ÏË%ÒÜŬêËíIĊ™ġÁDHjlé¤hŞ{3Orèu` ĵ ná\ &ÑŞ"ÖtbĝÓ1ó0ÔîĈ¸ T #-=êĞQ†vÛÇÜÈóŸ0”|ĤvYŜvXD[§’ùT­Kìv˘Š"mµfZŠÎƒÎ|§ż¨bĥı0dH>û‡µšd3­UT+Ĉş˜SùÔĤ‹BĞd5]|߸I%ÀTĞ' T“ @“Œ„TēYµvƒĉĴ´ËBĞÀìjYiSĜĦżşœ§¸Í~@0ÌIŬş òókÍn ÈWéĠtG/ĝXì­üy"ÙùŭcżH?’UŜĝ÷(ž|x +ىûû˘ÜĤĤAJ ïURïÔó÷5§rTr¨X߸ĤTN™D Ä ÎàÎم••˘È9Pċë‹]ÒYGı~÷eSËċıc*'——L’•h×ÁĜHVFÄùç/LgòúĦL Vcóˏ³µĉjşUC Íġ¸úÈ?Êĵ̟üÓ,@žJ °ûY€ZsoŒżÉԚxóĞ,@­ĝÄ;ò³µĉŠmä˲”EÙÓ7ċ,@v4ç³ÒP”O\à_S”OHÉ*Y[?.Ê'°,ŝeEù$½pW/ʧVçŭ:Eù íé½4½zQ>Y/ÜU‹òIĉŒ\½(ßUêWŞċŬ74(Ŭ™êŬPżë§\Ġï +™\WğJ½ŸöğĦ~S×ï4µ+Ü %[×OÙ+$֓Z×OıŞßî†’¨ë§ì.“ËŻĵ´ŸrU?-”Ĵ)dQħŞŸä-Í?¨ë÷ÛLkD+²™\WJD’ĞêwYŭJùş~ĝ-Q×O¸ĉĞ3\\×ïòĠŸÔġ“JGT…ğ´Ÿ%_§ŸòFw£r´ĤµŸ†Ĵ´+Ôġ;ĉoIWġûùZ×ïrûI]?İtÄkäĵ ëú)÷˘^ï·lġĝQ×O9ñ;ħúe]?ċ07é[h.Żë§lݝÇZ˙ĴŸ4GĞúİç½jĞ만ÊÓIâïêú)\ߜ™)?ĞëwIVÚµòÄUŭduË ëúŭ†÷µ×ġSL“´ó2RĠò-ÔğBĞÑ/ëúz‘:ĥâĴ¤_ÖġSêÇŝïëú)û +nŒ×İë'GìLU?ĊŒĦ êú)Ÿ7KÊħÔġğ$ŠàçuŭĝÔçUŭ~^ï’âšJġĝ~Á†ĵ^ŝòöŸ‚˙ë´ż(Ğöêú]v£ÎOëú)Ԝ„ùe]?.K2Á„o½juIKĠġSVspĵċêú)WġğN=>µ,\­ġĝ~çÍ:Ġû]]żc/ÒY¸Ċ\IÔġӖ /é˙A]?ċdxĤ^ÒïëúÉìÜlU?99vi]?ċŞ~ĵ“÷_ĠġS6Û×ċòş~ÊUŭ~á·bL[$ä/ëúIċ<Éç$ŝ´Ÿä8ë[íĥy­uŭÎC~U?Ù\Ñ ëúI,,OÜe£ëĝ¨T­ë§œ+ÒÇ~\×O*íä>Vô(^P×O=ğöuŭ”ĝ÷öüĤǟ’Uŭäâ-/­ë§D<ï¨bÑ×ó+ˆSÛD>Ğ›a\.âƒ'-E]BµûŞäÚUĵgü–ÂÄĊĴ(J8Ċ÷a}ĥG*CÌfÖZ°-V[Ÿ0*²EQî[>àԙ™v²­ƒßĥÉÇ(µŬFİdìé½cÑW~ŻÎ"²:Ûşñ¨£BŠ=ĵ%íħèĊó?•Ĥf"ó°ñÙ`&NdßßóDÎq¨eò•(˙˙Û;óġ¨ueÑ?AŜĦh2ğev!ó! C BÈ ! gßŭÏ}ö[%ÉĥìnµÌ +ë;YßġúÎa§ğĞeİTŞAúÙŭa˙„ĵ˜¸ŽÈëÇ£‚ĵ>|şHvżŸ’·£_ÉÛÍĝyûóÙCòîéñ29ĜŝŝœÜD{äpcú‚|žxĠ&Ÿg?ŭ•[Ó£W× òêúòÑĈĠíÌ͇ë?˙ŠĜfrkïìürı3'G‡_ì.ĥİ;íîËŜ½ğtüì<ž<ç/K?ıy­Eprvvz˘X?eiuÀ€‘Ï/Ĉ^éäß%OçÈê›wĞdíÁċÎĠuòîTßIšß‘ÊÇßL>éLë_£1÷$Ĵ|ë\]ĵ|Œï=¨$ìf•ËgîÉÏĥ³³ŞOìnëfZŞ_úibâ`ġsÏü|ĉԋw{cÓG#x‹í3üç1ŝ¤ĉÎtçÑ'TÛŝÖĉGü!Í;WxûGŜ½™Oôl-ü¸Üĵ^xŝîŬ§ÉċİöíêĜúĈT ?>Žxkú½ÀŒ!z(¸??˜6•Óœĝx/;Ö‹ġÑü/üu†ıĠÛsÜ ÂŸĠYŸ0÷ŭBĞ—SöċRáË(˙bgrċíŜ:öĉ#{úöçâÒÙQ'&9>ĥşB_`‡ŸŬÄĴ/½9šĵ9|…M:#˜Úœ<É?˜v?ĝ¤şùĊġ Ò|YÈ·jљRûœt֞LïĈKñc+ĥ4ċ|pôpéIöÁF„7GN€î>N˘²ĈÁƒ~ğ…^Ċú%{ş; /wĉ'†Úy‡:$ÂğĞZß°|ş‹Úl&h1 ,Ÿí+Ùîà£ċĤ4' /wu³ìaú^~`Żż3ĝî›ÉÉı³ôXL¢¤ó~s:żèçì*ŸAËrzıs4ûhĉËĊèîêì +˙VÄëğ×ö^şGÙîQ~šV }ĵXú3-êöèèÜÈrÖŜĝ³Ħvò2MÖVçGğo–7N흭0޽83–7´˜x:~~ĝ`ċäûŻDŽx>#¸ÊMj'ìx{4JUr·cOŜáï=onŒ_b;ǟè\şAaŽXö×)×MĜİŭŝJ·8­0xı×ħßŭŝd}ŠÙ?†TlsÎöçû)s>ĝ4ÌÍŞüüâWێċûİ# [LXò¸ûiüŻŻru{ñ' Ċ=¨Ċ„^Ï;éÒ#qıꤕú½‘…ĝÚĞ~[zʃi`\7`ŸĞ0ühêlÒÄäÒ§&'Ö &Kß³"‰ïŒÌ=]#§í‹eÈ2/'ÜD2OHşVÛĥFÖâ¤;":•&öövò&ÎĈœb@[<䙃•§Ù£Çb°ƒċ)œ!SĴë÷ ½ "ëw™Î2s?ĵ)iŝÁhñ‹ÙùÓ7ŠÜ +’²í¤³ŬéùĊh½s•ëD?pâÈùġhü5rŭÁĝĜÓh°| >ˆ£R2y‘ÍËí0^tĜÌżŝŽ~ġp/ş§òşŜ‡^˜{|­ĈǟçYïúA4òmW§ğúÇÂuѐ÷ĉĵz³˘ù­çÉÙċë×GäJ¸ŭ°+aŻĴ„IGĜqĤ‚™ĜQÁÒŝé'­È`u\%àŠ(aâĦ£‚§Kż.]*nlùʨÀ^Ô>í$›’° ÉŞ/ÊÔöwĞzĥÇ'wеħ7|ÙY1J¸Z|˙ĦP>òċ£ÇĈ'-ĥg‡?†¤mĴN“wħEó\ë)o/jöazpv^6ŬqIgUŝ½Ù˜ŞcÓCíÂŞ{mzjÊÓD]UNE·ôƒÍż³M=Ŭ.7×èƒV%xKO/hք|PÌĈġÈÚó’\g˘g íd˜ùAĞ66vWżğuîڇĝî66~w›¨ÑÄÀĤ`"nĠaÔVßĈÈg£,×ĦĥW›ĝ=ϧ£Xµ‰é;ÎF'ޘ”}6ÔoUçov™…ûÜ!wFÜoeàÎUŭażÙ‡"Oî°ú\çO^,Mš&ĉ+ġúc€‘i‚NŬÚ[Òğ[D oIë$7ƒâ%<ùï,q—_ÒòKV™}ÊKŸ‹İò˲ŠDùR˘S~IÊ/ÊzċTĴHbÊÌy¨Ċ“)wC~îĠÙꛧ3û+WŸ˘ŭ…uıµtôċÙ7³Ğ èâŝîS[³ŠÈ”Š˜ágšıŠ'ż+|èÛûOَ⋋b/ß[ü •ŭı.ċ§²ßä²;¸ħ”í Ĝ}fĊcúÑjĥjBWNĥ‡™ÍĊ½WĤ›ökĞ]u™]ân}Ž~ŭaw*~ħ—Yİ÷‹½L(ú‹ +áġÜF'ߞuŻ7ŭpkĤ˜­q[ÇoŽäĥ[î†-ԍù†í–ğa •żħä­|Ğy‹è½’x]n˘%o™ÇJĈǟÚyÛ/'ÈñÏóËéĵhxHGçĈ%x‘ı„­ĵ$ĉŝÊĞĝd}[ża›=Ù˙Ûızż:™ï¨šMl:.gN³‹‰ÌUÈĝ„ó×í•İtlƒĵ}8™Úd +f+½çT4ߓxÓİÑbżö†ĵ-§Ċ¸óàzvr÷ñ•œÛċ[ êàtLïñŭ×Ùfé‡b›ï3{8;ûÙìAŽßž~jgC7ċlµ.Ż?A›~-ïo˜ş|²mO–Ïwİŭëö'}JGWĈí_ô î şĦ6=ܟÇ÷#üÍúKzxIÌ·o_Ùĥ?ïċÖĥïnü~~|ú-˙€çĞòĜËçwKĉìġ1{úĉĉĠâyôebaçäŻÍċ篋-ĦüY‡K9ŝóÈĦ;òSHÖŬȏ:zìŬċ††zˆ[&Âŝµ|t–K2+ùöÇBµ7ÛKoV—ÏGN^½ù8şr<=˙Ġ,ŝHeĥİ|óSfkßìċŠìüI?wµóÈî瘅ôâÂ~qğ;a´8úäġ„ġTĞ·çĜ6>Üħî×Ów+Gf#²{t3fö-ğ×ßġÙNqÔÓĦËÓ&µ§Êw=§ġAvWxğg víù¸EöÀ{ù~ŭGlì”ӌ2ĠÇCĝĝĉˆœŽÍdîjFc,^ù43›½7?eö-Í^5¸-"ŽŸÄ>Çħ8ŽòçY~6{I*GAĈŒfמLÄëżÍ?fœ‹9ÖÑħbkÊúğ/ w+²– ߙïĜĥ×ĥ‰9rŽžÖvİŜOÖğTĉìò˙Î )Ç-•Â?W·çŬĞíг/g­İĦÇC…8Ŝ½8½\½êvßt˙ÏÍòċÉíîĊMkĤĠYx½´ħ‘ˆċîÉċi·ïğŸ•ó3ğkÎ|ÛéÚ—˙Jׯ?xġähù/ò~şÙ>úóÍ/Ül_jzüaxŠ[żžÂ—ïÍF“ÖÌÑáĠxmét‘üu8Œ ½’ñúüì3ż_íÈPÛߕqĥŝ÷ĝ_áöŝìpğ?Ǟ½Ĉ—ĞY~ĥЃslŸñğO%ÔıĜœl/Ŭ.ïŻv÷–œŜ,Ĵ½Ú“[K§#ó›ÙgóëÓÇĞéƒï;+ïĉÙ§Çû›skço÷>BŽ1| ­ĵŭUvÙ&‡j˙~ñû9^ċw³ˆ>9Äa~|:î~Äš€żs[Z€_òb7Xü…ċ÷ÖDi½íŽçı”ûÁžg\‚àÒpšĜŻOŻb$ߊA?}…/_N”N˜żL˘n_Úġ|òPÍX +ŽÌUœL?ÁşàeÇĉO7Pm/m³'/wu³LŸÀšó×ġ+èĝ4ŸÖ{3ížU>üÛѨ]e óhDÇ×Wg˙F|ÔâËÍ'Ċ‚7;ğkûɗĦöÂëۇg+û§;X҉ û·Ÿĉ­›{˙‰ċ‡´ÜÍžŞÜTŜMÛôáċÖBï:™ÙżÓùàñîċĵ‹³XöNSH—ĝË˙âĤ‰•Ç?MÙ·-žè‰ßÏÊ}’˙ğ³O?ÓOypŜgnRħüŭavûMdcٗżŸ µó ĝ¨7];ˆŠ‹²GÛ¨Ôĝçŭ;ÜÑ;ˆóż¨+÷â Ç÷xÑXûY^~~û~iy2_]]yñ6Ɏ}Ò=ž‘hĦQž퇐‹Q.ÒĊ÷“+ùdÙY[s=U£3.)_y·ĝë-xˉċɲ“Ìoŝ| +ĵxĥ|{´³ |uştìÁúÜŻ‡?6³<—3GHvʞŭ°> úköÑȳq½2‘·ż°#Ô1*+#WrĜ怷ԿÔ˙<ùYñ–Żın)Ö_vâĊü´~Ĵ7>3vüÁÛĞì\UÍîìŻŬ™}ĦÇż>Íì}ü=l§sìU§CĠnfê˓,ݘ[-”ċ|¨mŽi+Z‡=mŬ‰lşĥ6?YÒĈ+ç!][[6ĝŠÉœÖ6óÌi‹Xç)7żĠ€S‘MW€½2dûÈEµöÜaBŬvôRß`ÈşÎ·bŸ¤ßéf›o-żÌN7Ż&+¤WW³O_; l|œŠÜ{"ġÉÜîáÄJ~’ğÛç$÷{ĵOŸUÎqÉÊìvÑÀˢÍ|é&nKMĴ?Z/°Fԉyĵž0´-Šżd‡ıôú$ŝċïuò÷`^Ĥ^#‘1Ù,‹ö+<ßßÒ. dn‡³ß˜}üU~Šú~ÀŞ~¨ûïžĦ9ù9żß>@ÌUàßÈŻğ×ÈċJĝTœĦÚcmĞ‚}W›ÒséÌ+áhvĞPûp'… + ;,2H ĠíïßŬüžżĠ*ÀĉA§éìÀÜm´ĝÑĠ˘kHĤżA‘ßĠéZoÚ˘ùU:Ûsòï‰ĞşÈçڄá.ĝz[9ÔÏè’Ú³ħóñçïÛtééDs;‡žeQW•;Ŭë~lԕué„ıËápúŞ2cçv2|‡ż˙Q4AÖ_ĵ?)ħ sû}ïL|ù7K¨y<]mìġĊmĴ{ó[Mô6p>|g{{qg{y× _ġkyWûƒ†ñġïŞ²°ħï·w›÷‡ŝċ:Ô×ÄñŻğôA?ıżÛW™ġgŭ×+0)àĈ÷;öû‹[}·â]†qU]żO–ŬŽÜ­û„#2½ŝX41<úöëk·‰Ú1 È•^w…4èWǤÊŜ²&Žż_ßĠ[_Ü't`:ŝU]à}óäAvy|;ìż<ùŝŸ³ëîojѝr§¸Ûüħ;ô›ŭŽéïßmLôcú­nZ<6b›g˙Ó}ŭġ[Ù9ş:úqmğQj˘gœŻ]œžwŻĥŽ~tû·î8ëÍE7 ŠhÏ>=Ŭ7ŽÄy!@bšèpÒHbHâú$HˆHşC·ĉ&ô˙Ŝ÷˜BUXÊIš*Ĉ[ÓqG^ɘĈBA|ĝ1D !cAeÊxRbL`D(„!RQˆ +„ iˆ 0z6ŠËRZR ‰’·Oŝĝ2-#š°8‘Ħ£gnb÷4“M8MÒHÊTKJĞ=§ ?&#$‚QÇiĴ„HĞÚóHax,&yK•VF+Şds ˜O"žHĞ’¤jĵI +~¸"Äz–äZ(ŸÙë瘀Y) ygîÚ\Ş˘âV +—……•Á·Ĝ\Ê# Ġ‚Š!Ä%˘"$á­K)Ô ¨j^‚+#:‹Á/)A9Аü|HĜĠ¤€Ğ²ߐ­“!Ȗ#ˆ:pXá0”°˜ÄehŜ`‘wĦ˜‚Ĝ…™˙”Ĉ`pip§àÁ &î&QX€DCPDİ4ÑWb‘´D7„ ŝ.†É…vh$80 %ŠÀöö†€-ĥ8ä¨TŸQÁĤp)‚ö$OpE;°ş¤n'E˙–)TUÇ ^áĠı’à€À4\Ħ^Óílq4^ğüzc‰ıŞI0k×E +İ +A ([t,°%A˘W²š—–…I” Ì§ÂŻĴ.ú@êoë…´UĜvòU*`d ´CÀ=ƒ++_^ë°,Añ0ÄÌ!+>„ôlâLĤpħ´ây0ˆB32"™sŞú/0Nƒ" rb{7(ıs‰³0=N{Ü)TÚ! àhú~ގi ß~r?£§ kXGà.ÁÛĘÀ€BŒbĦA &j*ëhR•IM2è +ġX}.Ä&G`cĴ×!&½xYˆ’ž.eBLFœêI\‚@Y–é͖bÈ;P&?Ċ +Ĵ"cXPE÷4à–}ŞMı7˜q@‰ ‹$ĈD°§ÖżbB % úÁ2,i $ĉo\B1 z…˙ú¨ú ´„ pJġM¨u8a #PÚŒv\À +„á2ôFJU„ 5Ŭ'A Š€WúيԗcċÄ1ĉ XU„$(A·Ôӟšá¸µ *€ŽÛˁ‰ĊĈak3…ñÁpġš q¨Dsŝ …hDŒï‚ô85z7sİ0Ż´”(j4ĵÜ=µ_‚ÊR).>HĝyOıC°‡ĝÊ”b¤”ş. Abİ••ÊAB„CL|ÒD°ı„§ÚîPLĊ„£% ¸3”Á}L-@U‡äfK€§8U&6%JÏ +‰Ó]ÈeÀ¨ q†@é­î ¸LRSš&‡AD׺‚RŬŞ' +]”u 4³AĥÏ­ùán3ÔÏD˜N,Ñö NL +n€áTE;¸3 +B}J̳!.cj “Ċ‰I„2¤·³›í +™$Ĉ2Sj&Ôìf𗃲Ż"îLçĝN·yOKàƒ°ÛĊà!ĥ1šÁšıLÒlA%ŝİŠÊÄlfVr–éAÙé2{ }d@9hV0Úĵ•?TYĉ°ĝ3×­EpíBħÁpq›M +ú´ŞħûPXĈf~Ŭ§;O½œ'³_Ü#¤xĊ,8¤3ċq÷Z…G÷8ż„˜áúƒ€ÁÜV²Bf)Ì èp!€­öÉT2˘#ÀìNUj],6-ġî5à· e! á\QıBUçXçĵzBCĠ5RÑŬÓı€jÑéÖd•ƒĦa‘$$$…´koX-Ü LaġîÊ@Sâ=rÂ<ü1LVDàŭ´"CĞOéŬUs-Ĥ0`Š^' +™˘.$!XĠD–ö‰4ĠĤ{9NĞBP‡WûÔkL²èSĤH%ŞBÜ,aW¨zÜW9SÒ+„[ċ!ÏĵŬ3‹ó´b­‘´öN‡dklĵµ÷U@J\Ä,Š:[M)Ę3SÜ#N G‚w–ÀSD‰ı‹ĤÀŸrşƒĜ üž* ,HúS + |À |À |À |À |À |À |À÷jnĝ ĝ ĝ ĝ ĝ ĝ ĝ ĝ ĝ DÔ}"A˜Eĝß|bB@Ö!?˜@ê€ ŽL¨öéžÄ0ÁéıLp„ü`‚Ş&-ùÁGĈ&Ó2Lp„ĵ`n „À]³†À·!?˜à˜“Lp„ü`BuĉîİÍġ9Ŝv'Ĝ &8B^0AĠò† ސL(Ĥe˜àĜœLpLĊ &86ç܆ü`‚Ó%?˜àùÁ„êÌŬW›ë=ĵ"uÀHL 5Àpŝƒ ¸ÙpÛ.&`°R  ˜bÀ„8 ‚ ¸‘Üċê!/˜€— ‚ ¸Ê`‚Ŝ7 &èÁ‡ÀÜÇ€ (\/˜Pê&¸½ñ€ î¨ĵ`‚ИàêĜ&¸sċœY÷ƒ ސL(,q˜àX´Lp–…LpW—LpVİLpÖşLp}†Lp=L a0ÔHL a0ĦêÛ˙=`‚Ş&¨:`BaÀGÈ&¨:`‚Ş& …Lpd|`‚ú·‚ Žĥŭ`‚#ä +- UzÁtA0Áòƒ Îċü`‚#äŞzúgÁtĜA0Ïĥƒ`‚Û’LèıÜ=µ_˜PÌÍ0Áòƒ La0AÖdLa0AÖdLa0AÖdLPa0AĠTLPa0AĠTLPa0AĠTLPa0A…Á(²B`ŠÀÜb‚ èĤ`"80œ ˜€NLÀ >&è: &`ÑŻ € ÏÁÌ݃ xÚ0 ˜R‡ÀH0„Á'Ħ ˆLp/˜P!˙0˜ ê€ * &¨0˜ ê€ ޘ ê€ ޘ Â`‚ +ƒ U%ŝc`ä˜P’é &húc0˜€'&`É4‹8Lp%ĵ`BIÈ&¸ö =úğÇùeŸ£{Ç7ĝÁ„BÈ& Á„Bh˜;µA`‚ùü`But÷tnúp;*÷ƒ ސLPa0AĠT0AĠœ=D?˜à +yÁטĵ`‚+ä‹óƒ YzÁ„êĵŬ3‹û÷?Ħĝ ĝ ĠÀ |À |À |À |À |À |À |À |À­>hàƒ>hàƒ>hàƒ˙ġü²îçÜ4AÜ ĝ ˙ê§":`‚#äô-B`‚+äŞ}şg1Lpzî!?˜ ê€ EK~0Á‘ñ‚ δĝÁWÈ&È`‚Ş&È`‚kN^0Áòƒ Ġ™ğ§6×çx۝`/˜àyÁQLÈ&8B^0Á™?˜àڜL5ÀUL5À·K^0Áòƒ Ġ™ğŻ6×sxe÷pƒ LŒ & &C`‚Ŝš +€ *&¨:`‚ +ƒ * &¨`‚ +ƒ 2 &È:`‚ğ\½`‚#äd0A†Ád0A…ÁT0A…Ád0A†Ád0Á™u?˜àùÁYLA0A…ÁULPa0A…ÁULPA0Áñ_>0Áuƒ^0Áu§ŭÁ„’î&ôĝö˜ j€ ˘˜Pô0Áòƒ ˘˜ Â`‚“PxÁWĈ&ˆ+˜àhÛ&8B^0ÁђLpUéT0AĠÜËyÁWÈ&Tġôƒ ²˜ ë€ ²˜P½Ü=µ_˜PÌÍ0Áòƒ Làa0×xLàa0×xLàa0×xLa0AÔDLa0AÔDLa0AÔDLa0AÔdLa0AÖdLa0AÖdLa0AÖTLPa0AĠTLPa0AĠTLÀ”:&ÄI 0ƒnLp +˜Pñ ÄÄ &TcÈ? &ˆ:`‚ƒ " &ˆ:`‚¨&ˆ:`‚¨&ˆ0˜ Â`BU‰˙˜ j€ *&¨0˜ ë€ 2 &È ˜ ë€ ²˜ j€ UŭŬü²Ïѽü`B!4LPuÀUL(œÚ0Áġ|~0Ħ:ş{:7}¸•ûÁGÈ&ˆ0˜ ê€ ˘˜ ê€ ²˜ ë€ Ş˜ j€ ĊyÁ„’YzÁ„êĵŬ3‹û÷?Ħĝ ĝ ĠÀ |À |À |À |À |À |À |À |À­>hàƒ>hàƒ>hàƒ˙ġü²îçÜ4AÜ ĝ JZ¤Ek?żY?î¨@ġ€³ ïàÑÁ“UI1ĊÖìAêb¨tqdhâEë<Ö!?ˆ ë€ސD¨öéžÀÁéıDp„ü Ğ"-ùAGĈ"Ó2Dp„ü Ż"ˆ: Ż"8ĉä!?ˆPı{js}޳Ŭ ö‚ސD`u@„ĵĦA ‚#äŠi"86çx AÔxÁé’Dp„ü BuĉîĞÍġVÉ: ‚ ƒ2 "È ‚ ƒ""ˆ: ‚ƒ" "ˆ ‚ƒ< ": ‚ğ\½ ‚#äx‡AxA„ADA„Ax‡AxÁ™u?ˆàùA^DàAA„AQDaA„AQDaA†AYDAA†A„Şo˙÷€ĴˆÀꀅA!?ˆÀê€ĴˆP$~Á‘ñìß +"8ÚöƒސD(´4DpTéDAÔœËùAGÈ"TġôƒĵˆÀë€ĵˆP½Ü=µ_ˆPÌÍÁòƒD aÖhD aÖhD aÖhD`aĠXD`aĠXD`aĠXD`aĠxDàa×xDàa×xDàa×DDaAÔDDaAÔDDaAÖdDp +ˆàŠxA71ñ‚ĠòƒĴˆÀ  ƒĴˆÀê€ĴˆÀê€, "°0ˆPUâ?"ˆ ‚‚" ": ƒ<": Ż"ˆ BU÷8żìsTïĝ?ˆP DAÔr§6Dp<ŸD¨ŽîžÎMŸmGċ~Áò, "°: Ğ"°: Ż": ‚¨"ˆ: ‚cq~Á5K/ˆP·{fqƒ@„Ôƒ@ê'Ħcx΋'„€û³ 0Lş1 +|1nspΨÄwD .QĦ§ĦôĜ†ìAÏŻ4¸ŻAÊó$„˙ŸL²(ŝ(ä‡&)ĥ'xڂ +pD8Ó;ğTÚJSŸéê^Ğ|hP)Ud(+2R/E÷Rú„7Ĝ›{fónlĝ‹†ż¨·ä 5µ6nĴbä:Ó˙áÊàéĦv˙)n=`ڞêÀYV%„NeaiÊô„™ ~Fyn'([j)Á­—²ŝNıK`FFävÂ+k“qMYeÉ @J Ò#Qñ ”ˆ¸26)͖ĴˆR³ËƒyŽÍĠĈrK‰”ÚĦâÏ4ږİ^2ôŞP"* +|—Żĉ™·{ìR§!ujy'†÷ñY¨†`.a½j;)d`Ÿ˘·JËŞä²â0ħ׃S$7<Ŭ.µ¤ÀÑħŠP"ô^£Ó'¨èPœ +Ş—!Ò0 bˆĞ—ëqĝ[_Ĵ:şXôŝIÒÌR=ġ¸CÂtEÄp7ĜĥTM@HTeŞİ‡TĠŜî³wj˜†éj˜†éj˜†éşcŝâ\ĤŬŜ7OílħĜ†’x€§˜1ä"4ħ7úgĉœ@ñ슘³tm‚Yn +ÙZޝa!ÔSíàŽïMĴnj{ò¨@ĞB‚ĞÊċ¤Ùİv… $ZJĞrŽ'ÒĜ„£Hïvâv'MíA‚;à’DĈèĉӈeÖ,~rdf,Ñħ •&WAb•˜ +ÜĤ‚ÉċÒĝŬlgúiŸOdŝS)wâë ÑmĜÍgÎD„Ú ‘àè ž…•zMƒÏˆÈħ “‰ĴŒŠ€Óԗ†q› +OaŞÚ—í¨ÂĞ0VÑ1î2–Dôé}i(ä"ÚB=‰Ĥʰ#è×~`-ëÁêµDd)ÊB},ZP)½ë<˘hĠX_÷ÑÔTƒiŜLSò3‚ÁŻß[ĥ1<ĦÁ)„ —:„P••’·èôS„MtjA{„p‡ı"Ôhq[@ Q‚*á<í³‹ÀÈŞĴ^²?#„„ ÉŬy´(*B0Š + ô›Ñġtëğ† ½Ÿ-R]÷T ¨Z¤ËJ´@-€5ÑĊyV+„„Ŝ÷„ĝ-‡´ŒÓb…nìk!Èn-@Ù³Êş%ĵ½;†ıĥž>1ĝÖä'ˆS2L^++ÌÂ40Sà +•è^aÍĤzZ¸€ +Á2Ì,Ş}Jˆq-a=ŭİi1Ğ`–íFGá5„f–qµ@gG§ìóĦ¨Ĉ³¸dÌnĝàÜ%FOÈıV„0YÒz +^ÁĥlğÁĥlğÁĥlğÁĥl{0ĥ ġ,Ö` ïa b½n~h:×Ö#“(Xú¨D¸ÉÁÛÛí‹PŸFhogöħ°ÑÌip#Ĉk3½Ċa U%ĈP³éŠgÊ&ĉscîvs)ÖĴCIĉÇ,·!HÀŠLÀŜKÄ6Ĝ!7î6  fF_*É šÓ0;e2wĜp› Ñ?#’ċrXĵ 2§Ŝ#1ñ!³u°&Ĥ½6ɝ—`šĈ†Pdw)ÖZ}Y~‘QpozaáÒÖ"™G!D—ĞġXlCT÷vĤ3ÊĦ=êSôŝ4Ò! +Ş])jj;d>iI$†×ä™×ÖdşıT.$2B—efĴl;Äîü⣝ôa{>™¨ T ·Yƒ5 +Hr²hŽŝDOTv!žÔ$T9˘° &›µep@Y.½`uĤ-ÇMàfEÚD"r×Ġ+Ä 0îġ8jyñ°Sú£\"‹%Ñc§Úŭ( 9eWœˆJżĦÒĞ +AsÂĤöèó!ŬîӒ~ˆÎ^XßğÂuóJ…]¤°pÍâRF×`ħħŽÌñÀ&^“—ö´ŻL†›eÊܘPœğA3›á“ĵ&D²ݚsJͅeÒEä`ôvm节.ÚÄ4µKğâ jäÄĴbԃvqŒ*kÎV5uo`†5rL´j +÷Î'–’9÷şĤ8aĈœƒvñ§Ì½h=ÛĤ·•„7³§ŬٜíÄ8‘%rÂÔ= %–ıY ‹@;_ĥäK4xĦŸ`n½nŭà´gGù‰ 6öċF +nUOĈ &Ò,OeŞ„5ö,N€7F(вҕ3nħ3‹JAœqYDô¤)àóírĦÔ¸ŒÁg€!ëÜğœmhҞì>ĊßԁÖn`nl7ülÍÂ9OìTáM \ ÇM†–eDûfiqÛN˘m´\ì#‚6°TÇŜ›{›{›{›{›{ïâùn4Ú>ħ +)SêҕagL‘ŜÔşŒĦ 2w¸%=BúlŻ,ÄHú 5ĉHz…¸ı°êí7Ç-‡ÍcğÏVŜÜéÙÜéYcŭâï­X6°jP’p<‰/Éô,M‚ÛIoó;!X´²"„gi“)áÒ Ü}I%>yšUw˘*yZŠ ÉJ²b¨EÓ´z9YJ ıáAޔ˜rQAŻCPĥ*Ôx |6zùüöş0Ĥô]5Pġŝ#ĵT•Żĉ™ı{ĉêÜĵı8Ô^Ĝ‡+§›G˙í^MOµÛ;G_şoŽÎÎğWC_ŝ§Û:ş¸Àöğ?á“Ö—ĞîġÍċU·uŭġò?ĝ|%o·WĥW‡ŝ£÷H• endstream endobj 21 0 obj [/ICCBased 27 0 R] endobj 7 0 obj [6 0 R 5 0 R] endobj 40 0 obj <> endobj xref 0 41 0000000000 65535 f +0000000016 00000 n +0000000156 00000 n +0000038280 00000 n +0000000000 00000 f +0000053108 00000 n +0000053178 00000 n +0000378446 00000 n +0000038331 00000 n +0000038793 00000 n +0000041265 00000 n +0000053839 00000 n +0000050299 00000 n +0000050186 00000 n +0000053480 00000 n +0000053603 00000 n +0000053716 00000 n +0000042272 00000 n +0000044889 00000 n +0000047506 00000 n +0000041327 00000 n +0000378411 00000 n +0000041711 00000 n +0000041759 00000 n +0000053045 00000 n +0000052982 00000 n +0000050123 00000 n +0000050334 00000 n +0000053364 00000 n +0000053395 00000 n +0000053248 00000 n +0000053279 00000 n +0000053913 00000 n +0000054175 00000 n +0000055286 00000 n +0000067808 00000 n +0000133396 00000 n +0000198984 00000 n +0000264572 00000 n +0000330160 00000 n +0000378475 00000 n +trailer <<0C9D12E6EE994682A6EAD56912419B86>]>> startxref 378666 %%EOF \ No newline at end of file diff --git a/resources/identity.svg b/resources/identity.svg new file mode 100644 index 0000000000..b363971cef --- /dev/null +++ b/resources/identity.svg @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/jest.d.ts b/resources/jest.d.ts deleted file mode 100644 index 7d4410bf91..0000000000 --- a/resources/jest.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -declare var jasmine: any; - -declare function afterEach(fn: any): any; -declare function beforeEach(fn: any): any; -declare function describe(name: string, fn: any): void; -declare var it: { - (name: string, fn: any): void; - only: (name: string, fn: any) => void; -} -declare function expect(val: any): Expect; -declare var jest: Jest; -declare function pit(name: string, fn: any): void; -declare function xdescribe(name: string, fn: any): void; -declare function xit(name: string, fn: any): void; - -interface Expect { - not: Expect - toThrow(message?: string): void - toBe(value: any): void - toEqual(value: any): void - toBeFalsy(): void - toBeTruthy(): void - toBeNull(): void - toBeUndefined(): void - toBeDefined(): void - toMatch(regexp: RegExp): void - toContain(string: string): void - toBeCloseTo(number: number, delta: number): void - toBeGreaterThan(number: number): void - toBeLessThan(number: number): void - toBeCalled(): void - toBeCalledWith(...arguments): void - lastCalledWith(...arguments): void -} - -interface Jest { - autoMockOff(): void - autoMockOn(): void - clearAllTimers(): void - dontMock(moduleName: string): void - genMockFromModule(moduleObj: Object): Object - genMockFunction(): MockFunction - genMockFn(): MockFunction - mock(moduleName: string): void - runAllTicks(): void - runAllTimers(): void - runOnlyPendingTimers(): void - setMock(moduleName: string, moduleExports: Object): void -} - -interface MockFunction { - (...arguments): any - mock: { - calls: Array> - instances: Array - } - mockClear(): void - mockImplementation(fn: Function): MockFunction - mockImpl(fn: Function): MockFunction - mockReturnThis(): MockFunction - mockReturnValue(value: any): MockFunction - mockReturnValueOnce(value: any): MockFunction -} - -// Allow importing jasmine-check -declare module 'jasmine-check' { - export function install(global?: any): void; -} -declare var check: any; -declare var gen: any; diff --git a/resources/jestPreprocessor.js b/resources/jestPreprocessor.js index f5aa47674c..5ea6aa5036 100644 --- a/resources/jestPreprocessor.js +++ b/resources/jestPreprocessor.js @@ -1,29 +1,71 @@ -// preprocessor.js -var ts = require('ts-compiler'); -var react = require('react-tools'); +var typescript = require('typescript'); +const makeSynchronous = require('make-synchronous'); -module.exports = { - process: function(src, path) { - if (path.match(/\.ts$/) && !path.match(/\.d\.ts$/)) { - ts.compile([path], { - skipWrite: true, - module: 'commonjs' - }, function(err, results) { - if (err) { - throw err; - } - results.forEach(function(file) { - // This is gross, but jest doesn't provide an asynchronous way to - // process a module, and ts currently runs syncronously. - src = file.text; - }); - }); - return src.replace(/require\('immutable'\)/g, "require('../')"); +const TYPESCRIPT_OPTIONS = { + noEmitOnError: true, + target: typescript.ScriptTarget.ES2015, + module: typescript.ModuleKind.CommonJS, + strictNullChecks: true, + sourceMap: true, + inlineSourceMap: true, +}; + +function transpileTypeScript(src, path) { + return typescript.transpile(src, TYPESCRIPT_OPTIONS, path, []); +} + +function transpileJavaScript(src, path) { + // Need to make this sync by calling `makeSynchronous` + // while https://github.com/facebook/jest/issues/9504 is not resolved + const fn = makeSynchronous(async (path) => { + const rollup = require('rollup'); + const buble = require('@rollup/plugin-buble'); + const commonjs = require('@rollup/plugin-commonjs'); + const json = require('@rollup/plugin-json'); + const typescript = require('@rollup/plugin-typescript'); + + // same input options as in rollup-config.js + const inputOptions = { + input: path, + onwarn: () => {}, + plugins: [commonjs(), json(), typescript(), buble()], + }; + + const bundle = await rollup.rollup(inputOptions); + + const { output } = await bundle.generate({ + file: path, + format: 'cjs', + sourcemap: true, + }); + + await bundle.close(); + + const { code, map } = output[0]; + + if (!code) { + throw new Error( + 'Unable to get code from rollup output in jestPreprocessor. Did rollup version changed ?' + ); } - if (path.match(/\.js$/)) { - return react.transform(src, {harmony: true}) - .replace(/require\('immutable'\)/g, "require('../')"); + + return { code, map }; + }); + + return fn(path); +} + +module.exports = { + process(src, path) { + if (path.endsWith('.ts') || path.endsWith('.tsx')) { + return { code: transpileTypeScript(src, path) }; } - return src; - } + + return transpileJavaScript(src, path); + }, + + getCacheKey() { + // ignore cache, as there is a conflict between rollup compile and jest preprocessor. + return Date.now().toString(); + }, }; diff --git a/resources/jestResolver.js b/resources/jestResolver.js new file mode 100644 index 0000000000..a379bc4421 --- /dev/null +++ b/resources/jestResolver.js @@ -0,0 +1,17 @@ +const path = require('path'); +const pkg = require('../package.json'); + +module.exports = (request, options) => { + if (request === 'immutable') { + if (process.env.CI) { + // In CI environment, test the real built file to be sure that the build is not broken + return path.resolve(options.rootDir, pkg.main); + } + + // In development mode, we want sourcemaps, live reload, etc., so point to the src/ directory + return `${options.rootDir}/src/Immutable.js`; + } + + // Call the defaultResolver, if we want to load non-immutable + return options.defaultResolver(request, options); +}; diff --git a/resources/prepare-dist.sh b/resources/prepare-dist.sh new file mode 100755 index 0000000000..d8d86a0573 --- /dev/null +++ b/resources/prepare-dist.sh @@ -0,0 +1,25 @@ +#!/bin/sh -e + +# This script prepares an npm directory with files safe to publish to npm or the +# npm git branch: +# +# "immutable": "git://github.com/immutable-js/immutable-js.git#npm" +# + +# Create empty npm directory +rm -rf npm +mkdir -p npm + +# Copy over necessary files +cp -r dist npm/ +cp README.md npm/ +cp LICENSE npm/ + +# Ensure a vanilla package.json before deploying so other tools do not interpret +# The built output as requiring any further transformation. +node -e "var package = require('./package.json'); \ + package = Object.fromEntries(Object.entries(package).filter(([key]) => package.publishKeys.includes(key))); \ + require('fs').writeFileSync('./npm/package.json', JSON.stringify(package, null, 2));" + +# Retain marginal support for bower on the npm branch +cp npm/package.json npm/bower.json diff --git a/resources/react-global.js b/resources/react-global.js new file mode 100644 index 0000000000..45b0fd0871 --- /dev/null +++ b/resources/react-global.js @@ -0,0 +1 @@ +module.exports = global.React; diff --git a/resources/rollup-config.mjs b/resources/rollup-config.mjs new file mode 100644 index 0000000000..6963235c5d --- /dev/null +++ b/resources/rollup-config.mjs @@ -0,0 +1,47 @@ +import path from 'path'; +import buble from '@rollup/plugin-buble'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import terser from '@rollup/plugin-terser'; +// TODO replace @rollup/plugin-typescript with babel after babel migration +import typescript from '@rollup/plugin-typescript'; +import copyright from './copyright.mjs'; + +const SRC_DIR = path.resolve('src'); +const DIST_DIR = path.resolve('dist'); + +export default [ + { + input: path.join(SRC_DIR, 'Immutable.js'), + plugins: [commonjs(), json(), typescript(), buble()], + output: [ + // umd build + { + banner: copyright, + name: 'Immutable', + exports: 'named', + file: path.join(DIST_DIR, 'immutable.js'), + format: 'umd', + sourcemap: false, + }, + // minified build for browsers + { + banner: copyright, + name: 'Immutable', + exports: 'named', + file: path.join(DIST_DIR, 'immutable.min.js'), + format: 'umd', + sourcemap: false, + plugins: [terser()], + }, + // es build for bundlers and node + { + banner: copyright, + name: 'Immutable', + file: path.join(DIST_DIR, 'immutable.es.js'), + format: 'es', + sourcemap: false, + }, + ], + }, +]; diff --git a/resources/traceur-runtime.js b/resources/traceur-runtime.js deleted file mode 100644 index 9e747bad83..0000000000 --- a/resources/traceur-runtime.js +++ /dev/null @@ -1,33 +0,0 @@ -var $Object = Object; - -function createClass(ctor, methods, staticMethods, superClass) { - var proto; - if (superClass) { - var superProto = superClass.prototype; - proto = $Object.create(superProto); - } else { - proto = ctor.prototype; - } - $Object.keys(methods).forEach(function (key) { - proto[key] = methods[key]; - }); - $Object.keys(staticMethods).forEach(function (key) { - ctor[key] = staticMethods[key]; - }); - proto.constructor = ctor; - ctor.prototype = proto; - return ctor; -} - -function superCall(self, proto, name, args) { - return $Object.getPrototypeOf(proto)[name].apply(self, args); -} - -function defaultSuperCall(self, proto, args) { - superCall(self, proto, 'constructor', args); -} - -var $traceurRuntime = {}; -$traceurRuntime.createClass = createClass; -$traceurRuntime.superCall = superCall; -$traceurRuntime.defaultSuperCall = defaultSuperCall; diff --git a/resources/universal-module.js b/resources/universal-module.js deleted file mode 100644 index 686136d420..0000000000 --- a/resources/universal-module.js +++ /dev/null @@ -1,7 +0,0 @@ -function universalModule() { - %MODULE% - return Immutable; -} -typeof exports === 'object' ? module.exports = universalModule() : - typeof define === 'function' && define.amd ? define(universalModule) : - Immutable = universalModule(); diff --git a/src/Collection.js b/src/Collection.js new file mode 100644 index 0000000000..650ff654ff --- /dev/null +++ b/src/Collection.js @@ -0,0 +1,37 @@ +import { Seq, KeyedSeq, IndexedSeq, SetSeq } from './Seq'; +import { isCollection } from './predicates/isCollection'; +import { isKeyed } from './predicates/isKeyed'; +import { isIndexed } from './predicates/isIndexed'; +import { isAssociative } from './predicates/isAssociative'; + +export class Collection { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return isCollection(value) ? value : Seq(value); + } +} + +export class KeyedCollection extends Collection { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return isKeyed(value) ? value : KeyedSeq(value); + } +} + +export class IndexedCollection extends Collection { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return isIndexed(value) ? value : IndexedSeq(value); + } +} + +export class SetCollection extends Collection { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return isCollection(value) && !isAssociative(value) ? value : SetSeq(value); + } +} + +Collection.Keyed = KeyedCollection; +Collection.Indexed = IndexedCollection; +Collection.Set = SetCollection; diff --git a/src/CollectionImpl.js b/src/CollectionImpl.js new file mode 100644 index 0000000000..befb3dadc2 --- /dev/null +++ b/src/CollectionImpl.js @@ -0,0 +1,789 @@ +import { + Collection, + KeyedCollection, + IndexedCollection, + SetCollection, +} from './Collection'; +import { IS_COLLECTION_SYMBOL } from './predicates/isCollection'; +import { isKeyed, IS_KEYED_SYMBOL } from './predicates/isKeyed'; +import { isIndexed, IS_INDEXED_SYMBOL } from './predicates/isIndexed'; +import { isOrdered, IS_ORDERED_SYMBOL } from './predicates/isOrdered'; +import { is } from './is'; +import { + NOT_SET, + ensureSize, + wrapIndex, + returnTrue, + resolveBegin, +} from './TrieUtils'; +import { hash } from './Hash'; +import { imul, smi } from './Math'; +import { + Iterator, + ITERATOR_SYMBOL, + ITERATE_KEYS, + ITERATE_VALUES, + ITERATE_ENTRIES, +} from './Iterator'; + +import arrCopy from './utils/arrCopy'; +import assertNotInfinite from './utils/assertNotInfinite'; +import deepEqual from './utils/deepEqual'; +import mixin from './utils/mixin'; +import quoteString from './utils/quoteString'; + +import { toJS } from './toJS'; +import { Map } from './Map'; +import { OrderedMap } from './OrderedMap'; +import { List } from './List'; +import { Set } from './Set'; +import { OrderedSet } from './OrderedSet'; +import { Stack } from './Stack'; +import { Range } from './Range'; +import { KeyedSeq, IndexedSeq, SetSeq, ArraySeq } from './Seq'; +import { + reify, + ToKeyedSequence, + ToIndexedSequence, + ToSetSequence, + FromEntriesSequence, + flipFactory, + mapFactory, + reverseFactory, + filterFactory, + countByFactory, + groupByFactory, + sliceFactory, + takeWhileFactory, + skipWhileFactory, + concatFactory, + flattenFactory, + flatMapFactory, + interposeFactory, + sortFactory, + maxFactory, + zipWithFactory, + partitionFactory, +} from './Operations'; +import { getIn } from './methods/getIn'; +import { hasIn } from './methods/hasIn'; +import { toObject } from './methods/toObject'; + +export { Collection, CollectionPrototype, IndexedCollectionPrototype }; + +Collection.Iterator = Iterator; + +mixin(Collection, { + // ### Conversion to other types + + toArray() { + assertNotInfinite(this.size); + const array = new Array(this.size || 0); + const useTuples = isKeyed(this); + let i = 0; + this.__iterate((v, k) => { + // Keyed collections produce an array of tuples. + array[i++] = useTuples ? [k, v] : v; + }); + return array; + }, + + toIndexedSeq() { + return new ToIndexedSequence(this); + }, + + toJS() { + return toJS(this); + }, + + toKeyedSeq() { + return new ToKeyedSequence(this, true); + }, + + toMap() { + // Use Late Binding here to solve the circular dependency. + return Map(this.toKeyedSeq()); + }, + + toObject: toObject, + + toOrderedMap() { + // Use Late Binding here to solve the circular dependency. + return OrderedMap(this.toKeyedSeq()); + }, + + toOrderedSet() { + // Use Late Binding here to solve the circular dependency. + return OrderedSet(isKeyed(this) ? this.valueSeq() : this); + }, + + toSet() { + // Use Late Binding here to solve the circular dependency. + return Set(isKeyed(this) ? this.valueSeq() : this); + }, + + toSetSeq() { + return new ToSetSequence(this); + }, + + toSeq() { + return isIndexed(this) + ? this.toIndexedSeq() + : isKeyed(this) + ? this.toKeyedSeq() + : this.toSetSeq(); + }, + + toStack() { + // Use Late Binding here to solve the circular dependency. + return Stack(isKeyed(this) ? this.valueSeq() : this); + }, + + toList() { + // Use Late Binding here to solve the circular dependency. + return List(isKeyed(this) ? this.valueSeq() : this); + }, + + // ### Common JavaScript methods and properties + + toString() { + return '[Collection]'; + }, + + __toString(head, tail) { + if (this.size === 0) { + return head + tail; + } + return ( + head + + ' ' + + this.toSeq().map(this.__toStringMapper).join(', ') + + ' ' + + tail + ); + }, + + // ### ES6 Collection methods (ES6 Array and Map) + + concat(...values) { + return reify(this, concatFactory(this, values)); + }, + + includes(searchValue) { + return this.some((value) => is(value, searchValue)); + }, + + entries() { + return this.__iterator(ITERATE_ENTRIES); + }, + + every(predicate, context) { + assertNotInfinite(this.size); + let returnValue = true; + this.__iterate((v, k, c) => { + if (!predicate.call(context, v, k, c)) { + returnValue = false; + return false; + } + }); + return returnValue; + }, + + filter(predicate, context) { + return reify(this, filterFactory(this, predicate, context, true)); + }, + + partition(predicate, context) { + return partitionFactory(this, predicate, context); + }, + + find(predicate, context, notSetValue) { + const entry = this.findEntry(predicate, context); + return entry ? entry[1] : notSetValue; + }, + + forEach(sideEffect, context) { + assertNotInfinite(this.size); + return this.__iterate(context ? sideEffect.bind(context) : sideEffect); + }, + + join(separator) { + assertNotInfinite(this.size); + separator = separator !== undefined ? '' + separator : ','; + let joined = ''; + let isFirst = true; + this.__iterate((v) => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + isFirst ? (isFirst = false) : (joined += separator); + joined += v !== null && v !== undefined ? v.toString() : ''; + }); + return joined; + }, + + keys() { + return this.__iterator(ITERATE_KEYS); + }, + + map(mapper, context) { + return reify(this, mapFactory(this, mapper, context)); + }, + + reduce(reducer, initialReduction, context) { + return reduce( + this, + reducer, + initialReduction, + context, + arguments.length < 2, + false + ); + }, + + reduceRight(reducer, initialReduction, context) { + return reduce( + this, + reducer, + initialReduction, + context, + arguments.length < 2, + true + ); + }, + + reverse() { + return reify(this, reverseFactory(this, true)); + }, + + slice(begin, end) { + return reify(this, sliceFactory(this, begin, end, true)); + }, + + some(predicate, context) { + assertNotInfinite(this.size); + let returnValue = false; + this.__iterate((v, k, c) => { + if (predicate.call(context, v, k, c)) { + returnValue = true; + return false; + } + }); + return returnValue; + }, + + sort(comparator) { + return reify(this, sortFactory(this, comparator)); + }, + + values() { + return this.__iterator(ITERATE_VALUES); + }, + + // ### More sequential methods + + butLast() { + return this.slice(0, -1); + }, + + isEmpty() { + return this.size !== undefined ? this.size === 0 : !this.some(() => true); + }, + + count(predicate, context) { + return ensureSize( + predicate ? this.toSeq().filter(predicate, context) : this + ); + }, + + countBy(grouper, context) { + return countByFactory(this, grouper, context); + }, + + equals(other) { + return deepEqual(this, other); + }, + + entrySeq() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const collection = this; + if (collection._cache) { + // We cache as an entries array, so we can just return the cache! + return new ArraySeq(collection._cache); + } + const entriesSequence = collection.toSeq().map(entryMapper).toIndexedSeq(); + entriesSequence.fromEntrySeq = () => collection.toSeq(); + return entriesSequence; + }, + + filterNot(predicate, context) { + return this.filter(not(predicate), context); + }, + + findEntry(predicate, context, notSetValue) { + let found = notSetValue; + this.__iterate((v, k, c) => { + if (predicate.call(context, v, k, c)) { + found = [k, v]; + return false; + } + }); + return found; + }, + + findKey(predicate, context) { + const entry = this.findEntry(predicate, context); + return entry && entry[0]; + }, + + findLast(predicate, context, notSetValue) { + return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); + }, + + findLastEntry(predicate, context, notSetValue) { + return this.toKeyedSeq() + .reverse() + .findEntry(predicate, context, notSetValue); + }, + + findLastKey(predicate, context) { + return this.toKeyedSeq().reverse().findKey(predicate, context); + }, + + first(notSetValue) { + return this.find(returnTrue, null, notSetValue); + }, + + flatMap(mapper, context) { + return reify(this, flatMapFactory(this, mapper, context)); + }, + + flatten(depth) { + return reify(this, flattenFactory(this, depth, true)); + }, + + fromEntrySeq() { + return new FromEntriesSequence(this); + }, + + get(searchKey, notSetValue) { + return this.find((_, key) => is(key, searchKey), undefined, notSetValue); + }, + + getIn: getIn, + + groupBy(grouper, context) { + return groupByFactory(this, grouper, context); + }, + + has(searchKey) { + return this.get(searchKey, NOT_SET) !== NOT_SET; + }, + + hasIn: hasIn, + + isSubset(iter) { + iter = typeof iter.includes === 'function' ? iter : Collection(iter); + return this.every((value) => iter.includes(value)); + }, + + isSuperset(iter) { + iter = typeof iter.isSubset === 'function' ? iter : Collection(iter); + return iter.isSubset(this); + }, + + keyOf(searchValue) { + return this.findKey((value) => is(value, searchValue)); + }, + + keySeq() { + return this.toSeq().map(keyMapper).toIndexedSeq(); + }, + + last(notSetValue) { + return this.toSeq().reverse().first(notSetValue); + }, + + lastKeyOf(searchValue) { + return this.toKeyedSeq().reverse().keyOf(searchValue); + }, + + max(comparator) { + return maxFactory(this, comparator); + }, + + maxBy(mapper, comparator) { + return maxFactory(this, comparator, mapper); + }, + + min(comparator) { + return maxFactory( + this, + comparator ? neg(comparator) : defaultNegComparator + ); + }, + + minBy(mapper, comparator) { + return maxFactory( + this, + comparator ? neg(comparator) : defaultNegComparator, + mapper + ); + }, + + rest() { + return this.slice(1); + }, + + skip(amount) { + return amount === 0 ? this : this.slice(Math.max(0, amount)); + }, + + skipLast(amount) { + return amount === 0 ? this : this.slice(0, -Math.max(0, amount)); + }, + + skipWhile(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, true)); + }, + + skipUntil(predicate, context) { + return this.skipWhile(not(predicate), context); + }, + + sortBy(mapper, comparator) { + return reify(this, sortFactory(this, comparator, mapper)); + }, + + take(amount) { + return this.slice(0, Math.max(0, amount)); + }, + + takeLast(amount) { + return this.slice(-Math.max(0, amount)); + }, + + takeWhile(predicate, context) { + return reify(this, takeWhileFactory(this, predicate, context)); + }, + + takeUntil(predicate, context) { + return this.takeWhile(not(predicate), context); + }, + + update(fn) { + return fn(this); + }, + + valueSeq() { + return this.toIndexedSeq(); + }, + + // ### Hashable Object + + hashCode() { + return this.__hash || (this.__hash = hashCollection(this)); + }, + + // ### Internal + + // abstract __iterate(fn, reverse) + + // abstract __iterator(type, reverse) +}); + +const CollectionPrototype = Collection.prototype; +CollectionPrototype[IS_COLLECTION_SYMBOL] = true; +CollectionPrototype[ITERATOR_SYMBOL] = CollectionPrototype.values; +CollectionPrototype.toJSON = CollectionPrototype.toArray; +CollectionPrototype.__toStringMapper = quoteString; +CollectionPrototype.inspect = CollectionPrototype.toSource = function () { + return this.toString(); +}; +CollectionPrototype.chain = CollectionPrototype.flatMap; +CollectionPrototype.contains = CollectionPrototype.includes; + +mixin(KeyedCollection, { + // ### More sequential methods + + flip() { + return reify(this, flipFactory(this)); + }, + + mapEntries(mapper, context) { + let iterations = 0; + return reify( + this, + this.toSeq() + .map((v, k) => mapper.call(context, [k, v], iterations++, this)) + .fromEntrySeq() + ); + }, + + mapKeys(mapper, context) { + return reify( + this, + this.toSeq() + .flip() + .map((k, v) => mapper.call(context, k, v, this)) + .flip() + ); + }, +}); + +const KeyedCollectionPrototype = KeyedCollection.prototype; +KeyedCollectionPrototype[IS_KEYED_SYMBOL] = true; +KeyedCollectionPrototype[ITERATOR_SYMBOL] = CollectionPrototype.entries; +KeyedCollectionPrototype.toJSON = toObject; +KeyedCollectionPrototype.__toStringMapper = (v, k) => + quoteString(k) + ': ' + quoteString(v); + +mixin(IndexedCollection, { + // ### Conversion to other types + + toKeyedSeq() { + return new ToKeyedSequence(this, false); + }, + + // ### ES6 Collection methods (ES6 Array and Map) + + filter(predicate, context) { + return reify(this, filterFactory(this, predicate, context, false)); + }, + + findIndex(predicate, context) { + const entry = this.findEntry(predicate, context); + return entry ? entry[0] : -1; + }, + + indexOf(searchValue) { + const key = this.keyOf(searchValue); + return key === undefined ? -1 : key; + }, + + lastIndexOf(searchValue) { + const key = this.lastKeyOf(searchValue); + return key === undefined ? -1 : key; + }, + + reverse() { + return reify(this, reverseFactory(this, false)); + }, + + slice(begin, end) { + return reify(this, sliceFactory(this, begin, end, false)); + }, + + splice(index, removeNum /*, ...values*/) { + const numArgs = arguments.length; + removeNum = Math.max(removeNum || 0, 0); + if (numArgs === 0 || (numArgs === 2 && !removeNum)) { + return this; + } + // If index is negative, it should resolve relative to the size of the + // collection. However size may be expensive to compute if not cached, so + // only call count() if the number is in fact negative. + index = resolveBegin(index, index < 0 ? this.count() : this.size); + const spliced = this.slice(0, index); + return reify( + this, + numArgs === 1 + ? spliced + : spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) + ); + }, + + // ### More collection methods + + findLastIndex(predicate, context) { + const entry = this.findLastEntry(predicate, context); + return entry ? entry[0] : -1; + }, + + first(notSetValue) { + return this.get(0, notSetValue); + }, + + flatten(depth) { + return reify(this, flattenFactory(this, depth, false)); + }, + + get(index, notSetValue) { + index = wrapIndex(this, index); + return index < 0 || + this.size === Infinity || + (this.size !== undefined && index > this.size) + ? notSetValue + : this.find((_, key) => key === index, undefined, notSetValue); + }, + + has(index) { + index = wrapIndex(this, index); + return ( + index >= 0 && + (this.size !== undefined + ? this.size === Infinity || index < this.size + : this.indexOf(index) !== -1) + ); + }, + + interpose(separator) { + return reify(this, interposeFactory(this, separator)); + }, + + interleave(/*...collections*/) { + const collections = [this].concat(arrCopy(arguments)); + const zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, collections); + const interleaved = zipped.flatten(true); + if (zipped.size) { + interleaved.size = zipped.size * collections.length; + } + return reify(this, interleaved); + }, + + keySeq() { + return Range(0, this.size); + }, + + last(notSetValue) { + return this.get(-1, notSetValue); + }, + + skipWhile(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, false)); + }, + + zip(/*, ...collections */) { + const collections = [this].concat(arrCopy(arguments)); + return reify(this, zipWithFactory(this, defaultZipper, collections)); + }, + + zipAll(/*, ...collections */) { + const collections = [this].concat(arrCopy(arguments)); + return reify(this, zipWithFactory(this, defaultZipper, collections, true)); + }, + + zipWith(zipper /*, ...collections */) { + const collections = arrCopy(arguments); + collections[0] = this; + return reify(this, zipWithFactory(this, zipper, collections)); + }, +}); + +const IndexedCollectionPrototype = IndexedCollection.prototype; +IndexedCollectionPrototype[IS_INDEXED_SYMBOL] = true; +IndexedCollectionPrototype[IS_ORDERED_SYMBOL] = true; + +mixin(SetCollection, { + // ### ES6 Collection methods (ES6 Array and Map) + + get(value, notSetValue) { + return this.has(value) ? value : notSetValue; + }, + + includes(value) { + return this.has(value); + }, + + // ### More sequential methods + + keySeq() { + return this.valueSeq(); + }, +}); + +const SetCollectionPrototype = SetCollection.prototype; +SetCollectionPrototype.has = CollectionPrototype.includes; +SetCollectionPrototype.contains = SetCollectionPrototype.includes; +SetCollectionPrototype.keys = SetCollectionPrototype.values; + +// Mixin subclasses + +mixin(KeyedSeq, KeyedCollectionPrototype); +mixin(IndexedSeq, IndexedCollectionPrototype); +mixin(SetSeq, SetCollectionPrototype); + +// #pragma Helper functions + +function reduce(collection, reducer, reduction, context, useFirst, reverse) { + assertNotInfinite(collection.size); + collection.__iterate((v, k, c) => { + if (useFirst) { + useFirst = false; + reduction = v; + } else { + reduction = reducer.call(context, reduction, v, k, c); + } + }, reverse); + return reduction; +} + +function keyMapper(v, k) { + return k; +} + +function entryMapper(v, k) { + return [k, v]; +} + +function not(predicate) { + return function () { + return !predicate.apply(this, arguments); + }; +} + +function neg(predicate) { + return function () { + return -predicate.apply(this, arguments); + }; +} + +function defaultZipper() { + return arrCopy(arguments); +} + +function defaultNegComparator(a, b) { + return a < b ? 1 : a > b ? -1 : 0; +} + +function hashCollection(collection) { + if (collection.size === Infinity) { + return 0; + } + const ordered = isOrdered(collection); + const keyed = isKeyed(collection); + let h = ordered ? 1 : 0; + + collection.__iterate( + keyed + ? ordered + ? (v, k) => { + h = (31 * h + hashMerge(hash(v), hash(k))) | 0; + } + : (v, k) => { + h = (h + hashMerge(hash(v), hash(k))) | 0; + } + : ordered + ? (v) => { + h = (31 * h + hash(v)) | 0; + } + : (v) => { + h = (h + hash(v)) | 0; + } + ); + + return murmurHashOfSize(collection.size, h); +} + +function murmurHashOfSize(size, h) { + h = imul(h, 0xcc9e2d51); + h = imul((h << 15) | (h >>> -15), 0x1b873593); + h = imul((h << 13) | (h >>> -13), 5); + h = ((h + 0xe6546b64) | 0) ^ size; + h = imul(h ^ (h >>> 16), 0x85ebca6b); + h = imul(h ^ (h >>> 13), 0xc2b2ae35); + h = smi(h ^ (h >>> 16)); + return h; +} + +function hashMerge(a, b) { + return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; // int +} diff --git a/src/Cursor.js b/src/Cursor.js deleted file mode 100644 index 8a0d15784b..0000000000 --- a/src/Cursor.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Map" -import "Sequence" -import "TrieUtils" -/* global Map, Sequence, NOT_SET, DELETE */ - -class Cursor extends Sequence { - constructor(rootData, keyPath, onChange, value) { - value = value ? value : rootData.getIn(keyPath); - this.length = value instanceof Sequence ? value.length : null; - this._rootData = rootData; - this._keyPath = keyPath; - this._onChange = onChange; - } - - deref(notSetValue) { - return this._rootData.getIn(this._keyPath, notSetValue); - } - - get(key, notSetValue) { - if (Array.isArray(key) && key.length === 0) { - return this; - } - var value = this._rootData.getIn(this._keyPath.concat(key), NOT_SET); - return value === NOT_SET ? notSetValue : wrappedValue(this, key, value); - } - - set(key, value) { - return updateCursor(this, m => m.set(key, value), key); - } - - remove(key) { - return updateCursor(this, m => m.remove(key), key); - } - - clear() { - return updateCursor(this, m => m.clear()); - } - - update(keyOrFn, notSetValue, updater) { - return arguments.length === 1 ? - updateCursor(this, keyOrFn) : - updateCursor(this, map => map.update(keyOrFn, notSetValue, updater), keyOrFn); - } - - withMutations(fn) { - return updateCursor(this, m => (m || Map.empty()).withMutations(fn)); - } - - cursor(subKey) { - return Array.isArray(subKey) && subKey.length === 0 ? - this : subCursor(this, subKey); - } - - __iterate(fn, reverse) { - var cursor = this; - var deref = cursor.deref(); - return deref && deref.__iterate ? deref.__iterate( - (value, key) => fn(wrappedValue(cursor, key, value), key, this), - reverse - ) : 0; - } -} - -Cursor.prototype[DELETE] = Cursor.prototype.remove; -Cursor.prototype.getIn = Cursor.prototype.get; - -function wrappedValue(cursor, key, value) { - return value instanceof Sequence ? subCursor(cursor, key, value) : value; -} - -function subCursor(cursor, key, value) { - return new Cursor( - cursor._rootData, - cursor._keyPath.concat(key), - cursor._onChange, - value - ); -} - -function updateCursor(cursor, changeFn, changeKey) { - var newRootData = cursor._rootData.updateIn( - cursor._keyPath, - changeKey ? Map.empty() : undefined, - changeFn - ); - var keyPath = cursor._keyPath || []; - cursor._onChange && cursor._onChange.call( - undefined, - newRootData, - cursor._rootData, - changeKey ? keyPath.concat(changeKey) : keyPath - ); - return new Cursor(newRootData, cursor._keyPath, cursor._onChange); -} diff --git a/src/Hash.js b/src/Hash.js index 9f5ce6e183..d1c65f7978 100644 --- a/src/Hash.js +++ b/src/Hash.js @@ -1,51 +1,82 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/* global Symbol */ -/* exported hash, HASH_MAX_VAL */ - -function hash(o) { - if (!o) { // false, 0, and null - return 0; +import { smi } from './Math'; + +const defaultValueOf = Object.prototype.valueOf; + +export function hash(o) { + // eslint-disable-next-line eqeqeq + if (o == null) { + return hashNullish(o); } - if (o === true) { - return 1; + + if (typeof o.hashCode === 'function') { + // Drop any high bits from accidentally long hash codes. + return smi(o.hashCode(o)); } - var type = typeof o; - if (type === 'number') { - if ((o | 0) === o) { - return o & HASH_MAX_VAL; - } - o = '' + o; - type = 'string'; + + const v = valueOf(o); + + // eslint-disable-next-line eqeqeq + if (v == null) { + return hashNullish(v); + } + + switch (typeof v) { + case 'boolean': + // The hash values for built-in constants are a 1 value for each 5-byte + // shift region expect for the first, which encodes the value. This + // reduces the odds of a hash collision for these common values. + return v ? 0x42108421 : 0x42108420; + case 'number': + return hashNumber(v); + case 'string': + return v.length > STRING_HASH_CACHE_MIN_STRLEN + ? cachedHashString(v) + : hashString(v); + case 'object': + case 'function': + return hashJSObj(v); + case 'symbol': + return hashSymbol(v); + default: + if (typeof v.toString === 'function') { + return hashString(v.toString()); + } + throw new Error('Value type ' + typeof v + ' cannot be hashed.'); + } +} + +function hashNullish(nullish) { + return nullish === null ? 0x42108422 : /* undefined */ 0x42108423; +} + +// Compress arbitrarily large numbers into smi hashes. +function hashNumber(n) { + if (n !== n || n === Infinity) { + return 0; } - if (type === 'string') { - return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); + let hash = n | 0; + if (hash !== n) { + hash ^= n * 0xffffffff; } - if (o.hashCode) { - return hash(typeof o.hashCode === 'function' ? o.hashCode() : o.hashCode); + while (n > 0xffffffff) { + n /= 0xffffffff; + hash ^= n; } - return hashJSObj(o); + return smi(hash); } function cachedHashString(string) { - var hash = stringHashCache[string]; - if (hash == null) { - hash = hashString(string); + let hashed = stringHashCache[string]; + if (hashed === undefined) { + hashed = hashString(string); if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { STRING_HASH_CACHE_SIZE = 0; stringHashCache = {}; } STRING_HASH_CACHE_SIZE++; - stringHashCache[string] = hash; + stringHashCache[string] = hashed; } - return hash; + return hashed; } // http://jsperf.com/hashing-strings @@ -56,71 +87,106 @@ function hashString(string) { // where s[i] is the ith character of the string and n is the length of // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 // (exclusive) by dropping high bits. - var hash = 0; - for (var ii = 0; ii < string.length; ii++) { - hash = (31 * hash + string.charCodeAt(ii)) & HASH_MAX_VAL; + let hashed = 0; + for (let ii = 0; ii < string.length; ii++) { + hashed = (31 * hashed + string.charCodeAt(ii)) | 0; } - return hash; + return smi(hashed); +} + +function hashSymbol(sym) { + let hashed = symbolMap[sym]; + if (hashed !== undefined) { + return hashed; + } + + hashed = nextHash(); + + symbolMap[sym] = hashed; + + return hashed; } function hashJSObj(obj) { - var hash = obj[UID_HASH_KEY]; - if (hash) return hash; + let hashed; + if (usingWeakMap) { + hashed = weakMap.get(obj); + if (hashed !== undefined) { + return hashed; + } + } + + hashed = obj[UID_HASH_KEY]; + if (hashed !== undefined) { + return hashed; + } if (!canDefineProperty) { - hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; - if (hash) return hash; - - hash = getIENodeHash(obj); - if (hash) return hash; - } - - if (!canDefineProperty || Object.isExtensible(obj)) { - hash = ++objHashUID & HASH_MAX_VAL; - - if (canDefineProperty) { - Object.defineProperty(obj, UID_HASH_KEY, { - 'enumerable': false, - 'configurable': false, - 'writable': false, - 'value': hash - }); - } else if (propertyIsEnumerable && - obj.propertyIsEnumerable === propertyIsEnumerable) { - // Since we can't define a non-enumerable property on the object - // we'll hijack one of the less-used non-enumerable properties to - // save our hash on it. Since this is a function it will not show up in - // `JSON.stringify` which is what we want. - obj.propertyIsEnumerable = function() { - return propertyIsEnumerable.apply(this, arguments); - }; - obj.propertyIsEnumerable[UID_HASH_KEY] = hash; - } else if (obj.nodeType) { - // At this point we couldn't get the IE `uniqueID` to use as a hash - // and we couldn't use a non-enumerable property to exploit the - // dontEnum bug so we simply add the `UID_HASH_KEY` on the node - // itself. - obj[UID_HASH_KEY] = hash; - } else { - throw new Error('Unable to set a non-enumerable property on object.'); + hashed = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; + if (hashed !== undefined) { + return hashed; } - return hash; - } else { + + hashed = getIENodeHash(obj); + if (hashed !== undefined) { + return hashed; + } + } + + hashed = nextHash(); + + if (usingWeakMap) { + weakMap.set(obj, hashed); + } else if (isExtensible !== undefined && isExtensible(obj) === false) { throw new Error('Non-extensible objects are not allowed as keys.'); + } else if (canDefineProperty) { + Object.defineProperty(obj, UID_HASH_KEY, { + enumerable: false, + configurable: false, + writable: false, + value: hashed, + }); + } else if ( + obj.propertyIsEnumerable !== undefined && + obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable + ) { + // Since we can't define a non-enumerable property on the object + // we'll hijack one of the less-used non-enumerable properties to + // save our hash on it. Since this is a function it will not show up in + // `JSON.stringify` which is what we want. + obj.propertyIsEnumerable = function () { + return this.constructor.prototype.propertyIsEnumerable.apply( + this, + arguments + ); + }; + obj.propertyIsEnumerable[UID_HASH_KEY] = hashed; + } else if (obj.nodeType !== undefined) { + // At this point we couldn't get the IE `uniqueID` to use as a hash + // and we couldn't use a non-enumerable property to exploit the + // dontEnum bug so we simply add the `UID_HASH_KEY` on the node + // itself. + obj[UID_HASH_KEY] = hashed; + } else { + throw new Error('Unable to set a non-enumerable property on object.'); } + + return hashed; } -var propertyIsEnumerable = Object.prototype.propertyIsEnumerable; +// Get references to ES5 object methods. +const isExtensible = Object.isExtensible; // True if Object.defineProperty works as expected. IE8 fails this test. -var canDefineProperty = (function() { +const canDefineProperty = (function () { try { - Object.defineProperty({}, 'x', {}); + Object.defineProperty({}, '@', {}); return true; + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { return false; } -}()); +})(); // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it // and avoid memory leaks from the IE cloneNode bug. @@ -135,16 +201,37 @@ function getIENodeHash(node) { } } -var HASH_MAX_VAL = 0x7FFFFFFF; // 2^31 - 1 is an efficiently stored int +function valueOf(obj) { + return obj.valueOf !== defaultValueOf && typeof obj.valueOf === 'function' + ? obj.valueOf(obj) + : obj; +} + +function nextHash() { + const nextHash = ++_objHashUID; + if (_objHashUID & 0x40000000) { + _objHashUID = 0; + } + return nextHash; +} + +// If possible, use a WeakMap. +const usingWeakMap = typeof WeakMap === 'function'; +let weakMap; +if (usingWeakMap) { + weakMap = new WeakMap(); +} + +const symbolMap = Object.create(null); -var objHashUID = 0; +let _objHashUID = 0; -var UID_HASH_KEY = '__immutablehash__'; -if (typeof Symbol !== 'undefined') { +let UID_HASH_KEY = '__immutablehash__'; +if (typeof Symbol === 'function') { UID_HASH_KEY = Symbol(UID_HASH_KEY); } -var STRING_HASH_CACHE_MIN_STRLEN = 16; -var STRING_HASH_CACHE_MAX_SIZE = 255; -var STRING_HASH_CACHE_SIZE = 0; -var stringHashCache = {}; +const STRING_HASH_CACHE_MIN_STRLEN = 16; +const STRING_HASH_CACHE_MAX_SIZE = 255; +let STRING_HASH_CACHE_SIZE = 0; +let stringHashCache = {}; diff --git a/src/Immutable.js b/src/Immutable.js index 07b260342e..98945f762e 100644 --- a/src/Immutable.js +++ b/src/Immutable.js @@ -1,35 +1,103 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ +import { Seq } from './Seq'; +import { OrderedMap } from './OrderedMap'; +import { List } from './List'; +import { Map } from './Map'; +import { Stack } from './Stack'; +import { OrderedSet } from './OrderedSet'; +import { PairSorting } from './PairSorting'; +import { Set } from './Set'; +import { Record } from './Record'; +import { Range } from './Range'; +import { Repeat } from './Repeat'; +import { is } from './is'; +import { fromJS } from './fromJS'; -import "Sequence" -import "Map" -import "Vector" -import "Set" -import "OrderedMap" -import "Record" -import "Range" -import "Repeat" -import "is" -import "fromJS" -/* global Sequence, Map, Vector, Set, OrderedMap, Record, Range, Repeat, is, fromJS */ -/* exported Immutable */ +import isPlainObject from './utils/isPlainObj'; +// Functional predicates +import { isImmutable } from './predicates/isImmutable'; +import { isCollection } from './predicates/isCollection'; +import { isKeyed } from './predicates/isKeyed'; +import { isIndexed } from './predicates/isIndexed'; +import { isAssociative } from './predicates/isAssociative'; +import { isOrdered } from './predicates/isOrdered'; +import { isValueObject } from './predicates/isValueObject'; +import { isSeq } from './predicates/isSeq'; +import { isList } from './predicates/isList'; +import { isMap } from './predicates/isMap'; +import { isOrderedMap } from './predicates/isOrderedMap'; +import { isStack } from './predicates/isStack'; +import { isSet } from './predicates/isSet'; +import { isOrderedSet } from './predicates/isOrderedSet'; +import { isRecord } from './predicates/isRecord'; -var Immutable = { - Sequence: Sequence, - Map: Map, - Vector: Vector, - Set: Set, - OrderedMap: OrderedMap, - Record: Record, - Range: Range, - Repeat: Repeat, - is: is, - fromJS: fromJS, +import { Collection } from './CollectionImpl'; +import { hash } from './Hash'; + +// Functional read/write API +import { get } from './functional/get'; +import { getIn } from './functional/getIn'; +import { has } from './functional/has'; +import { hasIn } from './functional/hasIn'; +import { merge, mergeDeep, mergeWith, mergeDeepWith } from './functional/merge'; +import { remove } from './functional/remove'; +import { removeIn } from './functional/removeIn'; +import { set } from './functional/set'; +import { setIn } from './functional/setIn'; +import { update } from './functional/update'; +import { updateIn } from './functional/updateIn'; + +import { version } from '../package.json'; + +// Note: Iterable is deprecated +const Iterable = Collection; + +export { + version, + Collection, + Iterable, + Seq, + Map, + OrderedMap, + List, + Stack, + Set, + OrderedSet, + PairSorting, + Record, + Range, + Repeat, + is, + fromJS, + hash, + isImmutable, + isCollection, + isKeyed, + isIndexed, + isAssociative, + isOrdered, + isPlainObject, + isValueObject, + isSeq, + isList, + isMap, + isOrderedMap, + isStack, + isSet, + isOrderedSet, + isRecord, + get, + getIn, + has, + hasIn, + merge, + mergeDeep, + mergeWith, + mergeDeepWith, + remove, + removeIn, + set, + setIn, + update, + updateIn, }; diff --git a/src/Iterator.js b/src/Iterator.js index c86cf9d5c3..1954a3661c 100644 --- a/src/Iterator.js +++ b/src/Iterator.js @@ -1,28 +1,13 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ +export const ITERATE_KEYS = 0; +export const ITERATE_VALUES = 1; +export const ITERATE_ENTRIES = 2; -/* global Symbol */ -/* exported ITERATE_KEYS, ITERATE_VALUES, ITERATE_ENTRIES, ITERATOR_SYMBOL, - Iterator, iteratorValue, iteratorDone, iteratorMapper, - isIterable, isIterator, getIterator */ +const REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; +const FAUX_ITERATOR_SYMBOL = '@@iterator'; -var ITERATE_KEYS = 0; -var ITERATE_VALUES = 1; -var ITERATE_ENTRIES = 2; +export const ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; -var ITERATOR_SYMBOL = typeof Symbol !== 'undefined' ? - Symbol.iterator : - FAUX_ITERATOR_SYMBOL; - - -class Iterator { +export class Iterator { constructor(next) { this.next = next; } @@ -32,54 +17,68 @@ class Iterator { } } -var IteratorPrototype = Iterator.prototype; -IteratorPrototype.inspect = -IteratorPrototype.toSource = function () { return this.toString(); } -IteratorPrototype[ITERATOR_SYMBOL] = function () { +Iterator.KEYS = ITERATE_KEYS; +Iterator.VALUES = ITERATE_VALUES; +Iterator.ENTRIES = ITERATE_ENTRIES; + +Iterator.prototype.inspect = Iterator.prototype.toSource = function () { + return this.toString(); +}; +Iterator.prototype[ITERATOR_SYMBOL] = function () { return this; }; - -var iteratorResult = { value: undefined, done: false }; - -function iteratorValue(type, key, value) { - iteratorResult.value = type === 0 ? key : type === 1 ? value : [key, value]; - iteratorResult.done = false; +export function iteratorValue(type, k, v, iteratorResult) { + const value = + type === ITERATE_KEYS ? k : type === ITERATE_VALUES ? v : [k, v]; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + iteratorResult + ? (iteratorResult.value = value) + : (iteratorResult = { + value: value, + done: false, + }); return iteratorResult; } -function iteratorDone() { - iteratorResult.value = undefined; - iteratorResult.done = true; - return iteratorResult; +export function iteratorDone() { + return { value: undefined, done: true }; } -function iteratorMapper(iter, fn) { - var newIter = new Iterator(); - newIter.next = () => { - var step = iter.next(); - if (step.done) return step; - step.value = fn(step.value); - return step; - }; - return newIter; -} +export function hasIterator(maybeIterable) { + if (Array.isArray(maybeIterable)) { + // IE11 trick as it does not support `Symbol.iterator` + return true; + } -function isIterable(maybeIterable) { - return !!_iteratorFn(maybeIterable); + return !!getIteratorFn(maybeIterable); } -function isIterator(maybeIterator) { +export function isIterator(maybeIterator) { return maybeIterator && typeof maybeIterator.next === 'function'; } -function getIterator(iterable) { - var iteratorFn = _iteratorFn(iterable); +export function getIterator(iterable) { + const iteratorFn = getIteratorFn(iterable); + return iteratorFn && iteratorFn.call(iterable); +} + +function getIteratorFn(iterable) { + const iteratorFn = + iterable && + ((REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || + iterable[FAUX_ITERATOR_SYMBOL]); if (typeof iteratorFn === 'function') { - return iteratorFn.call(iterable); + return iteratorFn; } } -function _iteratorFn(iterable) { - return iterable && (iterable[ITERATOR_SYMBOL] || iterable[FAUX_ITERATOR_SYMBOL]); +export function isEntriesIterable(maybeIterable) { + const iteratorFn = getIteratorFn(maybeIterable); + return iteratorFn && iteratorFn === maybeIterable.entries; +} + +export function isKeysIterable(maybeIterable) { + const iteratorFn = getIteratorFn(maybeIterable); + return iteratorFn && iteratorFn === maybeIterable.keys; } diff --git a/src/List.js b/src/List.js new file mode 100644 index 0000000000..966b9e1b2c --- /dev/null +++ b/src/List.js @@ -0,0 +1,700 @@ +import { + DELETE, + SHIFT, + SIZE, + MASK, + OwnerID, + MakeRef, + SetRef, + wrapIndex, + wholeSlice, + resolveBegin, + resolveEnd, +} from './TrieUtils'; +import { IS_LIST_SYMBOL, isList } from './predicates/isList'; +import { IndexedCollection } from './Collection'; +import { hasIterator, Iterator, iteratorValue, iteratorDone } from './Iterator'; +import { setIn } from './methods/setIn'; +import { deleteIn } from './methods/deleteIn'; +import { update } from './methods/update'; +import { updateIn } from './methods/updateIn'; +import { mergeIn } from './methods/mergeIn'; +import { mergeDeepIn } from './methods/mergeDeepIn'; +import { withMutations } from './methods/withMutations'; +import { asMutable } from './methods/asMutable'; +import { asImmutable } from './methods/asImmutable'; +import { wasAltered } from './methods/wasAltered'; +import assertNotInfinite from './utils/assertNotInfinite'; + +export class List extends IndexedCollection { + // @pragma Construction + + constructor(value) { + const empty = emptyList(); + if (value === undefined || value === null) { + // eslint-disable-next-line no-constructor-return + return empty; + } + if (isList(value)) { + // eslint-disable-next-line no-constructor-return + return value; + } + const iter = IndexedCollection(value); + const size = iter.size; + if (size === 0) { + // eslint-disable-next-line no-constructor-return + return empty; + } + assertNotInfinite(size); + if (size > 0 && size < SIZE) { + // eslint-disable-next-line no-constructor-return + return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); + } + // eslint-disable-next-line no-constructor-return + return empty.withMutations((list) => { + list.setSize(size); + iter.forEach((v, i) => list.set(i, v)); + }); + } + + static of(/*...values*/) { + return this(arguments); + } + + toString() { + return this.__toString('List [', ']'); + } + + // @pragma Access + + get(index, notSetValue) { + index = wrapIndex(this, index); + if (index >= 0 && index < this.size) { + index += this._origin; + const node = listNodeFor(this, index); + return node && node.array[index & MASK]; + } + return notSetValue; + } + + // @pragma Modification + + set(index, value) { + return updateList(this, index, value); + } + + remove(index) { + return !this.has(index) + ? this + : index === 0 + ? this.shift() + : index === this.size - 1 + ? this.pop() + : this.splice(index, 1); + } + + insert(index, value) { + return this.splice(index, 0, value); + } + + clear() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = this._origin = this._capacity = 0; + this._level = SHIFT; + this._root = this._tail = this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyList(); + } + + push(/*...values*/) { + const values = arguments; + const oldSize = this.size; + return this.withMutations((list) => { + setListBounds(list, 0, oldSize + values.length); + for (let ii = 0; ii < values.length; ii++) { + list.set(oldSize + ii, values[ii]); + } + }); + } + + pop() { + return setListBounds(this, 0, -1); + } + + unshift(/*...values*/) { + const values = arguments; + return this.withMutations((list) => { + setListBounds(list, -values.length); + for (let ii = 0; ii < values.length; ii++) { + list.set(ii, values[ii]); + } + }); + } + + shift() { + return setListBounds(this, 1); + } + + shuffle(random = Math.random) { + return this.withMutations((mutable) => { + // implementation of the Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + let current = mutable.size; + let destination; + let tmp; + + while (current) { + destination = Math.floor(random() * current--); + + tmp = mutable.get(destination); + mutable.set(destination, mutable.get(current)); + mutable.set(current, tmp); + } + }); + } + + // @pragma Composition + + concat(/*...collections*/) { + const seqs = []; + for (let i = 0; i < arguments.length; i++) { + const argument = arguments[i]; + const seq = IndexedCollection( + typeof argument !== 'string' && hasIterator(argument) + ? argument + : [argument] + ); + if (seq.size !== 0) { + seqs.push(seq); + } + } + if (seqs.length === 0) { + return this; + } + if (this.size === 0 && !this.__ownerID && seqs.length === 1) { + return this.constructor(seqs[0]); + } + return this.withMutations((list) => { + seqs.forEach((seq) => seq.forEach((value) => list.push(value))); + }); + } + + setSize(size) { + return setListBounds(this, 0, size); + } + + map(mapper, context) { + return this.withMutations((list) => { + for (let i = 0; i < this.size; i++) { + list.set(i, mapper.call(context, list.get(i), i, this)); + } + }); + } + + // @pragma Iteration + + slice(begin, end) { + const size = this.size; + if (wholeSlice(begin, end, size)) { + return this; + } + return setListBounds( + this, + resolveBegin(begin, size), + resolveEnd(end, size) + ); + } + + __iterator(type, reverse) { + let index = reverse ? this.size : 0; + const values = iterateList(this, reverse); + return new Iterator(() => { + const value = values(); + return value === DONE + ? iteratorDone() + : iteratorValue(type, reverse ? --index : index++, value); + }); + } + + __iterate(fn, reverse) { + let index = reverse ? this.size : 0; + const values = iterateList(this, reverse); + let value; + while ((value = values()) !== DONE) { + if (fn(value, reverse ? --index : index++, this) === false) { + break; + } + } + return index; + } + + __ensureOwner(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + if (this.size === 0) { + return emptyList(); + } + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeList( + this._origin, + this._capacity, + this._level, + this._root, + this._tail, + ownerID, + this.__hash + ); + } +} + +List.isList = isList; + +const ListPrototype = List.prototype; +ListPrototype[IS_LIST_SYMBOL] = true; +ListPrototype[DELETE] = ListPrototype.remove; +ListPrototype.merge = ListPrototype.concat; +ListPrototype.setIn = setIn; +ListPrototype.deleteIn = ListPrototype.removeIn = deleteIn; +ListPrototype.update = update; +ListPrototype.updateIn = updateIn; +ListPrototype.mergeIn = mergeIn; +ListPrototype.mergeDeepIn = mergeDeepIn; +ListPrototype.withMutations = withMutations; +ListPrototype.wasAltered = wasAltered; +ListPrototype.asImmutable = asImmutable; +ListPrototype['@@transducer/init'] = ListPrototype.asMutable = asMutable; +ListPrototype['@@transducer/step'] = function (result, arr) { + return result.push(arr); +}; +ListPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +class VNode { + constructor(array, ownerID) { + this.array = array; + this.ownerID = ownerID; + } + + // TODO: seems like these methods are very similar + + removeBefore(ownerID, level, index) { + if ( + (index & ((1 << (level + SHIFT)) - 1)) === 0 || + this.array.length === 0 + ) { + return this; + } + const originIndex = (index >>> level) & MASK; + if (originIndex >= this.array.length) { + return new VNode([], ownerID); + } + const removingFirst = originIndex === 0; + let newChild; + if (level > 0) { + const oldChild = this.array[originIndex]; + newChild = + oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); + if (newChild === oldChild && removingFirst) { + return this; + } + } + if (removingFirst && !newChild) { + return this; + } + const editable = editableVNode(this, ownerID); + if (!removingFirst) { + for (let ii = 0; ii < originIndex; ii++) { + editable.array[ii] = undefined; + } + } + if (newChild) { + editable.array[originIndex] = newChild; + } + return editable; + } + + removeAfter(ownerID, level, index) { + if ( + index === (level ? 1 << (level + SHIFT) : SIZE) || + this.array.length === 0 + ) { + return this; + } + const sizeIndex = ((index - 1) >>> level) & MASK; + if (sizeIndex >= this.array.length) { + return this; + } + + let newChild; + if (level > 0) { + const oldChild = this.array[sizeIndex]; + newChild = + oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); + if (newChild === oldChild && sizeIndex === this.array.length - 1) { + return this; + } + } + + const editable = editableVNode(this, ownerID); + editable.array.splice(sizeIndex + 1); + if (newChild) { + editable.array[sizeIndex] = newChild; + } + return editable; + } +} + +const DONE = {}; + +function iterateList(list, reverse) { + const left = list._origin; + const right = list._capacity; + const tailPos = getTailOffset(right); + const tail = list._tail; + + return iterateNodeOrLeaf(list._root, list._level, 0); + + function iterateNodeOrLeaf(node, level, offset) { + return level === 0 + ? iterateLeaf(node, offset) + : iterateNode(node, level, offset); + } + + function iterateLeaf(node, offset) { + const array = offset === tailPos ? tail && tail.array : node && node.array; + let from = offset > left ? 0 : left - offset; + let to = right - offset; + if (to > SIZE) { + to = SIZE; + } + return () => { + if (from === to) { + return DONE; + } + const idx = reverse ? --to : from++; + return array && array[idx]; + }; + } + + function iterateNode(node, level, offset) { + let values; + const array = node && node.array; + let from = offset > left ? 0 : (left - offset) >> level; + let to = ((right - offset) >> level) + 1; + if (to > SIZE) { + to = SIZE; + } + return () => { + while (true) { + if (values) { + const value = values(); + if (value !== DONE) { + return value; + } + values = null; + } + if (from === to) { + return DONE; + } + const idx = reverse ? --to : from++; + values = iterateNodeOrLeaf( + array && array[idx], + level - SHIFT, + offset + (idx << level) + ); + } + }; + } +} + +function makeList(origin, capacity, level, root, tail, ownerID, hash) { + const list = Object.create(ListPrototype); + list.size = capacity - origin; + list._origin = origin; + list._capacity = capacity; + list._level = level; + list._root = root; + list._tail = tail; + list.__ownerID = ownerID; + list.__hash = hash; + list.__altered = false; + return list; +} + +export function emptyList() { + return makeList(0, 0, SHIFT); +} + +function updateList(list, index, value) { + index = wrapIndex(list, index); + + if (index !== index) { + return list; + } + + if (index >= list.size || index < 0) { + return list.withMutations((list) => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + index < 0 + ? setListBounds(list, index).set(0, value) + : setListBounds(list, 0, index + 1).set(index, value); + }); + } + + index += list._origin; + + let newTail = list._tail; + let newRoot = list._root; + const didAlter = MakeRef(); + if (index >= getTailOffset(list._capacity)) { + newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); + } else { + newRoot = updateVNode( + newRoot, + list.__ownerID, + list._level, + index, + value, + didAlter + ); + } + + if (!didAlter.value) { + return list; + } + + if (list.__ownerID) { + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; + } + return makeList(list._origin, list._capacity, list._level, newRoot, newTail); +} + +function updateVNode(node, ownerID, level, index, value, didAlter) { + const idx = (index >>> level) & MASK; + const nodeHas = node && idx < node.array.length; + if (!nodeHas && value === undefined) { + return node; + } + + let newNode; + + if (level > 0) { + const lowerNode = node && node.array[idx]; + const newLowerNode = updateVNode( + lowerNode, + ownerID, + level - SHIFT, + index, + value, + didAlter + ); + if (newLowerNode === lowerNode) { + return node; + } + newNode = editableVNode(node, ownerID); + newNode.array[idx] = newLowerNode; + return newNode; + } + + if (nodeHas && node.array[idx] === value) { + return node; + } + + if (didAlter) { + SetRef(didAlter); + } + + newNode = editableVNode(node, ownerID); + if (value === undefined && idx === newNode.array.length - 1) { + newNode.array.pop(); + } else { + newNode.array[idx] = value; + } + return newNode; +} + +function editableVNode(node, ownerID) { + if (ownerID && node && ownerID === node.ownerID) { + return node; + } + return new VNode(node ? node.array.slice() : [], ownerID); +} + +function listNodeFor(list, rawIndex) { + if (rawIndex >= getTailOffset(list._capacity)) { + return list._tail; + } + if (rawIndex < 1 << (list._level + SHIFT)) { + let node = list._root; + let level = list._level; + while (node && level > 0) { + node = node.array[(rawIndex >>> level) & MASK]; + level -= SHIFT; + } + return node; + } +} + +function setListBounds(list, begin, end) { + // Sanitize begin & end using this shorthand for ToInt32(argument) + // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 + if (begin !== undefined) { + begin |= 0; + } + if (end !== undefined) { + end |= 0; + } + const owner = list.__ownerID || new OwnerID(); + let oldOrigin = list._origin; + let oldCapacity = list._capacity; + let newOrigin = oldOrigin + begin; + let newCapacity = + end === undefined + ? oldCapacity + : end < 0 + ? oldCapacity + end + : oldOrigin + end; + if (newOrigin === oldOrigin && newCapacity === oldCapacity) { + return list; + } + + // If it's going to end after it starts, it's empty. + if (newOrigin >= newCapacity) { + return list.clear(); + } + + let newLevel = list._level; + let newRoot = list._root; + + // New origin might need creating a higher root. + let offsetShift = 0; + while (newOrigin + offsetShift < 0) { + newRoot = new VNode( + newRoot && newRoot.array.length ? [undefined, newRoot] : [], + owner + ); + newLevel += SHIFT; + offsetShift += 1 << newLevel; + } + if (offsetShift) { + newOrigin += offsetShift; + oldOrigin += offsetShift; + newCapacity += offsetShift; + oldCapacity += offsetShift; + } + + const oldTailOffset = getTailOffset(oldCapacity); + const newTailOffset = getTailOffset(newCapacity); + + // New size might need creating a higher root. + while (newTailOffset >= 1 << (newLevel + SHIFT)) { + newRoot = new VNode( + newRoot && newRoot.array.length ? [newRoot] : [], + owner + ); + newLevel += SHIFT; + } + + // Locate or create the new tail. + const oldTail = list._tail; + let newTail = + newTailOffset < oldTailOffset + ? listNodeFor(list, newCapacity - 1) + : newTailOffset > oldTailOffset + ? new VNode([], owner) + : oldTail; + + // Merge Tail into tree. + if ( + oldTail && + newTailOffset > oldTailOffset && + newOrigin < oldCapacity && + oldTail.array.length + ) { + newRoot = editableVNode(newRoot, owner); + let node = newRoot; + for (let level = newLevel; level > SHIFT; level -= SHIFT) { + const idx = (oldTailOffset >>> level) & MASK; + node = node.array[idx] = editableVNode(node.array[idx], owner); + } + node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; + } + + // If the size has been reduced, there's a chance the tail needs to be trimmed. + if (newCapacity < oldCapacity) { + newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); + } + + // If the new origin is within the tail, then we do not need a root. + if (newOrigin >= newTailOffset) { + newOrigin -= newTailOffset; + newCapacity -= newTailOffset; + newLevel = SHIFT; + newRoot = null; + newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); + + // Otherwise, if the root has been trimmed, garbage collect. + } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { + offsetShift = 0; + + // Identify the new top root node of the subtree of the old root. + while (newRoot) { + const beginIndex = (newOrigin >>> newLevel) & MASK; + if ((beginIndex !== newTailOffset >>> newLevel) & MASK) { + break; + } + if (beginIndex) { + offsetShift += (1 << newLevel) * beginIndex; + } + newLevel -= SHIFT; + newRoot = newRoot.array[beginIndex]; + } + + // Trim the new sides of the new root. + if (newRoot && newOrigin > oldOrigin) { + newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); + } + if (newRoot && newTailOffset < oldTailOffset) { + newRoot = newRoot.removeAfter( + owner, + newLevel, + newTailOffset - offsetShift + ); + } + if (offsetShift) { + newOrigin -= offsetShift; + newCapacity -= offsetShift; + } + } + + if (list.__ownerID) { + list.size = newCapacity - newOrigin; + list._origin = newOrigin; + list._capacity = newCapacity; + list._level = newLevel; + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; + } + return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); +} + +function getTailOffset(size) { + return size < SIZE ? 0 : ((size - 1) >>> SHIFT) << SHIFT; +} diff --git a/src/Map.js b/src/Map.js index a88cb8a04f..672e70cac4 100644 --- a/src/Map.js +++ b/src/Map.js @@ -1,41 +1,51 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Sequence" -import "is" -import "invariant" -import "Cursor" -import "TrieUtils" -import "Hash" -import "Iterator" -/* global Sequence, IndexedSequence, is, invariant, Cursor, - DELETE, SHIFT, SIZE, MASK, NOT_SET, CHANGE_LENGTH, DID_ALTER, OwnerID, - MakeRef, SetRef, arrCopy, hash, - Iterator, iteratorValue, iteratorDone */ -/* exported Map, MapPrototype */ - - -class Map extends Sequence { - +import { is } from './is'; +import { Collection, KeyedCollection } from './Collection'; +import { IS_MAP_SYMBOL, isMap } from './predicates/isMap'; +import { isOrdered } from './predicates/isOrdered'; +import { + DELETE, + SHIFT, + SIZE, + MASK, + NOT_SET, + OwnerID, + MakeRef, + SetRef, +} from './TrieUtils'; +import { hash } from './Hash'; +import { Iterator, iteratorValue, iteratorDone } from './Iterator'; +import { sortFactory } from './Operations'; +import arrCopy from './utils/arrCopy'; +import assertNotInfinite from './utils/assertNotInfinite'; +import { setIn } from './methods/setIn'; +import { deleteIn } from './methods/deleteIn'; +import { update } from './methods/update'; +import { updateIn } from './methods/updateIn'; +import { merge, mergeWith } from './methods/merge'; +import { mergeDeep, mergeDeepWith } from './methods/mergeDeep'; +import { mergeIn } from './methods/mergeIn'; +import { mergeDeepIn } from './methods/mergeDeepIn'; +import { withMutations } from './methods/withMutations'; +import { asMutable } from './methods/asMutable'; +import { asImmutable } from './methods/asImmutable'; +import { wasAltered } from './methods/wasAltered'; + +import { OrderedMap } from './OrderedMap'; + +export class Map extends KeyedCollection { // @pragma Construction - constructor(sequence) { - var map = Map.empty(); - return sequence ? - sequence.constructor === Map ? - sequence : - map.merge(sequence) : - map; - } - - static empty() { - return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyMap() + : isMap(value) && !isOrdered(value) + ? value + : emptyMap().withMutations((map) => { + const iter = KeyedCollection(value); + assertNotInfinite(iter.size); + iter.forEach((v, k) => map.set(k, v)); + }); } toString() { @@ -45,9 +55,9 @@ class Map extends Sequence { // @pragma Access get(k, notSetValue) { - return this._root ? - this._root.get(0, hash(k), k, notSetValue) : - notSetValue; + return this._root + ? this._root.get(0, undefined, k, notSetValue) + : notSetValue; } // @pragma Modification @@ -60,161 +70,248 @@ class Map extends Sequence { return updateMap(this, k, NOT_SET); } - update(k, notSetValue, updater) { - return arguments.length === 1 ? - this.updateIn([], null, k) : - this.updateIn([k], notSetValue, updater); - } + deleteAll(keys) { + const collection = Collection(keys); - updateIn(keyPath, notSetValue, updater) { - if (!updater) { - [updater, notSetValue] = [notSetValue, updater]; + if (collection.size === 0) { + return this; } - return updateInDeepMap(this, keyPath, notSetValue, updater, 0); + + return this.withMutations((map) => { + collection.forEach((key) => map.remove(key)); + }); } clear() { - if (this.length === 0) { + if (this.size === 0) { return this; } if (this.__ownerID) { - this.length = 0; + this.size = 0; this._root = null; this.__hash = undefined; this.__altered = true; return this; } - return Map.empty(); + return emptyMap(); } // @pragma Composition - merge(/*...seqs*/) { - return mergeIntoMapWith(this, null, arguments); - } - - mergeWith(merger, ...seqs) { - return mergeIntoMapWith(this, merger, seqs); + sort(comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator)); } - mergeDeep(/*...seqs*/) { - return mergeIntoMapWith(this, deepMerger(null), arguments); + sortBy(mapper, comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator, mapper)); } - mergeDeepWith(merger, ...seqs) { - return mergeIntoMapWith(this, deepMerger(merger), seqs); - } - - cursor(keyPath, onChange) { - if (!onChange && typeof keyPath === 'function') { - onChange = keyPath; - keyPath = []; - } else if (arguments.length === 0) { - keyPath = []; - } else if (!Array.isArray(keyPath)) { - keyPath = [keyPath]; - } - return new Cursor(this, keyPath, onChange); + map(mapper, context) { + return this.withMutations((map) => { + map.forEach((value, key) => { + map.set(key, mapper.call(context, value, key, this)); + }); + }); } // @pragma Mutability - withMutations(fn) { - var mutable = this.asMutable(); - fn(mutable); - return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; - } - - asMutable() { - return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); - } - - asImmutable() { - return this.__ensureOwner(); - } - - wasAltered() { - return this.__altered; - } - __iterator(type, reverse) { return new MapIterator(this, type, reverse); } __iterate(fn, reverse) { - var iterations = 0; - this._root && this._root.iterate(entry => { - iterations++; - return fn(entry[1], entry[0], this); - }, reverse); + let iterations = 0; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + this._root && + this._root.iterate((entry) => { + iterations++; + return fn(entry[1], entry[0], this); + }, reverse); return iterations; } - __deepEquals(other) { - // Using NOT_SET here ensures that a missing key is not interpretted as an - // existing key set to be null/undefined. - var self = this; - return other.every((v, k) => is(self.get(k, NOT_SET), v)); - } - __ensureOwner(ownerID) { if (ownerID === this.__ownerID) { return this; } if (!ownerID) { + if (this.size === 0) { + return emptyMap(); + } this.__ownerID = ownerID; this.__altered = false; return this; } - return makeMap(this.length, this._root, ownerID, this.__hash); + return makeMap(this.size, this._root, ownerID, this.__hash); } } -var MapPrototype = Map.prototype; +Map.isMap = isMap; + +const MapPrototype = Map.prototype; +MapPrototype[IS_MAP_SYMBOL] = true; MapPrototype[DELETE] = MapPrototype.remove; +MapPrototype.removeAll = MapPrototype.deleteAll; +MapPrototype.setIn = setIn; +MapPrototype.removeIn = MapPrototype.deleteIn = deleteIn; +MapPrototype.update = update; +MapPrototype.updateIn = updateIn; +MapPrototype.merge = MapPrototype.concat = merge; +MapPrototype.mergeWith = mergeWith; +MapPrototype.mergeDeep = mergeDeep; +MapPrototype.mergeDeepWith = mergeDeepWith; +MapPrototype.mergeIn = mergeIn; +MapPrototype.mergeDeepIn = mergeDeepIn; +MapPrototype.withMutations = withMutations; +MapPrototype.wasAltered = wasAltered; +MapPrototype.asImmutable = asImmutable; +MapPrototype['@@transducer/init'] = MapPrototype.asMutable = asMutable; +MapPrototype['@@transducer/step'] = function (result, arr) { + return result.set(arr[0], arr[1]); +}; +MapPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +// #pragma Trie Nodes + +class ArrayMapNode { + constructor(ownerID, entries) { + this.ownerID = ownerID; + this.entries = entries; + } -Map.from = Map; + get(shift, keyHash, key, notSetValue) { + const entries = this.entries; + for (let ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } + } + return notSetValue; + } + update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + const removed = value === NOT_SET; -class BitmapIndexedNode { + const entries = this.entries; + let idx = 0; + const len = entries.length; + for (; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + const exists = idx < len; + if (exists ? entries[idx][1] === value : removed) { + return this; + } + + SetRef(didAlter); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + (removed || !exists) && SetRef(didChangeSize); + + if (removed && entries.length === 1) { + return; // undefined + } + + if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { + return createNodes(ownerID, entries, key, value); + } + + const isEditable = ownerID && ownerID === this.ownerID; + const newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + idx === len - 1 + ? newEntries.pop() + : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new ArrayMapNode(ownerID, newEntries); + } +} + +class BitmapIndexedNode { constructor(ownerID, bitmap, nodes) { this.ownerID = ownerID; this.bitmap = bitmap; this.nodes = nodes; } - get(shift, hash, key, notSetValue) { - var bit = (1 << ((shift === 0 ? hash : hash >>> shift) & MASK)); - var bitmap = this.bitmap; - return (bitmap & bit) === 0 ? notSetValue : - this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, hash, key, notSetValue); + get(shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + const bit = 1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK); + const bitmap = this.bitmap; + return (bitmap & bit) === 0 + ? notSetValue + : this.nodes[popCount(bitmap & (bit - 1))].get( + shift + SHIFT, + keyHash, + key, + notSetValue + ); } - update(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var hashFrag = (shift === 0 ? hash : hash >>> shift) & MASK; - var bit = 1 << hashFrag; - var bitmap = this.bitmap; - var exists = (bitmap & bit) !== 0; + update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + const keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + const bit = 1 << keyHashFrag; + const bitmap = this.bitmap; + const exists = (bitmap & bit) !== 0; if (!exists && value === NOT_SET) { return this; } - var idx = popCount(bitmap & (bit - 1)); - var nodes = this.nodes; - var node = exists ? nodes[idx] : null; - var newNode = updateNode(node, ownerID, shift + SHIFT, hash, key, value, didChangeLength, didAlter); + const idx = popCount(bitmap & (bit - 1)); + const nodes = this.nodes; + const node = exists ? nodes[idx] : undefined; + const newNode = updateNode( + node, + ownerID, + shift + SHIFT, + keyHash, + key, + value, + didChangeSize, + didAlter + ); if (newNode === node) { return this; } - if (!exists && newNode && nodes.length >= MAX_BITMAP_SIZE) { - return expandNodes(ownerID, nodes, bitmap, hashFrag, newNode); + if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { + return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); } - if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { + if ( + exists && + !newNode && + nodes.length === 2 && + isLeafNode(nodes[idx ^ 1]) + ) { return nodes[idx ^ 1]; } @@ -222,12 +319,13 @@ class BitmapIndexedNode { return newNode; } - var isEditable = ownerID && ownerID === this.ownerID; - var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; - var newNodes = exists ? newNode ? - setIn(nodes, idx, newNode, isEditable) : - spliceOut(nodes, idx, isEditable) : - spliceIn(nodes, idx, newNode, isEditable); + const isEditable = ownerID && ownerID === this.ownerID; + const newBitmap = exists ? (newNode ? bitmap : bitmap ^ bit) : bitmap | bit; + const newNodes = exists + ? newNode + ? setAt(nodes, idx, newNode, isEditable) + : spliceOut(nodes, idx, isEditable) + : spliceIn(nodes, idx, newNode, isEditable); if (isEditable) { this.bitmap = newBitmap; @@ -237,58 +335,65 @@ class BitmapIndexedNode { return new BitmapIndexedNode(ownerID, newBitmap, newNodes); } - - iterate(fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - if (nodes[reverse ? maxIndex - ii : ii].iterate(fn, reverse) === false) { - return false; - } - } - } } -class ArrayNode { - +class HashArrayMapNode { constructor(ownerID, count, nodes) { this.ownerID = ownerID; this.count = count; this.nodes = nodes; } - get(shift, hash, key, notSetValue) { - var idx = (shift === 0 ? hash : hash >>> shift) & MASK; - var node = this.nodes[idx]; - return node ? node.get(shift + SHIFT, hash, key, notSetValue) : notSetValue; + get(shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + const idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + const node = this.nodes[idx]; + return node + ? node.get(shift + SHIFT, keyHash, key, notSetValue) + : notSetValue; } - update(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var idx = (shift === 0 ? hash : hash >>> shift) & MASK; - var removed = value === NOT_SET; - var nodes = this.nodes; - var node = nodes[idx]; + update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + const idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + const removed = value === NOT_SET; + const nodes = this.nodes; + const node = nodes[idx]; if (removed && !node) { return this; } - var newNode = updateNode(node, ownerID, shift + SHIFT, hash, key, value, didChangeLength, didAlter); + const newNode = updateNode( + node, + ownerID, + shift + SHIFT, + keyHash, + key, + value, + didChangeSize, + didAlter + ); if (newNode === node) { return this; } - var newCount = this.count; + let newCount = this.count; if (!node) { newCount++; } else if (!newNode) { newCount--; - if (newCount < MIN_ARRAY_SIZE) { + if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { return packNodes(ownerID, nodes, newCount, idx); } } - var isEditable = ownerID && ownerID === this.ownerID; - var newNodes = setIn(nodes, idx, newNode, isEditable); + const isEditable = ownerID && ownerID === this.ownerID; + const newNodes = setAt(nodes, idx, newNode, isEditable); if (isEditable) { this.count = newCount; @@ -296,31 +401,20 @@ class ArrayNode { return this; } - return new ArrayNode(ownerID, newCount, newNodes); - } - - iterate(fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - var node = nodes[reverse ? maxIndex - ii : ii]; - if (node && node.iterate(fn, reverse) === false) { - return false; - } - } + return new HashArrayMapNode(ownerID, newCount, newNodes); } } class HashCollisionNode { - - constructor(ownerID, hash, entries) { + constructor(ownerID, keyHash, entries) { this.ownerID = ownerID; - this.hash = hash; + this.keyHash = keyHash; this.entries = entries; } - get(shift, hash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, len = entries.length; ii < len; ii++) { + get(shift, keyHash, key, notSetValue) { + const entries = this.entries; + for (let ii = 0, len = entries.length; ii < len; ii++) { if (is(key, entries[ii][0])) { return entries[ii][1]; } @@ -328,44 +422,53 @@ class HashCollisionNode { return notSetValue; } - update(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var removed = value === NOT_SET; + update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } - if (hash !== this.hash) { + const removed = value === NOT_SET; + + if (keyHash !== this.keyHash) { if (removed) { return this; } SetRef(didAlter); - SetRef(didChangeLength); - return mergeIntoNode(this, ownerID, shift, hash, [key, value]); + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); } - var entries = this.entries; - var idx = 0; - for (var len = entries.length; idx < len; idx++) { + const entries = this.entries; + let idx = 0; + const len = entries.length; + for (; idx < len; idx++) { if (is(key, entries[idx][0])) { break; } } - var exists = idx < len; + const exists = idx < len; - if (removed && !exists) { + if (exists ? entries[idx][1] === value : removed) { return this; } SetRef(didAlter); - (removed || !exists) && SetRef(didChangeLength); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + (removed || !exists) && SetRef(didChangeSize); if (removed && len === 2) { - return new ValueNode(ownerID, this.hash, entries[idx ^ 1]); + return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); } - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); + const isEditable = ownerID && ownerID === this.ownerID; + const newEntries = isEditable ? entries : arrCopy(entries); if (exists) { if (removed) { - idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + idx === len - 1 + ? newEntries.pop() + : (newEntries[idx] = newEntries.pop()); } else { newEntries[idx] = [key, value]; } @@ -378,34 +481,24 @@ class HashCollisionNode { return this; } - return new HashCollisionNode(ownerID, this.hash, newEntries); - } - - iterate(fn, reverse) { - var entries = this.entries; - for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { - if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { - return false; - } - } + return new HashCollisionNode(ownerID, this.keyHash, newEntries); } } class ValueNode { - - constructor(ownerID, hash, entry) { + constructor(ownerID, keyHash, entry) { this.ownerID = ownerID; - this.hash = hash; + this.keyHash = keyHash; this.entry = entry; } - get(shift, hash, key, notSetValue) { + get(shift, keyHash, key, notSetValue) { return is(key, this.entry[0]) ? this.entry[1] : notSetValue; } - update(ownerID, shift, hash, key, value, didChangeLength, didAlter) { - var removed = value === NOT_SET; - var keyMatch = is(key, this.entry[0]); + update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + const removed = value === NOT_SET; + const keyMatch = is(key, this.entry[0]); if (keyMatch ? value === this.entry[1] : removed) { return this; } @@ -413,8 +506,8 @@ class ValueNode { SetRef(didAlter); if (removed) { - SetRef(didChangeLength); - return null; + SetRef(didChangeSize); + return; // undefined } if (keyMatch) { @@ -422,20 +515,43 @@ class ValueNode { this.entry[1] = value; return this; } - return new ValueNode(ownerID, hash, [key, value]); + return new ValueNode(ownerID, this.keyHash, [key, value]); } - SetRef(didChangeLength); - return mergeIntoNode(this, ownerID, shift, hash, [key, value]); - } - - iterate(fn) { - return fn(this.entry); + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); } } -class MapIterator extends Iterator { +// #pragma Iterators + +ArrayMapNode.prototype.iterate = HashCollisionNode.prototype.iterate = + function (fn, reverse) { + const entries = this.entries; + for (let ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { + if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { + return false; + } + } + }; +BitmapIndexedNode.prototype.iterate = HashArrayMapNode.prototype.iterate = + function (fn, reverse) { + const nodes = this.nodes; + for (let ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { + const node = nodes[reverse ? maxIndex - ii : ii]; + if (node && node.iterate(fn, reverse) === false) { + return false; + } + } + }; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +ValueNode.prototype.iterate = function (fn, reverse) { + return fn(this.entry); +}; + +class MapIterator extends Iterator { constructor(map, type, reverse) { this._type = type; this._reverse = reverse; @@ -443,12 +559,12 @@ class MapIterator extends Iterator { } next() { - var type = this._type; - var stack = this._stack; + const type = this._type; + let stack = this._stack; while (stack) { - var node = stack.node; - var index = stack.index++; - var maxIndex; + const node = stack.node; + const index = stack.index++; + let maxIndex; if (node.entry) { if (index === 0) { return mapIteratorValue(type, node.entry); @@ -456,12 +572,15 @@ class MapIterator extends Iterator { } else if (node.entries) { maxIndex = node.entries.length - 1; if (index <= maxIndex) { - return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); + return mapIteratorValue( + type, + node.entries[this._reverse ? maxIndex - index : index] + ); } } else { maxIndex = node.nodes.length - 1; if (index <= maxIndex) { - var subNode = node.nodes[this._reverse ? maxIndex - index : index]; + const subNode = node.nodes[this._reverse ? maxIndex - index : index]; if (subNode) { if (subNode.entry) { return mapIteratorValue(type, subNode.entry); @@ -485,13 +604,13 @@ function mapIteratorFrame(node, prev) { return { node: node, index: 0, - __prev: prev + __prev: prev, }; } -function makeMap(length, root, ownerID, hash) { - var map = Object.create(MapPrototype); - map.length = length; +function makeMap(size, root, ownerID, hash) { + const map = Object.create(MapPrototype); + map.size = size; map._root = root; map.__ownerID = ownerID; map.__hash = hash; @@ -499,63 +618,120 @@ function makeMap(length, root, ownerID, hash) { return map; } +let EMPTY_MAP; +export function emptyMap() { + return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); +} + function updateMap(map, k, v) { - var didChangeLength = MakeRef(CHANGE_LENGTH); - var didAlter = MakeRef(DID_ALTER); - var newRoot = updateNode(map._root, map.__ownerID, 0, hash(k), k, v, didChangeLength, didAlter); - if (!didAlter.value) { - return map; + let newRoot; + let newSize; + if (!map._root) { + if (v === NOT_SET) { + return map; + } + newSize = 1; + newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); + } else { + const didChangeSize = MakeRef(); + const didAlter = MakeRef(); + newRoot = updateNode( + map._root, + map.__ownerID, + 0, + undefined, + k, + v, + didChangeSize, + didAlter + ); + if (!didAlter.value) { + return map; + } + newSize = map.size + (didChangeSize.value ? (v === NOT_SET ? -1 : 1) : 0); } - var newLength = map.length + (didChangeLength.value ? v === NOT_SET ? -1 : 1 : 0); if (map.__ownerID) { - map.length = newLength; + map.size = newSize; map._root = newRoot; map.__hash = undefined; map.__altered = true; return map; } - return newRoot ? makeMap(newLength, newRoot) : Map.empty(); + return newRoot ? makeMap(newSize, newRoot) : emptyMap(); } -function updateNode(node, ownerID, shift, hash, key, value, didChangeLength, didAlter) { +function updateNode( + node, + ownerID, + shift, + keyHash, + key, + value, + didChangeSize, + didAlter +) { if (!node) { if (value === NOT_SET) { return node; } SetRef(didAlter); - SetRef(didChangeLength); - return new ValueNode(ownerID, hash, [key, value]); - } - return node.update(ownerID, shift, hash, key, value, didChangeLength, didAlter); + SetRef(didChangeSize); + return new ValueNode(ownerID, keyHash, [key, value]); + } + return node.update( + ownerID, + shift, + keyHash, + key, + value, + didChangeSize, + didAlter + ); } function isLeafNode(node) { - return node.constructor === ValueNode || node.constructor === HashCollisionNode; + return ( + node.constructor === ValueNode || node.constructor === HashCollisionNode + ); } -function mergeIntoNode(node, ownerID, shift, hash, entry) { - if (node.hash === hash) { - return new HashCollisionNode(ownerID, hash, [node.entry, entry]); +function mergeIntoNode(node, ownerID, shift, keyHash, entry) { + if (node.keyHash === keyHash) { + return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); } - var idx1 = (shift === 0 ? node.hash : node.hash >>> shift) & MASK; - var idx2 = (shift === 0 ? hash : hash >>> shift) & MASK; + const idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; + const idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var newNode; - var nodes = idx1 === idx2 ? - [mergeIntoNode(node, ownerID, shift + SHIFT, hash, entry)] : - ((newNode = new ValueNode(ownerID, hash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); + let newNode; + const nodes = + idx1 === idx2 + ? [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] + : ((newNode = new ValueNode(ownerID, keyHash, entry)), + idx1 < idx2 ? [node, newNode] : [newNode, node]); return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); } +function createNodes(ownerID, entries, key, value) { + if (!ownerID) { + ownerID = new OwnerID(); + } + let node = new ValueNode(ownerID, hash(key), [key, value]); + for (let ii = 0; ii < entries.length; ii++) { + const entry = entries[ii]; + node = node.update(ownerID, 0, undefined, entry[0], entry[1]); + } + return node; +} + function packNodes(ownerID, nodes, count, excluding) { - var bitmap = 0; - var packedII = 0; - var packedNodes = new Array(count); - for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { - var node = nodes[ii]; - if (node != null && ii !== excluding) { + let bitmap = 0; + let packedII = 0; + const packedNodes = new Array(count); + for (let ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { + const node = nodes[ii]; + if (node !== undefined && ii !== excluding) { bitmap |= bit; packedNodes[packedII++] = node; } @@ -564,95 +740,39 @@ function packNodes(ownerID, nodes, count, excluding) { } function expandNodes(ownerID, nodes, bitmap, including, node) { - var count = 0; - var expandedNodes = new Array(SIZE); - for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { - expandedNodes[ii] = bitmap & 1 ? nodes[count++] : null; + let count = 0; + const expandedNodes = new Array(SIZE); + for (let ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { + expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; } expandedNodes[including] = node; - return new ArrayNode(ownerID, count + 1, expandedNodes); -} - -function mergeIntoMapWith(map, merger, iterables) { - var seqs = []; - for (var ii = 0; ii < iterables.length; ii++) { - var seq = iterables[ii]; - if (!(seq instanceof Sequence)) { - seq = Sequence(seq); - if (seq instanceof IndexedSequence) { - seq = seq.fromEntrySeq(); - } - } - seq && seqs.push(seq); - } - return mergeIntoCollectionWith(map, merger, seqs); -} - -function deepMerger(merger) { - return (existing, value) => - existing && existing.mergeDeepWith ? - existing.mergeDeepWith(merger, value) : - merger ? merger(existing, value) : value; -} - -function mergeIntoCollectionWith(collection, merger, seqs) { - if (seqs.length === 0) { - return collection; - } - return collection.withMutations(collection => { - var mergeIntoMap = merger ? - (value, key) => { - var existing = collection.get(key, NOT_SET); - collection.set( - key, existing === NOT_SET ? value : merger(existing, value) - ); - } : - (value, key) => { - collection.set(key, value); - } - for (var ii = 0; ii < seqs.length; ii++) { - seqs[ii].forEach(mergeIntoMap); - } - }); -} - -function updateInDeepMap(collection, keyPath, notSetValue, updater, pathOffset) { - var pathLen = keyPath.length; - if (pathOffset === pathLen) { - return updater(collection); - } - invariant(collection.set, 'updateIn with invalid keyPath'); - var notSet = pathOffset === pathLen - 1 ? notSetValue : Map.empty(); - var key = keyPath[pathOffset]; - var existing = collection.get(key, notSet); - var value = updateInDeepMap(existing, keyPath, notSetValue, updater, pathOffset + 1); - return value === existing ? collection : collection.set(key, value); + return new HashArrayMapNode(ownerID, count + 1, expandedNodes); } function popCount(x) { - x = x - ((x >> 1) & 0x55555555); + x -= (x >> 1) & 0x55555555; x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; - x = x + (x >> 8); - x = x + (x >> 16); + x += x >> 8; + x += x >> 16; return x & 0x7f; } -function setIn(array, idx, val, canEdit) { - var newArray = canEdit ? array : arrCopy(array); +function setAt(array, idx, val, canEdit) { + const newArray = canEdit ? array : arrCopy(array); newArray[idx] = val; return newArray; } function spliceIn(array, idx, val, canEdit) { - var newLen = array.length + 1; + const newLen = array.length + 1; if (canEdit && idx + 1 === newLen) { array[idx] = val; return array; } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { + const newArray = new Array(newLen); + let after = 0; + for (let ii = 0; ii < newLen; ii++) { if (ii === idx) { newArray[ii] = val; after = -1; @@ -664,14 +784,14 @@ function spliceIn(array, idx, val, canEdit) { } function spliceOut(array, idx, canEdit) { - var newLen = array.length - 1; + const newLen = array.length - 1; if (canEdit && idx === newLen) { array.pop(); return array; } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { + const newArray = new Array(newLen); + let after = 0; + for (let ii = 0; ii < newLen; ii++) { if (ii === idx) { after = 1; } @@ -680,7 +800,6 @@ function spliceOut(array, idx, canEdit) { return newArray; } -var MAX_BITMAP_SIZE = SIZE / 2; -var MIN_ARRAY_SIZE = SIZE / 4; - -var EMPTY_MAP; +const MAX_ARRAY_MAP_SIZE = SIZE / 4; +const MAX_BITMAP_INDEXED_SIZE = SIZE / 2; +const MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; diff --git a/src/Math.js b/src/Math.js new file mode 100644 index 0000000000..0075e73cd3 --- /dev/null +++ b/src/Math.js @@ -0,0 +1,19 @@ +export const imul = + typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 + ? Math.imul + : function imul(a, b) { + a |= 0; // int + b |= 0; // int + const c = a & 0xffff; + const d = b & 0xffff; + // Shift by 0 fixes the sign on the high part. + return (c * d + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0)) | 0; // int + }; + +// v8 has an optimization for storing 31-bit signed numbers. +// Values which have either 00 or 11 as the high order bits qualify. +// This function drops the highest order bit in a signed number, maintaining +// the sign bit. +export function smi(i32) { + return ((i32 >>> 1) & 0x40000000) | (i32 & 0xbfffffff); +} diff --git a/src/Operations.js b/src/Operations.js new file mode 100644 index 0000000000..bb3b16568d --- /dev/null +++ b/src/Operations.js @@ -0,0 +1,985 @@ +import { + NOT_SET, + ensureSize, + wrapIndex, + wholeSlice, + resolveBegin, + resolveEnd, +} from './TrieUtils'; +import { + Collection, + KeyedCollection, + SetCollection, + IndexedCollection, +} from './Collection'; +import { isCollection } from './predicates/isCollection'; +import { IS_KEYED_SYMBOL, isKeyed } from './predicates/isKeyed'; +import { IS_INDEXED_SYMBOL, isIndexed } from './predicates/isIndexed'; +import { isOrdered, IS_ORDERED_SYMBOL } from './predicates/isOrdered'; +import { isSeq } from './predicates/isSeq'; +import { + getIterator, + Iterator, + iteratorValue, + iteratorDone, + ITERATE_KEYS, + ITERATE_VALUES, + ITERATE_ENTRIES, +} from './Iterator'; +import { + Seq, + KeyedSeq, + SetSeq, + IndexedSeq, + keyedSeqFromValue, + indexedSeqFromValue, + ArraySeq, +} from './Seq'; + +import { Map } from './Map'; +import { OrderedMap } from './OrderedMap'; + +export class ToKeyedSequence extends KeyedSeq { + constructor(indexed, useKeys) { + this._iter = indexed; + this._useKeys = useKeys; + this.size = indexed.size; + } + + get(key, notSetValue) { + return this._iter.get(key, notSetValue); + } + + has(key) { + return this._iter.has(key); + } + + valueSeq() { + return this._iter.valueSeq(); + } + + reverse() { + const reversedSequence = reverseFactory(this, true); + if (!this._useKeys) { + reversedSequence.valueSeq = () => this._iter.toSeq().reverse(); + } + return reversedSequence; + } + + map(mapper, context) { + const mappedSequence = mapFactory(this, mapper, context); + if (!this._useKeys) { + mappedSequence.valueSeq = () => this._iter.toSeq().map(mapper, context); + } + return mappedSequence; + } + + __iterate(fn, reverse) { + return this._iter.__iterate((v, k) => fn(v, k, this), reverse); + } + + __iterator(type, reverse) { + return this._iter.__iterator(type, reverse); + } +} +ToKeyedSequence.prototype[IS_ORDERED_SYMBOL] = true; + +export class ToIndexedSequence extends IndexedSeq { + constructor(iter) { + this._iter = iter; + this.size = iter.size; + } + + includes(value) { + return this._iter.includes(value); + } + + __iterate(fn, reverse) { + let i = 0; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + reverse && ensureSize(this); + return this._iter.__iterate( + (v) => fn(v, reverse ? this.size - ++i : i++, this), + reverse + ); + } + + __iterator(type, reverse) { + const iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + let i = 0; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + reverse && ensureSize(this); + return new Iterator(() => { + const step = iterator.next(); + return step.done + ? step + : iteratorValue( + type, + reverse ? this.size - ++i : i++, + step.value, + step + ); + }); + } +} + +export class ToSetSequence extends SetSeq { + constructor(iter) { + this._iter = iter; + this.size = iter.size; + } + + has(key) { + return this._iter.includes(key); + } + + __iterate(fn, reverse) { + return this._iter.__iterate((v) => fn(v, v, this), reverse); + } + + __iterator(type, reverse) { + const iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(() => { + const step = iterator.next(); + return step.done + ? step + : iteratorValue(type, step.value, step.value, step); + }); + } +} + +export class FromEntriesSequence extends KeyedSeq { + constructor(entries) { + this._iter = entries; + this.size = entries.size; + } + + entrySeq() { + return this._iter.toSeq(); + } + + __iterate(fn, reverse) { + return this._iter.__iterate((entry) => { + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + const indexedCollection = isCollection(entry); + return fn( + indexedCollection ? entry.get(1) : entry[1], + indexedCollection ? entry.get(0) : entry[0], + this + ); + } + }, reverse); + } + + __iterator(type, reverse) { + const iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(() => { + while (true) { + const step = iterator.next(); + if (step.done) { + return step; + } + const entry = step.value; + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + const indexedCollection = isCollection(entry); + return iteratorValue( + type, + indexedCollection ? entry.get(0) : entry[0], + indexedCollection ? entry.get(1) : entry[1], + step + ); + } + } + }); + } +} + +ToIndexedSequence.prototype.cacheResult = + ToKeyedSequence.prototype.cacheResult = + ToSetSequence.prototype.cacheResult = + FromEntriesSequence.prototype.cacheResult = + cacheResultThrough; + +export function flipFactory(collection) { + const flipSequence = makeSequence(collection); + flipSequence._iter = collection; + flipSequence.size = collection.size; + flipSequence.flip = () => collection; + flipSequence.reverse = function () { + const reversedSequence = collection.reverse.apply(this); // super.reverse() + reversedSequence.flip = () => collection.reverse(); + return reversedSequence; + }; + flipSequence.has = (key) => collection.includes(key); + flipSequence.includes = (key) => collection.has(key); + flipSequence.cacheResult = cacheResultThrough; + flipSequence.__iterateUncached = function (fn, reverse) { + return collection.__iterate((v, k) => fn(k, v, this) !== false, reverse); + }; + flipSequence.__iteratorUncached = function (type, reverse) { + if (type === ITERATE_ENTRIES) { + const iterator = collection.__iterator(type, reverse); + return new Iterator(() => { + const step = iterator.next(); + if (!step.done) { + const k = step.value[0]; + step.value[0] = step.value[1]; + step.value[1] = k; + } + return step; + }); + } + return collection.__iterator( + type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, + reverse + ); + }; + return flipSequence; +} + +export function mapFactory(collection, mapper, context) { + const mappedSequence = makeSequence(collection); + mappedSequence.size = collection.size; + mappedSequence.has = (key) => collection.has(key); + mappedSequence.get = (key, notSetValue) => { + const v = collection.get(key, NOT_SET); + return v === NOT_SET + ? notSetValue + : mapper.call(context, v, key, collection); + }; + mappedSequence.__iterateUncached = function (fn, reverse) { + return collection.__iterate( + (v, k, c) => fn(mapper.call(context, v, k, c), k, this) !== false, + reverse + ); + }; + mappedSequence.__iteratorUncached = function (type, reverse) { + const iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + return new Iterator(() => { + const step = iterator.next(); + if (step.done) { + return step; + } + const entry = step.value; + const key = entry[0]; + return iteratorValue( + type, + key, + mapper.call(context, entry[1], key, collection), + step + ); + }); + }; + return mappedSequence; +} + +export function reverseFactory(collection, useKeys) { + const reversedSequence = makeSequence(collection); + reversedSequence._iter = collection; + reversedSequence.size = collection.size; + reversedSequence.reverse = () => collection; + if (collection.flip) { + reversedSequence.flip = function () { + const flipSequence = flipFactory(collection); + flipSequence.reverse = () => collection.flip(); + return flipSequence; + }; + } + reversedSequence.get = (key, notSetValue) => + collection.get(useKeys ? key : -1 - key, notSetValue); + reversedSequence.has = (key) => collection.has(useKeys ? key : -1 - key); + reversedSequence.includes = (value) => collection.includes(value); + reversedSequence.cacheResult = cacheResultThrough; + reversedSequence.__iterate = function (fn, reverse) { + let i = 0; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + reverse && ensureSize(collection); + return collection.__iterate( + (v, k) => fn(v, useKeys ? k : reverse ? this.size - ++i : i++, this), + !reverse + ); + }; + reversedSequence.__iterator = (type, reverse) => { + let i = 0; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + reverse && ensureSize(collection); + const iterator = collection.__iterator(ITERATE_ENTRIES, !reverse); + return new Iterator(() => { + const step = iterator.next(); + if (step.done) { + return step; + } + const entry = step.value; + return iteratorValue( + type, + useKeys ? entry[0] : reverse ? this.size - ++i : i++, + entry[1], + step + ); + }); + }; + return reversedSequence; +} + +export function filterFactory(collection, predicate, context, useKeys) { + const filterSequence = makeSequence(collection); + if (useKeys) { + filterSequence.has = (key) => { + const v = collection.get(key, NOT_SET); + return v !== NOT_SET && !!predicate.call(context, v, key, collection); + }; + filterSequence.get = (key, notSetValue) => { + const v = collection.get(key, NOT_SET); + return v !== NOT_SET && predicate.call(context, v, key, collection) + ? v + : notSetValue; + }; + } + filterSequence.__iterateUncached = function (fn, reverse) { + let iterations = 0; + collection.__iterate((v, k, c) => { + if (predicate.call(context, v, k, c)) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this); + } + }, reverse); + return iterations; + }; + filterSequence.__iteratorUncached = function (type, reverse) { + const iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + let iterations = 0; + return new Iterator(() => { + while (true) { + const step = iterator.next(); + if (step.done) { + return step; + } + const entry = step.value; + const key = entry[0]; + const value = entry[1]; + if (predicate.call(context, value, key, collection)) { + return iteratorValue(type, useKeys ? key : iterations++, value, step); + } + } + }); + }; + return filterSequence; +} + +export function countByFactory(collection, grouper, context) { + const groups = Map().asMutable(); + collection.__iterate((v, k) => { + groups.update(grouper.call(context, v, k, collection), 0, (a) => a + 1); + }); + return groups.asImmutable(); +} + +export function groupByFactory(collection, grouper, context) { + const isKeyedIter = isKeyed(collection); + const groups = (isOrdered(collection) ? OrderedMap() : Map()).asMutable(); + collection.__iterate((v, k) => { + groups.update( + grouper.call(context, v, k, collection), + (a) => ((a = a || []), a.push(isKeyedIter ? [k, v] : v), a) + ); + }); + const coerce = collectionClass(collection); + return groups.map((arr) => reify(collection, coerce(arr))).asImmutable(); +} + +export function partitionFactory(collection, predicate, context) { + const isKeyedIter = isKeyed(collection); + const groups = [[], []]; + collection.__iterate((v, k) => { + groups[predicate.call(context, v, k, collection) ? 1 : 0].push( + isKeyedIter ? [k, v] : v + ); + }); + const coerce = collectionClass(collection); + return groups.map((arr) => reify(collection, coerce(arr))); +} + +export function sliceFactory(collection, begin, end, useKeys) { + const originalSize = collection.size; + + if (wholeSlice(begin, end, originalSize)) { + return collection; + } + + // begin or end can not be resolved if they were provided as negative numbers and + // this collection's size is unknown. In that case, cache first so there is + // a known size and these do not resolve to NaN. + if (typeof originalSize === 'undefined' && (begin < 0 || end < 0)) { + return sliceFactory(collection.toSeq().cacheResult(), begin, end, useKeys); + } + + const resolvedBegin = resolveBegin(begin, originalSize); + const resolvedEnd = resolveEnd(end, originalSize); + + // Note: resolvedEnd is undefined when the original sequence's length is + // unknown and this slice did not supply an end and should contain all + // elements after resolvedBegin. + // In that case, resolvedSize will be NaN and sliceSize will remain undefined. + const resolvedSize = resolvedEnd - resolvedBegin; + let sliceSize; + if (resolvedSize === resolvedSize) { + sliceSize = resolvedSize < 0 ? 0 : resolvedSize; + } + + const sliceSeq = makeSequence(collection); + + // If collection.size is undefined, the size of the realized sliceSeq is + // unknown at this point unless the number of items to slice is 0 + sliceSeq.size = + sliceSize === 0 ? sliceSize : (collection.size && sliceSize) || undefined; + + if (!useKeys && isSeq(collection) && sliceSize >= 0) { + sliceSeq.get = function (index, notSetValue) { + index = wrapIndex(this, index); + return index >= 0 && index < sliceSize + ? collection.get(index + resolvedBegin, notSetValue) + : notSetValue; + }; + } + + sliceSeq.__iterateUncached = function (fn, reverse) { + if (sliceSize === 0) { + return 0; + } + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + let skipped = 0; + let isSkipping = true; + let iterations = 0; + collection.__iterate((v, k) => { + if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { + iterations++; + return ( + fn(v, useKeys ? k : iterations - 1, this) !== false && + iterations !== sliceSize + ); + } + }); + return iterations; + }; + + sliceSeq.__iteratorUncached = function (type, reverse) { + if (sliceSize !== 0 && reverse) { + return this.cacheResult().__iterator(type, reverse); + } + // Don't bother instantiating parent iterator if taking 0. + if (sliceSize === 0) { + return new Iterator(iteratorDone); + } + const iterator = collection.__iterator(type, reverse); + let skipped = 0; + let iterations = 0; + return new Iterator(() => { + while (skipped++ < resolvedBegin) { + iterator.next(); + } + if (++iterations > sliceSize) { + return iteratorDone(); + } + const step = iterator.next(); + if (useKeys || type === ITERATE_VALUES || step.done) { + return step; + } + if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations - 1, undefined, step); + } + return iteratorValue(type, iterations - 1, step.value[1], step); + }); + }; + + return sliceSeq; +} + +export function takeWhileFactory(collection, predicate, context) { + const takeSequence = makeSequence(collection); + takeSequence.__iterateUncached = function (fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + let iterations = 0; + collection.__iterate( + (v, k, c) => + predicate.call(context, v, k, c) && ++iterations && fn(v, k, this) + ); + return iterations; + }; + takeSequence.__iteratorUncached = function (type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + const iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + let iterating = true; + return new Iterator(() => { + if (!iterating) { + return iteratorDone(); + } + const step = iterator.next(); + if (step.done) { + return step; + } + const entry = step.value; + const k = entry[0]; + const v = entry[1]; + if (!predicate.call(context, v, k, this)) { + iterating = false; + return iteratorDone(); + } + return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); + }); + }; + return takeSequence; +} + +export function skipWhileFactory(collection, predicate, context, useKeys) { + const skipSequence = makeSequence(collection); + skipSequence.__iterateUncached = function (fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + let isSkipping = true; + let iterations = 0; + collection.__iterate((v, k, c) => { + if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this); + } + }); + return iterations; + }; + skipSequence.__iteratorUncached = function (type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + const iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + let skipping = true; + let iterations = 0; + return new Iterator(() => { + let step; + let k; + let v; + do { + step = iterator.next(); + if (step.done) { + if (useKeys || type === ITERATE_VALUES) { + return step; + } + if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations++, undefined, step); + } + return iteratorValue(type, iterations++, step.value[1], step); + } + const entry = step.value; + k = entry[0]; + v = entry[1]; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + skipping && (skipping = predicate.call(context, v, k, this)); + } while (skipping); + return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); + }); + }; + return skipSequence; +} + +class ConcatSeq extends Seq { + constructor(iterables) { + this._wrappedIterables = iterables.flatMap((iterable) => { + if (iterable._wrappedIterables) { + return iterable._wrappedIterables; + } + return [iterable]; + }); + this.size = this._wrappedIterables.reduce((sum, iterable) => { + if (sum !== undefined) { + const size = iterable.size; + if (size !== undefined) { + return sum + size; + } + } + }, 0); + this[IS_KEYED_SYMBOL] = this._wrappedIterables[0][IS_KEYED_SYMBOL]; + this[IS_INDEXED_SYMBOL] = this._wrappedIterables[0][IS_INDEXED_SYMBOL]; + this[IS_ORDERED_SYMBOL] = this._wrappedIterables[0][IS_ORDERED_SYMBOL]; + } + + __iterateUncached(fn, reverse) { + if (this._wrappedIterables.length === 0) { + return; + } + + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + + let iterableIndex = 0; + const useKeys = isKeyed(this); + const iteratorType = useKeys ? ITERATE_ENTRIES : ITERATE_VALUES; + let currentIterator = this._wrappedIterables[iterableIndex].__iterator( + iteratorType, + reverse + ); + + let keepGoing = true; + let index = 0; + while (keepGoing) { + let next = currentIterator.next(); + while (next.done) { + iterableIndex++; + if (iterableIndex === this._wrappedIterables.length) { + return index; + } + currentIterator = this._wrappedIterables[iterableIndex].__iterator( + iteratorType, + reverse + ); + next = currentIterator.next(); + } + const fnResult = useKeys + ? fn(next.value[1], next.value[0], this) + : fn(next.value, index, this); + keepGoing = fnResult !== false; + index++; + } + return index; + } + + __iteratorUncached(type, reverse) { + if (this._wrappedIterables.length === 0) { + return new Iterator(iteratorDone); + } + + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + + let iterableIndex = 0; + let currentIterator = this._wrappedIterables[iterableIndex].__iterator( + type, + reverse + ); + return new Iterator(() => { + let next = currentIterator.next(); + while (next.done) { + iterableIndex++; + if (iterableIndex === this._wrappedIterables.length) { + return next; + } + currentIterator = this._wrappedIterables[iterableIndex].__iterator( + type, + reverse + ); + next = currentIterator.next(); + } + return next; + }); + } +} + +export function concatFactory(collection, values) { + const isKeyedCollection = isKeyed(collection); + const iters = [collection] + .concat(values) + .map((v) => { + if (!isCollection(v)) { + v = isKeyedCollection + ? keyedSeqFromValue(v) + : indexedSeqFromValue(Array.isArray(v) ? v : [v]); + } else if (isKeyedCollection) { + v = KeyedCollection(v); + } + return v; + }) + .filter((v) => v.size !== 0); + + if (iters.length === 0) { + return collection; + } + + if (iters.length === 1) { + const singleton = iters[0]; + if ( + singleton === collection || + (isKeyedCollection && isKeyed(singleton)) || + (isIndexed(collection) && isIndexed(singleton)) + ) { + return singleton; + } + } + + return new ConcatSeq(iters); +} + +export function flattenFactory(collection, depth, useKeys) { + const flatSequence = makeSequence(collection); + flatSequence.__iterateUncached = function (fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + let iterations = 0; + let stopped = false; + function flatDeep(iter, currentDepth) { + iter.__iterate((v, k) => { + if ((!depth || currentDepth < depth) && isCollection(v)) { + flatDeep(v, currentDepth + 1); + } else { + iterations++; + if (fn(v, useKeys ? k : iterations - 1, flatSequence) === false) { + stopped = true; + } + } + return !stopped; + }, reverse); + } + flatDeep(collection, 0); + return iterations; + }; + flatSequence.__iteratorUncached = function (type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + let iterator = collection.__iterator(type, reverse); + const stack = []; + let iterations = 0; + return new Iterator(() => { + while (iterator) { + const step = iterator.next(); + if (step.done !== false) { + iterator = stack.pop(); + continue; + } + let v = step.value; + if (type === ITERATE_ENTRIES) { + v = v[1]; + } + if ((!depth || stack.length < depth) && isCollection(v)) { + stack.push(iterator); + iterator = v.__iterator(type, reverse); + } else { + return useKeys ? step : iteratorValue(type, iterations++, v, step); + } + } + return iteratorDone(); + }); + }; + return flatSequence; +} + +export function flatMapFactory(collection, mapper, context) { + const coerce = collectionClass(collection); + return collection + .toSeq() + .map((v, k) => coerce(mapper.call(context, v, k, collection))) + .flatten(true); +} + +export function interposeFactory(collection, separator) { + const interposedSequence = makeSequence(collection); + interposedSequence.size = collection.size && collection.size * 2 - 1; + interposedSequence.__iterateUncached = function (fn, reverse) { + let iterations = 0; + collection.__iterate( + (v) => + (!iterations || fn(separator, iterations++, this) !== false) && + fn(v, iterations++, this) !== false, + reverse + ); + return iterations; + }; + interposedSequence.__iteratorUncached = function (type, reverse) { + const iterator = collection.__iterator(ITERATE_VALUES, reverse); + let iterations = 0; + let step; + return new Iterator(() => { + if (!step || iterations % 2) { + step = iterator.next(); + if (step.done) { + return step; + } + } + return iterations % 2 + ? iteratorValue(type, iterations++, separator) + : iteratorValue(type, iterations++, step.value, step); + }); + }; + return interposedSequence; +} + +export function sortFactory(collection, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + const isKeyedCollection = isKeyed(collection); + let index = 0; + const entries = collection + .toSeq() + .map((v, k) => [k, v, index++, mapper ? mapper(v, k, collection) : v]) + .valueSeq() + .toArray(); + entries + .sort((a, b) => comparator(a[3], b[3]) || a[2] - b[2]) + .forEach( + isKeyedCollection + ? (v, i) => { + entries[i].length = 2; + } + : (v, i) => { + entries[i] = v[1]; + } + ); + return isKeyedCollection + ? KeyedSeq(entries) + : isIndexed(collection) + ? IndexedSeq(entries) + : SetSeq(entries); +} + +export function maxFactory(collection, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + if (mapper) { + const entry = collection + .toSeq() + .map((v, k) => [v, mapper(v, k, collection)]) + .reduce((a, b) => (maxCompare(comparator, a[1], b[1]) ? b : a)); + return entry && entry[0]; + } + return collection.reduce((a, b) => (maxCompare(comparator, a, b) ? b : a)); +} + +function maxCompare(comparator, a, b) { + const comp = comparator(b, a); + // b is considered the new max if the comparator declares them equal, but + // they are not equal and b is in fact a nullish value. + return ( + (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || + comp > 0 + ); +} + +export function zipWithFactory(keyIter, zipper, iters, zipAll) { + const zipSequence = makeSequence(keyIter); + const sizes = new ArraySeq(iters).map((i) => i.size); + zipSequence.size = zipAll ? sizes.max() : sizes.min(); + // Note: this a generic base implementation of __iterate in terms of + // __iterator which may be more generically useful in the future. + zipSequence.__iterate = function (fn, reverse) { + /* generic: + var iterator = this.__iterator(ITERATE_ENTRIES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + iterations++; + if (fn(step.value[1], step.value[0], this) === false) { + break; + } + } + return iterations; + */ + // indexed: + const iterator = this.__iterator(ITERATE_VALUES, reverse); + let step; + let iterations = 0; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } + } + return iterations; + }; + zipSequence.__iteratorUncached = function (type, reverse) { + const iterators = iters.map( + (i) => ((i = Collection(i)), getIterator(reverse ? i.reverse() : i)) + ); + let iterations = 0; + let isDone = false; + return new Iterator(() => { + let steps; + if (!isDone) { + steps = iterators.map((i) => i.next()); + isDone = zipAll + ? steps.every((s) => s.done) + : steps.some((s) => s.done); + } + if (isDone) { + return iteratorDone(); + } + return iteratorValue( + type, + iterations++, + zipper.apply( + null, + steps.map((s) => s.value) + ) + ); + }); + }; + return zipSequence; +} + +// #pragma Helper Functions + +export function reify(iter, seq) { + return iter === seq ? iter : isSeq(iter) ? seq : iter.constructor(seq); +} + +function validateEntry(entry) { + if (entry !== Object(entry)) { + throw new TypeError('Expected [K, V] tuple: ' + entry); + } +} + +function collectionClass(collection) { + return isKeyed(collection) + ? KeyedCollection + : isIndexed(collection) + ? IndexedCollection + : SetCollection; +} + +function makeSequence(collection) { + return Object.create( + (isKeyed(collection) + ? KeyedSeq + : isIndexed(collection) + ? IndexedSeq + : SetSeq + ).prototype + ); +} + +function cacheResultThrough() { + if (this._iter.cacheResult) { + this._iter.cacheResult(); + this.size = this._iter.size; + return this; + } + return Seq.prototype.cacheResult.call(this); +} + +function defaultComparator(a, b) { + if (a === undefined && b === undefined) { + return 0; + } + + if (a === undefined) { + return 1; + } + + if (b === undefined) { + return -1; + } + + return a > b ? 1 : a < b ? -1 : 0; +} diff --git a/src/OrderedMap.js b/src/OrderedMap.js index 1fded9094f..c6867b6c83 100644 --- a/src/OrderedMap.js +++ b/src/OrderedMap.js @@ -1,37 +1,29 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Map" -import "Vector" -import "is" -import "TrieUtils" -import "Iterator" -/* global Map, Vector, is, DELETE, NOT_SET, - iteratorMapper, ITERATE_KEYS, ITERATE_VALUES */ -/* exported OrderedMap */ - - -class OrderedMap extends Map { - +import { KeyedCollection } from './Collection'; +import { IS_ORDERED_SYMBOL } from './predicates/isOrdered'; +import { isOrderedMap } from './predicates/isOrderedMap'; +import { Map, emptyMap } from './Map'; +import { emptyList } from './List'; +import { DELETE, NOT_SET, SIZE } from './TrieUtils'; +import assertNotInfinite from './utils/assertNotInfinite'; + +export class OrderedMap extends Map { // @pragma Construction - constructor(sequence) { - var map = OrderedMap.empty(); - return sequence ? - sequence.constructor === OrderedMap ? - sequence : - map.merge(sequence) : - map; + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyOrderedMap() + : isOrderedMap(value) + ? value + : emptyOrderedMap().withMutations((map) => { + const iter = KeyedCollection(value); + assertNotInfinite(iter.size); + iter.forEach((v, k) => map.set(k, v)); + }); } - static empty() { - return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(Map.empty(), Vector.empty())); + static of(/*...values*/) { + return this(arguments); } toString() { @@ -41,23 +33,24 @@ class OrderedMap extends Map { // @pragma Access get(k, notSetValue) { - var index = this._map.get(k); - return index != null ? this._vector.get(index)[1] : notSetValue; + const index = this._map.get(k); + return index !== undefined ? this._list.get(index)[1] : notSetValue; } // @pragma Modification clear() { - if (this.length === 0) { + if (this.size === 0) { return this; } if (this.__ownerID) { - this.length = 0; + this.size = 0; this._map.clear(); - this._vector.clear(); + this._list.clear(); + this.__altered = true; return this; } - return OrderedMap.empty(); + return emptyOrderedMap(); } set(k, v) { @@ -68,82 +61,104 @@ class OrderedMap extends Map { return updateOrderedMap(this, k, NOT_SET); } - wasAltered() { - return this._map.wasAltered() || this._vector.wasAltered(); - } - - __iterator(type, reverse) { - var iterator = this._vector.__iterator(ITERATE_VALUES, reverse); - return type === ITERATE_KEYS ? - iteratorMapper(iterator, entry => entry[0]) : - type === ITERATE_VALUES ? - iteratorMapper(iterator, entry => entry[1]) : - iterator; - } - __iterate(fn, reverse) { - return this._vector.fromEntrySeq().__iterate(fn, reverse); + return this._list.__iterate( + (entry) => entry && fn(entry[1], entry[0], this), + reverse + ); } - __deepEquals(other) { - var iterator = this.entries(); - return other.every((v, k) => { - var entry = iterator.next().value; - return entry && is(entry[0], k) && is(entry[1], v); - }); + __iterator(type, reverse) { + return this._list.fromEntrySeq().__iterator(type, reverse); } __ensureOwner(ownerID) { if (ownerID === this.__ownerID) { return this; } - var newMap = this._map.__ensureOwner(ownerID); - var newVector = this._vector.__ensureOwner(ownerID); + const newMap = this._map.__ensureOwner(ownerID); + const newList = this._list.__ensureOwner(ownerID); if (!ownerID) { + if (this.size === 0) { + return emptyOrderedMap(); + } this.__ownerID = ownerID; + this.__altered = false; this._map = newMap; - this._vector = newVector; + this._list = newList; return this; } - return makeOrderedMap(newMap, newVector, ownerID, this.__hash); + return makeOrderedMap(newMap, newList, ownerID, this.__hash); } } -OrderedMap.from = OrderedMap; +OrderedMap.isOrderedMap = isOrderedMap; + +OrderedMap.prototype[IS_ORDERED_SYMBOL] = true; OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; -function makeOrderedMap(map, vector, ownerID, hash) { - var omap = Object.create(OrderedMap.prototype); - omap.length = map ? map.length : 0; +function makeOrderedMap(map, list, ownerID, hash) { + const omap = Object.create(OrderedMap.prototype); + omap.size = map ? map.size : 0; omap._map = map; - omap._vector = vector; + omap._list = list; omap.__ownerID = ownerID; omap.__hash = hash; + omap.__altered = false; return omap; } +let EMPTY_ORDERED_MAP; +export function emptyOrderedMap() { + return ( + EMPTY_ORDERED_MAP || + (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())) + ); +} + function updateOrderedMap(omap, k, v) { - var map = omap._map; - var vector = omap._vector; - var i = map.get(k); - var has = i !== undefined; - var removed = v === NOT_SET; - if ((!has && removed) || (has && v === vector.get(i)[1])) { - return omap; - } - if (!has) { - i = vector.length; + const map = omap._map; + const list = omap._list; + const i = map.get(k); + const has = i !== undefined; + let newMap; + let newList; + if (v === NOT_SET) { + // removed + if (!has) { + return omap; + } + if (list.size >= SIZE && list.size >= map.size * 2) { + newList = list.filter((entry, idx) => entry !== undefined && i !== idx); + newMap = newList + .toKeyedSeq() + .map((entry) => entry[0]) + .flip() + .toMap(); + if (omap.__ownerID) { + newMap.__ownerID = newList.__ownerID = omap.__ownerID; + } + } else { + newMap = map.remove(k); + newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); + } + } else if (has) { + if (v === list.get(i)[1]) { + return omap; + } + newMap = map; + newList = list.set(i, [k, v]); + } else { + newMap = map.set(k, list.size); + newList = list.set(list.size, [k, v]); } - var newMap = removed ? map.remove(k) : has ? map : map.set(k, i); - var newVector = removed ? vector.remove(i) : vector.set(i, [k, v]); if (omap.__ownerID) { - omap.length = newMap.length; + omap.size = newMap.size; omap._map = newMap; - omap._vector = newVector; + omap._list = newList; omap.__hash = undefined; + omap.__altered = true; return omap; } - return makeOrderedMap(newMap, newVector); + return makeOrderedMap(newMap, newList); } - -var EMPTY_ORDERED_MAP; diff --git a/src/OrderedSet.js b/src/OrderedSet.js new file mode 100644 index 0000000000..98da36416f --- /dev/null +++ b/src/OrderedSet.js @@ -0,0 +1,62 @@ +import { SetCollection, KeyedCollection } from './Collection'; +import { IS_ORDERED_SYMBOL } from './predicates/isOrdered'; +import { isOrderedSet } from './predicates/isOrderedSet'; +import { IndexedCollectionPrototype } from './CollectionImpl'; +import { Set } from './Set'; +import { emptyOrderedMap } from './OrderedMap'; +import assertNotInfinite from './utils/assertNotInfinite'; + +export class OrderedSet extends Set { + // @pragma Construction + + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyOrderedSet() + : isOrderedSet(value) + ? value + : emptyOrderedSet().withMutations((set) => { + const iter = SetCollection(value); + assertNotInfinite(iter.size); + iter.forEach((v) => set.add(v)); + }); + } + + static of(/*...values*/) { + return this(arguments); + } + + static fromKeys(value) { + return this(KeyedCollection(value).keySeq()); + } + + toString() { + return this.__toString('OrderedSet {', '}'); + } +} + +OrderedSet.isOrderedSet = isOrderedSet; + +const OrderedSetPrototype = OrderedSet.prototype; +OrderedSetPrototype[IS_ORDERED_SYMBOL] = true; +OrderedSetPrototype.zip = IndexedCollectionPrototype.zip; +OrderedSetPrototype.zipWith = IndexedCollectionPrototype.zipWith; +OrderedSetPrototype.zipAll = IndexedCollectionPrototype.zipAll; + +OrderedSetPrototype.__empty = emptyOrderedSet; +OrderedSetPrototype.__make = makeOrderedSet; + +function makeOrderedSet(map, ownerID) { + const set = Object.create(OrderedSetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; +} + +let EMPTY_ORDERED_SET; +function emptyOrderedSet() { + return ( + EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())) + ); +} diff --git a/src/PairSorting.js b/src/PairSorting.js new file mode 100644 index 0000000000..a8d6e4e240 --- /dev/null +++ b/src/PairSorting.js @@ -0,0 +1,4 @@ +export const PairSorting = { + LeftThenRight: -1, + RightThenLeft: +1, +}; diff --git a/src/Range.js b/src/Range.js index 4ac7ecfe73..a7ac912aed 100644 --- a/src/Range.js +++ b/src/Range.js @@ -1,98 +1,92 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Sequence" -import "Vector" -import "invariant" -import "Iterator" -/* global IndexedSequence, wholeSlice, resolveBegin, resolveEnd, - VectorPrototype, wrapIndex, invariant, - Iterator, iteratorValue, iteratorDone */ -/* exported Range, RangePrototype */ +import { wrapIndex, wholeSlice, resolveBegin, resolveEnd } from './TrieUtils'; +import { IndexedSeq } from './Seq'; +import { Iterator, iteratorValue, iteratorDone } from './Iterator'; +import invariant from './utils/invariant'; +import deepEqual from './utils/deepEqual'; /** * Returns a lazy seq of nums from start (inclusive) to end * (exclusive), by step, where start defaults to 0, step to 1, and end to * infinity. When start is equal to end, returns empty list. */ -class Range extends IndexedSequence { - - constructor(start, end, step) { +export class Range extends IndexedSeq { + constructor(start, end, step = 1) { if (!(this instanceof Range)) { + // eslint-disable-next-line no-constructor-return return new Range(start, end, step); } invariant(step !== 0, 'Cannot step a Range by 0'); - start = start || 0; - if (end == null) { - end = Infinity; - } - if (start === end && __EMPTY_RANGE) { - return __EMPTY_RANGE; - } - step = step == null ? 1 : Math.abs(step); + invariant( + start !== undefined, + 'You must define a start value when using Range' + ); + invariant( + end !== undefined, + 'You must define an end value when using Range' + ); + + step = Math.abs(step); if (end < start) { step = -step; } this._start = start; this._end = end; this._step = step; - this.length = Math.max(0, Math.ceil((end - start) / step - 1) + 1); - } - - toString() { - if (this.length === 0) { - return 'Range []'; + this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); + if (this.size === 0) { + if (EMPTY_RANGE) { + // eslint-disable-next-line no-constructor-return + return EMPTY_RANGE; + } + // eslint-disable-next-line @typescript-eslint/no-this-alias + EMPTY_RANGE = this; } - return 'Range [ ' + - this._start + '...' + this._end + - (this._step > 1 ? ' by ' + this._step : '') + - ' ]'; } - has(index) { - index = wrapIndex(this, index); - return index >= 0 && (this.length === Infinity || index < this.length); + toString() { + return this.size === 0 + ? 'Range []' + : `Range [ ${this._start}...${this._end}${this._step !== 1 ? ' by ' + this._step : ''} ]`; } get(index, notSetValue) { - index = wrapIndex(this, index); - return this.has(index) ? - this._start + index * this._step : - notSetValue; + return this.has(index) + ? this._start + wrapIndex(this, index) * this._step + : notSetValue; } - contains(searchValue) { - var possibleIndex = (searchValue - this._start) / this._step; - return possibleIndex >= 0 && - possibleIndex < this.length && - possibleIndex === Math.floor(possibleIndex); + includes(searchValue) { + const possibleIndex = (searchValue - this._start) / this._step; + return ( + possibleIndex >= 0 && + possibleIndex < this.size && + possibleIndex === Math.floor(possibleIndex) + ); } slice(begin, end) { - if (wholeSlice(begin, end, this.length)) { + if (wholeSlice(begin, end, this.size)) { return this; } - begin = resolveBegin(begin, this.length); - end = resolveEnd(end, this.length); + begin = resolveBegin(begin, this.size); + end = resolveEnd(end, this.size); if (end <= begin) { - return __EMPTY_RANGE; + return new Range(0, 0); } - return new Range(this.get(begin, this._end), this.get(end, this._end), this._step); + return new Range( + this.get(begin, this._end), + this.get(end, this._end), + this._step + ); } indexOf(searchValue) { - var offsetValue = searchValue - this._start; + const offsetValue = searchValue - this._start; if (offsetValue % this._step === 0) { - var index = offsetValue / this._step; - if (index >= 0 && index < this.length) { - return index + const index = offsetValue / this._step; + if (index >= 0 && index < this.size) { + return index; } } return -1; @@ -102,50 +96,42 @@ class Range extends IndexedSequence { return this.indexOf(searchValue); } - take(amount) { - return this.slice(0, Math.max(0, amount)); - } - - skip(amount) { - return this.slice(Math.max(0, amount)); - } - __iterate(fn, reverse) { - var maxIndex = this.length - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(value, ii, this) === false) { - return ii + 1; + const size = this.size; + const step = this._step; + let value = reverse ? this._start + (size - 1) * step : this._start; + let i = 0; + while (i !== size) { + if (fn(value, reverse ? size - ++i : i++, this) === false) { + break; } value += reverse ? -step : step; } - return ii; + return i; } __iterator(type, reverse) { - var maxIndex = this.length - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - var ii = 0; + const size = this.size; + const step = this._step; + let value = reverse ? this._start + (size - 1) * step : this._start; + let i = 0; return new Iterator(() => { - var v = value; + if (i === size) { + return iteratorDone(); + } + const v = value; value += reverse ? -step : step; - return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); + return iteratorValue(type, reverse ? size - ++i : i++, v); }); } - __deepEquals(other) { - return this._start === other._start && - this._end === other._end && - this._step === other._step; + equals(other) { + return other instanceof Range + ? this._start === other._start && + this._end === other._end && + this._step === other._step + : deepEqual(this, other); } } -var RangePrototype = Range.prototype; - -RangePrototype.__toJS = RangePrototype.toArray; -RangePrototype.first = VectorPrototype.first; -RangePrototype.last = VectorPrototype.last; - -var __EMPTY_RANGE = Range(0, 0); +let EMPTY_RANGE; diff --git a/src/Record.js b/src/Record.js index 896f7ac062..89100a6410 100644 --- a/src/Record.js +++ b/src/Record.js @@ -1,161 +1,269 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ +import { toJS } from './toJS'; +import { KeyedCollection } from './Collection'; +import { keyedSeqFromValue } from './Seq'; +import { List } from './List'; +import { ITERATE_ENTRIES, ITERATOR_SYMBOL } from './Iterator'; +import { isRecord, IS_RECORD_SYMBOL } from './predicates/isRecord'; +import { CollectionPrototype } from './CollectionImpl'; +import { DELETE } from './TrieUtils'; +import { getIn } from './methods/getIn'; +import { setIn } from './methods/setIn'; +import { deleteIn } from './methods/deleteIn'; +import { update } from './methods/update'; +import { updateIn } from './methods/updateIn'; +import { merge, mergeWith } from './methods/merge'; +import { mergeDeep, mergeDeepWith } from './methods/mergeDeep'; +import { mergeIn } from './methods/mergeIn'; +import { mergeDeepIn } from './methods/mergeDeepIn'; +import { withMutations } from './methods/withMutations'; +import { asMutable } from './methods/asMutable'; +import { asImmutable } from './methods/asImmutable'; -import "Sequence" -import "Map" -import "invariant" -import "TrieUtils" -/* global Sequence, Map, MapPrototype, invariant, DELETE */ -/* exported Record */ +import invariant from './utils/invariant'; +import quoteString from './utils/quoteString'; +import { isImmutable } from './predicates/isImmutable'; +function throwOnInvalidDefaultValues(defaultValues) { + if (isRecord(defaultValues)) { + throw new Error( + 'Can not call `Record` with an immutable Record as default values. Use a plain javascript object instead.' + ); + } -class Record extends Sequence { + if (isImmutable(defaultValues)) { + throw new Error( + 'Can not call `Record` with an immutable Collection as default values. Use a plain javascript object instead.' + ); + } + if (defaultValues === null || typeof defaultValues !== 'object') { + throw new Error( + 'Can not call `Record` with a non-object as default values. Use a plain javascript object instead.' + ); + } +} + +export class Record { constructor(defaultValues, name) { - var RecordType = function(values) { + let hasInitialized; + + throwOnInvalidDefaultValues(defaultValues); + + const RecordType = function Record(values) { + if (values instanceof RecordType) { + return values; + } if (!(this instanceof RecordType)) { return new RecordType(values); } - this._map = Map(values); - }; - defaultValues = Sequence(defaultValues); - var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); - RecordTypePrototype.constructor = RecordType; - RecordTypePrototype._name = name; - RecordTypePrototype._defaultValues = defaultValues; - - var keys = Object.keys(defaultValues); - RecordType.prototype.length = keys.length; - if (Object.defineProperty) { - defaultValues.forEach((_, key) => { - Object.defineProperty(RecordType.prototype, key, { - get: function() { - return this.get(key); - }, - set: function(value) { - invariant(this.__ownerID, 'Cannot set on an immutable record.'); - this.set(key, value); + if (!hasInitialized) { + hasInitialized = true; + const keys = Object.keys(defaultValues); + const indices = (RecordTypePrototype._indices = {}); + // Deprecated: left to attempt not to break any external code which + // relies on a ._name property existing on record instances. + // Use Record.getDescriptiveName() instead + RecordTypePrototype._name = name; + RecordTypePrototype._keys = keys; + RecordTypePrototype._defaultValues = defaultValues; + for (let i = 0; i < keys.length; i++) { + const propName = keys[i]; + indices[propName] = i; + if (RecordTypePrototype[propName]) { + /* eslint-disable no-console */ + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + typeof console === 'object' && + console.warn && + console.warn( + 'Cannot define ' + + recordName(this) + + ' with property "' + + propName + + '" since that property name is part of the Record API.' + ); + /* eslint-enable no-console */ + } else { + setProp(RecordTypePrototype, propName); } + } + } + this.__ownerID = undefined; + this._values = List().withMutations((l) => { + l.setSize(this._keys.length); + KeyedCollection(values).forEach((v, k) => { + l.set(this._indices[k], v === this._defaultValues[k] ? undefined : v); }); }); + return this; + }; + + const RecordTypePrototype = (RecordType.prototype = + Object.create(RecordPrototype)); + RecordTypePrototype.constructor = RecordType; + + if (name) { + RecordType.displayName = name; } + // eslint-disable-next-line no-constructor-return return RecordType; } toString() { - return this.__toString((this._name || 'Record') + ' {', '}'); + let str = recordName(this) + ' { '; + const keys = this._keys; + let k; + for (let i = 0, l = keys.length; i !== l; i++) { + k = keys[i]; + str += (i ? ', ' : '') + k + ': ' + quoteString(this.get(k)); + } + return str + ' }'; + } + + equals(other) { + return ( + this === other || + (isRecord(other) && recordSeq(this).equals(recordSeq(other))) + ); + } + + hashCode() { + return recordSeq(this).hashCode(); } // @pragma Access has(k) { - return this._defaultValues.has(k); + return this._indices.hasOwnProperty(k); } get(k, notSetValue) { - if (notSetValue !== undefined && !this.has(k)) { + if (!this.has(k)) { return notSetValue; } - return this._map.get(k, this._defaultValues.get(k)); + const index = this._indices[k]; + const value = this._values.get(index); + return value === undefined ? this._defaultValues[k] : value; } // @pragma Modification - clear() { - if (this.__ownerID) { - this._map.clear(); - return this; - } - var Record = Object.getPrototypeOf(this).constructor; - return Record._empty || (Record._empty = makeRecord(this, Map.empty())); - } - set(k, v) { - if (k == null || !this.has(k)) { - return this; - } - var newMap = this._map.set(k, v); - if (this.__ownerID || newMap === this._map) { - return this; + if (this.has(k)) { + const newValues = this._values.set( + this._indices[k], + v === this._defaultValues[k] ? undefined : v + ); + if (newValues !== this._values && !this.__ownerID) { + return makeRecord(this, newValues); + } } - return makeRecord(this, newMap); + return this; } remove(k) { - if (k == null || !this.has(k)) { - return this; - } - var newMap = this._map.remove(k); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); + return this.set(k); } - keys() { - return this._map.keys(); + clear() { + const newValues = this._values.clear().setSize(this._keys.length); + + return this.__ownerID ? this : makeRecord(this, newValues); } - values() { - return this._map.values(); + wasAltered() { + return this._values.wasAltered(); } - entries() { - return this._map.entries(); + toSeq() { + return recordSeq(this); } - wasAltered() { - return this._map.wasAltered(); + toJS() { + return toJS(this); + } + + entries() { + return this.__iterator(ITERATE_ENTRIES); } __iterator(type, reverse) { - return this._map.__iterator(type, reverse); + return recordSeq(this).__iterator(type, reverse); } __iterate(fn, reverse) { - var record = this; - return this._defaultValues.map((_, k) => record.get(k)).__iterate(fn, reverse); + return recordSeq(this).__iterate(fn, reverse); } __ensureOwner(ownerID) { if (ownerID === this.__ownerID) { return this; } - var newMap = this._map && this._map.__ensureOwner(ownerID); + const newValues = this._values.__ensureOwner(ownerID); if (!ownerID) { this.__ownerID = ownerID; - this._map = newMap; + this._values = newValues; return this; } - return makeRecord(this, newMap, ownerID); + return makeRecord(this, newValues, ownerID); } } -var RecordPrototype = Record.prototype; +Record.isRecord = isRecord; +Record.getDescriptiveName = recordName; +const RecordPrototype = Record.prototype; +RecordPrototype[IS_RECORD_SYMBOL] = true; RecordPrototype[DELETE] = RecordPrototype.remove; -RecordPrototype.merge = MapPrototype.merge; -RecordPrototype.mergeWith = MapPrototype.mergeWith; -RecordPrototype.mergeDeep = MapPrototype.mergeDeep; -RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; -RecordPrototype.update = MapPrototype.update; -RecordPrototype.updateIn = MapPrototype.updateIn; -RecordPrototype.cursor = MapPrototype.cursor; -RecordPrototype.withMutations = MapPrototype.withMutations; -RecordPrototype.asMutable = MapPrototype.asMutable; -RecordPrototype.asImmutable = MapPrototype.asImmutable; -RecordPrototype.__deepEquals = MapPrototype.__deepEquals; - - -function makeRecord(likeRecord, map, ownerID) { - var record = Object.create(Object.getPrototypeOf(likeRecord)); - record._map = map; +RecordPrototype.deleteIn = RecordPrototype.removeIn = deleteIn; +RecordPrototype.getIn = getIn; +RecordPrototype.hasIn = CollectionPrototype.hasIn; +RecordPrototype.merge = merge; +RecordPrototype.mergeWith = mergeWith; +RecordPrototype.mergeIn = mergeIn; +RecordPrototype.mergeDeep = mergeDeep; +RecordPrototype.mergeDeepWith = mergeDeepWith; +RecordPrototype.mergeDeepIn = mergeDeepIn; +RecordPrototype.setIn = setIn; +RecordPrototype.update = update; +RecordPrototype.updateIn = updateIn; +RecordPrototype.withMutations = withMutations; +RecordPrototype.asMutable = asMutable; +RecordPrototype.asImmutable = asImmutable; +RecordPrototype[ITERATOR_SYMBOL] = RecordPrototype.entries; +RecordPrototype.toJSON = RecordPrototype.toObject = + CollectionPrototype.toObject; +RecordPrototype.inspect = RecordPrototype.toSource = function () { + return this.toString(); +}; + +function makeRecord(likeRecord, values, ownerID) { + const record = Object.create(Object.getPrototypeOf(likeRecord)); + record._values = values; record.__ownerID = ownerID; return record; } + +function recordName(record) { + return record.constructor.displayName || record.constructor.name || 'Record'; +} + +function recordSeq(record) { + return keyedSeqFromValue(record._keys.map((k) => [k, record.get(k)])); +} + +function setProp(prototype, name) { + try { + Object.defineProperty(prototype, name, { + get: function () { + return this.get(name); + }, + set: function (value) { + invariant(this.__ownerID, 'Cannot set on an immutable record.'); + this.set(name, value); + }, + }); + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- TODO enable eslint here + } catch (error) { + // Object.defineProperty failed. Probably IE8. + } +} diff --git a/src/Repeat.js b/src/Repeat.js index 140f45991d..0fb106156c 100644 --- a/src/Repeat.js +++ b/src/Repeat.js @@ -1,58 +1,55 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Sequence" -import "Range" -import "is" -import "Iterator" -/* global IndexedSequence, RangePrototype, is, - Iterator, iteratorValue, iteratorDone */ -/* exported Repeat */ +import { wholeSlice, resolveBegin, resolveEnd } from './TrieUtils'; +import { IndexedSeq } from './Seq'; +import { is } from './is'; +import { Iterator, iteratorValue, iteratorDone } from './Iterator'; +import deepEqual from './utils/deepEqual'; /** - * Returns a lazy seq of `value` repeated `times` times. When `times` is + * Returns a lazy Seq of `value` repeated `times` times. When `times` is * undefined, returns an infinite sequence of `value`. */ -class Repeat extends IndexedSequence { - +export class Repeat extends IndexedSeq { constructor(value, times) { - if (times === 0 && EMPTY_REPEAT) { - return EMPTY_REPEAT; - } if (!(this instanceof Repeat)) { + // eslint-disable-next-line no-constructor-return return new Repeat(value, times); } this._value = value; - this.length = times == null ? Infinity : Math.max(0, times); + this.size = times === undefined ? Infinity : Math.max(0, times); + if (this.size === 0) { + if (EMPTY_REPEAT) { + // eslint-disable-next-line no-constructor-return + return EMPTY_REPEAT; + } + // eslint-disable-next-line @typescript-eslint/no-this-alias + EMPTY_REPEAT = this; + } } toString() { - if (this.length === 0) { + if (this.size === 0) { return 'Repeat []'; } - return 'Repeat [ ' + this._value + ' ' + this.length + ' times ]'; + return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; } get(index, notSetValue) { return this.has(index) ? this._value : notSetValue; } - contains(searchValue) { + includes(searchValue) { return is(this._value, searchValue); } slice(begin, end) { - var length = this.length; - begin = begin < 0 ? Math.max(0, length + begin) : Math.min(length, begin); - end = end == null ? length : end > 0 ? Math.min(length, end) : Math.max(0, length + end); - return end > begin ? new Repeat(this._value, end - begin) : EMPTY_REPEAT; + const size = this.size; + return wholeSlice(begin, end, size) + ? this + : new Repeat( + this._value, + resolveEnd(end, size) - resolveBegin(begin, size) + ); } reverse() { @@ -68,38 +65,37 @@ class Repeat extends IndexedSequence { lastIndexOf(searchValue) { if (is(this._value, searchValue)) { - return this.length; + return this.size; } return -1; } __iterate(fn, reverse) { - for (var ii = 0; ii < this.length; ii++) { - if (fn(this._value, ii, this) === false) { - return ii + 1; + const size = this.size; + let i = 0; + while (i !== size) { + if (fn(this._value, reverse ? size - ++i : i++, this) === false) { + break; } } - return ii; + return i; } __iterator(type, reverse) { - var ii = 0; + const size = this.size; + let i = 0; return new Iterator(() => - ii < this.length ? iteratorValue(type, ii++, this._value) : iteratorDone() + i === size + ? iteratorDone() + : iteratorValue(type, reverse ? size - ++i : i++, this._value) ); } - __deepEquals(other) { - return is(this._value, other._value); + equals(other) { + return other instanceof Repeat + ? is(this._value, other._value) + : deepEqual(this, other); } } -var RepeatPrototype = Repeat.prototype; -RepeatPrototype.last = RepeatPrototype.first; -RepeatPrototype.has = RangePrototype.has; -RepeatPrototype.take = RangePrototype.take; -RepeatPrototype.skip = RangePrototype.skip; -RepeatPrototype.__toJS = RangePrototype.__toJS; - - -var EMPTY_REPEAT = new Repeat(undefined, 0); +let EMPTY_REPEAT; diff --git a/src/Seq.js b/src/Seq.js new file mode 100644 index 0000000000..fd2a1dea58 --- /dev/null +++ b/src/Seq.js @@ -0,0 +1,343 @@ +import { wrapIndex } from './TrieUtils'; +import { Collection } from './Collection'; +import { IS_SEQ_SYMBOL, isSeq } from './predicates/isSeq'; +import { isImmutable } from './predicates/isImmutable'; +import { isCollection } from './predicates/isCollection'; +import { isKeyed } from './predicates/isKeyed'; +import { isAssociative } from './predicates/isAssociative'; +import { isRecord } from './predicates/isRecord'; +import { IS_ORDERED_SYMBOL } from './predicates/isOrdered'; +import { + Iterator, + iteratorValue, + iteratorDone, + hasIterator, + isIterator, + getIterator, + isEntriesIterable, + isKeysIterable, +} from './Iterator'; + +import hasOwnProperty from './utils/hasOwnProperty'; +import isArrayLike from './utils/isArrayLike'; + +export class Seq extends Collection { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySequence() + : isImmutable(value) + ? value.toSeq() + : seqFromValue(value); + } + + toSeq() { + return this; + } + + toString() { + return this.__toString('Seq {', '}'); + } + + cacheResult() { + if (!this._cache && this.__iterateUncached) { + this._cache = this.entrySeq().toArray(); + this.size = this._cache.length; + } + return this; + } + + // abstract __iterateUncached(fn, reverse) + + __iterate(fn, reverse) { + const cache = this._cache; + if (cache) { + const size = cache.length; + let i = 0; + while (i !== size) { + const entry = cache[reverse ? size - ++i : i++]; + if (fn(entry[1], entry[0], this) === false) { + break; + } + } + return i; + } + return this.__iterateUncached(fn, reverse); + } + + // abstract __iteratorUncached(type, reverse) + + __iterator(type, reverse) { + const cache = this._cache; + if (cache) { + const size = cache.length; + let i = 0; + return new Iterator(() => { + if (i === size) { + return iteratorDone(); + } + const entry = cache[reverse ? size - ++i : i++]; + return iteratorValue(type, entry[0], entry[1]); + }); + } + return this.__iteratorUncached(type, reverse); + } +} + +export class KeyedSeq extends Seq { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySequence().toKeyedSeq() + : isCollection(value) + ? isKeyed(value) + ? value.toSeq() + : value.fromEntrySeq() + : isRecord(value) + ? value.toSeq() + : keyedSeqFromValue(value); + } + + toKeyedSeq() { + return this; + } +} + +export class IndexedSeq extends Seq { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySequence() + : isCollection(value) + ? isKeyed(value) + ? value.entrySeq() + : value.toIndexedSeq() + : isRecord(value) + ? value.toSeq().entrySeq() + : indexedSeqFromValue(value); + } + + static of(/*...values*/) { + return IndexedSeq(arguments); + } + + toIndexedSeq() { + return this; + } + + toString() { + return this.__toString('Seq [', ']'); + } +} + +export class SetSeq extends Seq { + constructor(value) { + // eslint-disable-next-line no-constructor-return + return ( + isCollection(value) && !isAssociative(value) ? value : IndexedSeq(value) + ).toSetSeq(); + } + + static of(/*...values*/) { + return SetSeq(arguments); + } + + toSetSeq() { + return this; + } +} + +Seq.isSeq = isSeq; +Seq.Keyed = KeyedSeq; +Seq.Set = SetSeq; +Seq.Indexed = IndexedSeq; + +Seq.prototype[IS_SEQ_SYMBOL] = true; + +// #pragma Root Sequences + +export class ArraySeq extends IndexedSeq { + constructor(array) { + this._array = array; + this.size = array.length; + } + + get(index, notSetValue) { + return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; + } + + __iterate(fn, reverse) { + const array = this._array; + const size = array.length; + let i = 0; + while (i !== size) { + const ii = reverse ? size - ++i : i++; + if (fn(array[ii], ii, this) === false) { + break; + } + } + return i; + } + + __iterator(type, reverse) { + const array = this._array; + const size = array.length; + let i = 0; + return new Iterator(() => { + if (i === size) { + return iteratorDone(); + } + const ii = reverse ? size - ++i : i++; + return iteratorValue(type, ii, array[ii]); + }); + } +} + +class ObjectSeq extends KeyedSeq { + constructor(object) { + const keys = Object.keys(object).concat( + Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [] + ); + this._object = object; + this._keys = keys; + this.size = keys.length; + } + + get(key, notSetValue) { + if (notSetValue !== undefined && !this.has(key)) { + return notSetValue; + } + return this._object[key]; + } + + has(key) { + return hasOwnProperty.call(this._object, key); + } + + __iterate(fn, reverse) { + const object = this._object; + const keys = this._keys; + const size = keys.length; + let i = 0; + while (i !== size) { + const key = keys[reverse ? size - ++i : i++]; + if (fn(object[key], key, this) === false) { + break; + } + } + return i; + } + + __iterator(type, reverse) { + const object = this._object; + const keys = this._keys; + const size = keys.length; + let i = 0; + return new Iterator(() => { + if (i === size) { + return iteratorDone(); + } + const key = keys[reverse ? size - ++i : i++]; + return iteratorValue(type, key, object[key]); + }); + } +} +ObjectSeq.prototype[IS_ORDERED_SYMBOL] = true; + +class CollectionSeq extends IndexedSeq { + constructor(collection) { + this._collection = collection; + this.size = collection.length || collection.size; + } + + __iterateUncached(fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + const collection = this._collection; + const iterator = getIterator(collection); + let iterations = 0; + if (isIterator(iterator)) { + let step; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } + } + } + return iterations; + } + + __iteratorUncached(type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + const collection = this._collection; + const iterator = getIterator(collection); + if (!isIterator(iterator)) { + return new Iterator(iteratorDone); + } + let iterations = 0; + return new Iterator(() => { + const step = iterator.next(); + return step.done ? step : iteratorValue(type, iterations++, step.value); + }); + } +} + +// # pragma Helper functions + +let EMPTY_SEQ; + +function emptySequence() { + return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); +} + +export function keyedSeqFromValue(value) { + const seq = maybeIndexedSeqFromValue(value); + if (seq) { + return seq.fromEntrySeq(); + } + if (typeof value === 'object') { + return new ObjectSeq(value); + } + throw new TypeError( + 'Expected Array or collection object of [k, v] entries, or keyed object: ' + + value + ); +} + +export function indexedSeqFromValue(value) { + const seq = maybeIndexedSeqFromValue(value); + if (seq) { + return seq; + } + throw new TypeError( + 'Expected Array or collection object of values: ' + value + ); +} + +function seqFromValue(value) { + const seq = maybeIndexedSeqFromValue(value); + if (seq) { + return isEntriesIterable(value) + ? seq.fromEntrySeq() + : isKeysIterable(value) + ? seq.toSetSeq() + : seq; + } + if (typeof value === 'object') { + return new ObjectSeq(value); + } + throw new TypeError( + 'Expected Array or collection object of values, or keyed object: ' + value + ); +} + +function maybeIndexedSeqFromValue(value) { + return isArrayLike(value) + ? new ArraySeq(value) + : hasIterator(value) + ? new CollectionSeq(value) + : undefined; +} diff --git a/src/Sequence.js b/src/Sequence.js deleted file mode 100644 index fe179b48cc..0000000000 --- a/src/Sequence.js +++ /dev/null @@ -1,1221 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/* Sequence has implicit lazy dependencies */ -import "TrieUtils" -import "invariant" -import "Hash" -import "Iterator" -/* global is, Map, OrderedMap, Vector, Set, - arrCopy, NOT_SET, - invariant, - hash, HASH_MAX_VAL, - Iterator, iteratorValue, iteratorDone, - isIterable, isIterator, getIterator, - ITERATOR_SYMBOL, ITERATE_KEYS, ITERATE_VALUES, ITERATE_ENTRIES */ -/* exported Sequence, IndexedSequence */ - -class Sequence { - - constructor(value) { - return Sequence.from( - arguments.length === 1 ? value : Array.prototype.slice.call(arguments) - ); - } - - static from(value) { - if (value instanceof Sequence) { - return value; - } - if (!Array.isArray(value)) { - if (isIterator(value)) { - return new IteratorSequence(value); - } - if (isIterable(value)) { - return new IterableSequence(value); - } - if (value && value.constructor === Object) { - return new ObjectSequence(value); - } - value = [value]; - } - return new ArraySequence(value); - } - - toString() { - return this.__toString('Seq {', '}'); - } - - __toString(head, tail) { - if (this.length === 0) { - return head + tail; - } - return head + ' ' + this.map(this.__toStringMapper).join(', ') + ' ' + tail; - } - - __toStringMapper(v, k) { - return k + ': ' + quoteString(v); - } - - toJS() { - return this.map( - value => value instanceof Sequence ? value.toJS() : value - ).__toJS(); - } - - toArray() { - assertNotInfinite(this.length); - var array = new Array(this.length || 0); - this.valueSeq().__iterate((v, i) => { array[i] = v; }); - return array; - } - - toObject() { - assertNotInfinite(this.length); - var object = {}; - this.__iterate((v, k) => { object[k] = v; }); - return object; - } - - toVector() { - // Use Late Binding here to solve the circular dependency. - assertNotInfinite(this.length); - return Vector.from(this); - } - - toMap() { - // Use Late Binding here to solve the circular dependency. - assertNotInfinite(this.length); - return Map.from(this); - } - - toOrderedMap() { - // Use Late Binding here to solve the circular dependency. - assertNotInfinite(this.length); - return OrderedMap.from(this); - } - - toSet() { - // Use Late Binding here to solve the circular dependency. - assertNotInfinite(this.length); - return Set.from(this); - } - - toKeyedSeq() { - return this; - } - - hashCode() { - return this.__hash || (this.__hash = - this.length === Infinity ? 0 : this.reduce( - (h, v, k) => (h + (hash(v) ^ (v === k ? 0 : hash(k)))) & HASH_MAX_VAL, 0 - )); - } - - equals(other) { - if (this === other) { - return true; - } - if (!(other instanceof Sequence)) { - return false; - } - if (this.length != null && other.length != null) { - if (this.length !== other.length) { - return false; - } - if (this.length === 0 && other.length === 0) { - return true; - } - } - if (this.__hash != null && other.__hash != null && - this.__hash !== other.__hash) { - return false; - } - return this.__deepEquals(other); - } - - __deepEquals(other) { - var entries = this.cacheResult().entrySeq().toArray(); - var iterations = 0; - return other.every((v, k) => { - var entry = entries[iterations++]; - return entry && is(k, entry[0]) && is(v, entry[1]); - }) && iterations === entries.length; - } - - join(separator) { - separator = separator !== undefined ? '' + separator : ','; - var joined = ''; - var isFirst = true; - this.__iterate(v => { - isFirst ? (isFirst = false) : (joined += separator); - joined += v != null ? v : ''; - }); - return joined; - } - - count(predicate, context) { - if (!predicate) { - if (this.length == null) { - this.length = this.__iterate(returnTrue); - } - return this.length; - } - return this.filter(predicate, context).count(); - } - - countBy(grouper, context) { - var groupMap = {}; - var groups = []; - this.__iterate((v, k) => { - var g = grouper.call(context, v, k, this); - var h = hash(g); - if (!groupMap.hasOwnProperty(h)) { - groupMap[h] = groups.length; - groups.push([g, 1]); - } else { - groups[groupMap[h]][1]++; - } - }); - return Sequence(groups).fromEntrySeq(); - } - - concat(...values) { - return concatFactory(this, values, true); - } - - flatten() { - return flattenFactory(this, true); - } - - flatMap(mapper, context) { - return this.map(mapper, context).flatten(); - } - - reverse() { - var sequence = this; - var reversedSequence = sequence.__makeSequence(); - reversedSequence.reverse = () => sequence; - reversedSequence.length = sequence.length; - reversedSequence.get = (key, notSetValue) => sequence.get(key, notSetValue); - reversedSequence.has = key => sequence.has(key); - reversedSequence.contains = value => sequence.contains(value); - reversedSequence.cacheResult = function () { - sequence.cacheResult(); - this.length = sequence.length; - }; - reversedSequence.__iterate = function (fn, reverse) { - return sequence.__iterate((v, k) => fn(v, k, this), !reverse); - }; - reversedSequence.__iterator = - (type, reverse) => sequence.__iterator(type, !reverse); - return reversedSequence; - } - - keySeq() { - return this.flip().valueSeq(); - } - - valueSeq() { - return new ValuesSequence(this); - } - - entrySeq() { - var sequence = this; - if (sequence._cache) { - // We cache as an entries array, so we can just return the cache! - return Sequence(sequence._cache); - } - var entriesSequence = sequence.toKeyedSeq().map(entryMapper).valueSeq(); - entriesSequence.fromEntries = () => sequence; - return entriesSequence; - } - - forEach(sideEffect, context) { - return this.__iterate(context ? sideEffect.bind(context) : sideEffect); - } - - reduce(reducer, initialReduction, context) { - var reduction; - var useFirst; - if (arguments.length < 2) { - useFirst = true; - } else { - reduction = initialReduction; - } - this.__iterate((v, k, c) => { - if (useFirst) { - useFirst = false; - reduction = v; - } else { - reduction = reducer.call(context, reduction, v, k, c); - } - }); - return reduction; - } - - reduceRight(reducer, initialReduction, context) { - var reversed = this.toKeyedSeq().reverse(); - return reversed.reduce.apply(reversed, arguments); - } - - every(predicate, context) { - var returnValue = true; - this.__iterate((v, k, c) => { - if (!predicate.call(context, v, k, c)) { - returnValue = false; - return false; - } - }); - return returnValue; - } - - some(predicate, context) { - return !this.every(not(predicate), context); - } - - first() { - return this.find(returnTrue); - } - - last() { - return this.findLast(returnTrue); - } - - rest() { - return this.slice(1); - } - - butLast() { - return this.slice(0, -1); - } - - has(searchKey) { - return this.get(searchKey, NOT_SET) !== NOT_SET; - } - - get(searchKey, notSetValue) { - return this.find((_, key) => is(key, searchKey), null, notSetValue); - } - - getIn(searchKeyPath, notSetValue) { - var nested = this; - if (searchKeyPath) { - for (var ii = 0; ii < searchKeyPath.length; ii++) { - nested = nested && nested.get ? nested.get(searchKeyPath[ii], NOT_SET) : NOT_SET; - if (nested === NOT_SET) { - return notSetValue; - } - } - } - return nested; - } - - contains(searchValue) { - return this.find(value => is(value, searchValue), null, NOT_SET) !== NOT_SET; - } - - find(predicate, context, notSetValue) { - var foundValue = notSetValue; - this.__iterate((v, k, c) => { - if (predicate.call(context, v, k, c)) { - foundValue = v; - return false; - } - }); - return foundValue; - } - - findKey(predicate, context) { - var foundKey; - this.__iterate((v, k, c) => { - if (predicate.call(context, v, k, c)) { - foundKey = k; - return false; - } - }); - return foundKey; - } - - findLast(predicate, context, notSetValue) { - return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); - } - - findLastKey(predicate, context) { - return this.toKeyedSeq().reverse().findKey(predicate, context); - } - - flip() { - var sequence = this.toKeyedSeq(); - var flipSequence = sequence.__makeSequence(); - flipSequence.length = sequence.length; - flipSequence.flip = () => sequence; - flipSequence.has = key => sequence.contains(key); - flipSequence.contains = key => sequence.has(key); - flipSequence.__iterateUncached = function (fn, reverse) { - return sequence.__iterate((v, k) => fn(k, v, this) !== false, reverse); - } - return flipSequence; - } - - map(mapper, context) { - var sequence = this; - var mappedSequence = sequence.__makeSequence(); - mappedSequence.length = sequence.length; - mappedSequence.has = key => sequence.has(key); - mappedSequence.get = (key, notSetValue) => { - var v = sequence.get(key, NOT_SET); - return v === NOT_SET ? - notSetValue : - mapper.call(context, v, key, sequence); - }; - mappedSequence.__iterateUncached = function (fn, reverse) { - return sequence.__iterate( - (v, k, c) => fn(mapper.call(context, v, k, c), k, this) !== false, - reverse - ); - } - mappedSequence.__iteratorUncached = function (type, reverse) { - var iterator = sequence.__iterator(ITERATE_ENTRIES, reverse); - return new Iterator(() => { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - return iteratorValue( - type, - key, - mapper.call(context, entry[1], key, sequence) - ); - }); - } - return mappedSequence; - } - - mapKeys(mapper, context) { - return this.flip().map( - (k, v) => mapper.call(context, k, v, this) - ).flip(); - } - - mapEntries(mapper, context) { - return this.entrySeq().map( - (entry, index) => mapper.call(context, entry, index, this) - ).fromEntrySeq(); - } - - filter(predicate, context) { - return filterFactory(this, predicate, context, true); - } - - slice(begin, end) { - if (wholeSlice(begin, end, this.length)) { - return this; - } - var resolvedBegin = resolveBegin(begin, this.length); - var resolvedEnd = resolveEnd(end, this.length); - // begin or end will be NaN if they were provided as negative numbers and - // this sequence's length is unknown. In that case, cache first so there is - // a known length. - if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { - return this.cacheResult().slice(begin, end); - } - var skipped = resolvedBegin === 0 ? this : this.skip(resolvedBegin); - return resolvedEnd == null || resolvedEnd === this.length ? - skipped : skipped.take(resolvedEnd - resolvedBegin); - } - - take(amount) { - var sequence = this; - if (amount > sequence.length) { - return sequence; - } - if (amount < 0) { - amount = 0; - } - var takeSequence = sequence.__makeSequence(); - takeSequence.__iterateUncached = function(fn, reverse) { - if (amount === 0) { - return 0; - } - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - sequence.__iterate((v, k) => - ++iterations && fn(v, k, this) !== false && iterations < amount - ); - return iterations; - }; - takeSequence.length = this.length && Math.min(this.length, amount); - return takeSequence; - } - - takeLast(amount) { - return this.reverse().take(amount).reverse(); - } - - takeWhile(predicate, context) { - var sequence = this; - var takeSequence = sequence.__makeSequence(); - takeSequence.__iterateUncached = function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - sequence.__iterate((v, k, c) => - predicate.call(context, v, k, c) && ++iterations && fn(v, k, this) - ); - return iterations; - }; - return takeSequence; - } - - takeUntil(predicate, context) { - return this.takeWhile(not(predicate), context); - } - - skip(amount) { - return skipFactory(this, amount, true); - } - - skipLast(amount) { - return this.reverse().skip(amount).reverse(); - } - - skipWhile(predicate, context) { - return skipWhileFactory(this, predicate, context, true); - } - - skipUntil(predicate, context) { - return this.skipWhile(not(predicate), context); - } - - groupBy(grouper, context) { - return groupByFactory(this, grouper, context, true); - } - - sort(comparator) { - return this.sortBy(valueMapper, comparator); - } - - sortBy(mapper, comparator) { - comparator = comparator || defaultComparator; - var seq = this; - return Sequence(this.entrySeq().entrySeq().toArray().sort( - (a, b) => comparator( - mapper(a[1][1], a[1][0], seq), - mapper(b[1][1], b[1][0], seq) - ) || a[0] - b[0] - )).fromEntrySeq().valueSeq().fromEntrySeq(); - } - - cacheResult() { - if (!this._cache && this.__iterateUncached) { - assertNotInfinite(this.length); - this._cache = this.entrySeq().toArray(); - if (this.length == null) { - this.length = this._cache.length; - } - } - return this; - } - - keys() { - return this.__iterator(ITERATE_KEYS); - } - - values() { - return this.__iterator(ITERATE_VALUES); - } - - entries() { - return this.__iterator(ITERATE_ENTRIES); - } - - // abstract __iterateUncached(fn, reverse) - - __iterate(fn, reverse) { - return iterate(this, fn, reverse, true); - } - - // abstract __iteratorUncached(type, reverse) - - __iterator(type, reverse) { - return iterator(this, type, reverse, true); - } - - __makeSequence() { - return makeSequence(); - } -} - -var SequencePrototype = Sequence.prototype -SequencePrototype[ITERATOR_SYMBOL] = SequencePrototype.entries; -SequencePrototype.toJSON = SequencePrototype.toJS; -SequencePrototype.__toJS = SequencePrototype.toObject; -SequencePrototype.inspect = -SequencePrototype.toSource = function() { return this.toString(); }; -SequencePrototype.chain = SequencePrototype.flatMap; - - -class IndexedSequence extends Sequence { - - toString() { - return this.__toString('Seq [', ']'); - } - - toKeyedSeq() { - return new KeyedIndexedSequence(this); - } - - valueSeq() { - return this; - } - - fromEntrySeq() { - var sequence = this; - var fromEntriesSequence = makeSequence(); - fromEntriesSequence.length = sequence.length; - fromEntriesSequence.entrySeq = () => sequence; - fromEntriesSequence.__iterateUncached = function (fn, reverse) { - // Check if entry exists first so array access doesn't throw for holes - // in the parent iteration. - return sequence.__iterate( - entry => entry && fn(entry[1], entry[0], this), - reverse - ); - } - return fromEntriesSequence; - } - - concat(...values) { - return concatFactory(this, values, false); - } - - filter(predicate, context) { - return filterFactory(this, predicate, context, false); - } - - get(index, notSetValue) { - index = wrapIndex(this, index); - return this.find((_, key) => key === index, null, notSetValue); - } - - first() { - return this.get(0); - } - - last() { - return this.get(this.length ? this.length - 1 : 0); - } - - indexOf(searchValue) { - return this.findIndex(value => is(value, searchValue)); - } - - lastIndexOf(searchValue) { - return this.toKeyedSeq().reverse().indexOf(searchValue); - } - - findIndex(predicate, context) { - var key = this.findKey(predicate, context); - return key == null ? -1 : key; - } - - findLastIndex(predicate, context) { - return this.toKeyedSeq().reverse().findIndex(predicate, context); - } - - splice(index, removeNum /*, ...values*/) { - var numArgs = arguments.length; - removeNum = Math.max(removeNum | 0, 0); - if (numArgs === 0 || (numArgs === 2 && !removeNum)) { - return this; - } - index = resolveBegin(index, this.length); - var spliced = this.slice(0, index); - return numArgs === 1 ? - spliced : - spliced.concat( - arrCopy(arguments, 2), - this.slice(index + removeNum) - ); - } - - flatten() { - return flattenFactory(this, false); - } - - skip(amount) { - return skipFactory(this, amount, false); - } - - skipWhile(predicate, context) { - return skipWhileFactory(this, predicate, context, false); - } - - groupBy(grouper, context) { - return groupByFactory(this, grouper, context, false); - } - - sortBy(mapper, comparator) { - comparator = comparator || defaultComparator; - var seq = this; - return Sequence(this.entrySeq().toArray().sort( - (a, b) => comparator( - mapper(a[1], a[0], seq), - mapper(b[1], b[0], seq) - ) || a[0] - b[0] - )).fromEntrySeq().valueSeq(); - } - - __iterate(fn, reverse) { - return iterate(this, fn, reverse, false); - } - - __iterator(type, reverse) { - return iterator(this, type, reverse, false); - } - - __makeSequence() { - return makeIndexedSequence(this); - } -} - -var IndexedSequencePrototype = IndexedSequence.prototype; -IndexedSequencePrototype[ITERATOR_SYMBOL] = IndexedSequencePrototype.values; -IndexedSequencePrototype.__toJS = IndexedSequencePrototype.toArray; -IndexedSequencePrototype.__toStringMapper = quoteString; - - -class ValuesSequence extends IndexedSequence { - constructor(seq) { - this._seq = seq; - this.length = seq.length; - } - - get(key, notSetValue) { - return this._seq.get(key, notSetValue); - } - - has(key) { - return this._seq.has(key); - } - - cacheResult() { - this._seq.cacheResult(); - this.length = this._seq.length; - } - - __iterate(fn, reverse) { - var iterations = 0; - return this._seq.__iterate(v => fn(v, iterations++, this), reverse); - } - - __iterator(type, reverse) { - var iterator = this._seq.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - var step; - return new Iterator(() => - (step = iterator.next()).done ? - iteratorDone() : - iteratorValue(type, iterations++, step.value) - ); - } -} - - -class KeyedIndexedSequence extends Sequence { - constructor(indexedSeq) { - this._seq = indexedSeq; - this.length = indexedSeq.length; - } - - get(key, notSetValue) { - return this._seq.get(key, notSetValue); - } - - has(key) { - return this._seq.has(key); - } - - cacheResult() { - this._seq.cacheResult(); - this.length = this._seq.length; - } - - __iterate(fn, reverse) { - var ii = reverse ? ensureLength(this) : 0; - return this._seq.__iterate( - v => fn(v, reverse ? --ii : ii++, this), - reverse - ); - } - - __iterator(type, reverse) { - var iterator = this._seq.__iterator(ITERATE_VALUES, reverse); - var ii = reverse ? ensureLength(this) : 0; - return new Iterator(() => { - var step = iterator.next(); - return step.done ? step : - iteratorValue(type, reverse ? --ii : ii++, step.value) - }); - } -} - - -class IteratorSequence extends IndexedSequence { - constructor(iterator) { - this._iterator = iterator; - this._iteratorCache = []; - } - - __iterateUncached(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - while (iterations < cache.length) { - if (fn(cache[iterations], iterations++, this) === false) { - return iterations; - } - } - var step; - while (!(step = iterator.next()).done) { - var val = step.value; - cache[iterations] = val; - if (fn(val, iterations++, this) === false) { - break; - } - } - return iterations; - } - - __iteratorUncached(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - return new Iterator(() => { - if (iterations >= cache.length) { - var step = iterator.next(); - if (step.done) { - return step; - } - cache[iterations] = step.value; - } - return iteratorValue(type, iterations, cache[iterations++]); - }); - } -} - - -class IterableSequence extends IndexedSequence { - constructor(iterable) { - this._iterable = iterable; - this.length = iterable.length || iterable.size; - } - - __iterateUncached(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterable = this._iterable; - var iterator = getIterator(iterable); - var iterations = 0; - if (isIterator(iterator)) { - var step; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } - } - return iterations; - } - - __iteratorUncached(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterable = this._iterable; - var iterator = getIterator(iterable); - if (!isIterator(iterator)) { - return new Iterator(() => iteratorDone()); - } - var iterations = 0; - return new Iterator(() => { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, iterations++, step.value); - }); - } -} - - -class ObjectSequence extends Sequence { - constructor(object) { - var keys = Object.keys(object); - this._object = object; - this._keys = keys; - this.length = keys.length; - } - - toObject() { - return this._object; - } - - get(key, notSetValue) { - if (notSetValue !== undefined && !this.has(key)) { - return notSetValue; - } - return this._object[key]; - } - - has(key) { - return this._object.hasOwnProperty(key); - } - - __iterate(fn, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var key = keys[reverse ? maxIndex - ii : ii]; - if (fn(object[key], key, this) === false) { - return ii + 1; - } - } - return ii; - } - - __iterator(type, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - var ii = 0; - return new Iterator(() => { - var key = keys[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? - iteratorDone() : - iteratorValue(type, key, object[key]); - }); - } -} - - -class ArraySequence extends IndexedSequence { - constructor(array) { - this._array = array; - this.length = array.length; - } - - toArray() { - return this._array; - } - - get(index, notSetValue) { - return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; - } - - has(index) { - index = wrapIndex(this, index); - return index >= 0 && index < this.length; - } - - __iterate(fn, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { - return ii + 1; - } - } - return ii; - } - - __iterator(type, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - var ii = 0; - return new Iterator(() => - ii > maxIndex ? - iteratorDone() : - iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++]) - ); - } -} - - -function makeSequence() { - return Object.create(SequencePrototype); -} - -function makeIndexedSequence(parent) { - return Object.create(IndexedSequencePrototype); -} - -function ensureLength(indexedSeq) { - if (indexedSeq.length == null) { - indexedSeq.cacheResult(); - } - invariant(indexedSeq.length < Infinity, 'Cannot reverse infinite range.'); - return indexedSeq.length; -} - -function wholeSlice(begin, end, length) { - return (begin === 0 || (length != null && begin <= -length)) && - (end == null || (length != null && end >= length)); -} - -function resolveBegin(begin, length) { - return resolveIndex(begin, length, 0); -} - -function resolveEnd(end, length) { - return resolveIndex(end, length, length); -} - -function resolveIndex(index, length, defaultIndex) { - return index == null ? - defaultIndex : - index < 0 ? - Math.max(0, length + index) : - length ? - Math.min(length, index) : - index; -} - -function valueMapper(v) { - return v; -} - -function entryMapper(v, k) { - return [k, v]; -} - -function returnTrue() { - return true; -} - -function iterate(sequence, fn, reverse, useKeys) { - var cache = sequence._cache; - if (cache) { - var maxIndex = cache.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var entry = cache[reverse ? maxIndex - ii : ii]; - if (fn(entry[1], useKeys ? entry[0] : ii, sequence) === false) { - return ii + 1; - } - } - return ii; - } - return sequence.__iterateUncached(fn, reverse); -} - -function iterator(sequence, type, reverse, useKeys) { - var cache = sequence._cache; - if (cache) { - var maxIndex = cache.length - 1; - var ii = 0; - return new Iterator(() => { - var entry = cache[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? - iteratorDone() : - iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); - }); - } - // TODO: remove when all Sequences implement __iterator or __iteratorUncached - if (!sequence.__iteratorUncached) { - return sequence.cacheResult().__iterator(type, reverse); - } - return sequence.__iteratorUncached(type, reverse); -} - -function filterFactory(sequence, predicate, context, useKeys) { - var filterSequence = sequence.__makeSequence(); - filterSequence.has = key => { - var v = sequence.get(key, NOT_SET); - return v !== NOT_SET && !!predicate.call(context, v, key, sequence); - }; - filterSequence.get = (key, notSetValue) => { - var v = sequence.get(key, NOT_SET); - return v !== NOT_SET && predicate.call(context, v, key, sequence) ? - v : notSetValue; - }; - filterSequence.__iterateUncached = function (fn, reverse) { - var iterations = 0; - sequence.__iterate((v, k, c) => { - if (predicate.call(context, v, k, c)) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this); - } - }, reverse); - return iterations; - }; - filterSequence.__iteratorUncached = function (type, reverse) { - var iterator = sequence.__iterator(ITERATE_ENTRIES, reverse); - var iterations = 0; - return new Iterator(() => { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - var value = entry[1]; - if (predicate.call(context, value, key, sequence)) { - return iteratorValue(type, useKeys ? key : iterations++, value); - } - } - }); - } - return filterSequence; -} - -function groupByFactory(seq, grouper, context, useKeys) { - var groupMap = {}; - var groups = []; - seq.__iterate((v, k) => { - var g = grouper.call(context, v, k, seq); - var h = hash(g); - var e = useKeys ? [k, v] : v; - if (!groupMap.hasOwnProperty(h)) { - groupMap[h] = groups.length; - groups.push([g, [e]]); - } else { - groups[groupMap[h]][1].push(e); - } - }); - return Sequence(groups).fromEntrySeq().map(useKeys ? - group => Sequence(group).fromEntrySeq() : - group => Sequence(group) - ); -} - -function skipFactory(sequence, amount, useKeys) { - if (amount <= 0) { - return sequence; - } - var skipSequence = sequence.__makeSequence(); - skipSequence.__iterateUncached = function (fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var skipped = 0; - var isSkipping = true; - var iterations = 0; - sequence.__iterate((v, k) => { - if (!(isSkipping && (isSkipping = skipped++ < amount))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this); - } - }); - return iterations; - }; - skipSequence.length = sequence.length && Math.max(0, sequence.length - amount); - return skipSequence; -} - -function skipWhileFactory(sequence, predicate, context, useKeys) { - var skipSequence = sequence.__makeSequence(); - skipSequence.__iterateUncached = function (fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var isSkipping = true; - var iterations = 0; - sequence.__iterate((v, k, c) => { - if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this); - } - }); - return iterations; - }; - return skipSequence; -} - -function concatFactory(sequence, values, useKeys) { - var sequences = [sequence].concat(values); - var concatSequence = Sequence(sequences); - if (useKeys) { - concatSequence = concatSequence.toKeyedSeq(); - } - concatSequence = concatSequence.flatten(); - concatSequence.length = sequences.reduce( - (sum, seq) => { - if (sum !== undefined) { - var len = Sequence(seq).length; - if (len != null) { - return sum + len; - } - } - }, - 0 - ); - return concatSequence; -} - -function flattenFactory(sequence, useKeys) { - var flatSequence = sequence.__makeSequence(); - flatSequence.__iterateUncached = function(fn, reverse) { - var iterations = 0; - sequence.__iterate(seq => { - var stopped = false; - Sequence(seq).__iterate((v, k) => { - if (fn(v, useKeys ? k : iterations++, this) === false) { - stopped = true; - return false; - } - }, reverse); - return !stopped; - }, reverse); - return iterations; - } - return flatSequence; -} - -function not(predicate) { - return function() { - return !predicate.apply(this, arguments); - } -} - -function quoteString(value) { - return typeof value === 'string' ? JSON.stringify(value) : value; -} - -function defaultComparator(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -} - -function wrapIndex(seq, index) { - if (index < 0) { - if (seq.length == null) { - seq.cacheResult(); - } - return seq.length + index; - } - return index; -} - -function assertNotInfinite(length) { - invariant( - length !== Infinity, - 'Cannot perform this action with an infinite sequence.' - ); -} diff --git a/src/Set.js b/src/Set.js index d171f34437..cc42bc10f7 100644 --- a/src/Set.js +++ b/src/Set.js @@ -1,45 +1,52 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Sequence" -import "Map" -import "TrieUtils" -import "Iterator" -/* global Sequence, IndexedSequencePrototype, iteratorMapper, - Map, MapPrototype, DELETE, - ITERATOR_SYMBOL, ITERATE_KEYS, ITERATE_ENTRIES */ -/* exported Set */ - - -class Set extends Sequence { - +import { Collection, SetCollection, KeyedCollection } from './Collection'; +import { isOrdered } from './predicates/isOrdered'; +import { IS_SET_SYMBOL, isSet } from './predicates/isSet'; +import { emptyMap } from './Map'; +import { DELETE } from './TrieUtils'; +import { sortFactory } from './Operations'; +import assertNotInfinite from './utils/assertNotInfinite'; +import { asImmutable } from './methods/asImmutable'; +import { asMutable } from './methods/asMutable'; +import { withMutations } from './methods/withMutations'; + +import { OrderedSet } from './OrderedSet'; + +export class Set extends SetCollection { // @pragma Construction - constructor(...values) { - return Set.from(values); + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySet() + : isSet(value) && !isOrdered(value) + ? value + : emptySet().withMutations((set) => { + const iter = SetCollection(value); + assertNotInfinite(iter.size); + iter.forEach((v) => set.add(v)); + }); + } + + static of(/*...values*/) { + return this(arguments); } - static empty() { - return EMPTY_SET || (EMPTY_SET = makeSet(Map.empty())); + static fromKeys(value) { + return this(KeyedCollection(value).keySeq()); } - static from(sequence) { - var set = Set.empty(); - return sequence ? - sequence.constructor === Set ? - sequence : - set.union(sequence) : - set; + static intersect(sets) { + sets = Collection(sets).toArray(); + return sets.length + ? SetPrototype.intersect.apply(Set(sets.pop()), sets) + : emptySet(); } - static fromKeys(sequence) { - return Set.from(Sequence(sequence).flip()); + static union(sets) { + sets = Collection(sets).toArray(); + return sets.length + ? SetPrototype.union.apply(Set(sets.pop()), sets) + : emptySet(); } toString() { @@ -52,158 +59,177 @@ class Set extends Sequence { return this._map.has(value); } - get(value, notSetValue) { - return this.has(value) ? value : notSetValue; - } - // @pragma Modification add(value) { - var newMap = this._map.set(value, null); - if (this.__ownerID) { - this.length = newMap.length; - this._map = newMap; - return this; - } - return newMap === this._map ? this : makeSet(newMap); + return updateSet(this, this._map.set(value, value)); } remove(value) { - var newMap = this._map.remove(value); - if (this.__ownerID) { - this.length = newMap.length; - this._map = newMap; - return this; - } - return newMap === this._map ? this : newMap.length === 0 ? Set.empty() : makeSet(newMap); + return updateSet(this, this._map.remove(value)); } clear() { - if (this.length === 0) { - return this; - } - if (this.__ownerID) { - this.length = 0; - this._map.clear(); - return this; - } - return Set.empty(); + return updateSet(this, this._map.clear()); } // @pragma Composition - union(/*...seqs*/) { - var seqs = arguments; - if (seqs.length === 0) { + map(mapper, context) { + // keep track if the set is altered by the map function + let didChanges = false; + + const newMap = updateSet( + this, + this._map.mapEntries(([, v]) => { + const mapped = mapper.call(context, v, v, this); + + if (mapped !== v) { + didChanges = true; + } + + return [mapped, mapped]; + }, context) + ); + + return didChanges ? newMap : this; + } + + union(...iters) { + iters = iters.filter((x) => x.size !== 0); + if (iters.length === 0) { return this; } - return this.withMutations(set => { - for (var ii = 0; ii < seqs.length; ii++) { - Sequence(seqs[ii]).forEach(value => set.add(value)); + if (this.size === 0 && !this.__ownerID && iters.length === 1) { + return this.constructor(iters[0]); + } + return this.withMutations((set) => { + for (let ii = 0; ii < iters.length; ii++) { + if (typeof iters[ii] === 'string') { + set.add(iters[ii]); + } else { + SetCollection(iters[ii]).forEach((value) => set.add(value)); + } } }); } - intersect(...seqs) { - if (seqs.length === 0) { + intersect(...iters) { + if (iters.length === 0) { return this; } - seqs = seqs.map(seq => Sequence(seq)); - var originalSet = this; - return this.withMutations(set => { - originalSet.forEach(value => { - if (!seqs.every(seq => seq.contains(value))) { - set.remove(value); - } + iters = iters.map((iter) => SetCollection(iter)); + const toRemove = []; + this.forEach((value) => { + if (!iters.every((iter) => iter.includes(value))) { + toRemove.push(value); + } + }); + return this.withMutations((set) => { + toRemove.forEach((value) => { + set.remove(value); }); }); } - subtract(...seqs) { - if (seqs.length === 0) { + subtract(...iters) { + if (iters.length === 0) { return this; } - seqs = seqs.map(seq => Sequence(seq)); - var originalSet = this; - return this.withMutations(set => { - originalSet.forEach(value => { - if (seqs.some(seq => seq.contains(value))) { - set.remove(value); - } + iters = iters.map((iter) => SetCollection(iter)); + const toRemove = []; + this.forEach((value) => { + if (iters.some((iter) => iter.includes(value))) { + toRemove.push(value); + } + }); + return this.withMutations((set) => { + toRemove.forEach((value) => { + set.remove(value); }); }); } - isSubset(seq) { - seq = Sequence(seq); - return this.every(value => seq.contains(value)); + sort(comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator)); } - isSuperset(seq) { - var set = this; - seq = Sequence(seq); - return seq.every(value => set.contains(value)); + sortBy(mapper, comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator, mapper)); } wasAltered() { return this._map.wasAltered(); } - hashCode() { - return this._map.hashCode(); - } - - __iterator(type, reverse) { - var iterator = this._map.__iterator(ITERATE_KEYS, reverse); - return type === ITERATE_ENTRIES ? - iteratorMapper(iterator, key => [key, key]) : - iterator; - } - __iterate(fn, reverse) { - var collection = this; - return this._map.__iterate((_, k) => fn(k, k, collection), reverse); + return this._map.__iterate((k) => fn(k, k, this), reverse); } - __deepEquals(other) { - return this.isSuperset(other); + __iterator(type, reverse) { + return this._map.__iterator(type, reverse); } __ensureOwner(ownerID) { if (ownerID === this.__ownerID) { return this; } - var newMap = this._map.__ensureOwner(ownerID); + const newMap = this._map.__ensureOwner(ownerID); if (!ownerID) { + if (this.size === 0) { + return this.__empty(); + } this.__ownerID = ownerID; this._map = newMap; return this; } - return makeSet(newMap, ownerID); + return this.__make(newMap, ownerID); } } -var SetPrototype = Set.prototype; +Set.isSet = isSet; + +const SetPrototype = Set.prototype; +SetPrototype[IS_SET_SYMBOL] = true; SetPrototype[DELETE] = SetPrototype.remove; -SetPrototype[ITERATOR_SYMBOL] = SetPrototype.values; -SetPrototype.contains = SetPrototype.has; -SetPrototype.mergeDeep = SetPrototype.merge = SetPrototype.union; -SetPrototype.mergeDeepWith = SetPrototype.mergeWith = function(merger, ...seqs) { - return this.merge.apply(this, seqs); +SetPrototype.merge = SetPrototype.concat = SetPrototype.union; +SetPrototype.withMutations = withMutations; +SetPrototype.asImmutable = asImmutable; +SetPrototype['@@transducer/init'] = SetPrototype.asMutable = asMutable; +SetPrototype['@@transducer/step'] = function (result, arr) { + return result.add(arr); +}; +SetPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); }; -SetPrototype.withMutations = MapPrototype.withMutations; -SetPrototype.asMutable = MapPrototype.asMutable; -SetPrototype.asImmutable = MapPrototype.asImmutable; -SetPrototype.__toJS = IndexedSequencePrototype.__toJS; -SetPrototype.__toStringMapper = IndexedSequencePrototype.__toStringMapper; +SetPrototype.__empty = emptySet; +SetPrototype.__make = makeSet; + +function updateSet(set, newMap) { + if (set.__ownerID) { + set.size = newMap.size; + set._map = newMap; + return set; + } + return newMap === set._map + ? set + : newMap.size === 0 + ? set.__empty() + : set.__make(newMap); +} function makeSet(map, ownerID) { - var set = Object.create(SetPrototype); - set.length = map ? map.length : 0; + const set = Object.create(SetPrototype); + set.size = map ? map.size : 0; set._map = map; set.__ownerID = ownerID; return set; } -var EMPTY_SET; +let EMPTY_SET; +function emptySet() { + return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); +} diff --git a/src/Stack.js b/src/Stack.js new file mode 100644 index 0000000000..32414fa3a0 --- /dev/null +++ b/src/Stack.js @@ -0,0 +1,227 @@ +import { wholeSlice, resolveBegin, resolveEnd, wrapIndex } from './TrieUtils'; +import { IndexedCollection } from './Collection'; +import { ArraySeq } from './Seq'; +import { Iterator, iteratorValue, iteratorDone } from './Iterator'; +import { IS_STACK_SYMBOL, isStack } from './predicates/isStack'; +import assertNotInfinite from './utils/assertNotInfinite'; +import { asImmutable } from './methods/asImmutable'; +import { asMutable } from './methods/asMutable'; +import { wasAltered } from './methods/wasAltered'; +import { withMutations } from './methods/withMutations'; + +export class Stack extends IndexedCollection { + // @pragma Construction + + constructor(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyStack() + : isStack(value) + ? value + : emptyStack().pushAll(value); + } + + static of(/*...values*/) { + return this(arguments); + } + + toString() { + return this.__toString('Stack [', ']'); + } + + // @pragma Access + + get(index, notSetValue) { + let head = this._head; + index = wrapIndex(this, index); + while (head && index--) { + head = head.next; + } + return head ? head.value : notSetValue; + } + + peek() { + return this._head && this._head.value; + } + + // @pragma Modification + + push(/*...values*/) { + if (arguments.length === 0) { + return this; + } + const newSize = this.size + arguments.length; + let head = this._head; + for (let ii = arguments.length - 1; ii >= 0; ii--) { + head = { + value: arguments[ii], + next: head, + }; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + } + + pushAll(iter) { + iter = IndexedCollection(iter); + if (iter.size === 0) { + return this; + } + if (this.size === 0 && isStack(iter)) { + return iter; + } + assertNotInfinite(iter.size); + let newSize = this.size; + let head = this._head; + iter.__iterate((value) => { + newSize++; + head = { + value: value, + next: head, + }; + }, /* reverse */ true); + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + } + + pop() { + return this.slice(1); + } + + clear() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._head = undefined; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyStack(); + } + + slice(begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + let resolvedBegin = resolveBegin(begin, this.size); + const resolvedEnd = resolveEnd(end, this.size); + if (resolvedEnd !== this.size) { + // super.slice(begin, end); + return IndexedCollection.prototype.slice.call(this, begin, end); + } + const newSize = this.size - resolvedBegin; + let head = this._head; + while (resolvedBegin--) { + head = head.next; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + } + + // @pragma Mutability + + __ensureOwner(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + if (this.size === 0) { + return emptyStack(); + } + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeStack(this.size, this._head, ownerID, this.__hash); + } + + // @pragma Iteration + + __iterate(fn, reverse) { + if (reverse) { + return new ArraySeq(this.toArray()).__iterate( + (v, k) => fn(v, k, this), + reverse + ); + } + let iterations = 0; + let node = this._head; + while (node) { + if (fn(node.value, iterations++, this) === false) { + break; + } + node = node.next; + } + return iterations; + } + + __iterator(type, reverse) { + if (reverse) { + return new ArraySeq(this.toArray()).__iterator(type, reverse); + } + let iterations = 0; + let node = this._head; + return new Iterator(() => { + if (node) { + const value = node.value; + node = node.next; + return iteratorValue(type, iterations++, value); + } + return iteratorDone(); + }); + } +} + +Stack.isStack = isStack; + +const StackPrototype = Stack.prototype; +StackPrototype[IS_STACK_SYMBOL] = true; +StackPrototype.shift = StackPrototype.pop; +StackPrototype.unshift = StackPrototype.push; +StackPrototype.unshiftAll = StackPrototype.pushAll; +StackPrototype.withMutations = withMutations; +StackPrototype.wasAltered = wasAltered; +StackPrototype.asImmutable = asImmutable; +StackPrototype['@@transducer/init'] = StackPrototype.asMutable = asMutable; +StackPrototype['@@transducer/step'] = function (result, arr) { + return result.unshift(arr); +}; +StackPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +function makeStack(size, head, ownerID, hash) { + const map = Object.create(StackPrototype); + map.size = size; + map._head = head; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; +} + +let EMPTY_STACK; +function emptyStack() { + return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); +} diff --git a/src/TrieUtils.js b/src/TrieUtils.js deleted file mode 100644 index 9eaa300bd1..0000000000 --- a/src/TrieUtils.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/* exported DELETE, SHIFT, SIZE, MASK, NOT_SET, CHANGE_LENGTH, DID_ALTER, - OwnerID, MakeRef, SetRef, arrCopy */ - -// Used for setting prototype methods that IE8 chokes on. -var DELETE = 'delete'; - -// Constants describing the size of trie nodes. -var SHIFT = 5; // Resulted in best performance after ______? -var SIZE = 1 << SHIFT; -var MASK = SIZE - 1; - -// A consistent shared value representing "not set" which equals nothing other -// than itself, and nothing that could be provided externally. -var NOT_SET = {}; - -// Boolean references, Rough equivalent of `bool &`. -var CHANGE_LENGTH = { value: false }; -var DID_ALTER = { value: false }; - -function MakeRef(ref) { - ref.value = false; - return ref; -} - -function SetRef(ref) { - ref && (ref.value = true); -} - -// A function which returns a value representing an "owner" for transient writes -// to tries. The return value will only ever equal itself, and will not equal -// the return of any subsequent call of this function. -function OwnerID() {} - -// http://jsperf.com/copy-array-inline -function arrCopy(arr, offset) { - offset = offset || 0; - var len = Math.max(0, arr.length - offset); - var newArr = new Array(len); - for (var ii = 0; ii < len; ii++) { - newArr[ii] = arr[ii + offset]; - } - return newArr; -} diff --git a/src/TrieUtils.ts b/src/TrieUtils.ts new file mode 100644 index 0000000000..d5c75c179b --- /dev/null +++ b/src/TrieUtils.ts @@ -0,0 +1,105 @@ +import type { Collection } from '../type-definitions/immutable'; + +// Used for setting prototype methods that IE8 chokes on. +export const DELETE = 'delete'; + +// Constants describing the size of trie nodes. +export const SHIFT = 5; // Resulted in best performance after ______? +export const SIZE = 1 << SHIFT; +export const MASK = SIZE - 1; + +// A consistent shared value representing "not set" which equals nothing other +// than itself, and nothing that could be provided externally. +export const NOT_SET = {}; + +type Ref = { value: boolean }; + +// Boolean references, Rough equivalent of `bool &`. +export function MakeRef(): Ref { + return { value: false }; +} + +export function SetRef(ref: Ref): void { + if (ref) { + ref.value = true; + } +} + +// A function which returns a value representing an "owner" for transient writes +// to tries. The return value will only ever equal itself, and will not equal +// the return of any subsequent call of this function. +export function OwnerID() {} + +export function ensureSize(iter: Collection): number { + // @ts-expect-error size should exists on Collection + if (iter.size === undefined) { + // @ts-expect-error size should exists on Collection, __iterate does exist on Collection + iter.size = iter.__iterate(returnTrue); + } + // @ts-expect-error size should exists on Collection + return iter.size; +} + +export function wrapIndex( + iter: Collection, + index: number +): number { + // This implements "is array index" which the ECMAString spec defines as: + // + // A String property name P is an array index if and only if + // ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal + // to 2^32−1. + // + // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects + if (typeof index !== 'number') { + const uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32 + if ('' + uint32Index !== index || uint32Index === 4294967295) { + return NaN; + } + index = uint32Index; + } + return index < 0 ? ensureSize(iter) + index : index; +} + +export function returnTrue(): true { + return true; +} + +export function wholeSlice(begin: number, end: number, size: number): boolean { + return ( + ((begin === 0 && !isNeg(begin)) || + (size !== undefined && begin <= -size)) && + (end === undefined || (size !== undefined && end >= size)) + ); +} + +export function resolveBegin(begin: number, size: number): number { + return resolveIndex(begin, size, 0); +} + +export function resolveEnd(end: number, size: number): number { + return resolveIndex(end, size, size); +} + +function resolveIndex( + index: number, + size: number, + defaultIndex: number +): number { + // Sanitize indices using this shorthand for ToInt32(argument) + // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 + return index === undefined + ? defaultIndex + : isNeg(index) + ? size === Infinity + ? size + : Math.max(0, size + index) | 0 + : size === undefined || size === index + ? index + : Math.min(size, index) | 0; +} + +function isNeg(value: number): boolean { + // Account for -0 which is negative, but not less than 0. + return value < 0 || (value === 0 && 1 / value === -Infinity); +} diff --git a/src/Vector.js b/src/Vector.js deleted file mode 100644 index 6bffe2c337..0000000000 --- a/src/Vector.js +++ /dev/null @@ -1,634 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Sequence" -import "is" -import "Map" -import "TrieUtils" -import "Iterator" -/* global Sequence, IndexedSequence, is, wrapIndex, - MapPrototype, mergeIntoCollectionWith, deepMerger, - DELETE, SHIFT, SIZE, MASK, NOT_SET, DID_ALTER, OwnerID, MakeRef, - SetRef, arrCopy, Iterator, iteratorValue, iteratorDone */ -/* exported Vector, VectorPrototype */ - - -class Vector extends IndexedSequence { - - // @pragma Construction - - constructor(...values) { - return Vector.from(values); - } - - static empty() { - return EMPTY_VECT || (EMPTY_VECT = makeVector(0, 0, SHIFT)); - } - - static from(sequence) { - if (!sequence || sequence.length === 0) { - return Vector.empty(); - } - if (sequence.constructor === Vector) { - return sequence; - } - var isArray = Array.isArray(sequence); - if (sequence.length > 0 && sequence.length < SIZE) { - return makeVector(0, sequence.length, SHIFT, null, new VNode( - isArray ? arrCopy(sequence) : Sequence(sequence).toArray() - )); - } - if (!isArray) { - sequence = Sequence(sequence).valueSeq(); - } - return Vector.empty().merge(sequence); - } - - toString() { - return this.__toString('Vector [', ']'); - } - - // @pragma Access - - has(index) { - index = wrapIndex(this, index); - return index >= 0 && index < this.length; - } - - get(index, notSetValue) { - index = wrapIndex(this, index); - if (index < 0 || index >= this.length) { - return notSetValue; - } - index += this._origin; - var node = vectorNodeFor(this, index); - return node && node.array[index & MASK]; - } - - // @pragma Modification - - set(index, value) { - return updateVector(this, index, value); - } - - remove(index) { - return updateVector(this, index, NOT_SET); - } - - clear() { - if (this.length === 0) { - return this; - } - if (this.__ownerID) { - this.length = this._origin = this._size = 0; - this._level = SHIFT; - this._root = this._tail = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return Vector.empty(); - } - - push(/*...values*/) { - var values = arguments; - var oldLength = this.length; - return this.withMutations(vect => { - setVectorBounds(vect, 0, oldLength + values.length); - for (var ii = 0; ii < values.length; ii++) { - vect.set(oldLength + ii, values[ii]); - } - }); - } - - pop() { - return setVectorBounds(this, 0, -1); - } - - unshift(/*...values*/) { - var values = arguments; - return this.withMutations(vect => { - setVectorBounds(vect, -values.length); - for (var ii = 0; ii < values.length; ii++) { - vect.set(ii, values[ii]); - } - }); - } - - shift() { - return setVectorBounds(this, 1); - } - - // @pragma Composition - - merge(/*...seqs*/) { - return mergeIntoVectorWith(this, null, arguments); - } - - mergeWith(merger, ...seqs) { - return mergeIntoVectorWith(this, merger, seqs); - } - - mergeDeep(/*...seqs*/) { - return mergeIntoVectorWith(this, deepMerger(null), arguments); - } - - mergeDeepWith(merger, ...seqs) { - return mergeIntoVectorWith(this, deepMerger(merger), seqs); - } - - setLength(length) { - return setVectorBounds(this, 0, length); - } - - // @pragma Iteration - - slice(begin, end) { - var sliceSequence = super.slice(begin, end); - // Optimize the case of vector.slice(b, e).toVector() - if (sliceSequence !== this) { - var vector = this; - var length = vector.length; - sliceSequence.toVector = () => setVectorBounds( - vector, - begin < 0 ? Math.max(0, length + begin) : length ? Math.min(length, begin) : begin, - end == null ? length : end < 0 ? Math.max(0, length + end) : length ? Math.min(length, end) : end - ); - } - return sliceSequence; - } - - __iterator(type, reverse) { - return new VectorIterator(this, type, reverse); - } - - __iterate(fn, reverse) { - var iterations = 0; - var eachFn = v => fn(v, iterations++, this); - var tailOffset = getTailOffset(this._size); - if (reverse) { - iterateVNode(this._tail, 0, tailOffset - this._origin, this._size - this._origin, eachFn, reverse) && - iterateVNode(this._root, this._level, -this._origin, tailOffset - this._origin, eachFn, reverse); - } else { - iterateVNode(this._root, this._level, -this._origin, tailOffset - this._origin, eachFn, reverse) && - iterateVNode(this._tail, 0, tailOffset - this._origin, this._size - this._origin, eachFn, reverse); - } - return iterations; - } - - __deepEquals(other) { - var iterator = this.entries(true); - return other.every((v, i) => { - var entry = iterator.next().value; - return entry && entry[0] === i && is(entry[1], v); - }); - } - - __ensureOwner(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - return this; - } - return makeVector(this._origin, this._size, this._level, this._root, this._tail, ownerID, this.__hash); - } -} - -var VectorPrototype = Vector.prototype; -VectorPrototype[DELETE] = VectorPrototype.remove; -VectorPrototype.update = MapPrototype.update; -VectorPrototype.updateIn = MapPrototype.updateIn; -VectorPrototype.cursor = MapPrototype.cursor; -VectorPrototype.withMutations = MapPrototype.withMutations; -VectorPrototype.asMutable = MapPrototype.asMutable; -VectorPrototype.asImmutable = MapPrototype.asImmutable; -VectorPrototype.wasAltered = MapPrototype.wasAltered; - - -class VNode { - constructor(array, ownerID) { - this.array = array; - this.ownerID = ownerID; - } - - // TODO: seems like these methods are very similar - - removeBefore(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var originIndex = (index >>> level) & MASK; - if (originIndex >= this.array.length) { - return new VNode([], ownerID); - } - var removingFirst = originIndex === 0; - var newChild; - if (level > 0) { - var oldChild = this.array[originIndex]; - newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingFirst) { - return this; - } - } - if (removingFirst && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingFirst) { - for (var ii = 0; ii < originIndex; ii++) { - editable.array[ii] = undefined; - } - } - if (newChild) { - editable.array[originIndex] = newChild; - } - return editable; - } - - removeAfter(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var sizeIndex = ((index - 1) >>> level) & MASK; - if (sizeIndex >= this.array.length) { - return this; - } - var removingLast = sizeIndex === this.array.length - 1; - var newChild; - if (level > 0) { - var oldChild = this.array[sizeIndex]; - newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingLast) { - return this; - } - } - if (removingLast && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingLast) { - editable.array.pop(); - } - if (newChild) { - editable.array[sizeIndex] = newChild; - } - return editable; - } -} - -function iterateVNode(node, level, offset, max, fn, reverse) { - var ii; - var array = node && node.array; - if (level === 0) { - var from = offset < 0 ? -offset : 0; - var to = max - offset; - if (to > SIZE) { - to = SIZE; - } - for (ii = from; ii < to; ii++) { - if (fn(array && array[reverse ? from + to - 1 - ii : ii]) === false) { - return false; - } - } - } else { - var step = 1 << level; - var newLevel = level - SHIFT; - for (ii = 0; ii <= MASK; ii++) { - var levelIndex = reverse ? MASK - ii : ii; - var newOffset = offset + (levelIndex << level); - if (newOffset < max && newOffset + step > 0) { - var nextNode = array && array[levelIndex]; - if (!iterateVNode(nextNode, newLevel, newOffset, max, fn, reverse)) { - return false; - } - } - } - } - return true; -} - -class VectorIterator extends Iterator { - - constructor(vector, type, reverse) { - this._type = type; - this._reverse = !!reverse; - this._maxIndex = vector.length - 1; - var tailOffset = getTailOffset(vector._size); - var rootStack = vectIteratorFrame( - vector._root && vector._root.array, - vector._level, - -vector._origin, - tailOffset - vector._origin - 1 - ); - var tailStack = vectIteratorFrame( - vector._tail && vector._tail.array, - 0, - tailOffset - vector._origin, - vector._size - vector._origin - 1 - ); - this._stack = reverse ? tailStack : rootStack; - this._stack.__prev = reverse ? rootStack : tailStack; - } - - next() { - var stack = this._stack; - while (stack) { - var array = stack.array; - var rawIndex = stack.index++; - if (this._reverse) { - rawIndex = MASK - rawIndex; - if (rawIndex > stack.rawMax) { - rawIndex = stack.rawMax; - stack.index = SIZE - rawIndex; - } - } - if (rawIndex >= 0 && rawIndex < SIZE && rawIndex <= stack.rawMax) { - var value = array && array[rawIndex]; - if (stack.level === 0) { - var type = this._type; - var index; - if (type !== 1) { - index = stack.offset + (rawIndex << stack.level); - if (this._reverse) { - index = this._maxIndex - index; - } - } - return iteratorValue(type, index, value); - } else { - this._stack = stack = vectIteratorFrame( - value && value.array, - stack.level - SHIFT, - stack.offset + (rawIndex << stack.level), - stack.max, - stack - ); - } - continue; - } - stack = this._stack = this._stack.__prev; - } - return iteratorDone(); - } -} - -function vectIteratorFrame(array, level, offset, max, prevFrame) { - return { - array: array, - level: level, - offset: offset, - max: max, - rawMax: ((max - offset) >> level), - index: 0, - __prev: prevFrame - }; -} - -function makeVector(origin, size, level, root, tail, ownerID, hash) { - var vect = Object.create(VectorPrototype); - vect.length = size - origin; - vect._origin = origin; - vect._size = size; - vect._level = level; - vect._root = root; - vect._tail = tail; - vect.__ownerID = ownerID; - vect.__hash = hash; - vect.__altered = false; - return vect; -} - -function updateVector(vector, index, value) { - index = wrapIndex(vector, index); - - if (index >= vector.length || index < 0) { - return value === NOT_SET ? vector : vector.withMutations(vect => { - index < 0 ? - setVectorBounds(vect, index).set(0, value) : - setVectorBounds(vect, 0, index + 1).set(index, value) - }); - } - - index += vector._origin; - - var newTail = vector._tail; - var newRoot = vector._root; - var didAlter = MakeRef(DID_ALTER); - if (index >= getTailOffset(vector._size)) { - newTail = updateVNode(newTail, vector.__ownerID, 0, index, value, didAlter); - } else { - newRoot = updateVNode(newRoot, vector.__ownerID, vector._level, index, value, didAlter); - } - - if (!didAlter.value) { - return vector; - } - - if (vector.__ownerID) { - vector._root = newRoot; - vector._tail = newTail; - vector.__hash = undefined; - vector.__altered = true; - return vector; - } - return makeVector(vector._origin, vector._size, vector._level, newRoot, newTail); -} - -function updateVNode(node, ownerID, level, index, value, didAlter) { - var removed = value === NOT_SET; - var newNode; - var idx = (index >>> level) & MASK; - var nodeHas = node && idx < node.array.length; - if (removed && !nodeHas) { - return node; - } - - if (level > 0) { - var lowerNode = node && node.array[idx]; - var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); - if (newLowerNode === lowerNode) { - return node; - } - newNode = editableVNode(node, ownerID); - newNode.array[idx] = newLowerNode; - return newNode; - } - - if (!removed && nodeHas && node.array[idx] === value) { - return node; - } - - SetRef(didAlter); - - newNode = editableVNode(node, ownerID); - if (removed && idx === newNode.array.length - 1) { - newNode.array.pop() - } else { - newNode.array[idx] = removed ? undefined : value; - } - return newNode; -} - -function editableVNode(node, ownerID) { - if (ownerID && node && ownerID === node.ownerID) { - return node; - } - return new VNode(node ? node.array.slice() : [], ownerID); -} - -function vectorNodeFor(vector, rawIndex) { - if (rawIndex >= getTailOffset(vector._size)) { - return vector._tail; - } - if (rawIndex < 1 << (vector._level + SHIFT)) { - var node = vector._root; - var level = vector._level; - while (node && level > 0) { - node = node.array[(rawIndex >>> level) & MASK]; - level -= SHIFT; - } - return node; - } -} - -function setVectorBounds(vector, begin, end) { - var owner = vector.__ownerID || new OwnerID(); - var oldOrigin = vector._origin; - var oldSize = vector._size; - var newOrigin = oldOrigin + begin; - var newSize = end == null ? oldSize : end < 0 ? oldSize + end : oldOrigin + end; - if (newOrigin === oldOrigin && newSize === oldSize) { - return vector; - } - - // If it's going to end after it starts, it's empty. - if (newOrigin >= newSize) { - return vector.clear(); - } - - var newLevel = vector._level; - var newRoot = vector._root; - - // New origin might require creating a higher root. - var offsetShift = 0; - while (newOrigin + offsetShift < 0) { - newRoot = new VNode(newRoot && newRoot.array.length ? [null, newRoot] : [], owner); - newLevel += SHIFT; - offsetShift += 1 << newLevel; - } - if (offsetShift) { - newOrigin += offsetShift; - oldOrigin += offsetShift; - newSize += offsetShift; - oldSize += offsetShift; - } - - var oldTailOffset = getTailOffset(oldSize); - var newTailOffset = getTailOffset(newSize); - - // New size might require creating a higher root. - while (newTailOffset >= 1 << (newLevel + SHIFT)) { - newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); - newLevel += SHIFT; - } - - // Locate or create the new tail. - var oldTail = vector._tail; - var newTail = newTailOffset < oldTailOffset ? - vectorNodeFor(vector, newSize - 1) : - newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; - - // Merge Tail into tree. - if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldSize && oldTail.array.length) { - newRoot = editableVNode(newRoot, owner); - var node = newRoot; - for (var level = newLevel; level > SHIFT; level -= SHIFT) { - var idx = (oldTailOffset >>> level) & MASK; - node = node.array[idx] = editableVNode(node.array[idx], owner); - } - node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; - } - - // If the size has been reduced, there's a chance the tail needs to be trimmed. - if (newSize < oldSize) { - newTail = newTail && newTail.removeAfter(owner, 0, newSize); - } - - // If the new origin is within the tail, then we do not need a root. - if (newOrigin >= newTailOffset) { - newOrigin -= newTailOffset; - newSize -= newTailOffset; - newLevel = SHIFT; - newRoot = null; - newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); - - // Otherwise, if the root has been trimmed, garbage collect. - } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { - var beginIndex, endIndex; - offsetShift = 0; - - // Identify the new top root node of the subtree of the old root. - do { - beginIndex = ((newOrigin) >>> newLevel) & MASK; - endIndex = ((newTailOffset - 1) >>> newLevel) & MASK; - if (beginIndex === endIndex) { - if (beginIndex) { - offsetShift += (1 << newLevel) * beginIndex; - } - newLevel -= SHIFT; - newRoot = newRoot && newRoot.array[beginIndex]; - } - } while (newRoot && beginIndex === endIndex); - - // Trim the new sides of the new root. - if (newRoot && newOrigin > oldOrigin) { - newRoot = newRoot && newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); - } - if (newRoot && newTailOffset < oldTailOffset) { - newRoot = newRoot && newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); - } - if (offsetShift) { - newOrigin -= offsetShift; - newSize -= offsetShift; - } - } - - if (vector.__ownerID) { - vector.length = newSize - newOrigin; - vector._origin = newOrigin; - vector._size = newSize; - vector._level = newLevel; - vector._root = newRoot; - vector._tail = newTail; - vector.__hash = undefined; - vector.__altered = true; - return vector; - } - return makeVector(newOrigin, newSize, newLevel, newRoot, newTail); -} - -function mergeIntoVectorWith(vector, merger, iterables) { - var seqs = []; - for (var ii = 0; ii < iterables.length; ii++) { - var seq = iterables[ii]; - seq && seqs.push(Sequence(seq)); - } - var maxLength = Math.max.apply(null, seqs.map(s => s.length || 0)); - if (maxLength > vector.length) { - vector = vector.setLength(maxLength); - } - return mergeIntoCollectionWith(vector, merger, seqs); -} - -function getTailOffset(size) { - return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); -} - -var EMPTY_VECT; diff --git a/src/fromJS.js b/src/fromJS.js index b96343b22d..7586c12a58 100644 --- a/src/fromJS.js +++ b/src/fromJS.js @@ -1,38 +1,51 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ +import { Seq } from './Seq'; +import { hasIterator } from './Iterator'; +import { isImmutable } from './predicates/isImmutable'; +import { isIndexed } from './predicates/isIndexed'; +import { isKeyed } from './predicates/isKeyed'; +import isArrayLike from './utils/isArrayLike'; +import isPlainObj from './utils/isPlainObj'; -import "Sequence" -/* global Sequence */ -/* exported fromJS */ - -function fromJS(json, converter) { - if (converter) { - return _fromJSWith(converter, json, '', {'': json}); - } - return _fromJSDefault(json); +export function fromJS(value, converter) { + return fromJSWith( + [], + converter || defaultConverter, + value, + '', + converter && converter.length > 2 ? [] : undefined, + { '': value } + ); } -function _fromJSWith(converter, json, key, parentJSON) { - if (json && (Array.isArray(json) || json.constructor === Object)) { - return converter.call(parentJSON, key, Sequence(json).map((v, k) => _fromJSWith(converter, v, k, json))); +function fromJSWith(stack, converter, value, key, keyPath, parentValue) { + if ( + typeof value !== 'string' && + !isImmutable(value) && + (isArrayLike(value) || hasIterator(value) || isPlainObj(value)) + ) { + if (~stack.indexOf(value)) { + throw new TypeError('Cannot convert circular structure to Immutable'); + } + stack.push(value); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + keyPath && key !== '' && keyPath.push(key); + const converted = converter.call( + parentValue, + key, + Seq(value).map((v, k) => + fromJSWith(stack, converter, v, k, keyPath, value) + ), + keyPath && keyPath.slice() + ); + stack.pop(); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + keyPath && keyPath.pop(); + return converted; } - return json; + return value; } -function _fromJSDefault(json) { - if (json) { - if (Array.isArray(json)) { - return Sequence(json).map(_fromJSDefault).toVector(); - } - if (json.constructor === Object) { - return Sequence(json).map(_fromJSDefault).toMap(); - } - } - return json; +function defaultConverter(k, v) { + // Effectively the opposite of "Collection.toSeq()" + return isIndexed(v) ? v.toList() : isKeyed(v) ? v.toMap() : v.toSet(); } diff --git a/src/functional/get.ts b/src/functional/get.ts new file mode 100644 index 0000000000..e6306b8f58 --- /dev/null +++ b/src/functional/get.ts @@ -0,0 +1,72 @@ +import type { Collection, Record } from '../../type-definitions/immutable'; +import { isImmutable } from '../predicates/isImmutable'; +import { has } from './has'; + +/** + * Returns the value within the provided collection associated with the + * provided key, or notSetValue if the key is not defined in the collection. + * + * A functional alternative to `collection.get(key)` which will also work on + * plain Objects and Arrays as an alternative for `collection[key]`. + * + * + * ```js + * import { get } from 'immutable'; + * + * get([ 'dog', 'frog', 'cat' ], 1) // 'frog' + * get({ x: 123, y: 456 }, 'x') // 123 + * get({ x: 123, y: 456 }, 'z', 'ifNotSet') // 'ifNotSet' + * ``` + */ +export function get(collection: Collection, key: K): V | undefined; +export function get( + collection: Collection, + key: K, + notSetValue: NSV +): V | NSV; +export function get( + record: Record, + key: K, + notSetValue: unknown +): TProps[K]; +export function get(collection: Array, key: number): V | undefined; +export function get( + collection: Array, + key: number, + notSetValue: NSV +): V | NSV; +export function get( + object: C, + key: K, + notSetValue: unknown +): C[K]; +export function get( + collection: { [key: string]: V }, + key: string +): V | undefined; +export function get( + collection: { [key: string]: V }, + key: string, + notSetValue: NSV +): V | NSV; +export function get( + collection: Collection | Array | { [key: string]: V }, + key: K, + notSetValue?: NSV +): V | NSV; +export function get( + collection: Collection | Array | { [key: string]: V }, + key: K, + notSetValue?: NSV +): V | NSV { + return isImmutable(collection) + ? collection.get(key, notSetValue) + : !has(collection, key) + ? notSetValue + : // @ts-expect-error weird "get" here, + typeof collection.get === 'function' + ? // @ts-expect-error weird "get" here, + collection.get(key) + : // @ts-expect-error key is unknown here, + collection[key]; +} diff --git a/src/functional/getIn.ts b/src/functional/getIn.ts new file mode 100644 index 0000000000..11f9cdf384 --- /dev/null +++ b/src/functional/getIn.ts @@ -0,0 +1,41 @@ +import coerceKeyPath from '../utils/coerceKeyPath'; +import { NOT_SET } from '../TrieUtils'; +import { get } from './get'; +import type { KeyPath } from '../../type-definitions/immutable'; + +type GetType = typeof get; +type GetTypeParameters = Parameters; +type CollectionType = GetTypeParameters[0]; +type Key = GetTypeParameters[1]; + +/** + * Returns the value at the provided key path starting at the provided + * collection, or notSetValue if the key path is not defined. + * + * A functional alternative to `collection.getIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * import { getIn } from 'immutable'; + * + * getIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // 123 + * getIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p'], 'ifNotSet') // 'ifNotSet' + * ``` + */ +export function getIn( + collection: CollectionType, + searchKeyPath: KeyPath, + notSetValue?: GetTypeParameters[2] +): ReturnType { + const keyPath = coerceKeyPath(searchKeyPath); + let i = 0; + while (i !== keyPath.length) { + // @ts-expect-error keyPath[i++] can not be undefined by design + collection = get(collection, keyPath[i++], NOT_SET); + if (collection === NOT_SET) { + return notSetValue; + } + } + return collection; +} diff --git a/src/functional/has.ts b/src/functional/has.ts new file mode 100644 index 0000000000..322370314e --- /dev/null +++ b/src/functional/has.ts @@ -0,0 +1,28 @@ +import { isImmutable } from '../predicates/isImmutable'; +import hasOwnProperty from '../utils/hasOwnProperty'; +import isDataStructure from '../utils/isDataStructure'; + +/** + * Returns true if the key is defined in the provided collection. + * + * A functional alternative to `collection.has(key)` which will also work with + * plain Objects and Arrays as an alternative for + * `collection.hasOwnProperty(key)`. + * + * + * ```js + * import { has } from 'immutable'; + * + * has([ 'dog', 'frog', 'cat' ], 2) // true + * has([ 'dog', 'frog', 'cat' ], 5) // false + * has({ x: 123, y: 456 }, 'x') // true + * has({ x: 123, y: 456 }, 'z') // false + * ``` + */ +export function has(collection: object, key: unknown): boolean { + return isImmutable(collection) + ? // @ts-expect-error key might be a number or symbol, which is not handled be Record key type + collection.has(key) + : // @ts-expect-error key might be anything else than PropertyKey, and will return false in that case but runtime is OK + isDataStructure(collection) && hasOwnProperty.call(collection, key); +} diff --git a/src/functional/hasIn.ts b/src/functional/hasIn.ts new file mode 100644 index 0000000000..28041a7323 --- /dev/null +++ b/src/functional/hasIn.ts @@ -0,0 +1,25 @@ +import { getIn } from './getIn'; +import { NOT_SET } from '../TrieUtils'; + +type GetInParameters = Parameters; + +/** + * Returns true if the key path is defined in the provided collection. + * + * A functional alternative to `collection.hasIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * import { hasIn } from 'immutable'; + * + * hasIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // true + * hasIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p']) // false + * ``` + */ +export function hasIn( + collection: GetInParameters[0], + keyPath: GetInParameters[1] +): boolean { + return getIn(collection, keyPath, NOT_SET) !== NOT_SET; +} diff --git a/src/functional/merge.js b/src/functional/merge.js new file mode 100644 index 0000000000..b2d231a0c9 --- /dev/null +++ b/src/functional/merge.js @@ -0,0 +1,99 @@ +import { isImmutable } from '../predicates/isImmutable'; +import { isIndexed } from '../predicates/isIndexed'; +import { isKeyed } from '../predicates/isKeyed'; +import { IndexedCollection, KeyedCollection } from '../Collection'; +import { Seq } from '../Seq'; +import hasOwnProperty from '../utils/hasOwnProperty'; +import isDataStructure from '../utils/isDataStructure'; +import shallowCopy from '../utils/shallowCopy'; + +export function merge(collection, ...sources) { + return mergeWithSources(collection, sources); +} + +export function mergeWith(merger, collection, ...sources) { + return mergeWithSources(collection, sources, merger); +} + +export function mergeDeep(collection, ...sources) { + return mergeDeepWithSources(collection, sources); +} + +export function mergeDeepWith(merger, collection, ...sources) { + return mergeDeepWithSources(collection, sources, merger); +} + +export function mergeDeepWithSources(collection, sources, merger) { + return mergeWithSources(collection, sources, deepMergerWith(merger)); +} + +export function mergeWithSources(collection, sources, merger) { + if (!isDataStructure(collection)) { + throw new TypeError( + 'Cannot merge into non-data-structure value: ' + collection + ); + } + if (isImmutable(collection)) { + return typeof merger === 'function' && collection.mergeWith + ? collection.mergeWith(merger, ...sources) + : collection.merge + ? collection.merge(...sources) + : collection.concat(...sources); + } + const isArray = Array.isArray(collection); + let merged = collection; + const Collection = isArray ? IndexedCollection : KeyedCollection; + const mergeItem = isArray + ? (value) => { + // Copy on write + if (merged === collection) { + merged = shallowCopy(merged); + } + merged.push(value); + } + : (value, key) => { + const hasVal = hasOwnProperty.call(merged, key); + const nextVal = + hasVal && merger ? merger(merged[key], value, key) : value; + if (!hasVal || nextVal !== merged[key]) { + // Copy on write + if (merged === collection) { + merged = shallowCopy(merged); + } + merged[key] = nextVal; + } + }; + for (let i = 0; i < sources.length; i++) { + Collection(sources[i]).forEach(mergeItem); + } + return merged; +} + +function deepMergerWith(merger) { + function deepMerger(oldValue, newValue, key) { + return isDataStructure(oldValue) && + isDataStructure(newValue) && + areMergeable(oldValue, newValue) + ? mergeWithSources(oldValue, [newValue], deepMerger) + : merger + ? merger(oldValue, newValue, key) + : newValue; + } + return deepMerger; +} + +/** + * It's unclear what the desired behavior is for merging two collections that + * fall into separate categories between keyed, indexed, or set-like, so we only + * consider them mergeable if they fall into the same category. + */ +function areMergeable(oldDataStructure, newDataStructure) { + const oldSeq = Seq(oldDataStructure); + const newSeq = Seq(newDataStructure); + // This logic assumes that a sequence can only fall into one of the three + // categories mentioned above (since there's no `isSetLike()` method). + return ( + isIndexed(oldSeq) === isIndexed(newSeq) && + isKeyed(oldSeq) === isKeyed(newSeq) + ); +} diff --git a/src/functional/remove.ts b/src/functional/remove.ts new file mode 100644 index 0000000000..60aff0fa36 --- /dev/null +++ b/src/functional/remove.ts @@ -0,0 +1,83 @@ +import type { Collection, Record } from '../../type-definitions/immutable'; +import { isImmutable } from '../predicates/isImmutable'; +import hasOwnProperty from '../utils/hasOwnProperty'; +import isDataStructure from '../utils/isDataStructure'; +import shallowCopy from '../utils/shallowCopy'; + +/** + * Returns a copy of the collection with the value at key removed. + * + * A functional alternative to `collection.remove(key)` which will also work + * with plain Objects and Arrays as an alternative for + * `delete collectionCopy[key]`. + * + * + * ```js + * import { remove } from 'immutable'; + * + * const originalArray = [ 'dog', 'frog', 'cat' ] + * remove(originalArray, 1) // [ 'dog', 'cat' ] + * console.log(originalArray) // [ 'dog', 'frog', 'cat' ] + * const originalObject = { x: 123, y: 456 } + * remove(originalObject, 'x') // { y: 456 } + * console.log(originalObject) // { x: 123, y: 456 } + * ``` + */ +export function remove>( + collection: C, + key: K +): C; +export function remove< + TProps extends object, + C extends Record, + K extends keyof TProps, +>(collection: C, key: K): C; +export function remove>(collection: C, key: number): C; +export function remove(collection: C, key: K): C; +export function remove< + C extends { [key: PropertyKey]: unknown }, + K extends keyof C, +>(collection: C, key: K): C; +export function remove< + K, + C extends + | Collection + | Array + | { [key: PropertyKey]: unknown }, +>(collection: C, key: K): C; +export function remove( + collection: + | Collection + | Array + | { [key: PropertyKey]: unknown }, + key: K +) { + if (!isDataStructure(collection)) { + throw new TypeError( + 'Cannot update non-data-structure value: ' + collection + ); + } + if (isImmutable(collection)) { + // @ts-expect-error weird "remove" here, + if (!collection.remove) { + throw new TypeError( + 'Cannot update immutable value without .remove() method: ' + collection + ); + } + // @ts-expect-error weird "remove" here, + return collection.remove(key); + } + // @ts-expect-error assert that key is a string, a number or a symbol here + if (!hasOwnProperty.call(collection, key)) { + return collection; + } + const collectionCopy = shallowCopy(collection); + if (Array.isArray(collectionCopy)) { + // @ts-expect-error assert that key is a number here + collectionCopy.splice(key, 1); + } else { + // @ts-expect-error assert that key is a string, a number or a symbol here + delete collectionCopy[key]; + } + return collectionCopy; +} diff --git a/src/functional/removeIn.ts b/src/functional/removeIn.ts new file mode 100644 index 0000000000..3b97be0dcd --- /dev/null +++ b/src/functional/removeIn.ts @@ -0,0 +1,27 @@ +import { updateIn, type PossibleCollection } from './updateIn'; +import { NOT_SET } from '../TrieUtils'; +import type { KeyPath } from '../../type-definitions/immutable'; + +/** + * Returns a copy of the collection with the value at the key path removed. + * + * A functional alternative to `collection.removeIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * import { removeIn } from 'immutable'; + * + * const original = { x: { y: { z: 123 }}} + * removeIn(original, ['x', 'y', 'z']) // { x: { y: {}}} + * console.log(original) // { x: { y: { z: 123 }}} + * ``` + */ +export function removeIn< + K extends PropertyKey, + V, + TProps extends object, + C extends PossibleCollection, +>(collection: C, keyPath: KeyPath): C { + return updateIn(collection, keyPath, () => NOT_SET); +} diff --git a/src/functional/set.ts b/src/functional/set.ts new file mode 100644 index 0000000000..e8e688abd0 --- /dev/null +++ b/src/functional/set.ts @@ -0,0 +1,76 @@ +import type { Collection, Record } from '../../type-definitions/immutable'; +import { isImmutable } from '../predicates/isImmutable'; +import hasOwnProperty from '../utils/hasOwnProperty'; +import isDataStructure from '../utils/isDataStructure'; +import shallowCopy from '../utils/shallowCopy'; + +/** + * Returns a copy of the collection with the value at key set to the provided + * value. + * + * A functional alternative to `collection.set(key, value)` which will also + * work with plain Objects and Arrays as an alternative for + * `collectionCopy[key] = value`. + * + * + * ```js + * import { set } from 'immutable'; + * + * const originalArray = [ 'dog', 'frog', 'cat' ] + * set(originalArray, 1, 'cow') // [ 'dog', 'cow', 'cat' ] + * console.log(originalArray) // [ 'dog', 'frog', 'cat' ] + * const originalObject = { x: 123, y: 456 } + * set(originalObject, 'x', 789) // { x: 789, y: 456 } + * console.log(originalObject) // { x: 123, y: 456 } + * ``` + */ +export function set>( + collection: C, + key: K, + value: V +): C; +export function set< + TProps extends object, + C extends Record, + K extends keyof TProps, +>(record: C, key: K, value: TProps[K]): C; +export function set>( + collection: C, + key: number, + value: V +): C; +export function set(object: C, key: K, value: C[K]): C; +export function set( + collection: C, + key: string, + value: V +): C; +export function set | { [key: string]: V }>( + collection: C, + key: K | string, + value: V +): C { + if (!isDataStructure(collection)) { + throw new TypeError( + 'Cannot update non-data-structure value: ' + collection + ); + } + if (isImmutable(collection)) { + // @ts-expect-error weird "set" here, + if (!collection.set) { + throw new TypeError( + 'Cannot update immutable value without .set() method: ' + collection + ); + } + // @ts-expect-error weird "set" here, + return collection.set(key, value); + } + // @ts-expect-error mix of key and string here. Probably need a more fine type here + if (hasOwnProperty.call(collection, key) && value === collection[key]) { + return collection; + } + const collectionCopy = shallowCopy(collection); + // @ts-expect-error mix of key and string here. Probably need a more fine type here + collectionCopy[key] = value; + return collectionCopy; +} diff --git a/src/functional/setIn.ts b/src/functional/setIn.ts new file mode 100644 index 0000000000..7955e3e38d --- /dev/null +++ b/src/functional/setIn.ts @@ -0,0 +1,28 @@ +import { updateIn, type PossibleCollection } from './updateIn'; +import { NOT_SET } from '../TrieUtils'; +import type { KeyPath } from '../../type-definitions/immutable'; + +/** + * Returns a copy of the collection with the value at the key path set to the + * provided value. + * + * A functional alternative to `collection.setIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * import { setIn } from 'immutable'; + * + * const original = { x: { y: { z: 123 }}} + * setIn(original, ['x', 'y', 'z'], 456) // { x: { y: { z: 456 }}} + * console.log(original) // { x: { y: { z: 123 }}} + * ``` + */ +export function setIn< + K extends PropertyKey, + V, + TProps extends object, + C extends PossibleCollection, +>(collection: C, keyPath: KeyPath, value: unknown): C { + return updateIn(collection, keyPath, NOT_SET, () => value); +} diff --git a/src/functional/update.ts b/src/functional/update.ts new file mode 100644 index 0000000000..81d5426539 --- /dev/null +++ b/src/functional/update.ts @@ -0,0 +1,112 @@ +import type { Collection, Record } from '../../type-definitions/immutable'; +import { updateIn, type PossibleCollection } from './updateIn'; + +type UpdaterFunction = (value: V | undefined) => V | undefined; +type UpdaterFunctionWithNSV = (value: V | NSV) => V; + +/** + * Returns a copy of the collection with the value at key set to the result of + * providing the existing value to the updating function. + * + * A functional alternative to `collection.update(key, fn)` which will also + * work with plain Objects and Arrays as an alternative for + * `collectionCopy[key] = fn(collection[key])`. + * + * + * ```js + * import { update } from 'immutable'; + * + * const originalArray = [ 'dog', 'frog', 'cat' ] + * update(originalArray, 1, val => val.toUpperCase()) // [ 'dog', 'FROG', 'cat' ] + * console.log(originalArray) // [ 'dog', 'frog', 'cat' ] + * const originalObject = { x: 123, y: 456 } + * update(originalObject, 'x', val => val * 6) // { x: 738, y: 456 } + * console.log(originalObject) // { x: 123, y: 456 } + * ``` + */ +export function update>( + collection: C, + key: K, + updater: (value: V | undefined) => V | undefined +): C; +export function update, NSV>( + collection: C, + key: K, + notSetValue: NSV, + updater: (value: V | NSV) => V +): C; +export function update< + TProps extends object, + C extends Record, + K extends keyof TProps, +>(record: C, key: K, updater: (value: TProps[K]) => TProps[K]): C; +export function update< + TProps extends object, + C extends Record, + K extends keyof TProps, + NSV, +>( + record: C, + key: K, + notSetValue: NSV, + updater: (value: TProps[K] | NSV) => TProps[K] +): C; +export function update>( + collection: C, + key: number, + updater: UpdaterFunction +): C; +export function update, NSV>( + collection: C, + key: number, + notSetValue: NSV, + updater: (value: V | NSV) => V +): C; +export function update( + object: C, + key: K, + updater: (value: C[K]) => C[K] +): C; +export function update( + object: C, + key: K, + notSetValue: NSV, + updater: (value: C[K] | NSV) => C[K] +): C; +export function update( + collection: C, + key: K, + updater: (value: V) => V +): { [key: string]: V }; +export function update< + V, + C extends { [key: string]: V }, + K extends keyof C, + NSV, +>( + collection: C, + key: K, + notSetValue: NSV, + updater: (value: V | NSV) => V +): { [key: string]: V }; + +export function update< + K, + V, + TProps extends object, + C extends PossibleCollection, + NSV, +>( + collection: C, + key: K, + notSetValue: NSV | UpdaterFunction, + updater?: UpdaterFunctionWithNSV +) { + return updateIn( + // @ts-expect-error Index signature for type string is missing in type V[] + collection, + [key], + notSetValue, + updater + ); +} diff --git a/src/functional/updateIn.ts b/src/functional/updateIn.ts new file mode 100644 index 0000000000..99eed7980e --- /dev/null +++ b/src/functional/updateIn.ts @@ -0,0 +1,189 @@ +import { isImmutable } from '../predicates/isImmutable'; +import coerceKeyPath from '../utils/coerceKeyPath'; +import isDataStructure from '../utils/isDataStructure'; +import quoteString from '../utils/quoteString'; +import { NOT_SET } from '../TrieUtils'; +import { emptyMap } from '../Map'; +import { get } from './get'; +import { remove } from './remove'; +import { set } from './set'; +import type { + Collection, + KeyPath, + Record, + RetrievePath, +} from '../../type-definitions/immutable'; + +/** + * Returns a copy of the collection with the value at key path set to the + * result of providing the existing value to the updating function. + * + * A functional alternative to `collection.updateIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * import { updateIn } from 'immutable' + * + * const original = { x: { y: { z: 123 }}} + * updateIn(original, ['x', 'y', 'z'], val => val * 6) // { x: { y: { z: 738 }}} + * console.log(original) // { x: { y: { z: 123 }}} + * ``` + */ + +export type PossibleCollection = + | Collection + | Record + | Array; + +type UpdaterFunction = ( + value: RetrievePath> | undefined +) => unknown | undefined; +type UpdaterFunctionWithNSV = ( + value: RetrievePath> | NSV +) => unknown; + +export function updateIn>( + collection: C, + keyPath: KeyPath, + updater: UpdaterFunction +): C; +export function updateIn, NSV>( + collection: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: UpdaterFunctionWithNSV +): C; +export function updateIn< + TProps extends object, + C extends Record, + K extends keyof TProps, +>(record: C, keyPath: KeyPath, updater: UpdaterFunction): C; +export function updateIn< + TProps extends object, + C extends Record, + K extends keyof TProps, + NSV, +>( + record: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: UpdaterFunctionWithNSV +): C; +export function updateIn>( + collection: C, + keyPath: KeyPath, + updater: UpdaterFunction +): Array; +export function updateIn, NSV>( + collection: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: UpdaterFunctionWithNSV +): Array; +export function updateIn( + object: C, + keyPath: KeyPath, + updater: UpdaterFunction +): C; +export function updateIn( + object: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: UpdaterFunctionWithNSV +): C; +export function updateIn( + collection: C, + keyPath: KeyPath, + updater: UpdaterFunction +): { [key: PropertyKey]: V }; +export function updateIn( + collection: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: UpdaterFunction +): { [key: PropertyKey]: V }; + +export function updateIn< + K, + V, + TProps extends object, + C extends PossibleCollection, + NSV, +>( + collection: C, + keyPath: KeyPath, + notSetValue: NSV | UpdaterFunction | undefined, + updater?: UpdaterFunctionWithNSV +): C { + if (!updater) { + // handle the fact that `notSetValue` is optional here, in that case `updater` is the updater function + // @ts-expect-error updater is a function here + updater = notSetValue as UpdaterFunction; + notSetValue = undefined; + } + const updatedValue = updateInDeeply( + isImmutable(collection), + // @ts-expect-error type issues with Record and mixed types + collection, + coerceKeyPath(keyPath), + 0, + notSetValue, + updater + ); + // @ts-expect-error mixed return type + return updatedValue === NOT_SET ? notSetValue : updatedValue; +} + +function updateInDeeply< + K, + TProps extends object, + C extends PossibleCollection, + NSV, +>( + inImmutable: boolean, + existing: C, + keyPath: Array, + i: number, + notSetValue: NSV | undefined, + updater: UpdaterFunctionWithNSV | UpdaterFunction +): C { + const wasNotSet = existing === NOT_SET; + if (i === keyPath.length) { + const existingValue = wasNotSet ? notSetValue : existing; + // @ts-expect-error mixed type with optional value + const newValue = updater(existingValue); + // @ts-expect-error mixed type + return newValue === existingValue ? existing : newValue; + } + if (!wasNotSet && !isDataStructure(existing)) { + throw new TypeError( + 'Cannot update within non-data-structure value in path [' + + Array.from(keyPath).slice(0, i).map(quoteString) + + ']: ' + + existing + ); + } + const key = keyPath[i]; + + const nextExisting = wasNotSet ? NOT_SET : get(existing, key, NOT_SET); + const nextUpdated = updateInDeeply( + nextExisting === NOT_SET ? inImmutable : isImmutable(nextExisting), + // @ts-expect-error mixed type + nextExisting, + keyPath, + i + 1, + notSetValue, + updater + ); + + return nextUpdated === nextExisting + ? existing + : nextUpdated === NOT_SET + ? remove(existing, key) + : set( + wasNotSet ? (inImmutable ? emptyMap() : {}) : existing, + key, + nextUpdated + ); +} diff --git a/src/invariant.js b/src/invariant.js deleted file mode 100644 index 21799e4fd6..0000000000 --- a/src/invariant.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/* exported invariant */ - -function invariant(condition, error) { - if (!condition) throw new Error(error); -} diff --git a/src/is.js b/src/is.js deleted file mode 100644 index f2fa0be913..0000000000 --- a/src/is.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -import "Sequence" -import "Cursor" -/* global Sequence, Cursor */ -/* exported is */ - - -/** - * The same semantics as Object.is(), but treats immutable sequences as - * data, equal when the structure contains equivalent data. - */ -function is(first, second) { - if (first instanceof Cursor) { - first = first.deref(); - } - if (second instanceof Cursor) { - second = second.deref(); - } - if (first === second) { - return first !== 0 || second !== 0 || 1 / first === 1 / second; - } - if (first !== first) { - return second !== second; - } - if (first instanceof Sequence) { - return first.equals(second); - } - return false; -} diff --git a/src/is.ts b/src/is.ts new file mode 100644 index 0000000000..f4430c52fd --- /dev/null +++ b/src/is.ts @@ -0,0 +1,82 @@ +import { isValueObject } from './predicates/isValueObject'; + +/** + * An extension of the "same-value" algorithm as [described for use by ES6 Map + * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) + * + * NaN is considered the same as NaN, however -0 and 0 are considered the same + * value, which is different from the algorithm described by + * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). + * + * This is extended further to allow Objects to describe the values they + * represent, by way of `valueOf` or `equals` (and `hashCode`). + * + * Note: because of this extension, the key equality of Immutable.Map and the + * value equality of Immutable.Set will differ from ES6 Map and Set. + * + * ### Defining custom values + * + * The easiest way to describe the value an object represents is by implementing + * `valueOf`. For example, `Date` represents a value by returning a unix + * timestamp for `valueOf`: + * + * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... + * var date2 = new Date(1234567890000); + * date1.valueOf(); // 1234567890000 + * assert( date1 !== date2 ); + * assert( Immutable.is( date1, date2 ) ); + * + * Note: overriding `valueOf` may have other implications if you use this object + * where JavaScript expects a primitive, such as implicit string coercion. + * + * For more complex types, especially collections, implementing `valueOf` may + * not be performant. An alternative is to implement `equals` and `hashCode`. + * + * `equals` takes another object, presumably of similar type, and returns true + * if it is equal. Equality is symmetrical, so the same result should be + * returned if this and the argument are flipped. + * + * assert( a.equals(b) === b.equals(a) ); + * + * `hashCode` returns a 32bit integer number representing the object which will + * be used to determine how to store the value object in a Map or Set. You must + * provide both or neither methods, one must not exist without the other. + * + * Also, an important relationship between these methods must be upheld: if two + * values are equal, they *must* return the same hashCode. If the values are not + * equal, they might have the same hashCode; this is called a hash collision, + * and while undesirable for performance reasons, it is acceptable. + * + * if (a.equals(b)) { + * assert( a.hashCode() === b.hashCode() ); + * } + * + * All Immutable collections are Value Objects: they implement `equals()` + * and `hashCode()`. + */ +export function is(valueA: unknown, valueB: unknown): boolean { + if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { + return true; + } + if (!valueA || !valueB) { + return false; + } + if ( + typeof valueA.valueOf === 'function' && + typeof valueB.valueOf === 'function' + ) { + valueA = valueA.valueOf(); + valueB = valueB.valueOf(); + if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { + return true; + } + if (!valueA || !valueB) { + return false; + } + } + return !!( + isValueObject(valueA) && + isValueObject(valueB) && + valueA.equals(valueB) + ); +} diff --git a/src/methods/README.md b/src/methods/README.md new file mode 100644 index 0000000000..df2d26482f --- /dev/null +++ b/src/methods/README.md @@ -0,0 +1,5 @@ +These files represent common methods on Collection types, each will contain +references to "this" - expecting to be called as a prototypal method. + +They are separated into individual files to avoid circular dependencies when +possible, and to allow their use in multiple different Collections. diff --git a/src/methods/asImmutable.js b/src/methods/asImmutable.js new file mode 100644 index 0000000000..71ba0d2bf5 --- /dev/null +++ b/src/methods/asImmutable.js @@ -0,0 +1,3 @@ +export function asImmutable() { + return this.__ensureOwner(); +} diff --git a/src/methods/asMutable.js b/src/methods/asMutable.js new file mode 100644 index 0000000000..2e7abf576a --- /dev/null +++ b/src/methods/asMutable.js @@ -0,0 +1,5 @@ +import { OwnerID } from '../TrieUtils'; + +export function asMutable() { + return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); +} diff --git a/src/methods/deleteIn.js b/src/methods/deleteIn.js new file mode 100644 index 0000000000..5a312ce8f9 --- /dev/null +++ b/src/methods/deleteIn.js @@ -0,0 +1,5 @@ +import { removeIn } from '../functional/removeIn'; + +export function deleteIn(keyPath) { + return removeIn(this, keyPath); +} diff --git a/src/methods/getIn.js b/src/methods/getIn.js new file mode 100644 index 0000000000..e202bae92c --- /dev/null +++ b/src/methods/getIn.js @@ -0,0 +1,5 @@ +import { getIn as _getIn } from '../functional/getIn'; + +export function getIn(searchKeyPath, notSetValue) { + return _getIn(this, searchKeyPath, notSetValue); +} diff --git a/src/methods/hasIn.js b/src/methods/hasIn.js new file mode 100644 index 0000000000..704dc5c80f --- /dev/null +++ b/src/methods/hasIn.js @@ -0,0 +1,5 @@ +import { hasIn as _hasIn } from '../functional/hasIn'; + +export function hasIn(searchKeyPath) { + return _hasIn(this, searchKeyPath); +} diff --git a/src/methods/merge.js b/src/methods/merge.js new file mode 100644 index 0000000000..427f7c466c --- /dev/null +++ b/src/methods/merge.js @@ -0,0 +1,51 @@ +import { KeyedCollection } from '../Collection'; +import { NOT_SET } from '../TrieUtils'; +import { update } from '../functional/update'; +import { isRecord } from '../predicates/isRecord'; + +export function merge(...iters) { + return mergeIntoKeyedWith(this, iters); +} + +export function mergeWith(merger, ...iters) { + if (typeof merger !== 'function') { + throw new TypeError('Invalid merger function: ' + merger); + } + return mergeIntoKeyedWith(this, iters, merger); +} + +function mergeIntoKeyedWith(collection, collections, merger) { + const iters = []; + for (let ii = 0; ii < collections.length; ii++) { + const collection = KeyedCollection(collections[ii]); + if (collection.size !== 0) { + iters.push(collection); + } + } + if (iters.length === 0) { + return collection; + } + if ( + collection.toSeq().size === 0 && + !collection.__ownerID && + iters.length === 1 + ) { + return isRecord(collection) + ? collection // Record is empty and will not be updated: return the same instance + : collection.constructor(iters[0]); + } + return collection.withMutations((collection) => { + const mergeIntoCollection = merger + ? (value, key) => { + update(collection, key, NOT_SET, (oldVal) => + oldVal === NOT_SET ? value : merger(oldVal, value, key) + ); + } + : (value, key) => { + collection.set(key, value); + }; + for (let ii = 0; ii < iters.length; ii++) { + iters[ii].forEach(mergeIntoCollection); + } + }); +} diff --git a/src/methods/mergeDeep.js b/src/methods/mergeDeep.js new file mode 100644 index 0000000000..e2238f664c --- /dev/null +++ b/src/methods/mergeDeep.js @@ -0,0 +1,9 @@ +import { mergeDeepWithSources } from '../functional/merge'; + +export function mergeDeep(...iters) { + return mergeDeepWithSources(this, iters); +} + +export function mergeDeepWith(merger, ...iters) { + return mergeDeepWithSources(this, iters, merger); +} diff --git a/src/methods/mergeDeepIn.js b/src/methods/mergeDeepIn.js new file mode 100644 index 0000000000..119369b7ba --- /dev/null +++ b/src/methods/mergeDeepIn.js @@ -0,0 +1,9 @@ +import { mergeDeepWithSources } from '../functional/merge'; +import { updateIn } from '../functional/updateIn'; +import { emptyMap } from '../Map'; + +export function mergeDeepIn(keyPath, ...iters) { + return updateIn(this, keyPath, emptyMap(), (m) => + mergeDeepWithSources(m, iters) + ); +} diff --git a/src/methods/mergeIn.js b/src/methods/mergeIn.js new file mode 100644 index 0000000000..9af239c4d0 --- /dev/null +++ b/src/methods/mergeIn.js @@ -0,0 +1,7 @@ +import { mergeWithSources } from '../functional/merge'; +import { updateIn } from '../functional/updateIn'; +import { emptyMap } from '../Map'; + +export function mergeIn(keyPath, ...iters) { + return updateIn(this, keyPath, emptyMap(), (m) => mergeWithSources(m, iters)); +} diff --git a/src/methods/setIn.js b/src/methods/setIn.js new file mode 100644 index 0000000000..3ea05b89d6 --- /dev/null +++ b/src/methods/setIn.js @@ -0,0 +1,5 @@ +import { setIn as _setIn } from '../functional/setIn'; + +export function setIn(keyPath, v) { + return _setIn(this, keyPath, v); +} diff --git a/src/methods/toObject.js b/src/methods/toObject.js new file mode 100644 index 0000000000..fb927f0e48 --- /dev/null +++ b/src/methods/toObject.js @@ -0,0 +1,10 @@ +import assertNotInfinite from '../utils/assertNotInfinite'; + +export function toObject() { + assertNotInfinite(this.size); + const object = {}; + this.__iterate((v, k) => { + object[k] = v; + }); + return object; +} diff --git a/src/methods/update.js b/src/methods/update.js new file mode 100644 index 0000000000..0d533f7037 --- /dev/null +++ b/src/methods/update.js @@ -0,0 +1,7 @@ +import { update as _update } from '../functional/update'; + +export function update(key, notSetValue, updater) { + return arguments.length === 1 + ? key(this) + : _update(this, key, notSetValue, updater); +} diff --git a/src/methods/updateIn.js b/src/methods/updateIn.js new file mode 100644 index 0000000000..8df1860868 --- /dev/null +++ b/src/methods/updateIn.js @@ -0,0 +1,5 @@ +import { updateIn as _updateIn } from '../functional/updateIn'; + +export function updateIn(keyPath, notSetValue, updater) { + return _updateIn(this, keyPath, notSetValue, updater); +} diff --git a/src/methods/wasAltered.js b/src/methods/wasAltered.js new file mode 100644 index 0000000000..165a3e3ab2 --- /dev/null +++ b/src/methods/wasAltered.js @@ -0,0 +1,3 @@ +export function wasAltered() { + return this.__altered; +} diff --git a/src/methods/withMutations.js b/src/methods/withMutations.js new file mode 100644 index 0000000000..59c5cc83dc --- /dev/null +++ b/src/methods/withMutations.js @@ -0,0 +1,5 @@ +export function withMutations(fn) { + const mutable = this.asMutable(); + fn(mutable); + return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; +} diff --git a/src/predicates/isAssociative.ts b/src/predicates/isAssociative.ts new file mode 100644 index 0000000000..e174616f7b --- /dev/null +++ b/src/predicates/isAssociative.ts @@ -0,0 +1,25 @@ +import { isKeyed } from './isKeyed'; +import { isIndexed } from './isIndexed'; +import type { Collection } from '../../type-definitions/immutable'; + +/** + * True if `maybeAssociative` is either a Keyed or Indexed Collection. + * + * ```js + * import { isAssociative, Map, List, Stack, Set } from 'immutable'; + * + * isAssociative([]); // false + * isAssociative({}); // false + * isAssociative(Map()); // true + * isAssociative(List()); // true + * isAssociative(Stack()); // true + * isAssociative(Set()); // false + * ``` + */ +export function isAssociative( + maybeAssociative: unknown +): maybeAssociative is + | Collection.Keyed + | Collection.Indexed { + return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); +} diff --git a/src/predicates/isCollection.ts b/src/predicates/isCollection.ts new file mode 100644 index 0000000000..738a4614e0 --- /dev/null +++ b/src/predicates/isCollection.ts @@ -0,0 +1,27 @@ +import type { Collection } from '../../type-definitions/immutable'; + +// Note: value is unchanged to not break immutable-devtools. +export const IS_COLLECTION_SYMBOL = '@@__IMMUTABLE_ITERABLE__@@'; + +/** + * True if `maybeCollection` is a Collection, or any of its subclasses. + * + * ```js + * import { isCollection, Map, List, Stack } from 'immutable'; + * + * isCollection([]); // false + * isCollection({}); // false + * isCollection(Map()); // true + * isCollection(List()); // true + * isCollection(Stack()); // true + * ``` + */ +export function isCollection( + maybeCollection: unknown +): maybeCollection is Collection { + return Boolean( + maybeCollection && + // @ts-expect-error: maybeCollection is typed as `{}`, need to change in 6.0 to `maybeCollection && typeof maybeCollection === 'object' && IS_COLLECTION_SYMBOL in maybeCollection` + maybeCollection[IS_COLLECTION_SYMBOL] + ); +} diff --git a/src/predicates/isImmutable.ts b/src/predicates/isImmutable.ts new file mode 100644 index 0000000000..d01bd03afb --- /dev/null +++ b/src/predicates/isImmutable.ts @@ -0,0 +1,24 @@ +import type { Collection, Record } from '../../type-definitions/immutable'; +import { isCollection } from './isCollection'; +import { isRecord } from './isRecord'; + +/** + * True if `maybeImmutable` is an Immutable Collection or Record. + * + * Note: Still returns true even if the collections is within a `withMutations()`. + * + * ```js + * import { isImmutable, Map, List, Stack } from 'immutable'; + * isImmutable([]); // false + * isImmutable({}); // false + * isImmutable(Map()); // true + * isImmutable(List()); // true + * isImmutable(Stack()); // true + * isImmutable(Map().asMutable()); // true + * ``` + */ +export function isImmutable( + maybeImmutable: unknown +): maybeImmutable is Collection | Record { + return isCollection(maybeImmutable) || isRecord(maybeImmutable); +} diff --git a/src/predicates/isIndexed.ts b/src/predicates/isIndexed.ts new file mode 100644 index 0000000000..3e20595af5 --- /dev/null +++ b/src/predicates/isIndexed.ts @@ -0,0 +1,27 @@ +import type { Collection } from '../../type-definitions/immutable'; + +export const IS_INDEXED_SYMBOL = '@@__IMMUTABLE_INDEXED__@@'; + +/** + * True if `maybeIndexed` is a Collection.Indexed, or any of its subclasses. + * + * ```js + * import { isIndexed, Map, List, Stack, Set } from 'immutable'; + * + * isIndexed([]); // false + * isIndexed({}); // false + * isIndexed(Map()); // false + * isIndexed(List()); // true + * isIndexed(Stack()); // true + * isIndexed(Set()); // false + * ``` + */ +export function isIndexed( + maybeIndexed: unknown +): maybeIndexed is Collection.Indexed { + return Boolean( + maybeIndexed && + // @ts-expect-error: maybeIndexed is typed as `{}`, need to change in 6.0 to `maybeIndexed && typeof maybeIndexed === 'object' && IS_INDEXED_SYMBOL in maybeIndexed` + maybeIndexed[IS_INDEXED_SYMBOL] + ); +} diff --git a/src/predicates/isKeyed.ts b/src/predicates/isKeyed.ts new file mode 100644 index 0000000000..35f7b7e9c8 --- /dev/null +++ b/src/predicates/isKeyed.ts @@ -0,0 +1,26 @@ +import type { Collection } from '../../type-definitions/immutable'; + +export const IS_KEYED_SYMBOL = '@@__IMMUTABLE_KEYED__@@'; + +/** + * True if `maybeKeyed` is a Collection.Keyed, or any of its subclasses. + * + * ```js + * import { isKeyed, Map, List, Stack } from 'immutable'; + * + * isKeyed([]); // false + * isKeyed({}); // false + * isKeyed(Map()); // true + * isKeyed(List()); // false + * isKeyed(Stack()); // false + * ``` + */ +export function isKeyed( + maybeKeyed: unknown +): maybeKeyed is Collection.Keyed { + return Boolean( + maybeKeyed && + // @ts-expect-error: maybeKeyed is typed as `{}`, need to change in 6.0 to `maybeKeyed && typeof maybeKeyed === 'object' && IS_KEYED_SYMBOL in maybeKeyed` + maybeKeyed[IS_KEYED_SYMBOL] + ); +} diff --git a/src/predicates/isList.ts b/src/predicates/isList.ts new file mode 100644 index 0000000000..080427eb2a --- /dev/null +++ b/src/predicates/isList.ts @@ -0,0 +1,14 @@ +import type { List } from '../../type-definitions/immutable'; + +export const IS_LIST_SYMBOL = '@@__IMMUTABLE_LIST__@@'; + +/** + * True if `maybeList` is a List. + */ +export function isList(maybeList: unknown): maybeList is List { + return Boolean( + maybeList && + // @ts-expect-error: maybeList is typed as `{}`, need to change in 6.0 to `maybeList && typeof maybeList === 'object' && IS_LIST_SYMBOL in maybeList` + maybeList[IS_LIST_SYMBOL] + ); +} diff --git a/src/predicates/isMap.ts b/src/predicates/isMap.ts new file mode 100644 index 0000000000..ef96c7e138 --- /dev/null +++ b/src/predicates/isMap.ts @@ -0,0 +1,16 @@ +import type { Map } from '../../type-definitions/immutable'; + +export const IS_MAP_SYMBOL = '@@__IMMUTABLE_MAP__@@'; + +/** + * True if `maybeMap` is a Map. + * + * Also true for OrderedMaps. + */ +export function isMap(maybeMap: unknown): maybeMap is Map { + return Boolean( + maybeMap && + // @ts-expect-error: maybeMap is typed as `{}`, need to change in 6.0 to `maybeMap && typeof maybeMap === 'object' && IS_MAP_SYMBOL in maybeMap` + maybeMap[IS_MAP_SYMBOL] + ); +} diff --git a/src/predicates/isOrdered.ts b/src/predicates/isOrdered.ts new file mode 100644 index 0000000000..2e20d415ff --- /dev/null +++ b/src/predicates/isOrdered.ts @@ -0,0 +1,31 @@ +import type { OrderedCollection } from '../../type-definitions/immutable'; + +export const IS_ORDERED_SYMBOL = '@@__IMMUTABLE_ORDERED__@@'; + +/** + * True if `maybeOrdered` is a Collection where iteration order is well + * defined. True for Collection.Indexed as well as OrderedMap and OrderedSet. + * + * ```js + * import { isOrdered, Map, OrderedMap, List, Set } from 'immutable'; + * + * isOrdered([]); // false + * isOrdered({}); // false + * isOrdered(Map()); // false + * isOrdered(OrderedMap()); // true + * isOrdered(List()); // true + * isOrdered(Set()); // false + * ``` + */ +export function isOrdered( + maybeOrdered: Iterable +): maybeOrdered is OrderedCollection; +export function isOrdered( + maybeOrdered: unknown +): maybeOrdered is OrderedCollection { + return Boolean( + maybeOrdered && + // @ts-expect-error: maybeOrdered is typed as `{}`, need to change in 6.0 to `maybeOrdered && typeof maybeOrdered === 'object' && IS_ORDERED_SYMBOL in maybeOrdered` + maybeOrdered[IS_ORDERED_SYMBOL] + ); +} diff --git a/src/predicates/isOrderedMap.ts b/src/predicates/isOrderedMap.ts new file mode 100644 index 0000000000..ac56e200b5 --- /dev/null +++ b/src/predicates/isOrderedMap.ts @@ -0,0 +1,12 @@ +import type { OrderedMap } from '../../type-definitions/immutable'; +import { isMap } from './isMap'; +import { isOrdered } from './isOrdered'; + +/** + * True if `maybeOrderedMap` is an OrderedMap. + */ +export function isOrderedMap( + maybeOrderedMap: unknown +): maybeOrderedMap is OrderedMap { + return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); +} diff --git a/src/predicates/isOrderedSet.ts b/src/predicates/isOrderedSet.ts new file mode 100644 index 0000000000..8ac58beb96 --- /dev/null +++ b/src/predicates/isOrderedSet.ts @@ -0,0 +1,12 @@ +import { isSet } from './isSet'; +import { isOrdered } from './isOrdered'; +import type { OrderedSet } from '../../type-definitions/immutable'; + +/** + * True if `maybeOrderedSet` is an OrderedSet. + */ +export function isOrderedSet( + maybeOrderedSet: unknown +): maybeOrderedSet is OrderedSet { + return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); +} diff --git a/src/predicates/isRecord.ts b/src/predicates/isRecord.ts new file mode 100644 index 0000000000..ff9b1cdde8 --- /dev/null +++ b/src/predicates/isRecord.ts @@ -0,0 +1,14 @@ +import type { Record } from '../../type-definitions/immutable'; + +export const IS_RECORD_SYMBOL = '@@__IMMUTABLE_RECORD__@@'; + +/** + * True if `maybeRecord` is a Record. + */ +export function isRecord(maybeRecord: unknown): maybeRecord is Record { + return Boolean( + maybeRecord && + // @ts-expect-error: maybeRecord is typed as `{}`, need to change in 6.0 to `maybeRecord && typeof maybeRecord === 'object' && IS_RECORD_SYMBOL in maybeRecord` + maybeRecord[IS_RECORD_SYMBOL] + ); +} diff --git a/src/predicates/isSeq.ts b/src/predicates/isSeq.ts new file mode 100644 index 0000000000..1b0f26f04a --- /dev/null +++ b/src/predicates/isSeq.ts @@ -0,0 +1,19 @@ +import type { Seq } from '../../type-definitions/immutable'; + +export const IS_SEQ_SYMBOL = '@@__IMMUTABLE_SEQ__@@'; + +/** + * True if `maybeSeq` is a Seq. + */ +export function isSeq( + maybeSeq: unknown +): maybeSeq is + | Seq.Indexed + | Seq.Keyed + | Seq.Set { + return Boolean( + maybeSeq && + // @ts-expect-error: maybeSeq is typed as `{}`, need to change in 6.0 to `maybeSeq && typeof maybeSeq === 'object' && MAYBE_SEQ_SYMBOL in maybeSeq` + maybeSeq[IS_SEQ_SYMBOL] + ); +} diff --git a/src/predicates/isSet.ts b/src/predicates/isSet.ts new file mode 100644 index 0000000000..a9a59fe71c --- /dev/null +++ b/src/predicates/isSet.ts @@ -0,0 +1,16 @@ +import type { Set } from '../../type-definitions/immutable'; + +export const IS_SET_SYMBOL = '@@__IMMUTABLE_SET__@@'; + +/** + * True if `maybeSet` is a Set. + * + * Also true for OrderedSets. + */ +export function isSet(maybeSet: unknown): maybeSet is Set { + return Boolean( + maybeSet && + // @ts-expect-error: maybeSet is typed as `{}`, need to change in 6.0 to `maybeSeq && typeof maybeSet === 'object' && MAYBE_SET_SYMBOL in maybeSet` + maybeSet[IS_SET_SYMBOL] + ); +} diff --git a/src/predicates/isStack.ts b/src/predicates/isStack.ts new file mode 100644 index 0000000000..b62768f88e --- /dev/null +++ b/src/predicates/isStack.ts @@ -0,0 +1,14 @@ +import type { Stack } from '../../type-definitions/immutable'; + +export const IS_STACK_SYMBOL = '@@__IMMUTABLE_STACK__@@'; + +/** + * True if `maybeStack` is a Stack. + */ +export function isStack(maybeStack: unknown): maybeStack is Stack { + return Boolean( + maybeStack && + // @ts-expect-error: maybeStack is typed as `{}`, need to change in 6.0 to `maybeStack && typeof maybeStack === 'object' && MAYBE_STACK_SYMBOL in maybeStack` + maybeStack[IS_STACK_SYMBOL] + ); +} diff --git a/src/predicates/isValueObject.ts b/src/predicates/isValueObject.ts new file mode 100644 index 0000000000..f603b517ea --- /dev/null +++ b/src/predicates/isValueObject.ts @@ -0,0 +1,18 @@ +import type { ValueObject } from '../../type-definitions/immutable'; + +/** + * True if `maybeValue` is a JavaScript Object which has *both* `equals()` + * and `hashCode()` methods. + * + * Any two instances of *value objects* can be compared for value equality with + * `Immutable.is()` and can be used as keys in a `Map` or members in a `Set`. + */ +export function isValueObject(maybeValue: unknown): maybeValue is ValueObject { + return Boolean( + maybeValue && + // @ts-expect-error: maybeValue is typed as `{}` + typeof maybeValue.equals === 'function' && + // @ts-expect-error: maybeValue is typed as `{}` + typeof maybeValue.hashCode === 'function' + ); +} diff --git a/src/toJS.js b/src/toJS.js new file mode 100644 index 0000000000..2d820416c8 --- /dev/null +++ b/src/toJS.js @@ -0,0 +1,28 @@ +import { Seq } from './Seq'; +import { isCollection } from './predicates/isCollection'; +import { isKeyed } from './predicates/isKeyed'; +import isDataStructure from './utils/isDataStructure'; + +export function toJS(value) { + if (!value || typeof value !== 'object') { + return value; + } + if (!isCollection(value)) { + if (!isDataStructure(value)) { + return value; + } + value = Seq(value); + } + if (isKeyed(value)) { + const result = {}; + value.__iterate((v, k) => { + result[k] = toJS(v); + }); + return result; + } + const result = []; + value.__iterate((v) => { + result.push(toJS(v)); + }); + return result; +} diff --git a/src/utils/arrCopy.ts b/src/utils/arrCopy.ts new file mode 100644 index 0000000000..e6cc653f98 --- /dev/null +++ b/src/utils/arrCopy.ts @@ -0,0 +1,12 @@ +// http://jsperf.com/copy-array-inline + +export default function arrCopy(arr: Array, offset?: number): Array { + offset = offset || 0; + const len = Math.max(0, arr.length - offset); + const newArr: Array = new Array(len); + for (let ii = 0; ii < len; ii++) { + // @ts-expect-error We may want to guard for undefined values with `if (arr[ii + offset] !== undefined`, but ths should not happen by design + newArr[ii] = arr[ii + offset]; + } + return newArr; +} diff --git a/src/utils/assertNotInfinite.ts b/src/utils/assertNotInfinite.ts new file mode 100644 index 0000000000..52abc8fc4c --- /dev/null +++ b/src/utils/assertNotInfinite.ts @@ -0,0 +1,8 @@ +import invariant from './invariant'; + +export default function assertNotInfinite(size: number): void { + invariant( + size !== Infinity, + 'Cannot perform this action with an infinite size.' + ); +} diff --git a/src/utils/coerceKeyPath.ts b/src/utils/coerceKeyPath.ts new file mode 100644 index 0000000000..843981f0ea --- /dev/null +++ b/src/utils/coerceKeyPath.ts @@ -0,0 +1,15 @@ +import type { KeyPath } from '../../type-definitions/immutable'; +import { isOrdered } from '../predicates/isOrdered'; +import isArrayLike from './isArrayLike'; + +export default function coerceKeyPath(keyPath: KeyPath): ArrayLike { + if (isArrayLike(keyPath) && typeof keyPath !== 'string') { + return keyPath; + } + if (isOrdered(keyPath)) { + return keyPath.toArray(); + } + throw new TypeError( + 'Invalid keyPath: expected Ordered Collection or Array: ' + keyPath + ); +} diff --git a/src/utils/deepEqual.ts b/src/utils/deepEqual.ts new file mode 100644 index 0000000000..c76d62c840 --- /dev/null +++ b/src/utils/deepEqual.ts @@ -0,0 +1,97 @@ +import { is } from '../is'; +import { NOT_SET } from '../TrieUtils'; +import { isCollection } from '../predicates/isCollection'; +import { isKeyed } from '../predicates/isKeyed'; +import { isIndexed } from '../predicates/isIndexed'; +import { isAssociative } from '../predicates/isAssociative'; +import { isOrdered } from '../predicates/isOrdered'; +import type { Collection } from '../../type-definitions/immutable'; +import type { Repeat } from '../Repeat'; +import type { Range } from '../Range'; + +export default function deepEqual( + a: Range | Repeat | Collection, + b: unknown +): boolean { + if (a === b) { + return true; + } + + if ( + !isCollection(b) || + // @ts-expect-error size should exists on Collection + (a.size !== undefined && b.size !== undefined && a.size !== b.size) || + // @ts-expect-error __hash exists on Collection + (a.__hash !== undefined && + // @ts-expect-error __hash exists on Collection + b.__hash !== undefined && + // @ts-expect-error __hash exists on Collection + a.__hash !== b.__hash) || + isKeyed(a) !== isKeyed(b) || + isIndexed(a) !== isIndexed(b) || + // @ts-expect-error Range extends Collection, which implements [Symbol.iterator], so it is valid + isOrdered(a) !== isOrdered(b) + ) { + return false; + } + + // @ts-expect-error size should exists on Collection + if (a.size === 0 && b.size === 0) { + return true; + } + + const notAssociative = !isAssociative(a); + + // @ts-expect-error Range extends Collection, which implements [Symbol.iterator], so it is valid + if (isOrdered(a)) { + const entries = a.entries(); + // @ts-expect-error need to cast as boolean + return ( + b.every((v, k) => { + const entry = entries.next().value; + return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); + }) && entries.next().done + ); + } + + let flipped = false; + + if (a.size === undefined) { + // @ts-expect-error size should exists on Collection + if (b.size === undefined) { + if (typeof a.cacheResult === 'function') { + a.cacheResult(); + } + } else { + flipped = true; + const _ = a; + a = b; + b = _; + } + } + + let allEqual = true; + const bSize: number = + // @ts-expect-error b is Range | Repeat | Collection as it may have been flipped, and __iterate is valid + b.__iterate((v, k) => { + if ( + notAssociative + ? // @ts-expect-error has exists on Collection + !a.has(v) + : flipped + ? // @ts-expect-error type of `get` does not "catch" the version with `notSetValue` + !is(v, a.get(k, NOT_SET)) + : // @ts-expect-error type of `get` does not "catch" the version with `notSetValue` + !is(a.get(k, NOT_SET), v) + ) { + allEqual = false; + return false; + } + }); + + return ( + allEqual && + // @ts-expect-error size should exists on Collection + a.size === bSize + ); +} diff --git a/src/utils/hasOwnProperty.ts b/src/utils/hasOwnProperty.ts new file mode 100644 index 0000000000..cb5ba22368 --- /dev/null +++ b/src/utils/hasOwnProperty.ts @@ -0,0 +1 @@ +export default Object.prototype.hasOwnProperty; diff --git a/src/utils/invariant.ts b/src/utils/invariant.ts new file mode 100644 index 0000000000..958e6c977b --- /dev/null +++ b/src/utils/invariant.ts @@ -0,0 +1,6 @@ +export default function invariant( + condition: unknown, + error: string +): asserts condition { + if (!condition) throw new Error(error); +} diff --git a/src/utils/isArrayLike.ts b/src/utils/isArrayLike.ts new file mode 100644 index 0000000000..82659d6c54 --- /dev/null +++ b/src/utils/isArrayLike.ts @@ -0,0 +1,25 @@ +export default function isArrayLike( + value: unknown +): value is ArrayLike { + if (Array.isArray(value) || typeof value === 'string') { + return true; + } + + // @ts-expect-error "Type 'unknown' is not assignable to type 'boolean'" : convert to Boolean + return ( + value && + typeof value === 'object' && + // @ts-expect-error check that `'length' in value &&` + Number.isInteger(value.length) && + // @ts-expect-error check that `'length' in value &&` + value.length >= 0 && + // @ts-expect-error check that `'length' in value &&` + (value.length === 0 + ? // Only {length: 0} is considered Array-like. + Object.keys(value).length === 1 + : // An object is only Array-like if it has a property where the last value + // in the array-like may be found (which could be undefined). + // @ts-expect-error check that `'length' in value &&` + value.hasOwnProperty(value.length - 1)) + ); +} diff --git a/src/utils/isDataStructure.ts b/src/utils/isDataStructure.ts new file mode 100644 index 0000000000..e71c55bb7d --- /dev/null +++ b/src/utils/isDataStructure.ts @@ -0,0 +1,20 @@ +import type { Collection, Record } from '../../type-definitions/immutable'; +import { isImmutable } from '../predicates/isImmutable'; +import isPlainObj from './isPlainObj'; + +/** + * Returns true if the value is a potentially-persistent data structure, either + * provided by Immutable.js or a plain Array or Object. + */ +export default function isDataStructure( + value: unknown +): value is + | Collection + | Record + | Array + | object { + return ( + typeof value === 'object' && + (isImmutable(value) || Array.isArray(value) || isPlainObj(value)) + ); +} diff --git a/src/utils/isPlainObj.ts b/src/utils/isPlainObj.ts new file mode 100644 index 0000000000..07e73e208a --- /dev/null +++ b/src/utils/isPlainObj.ts @@ -0,0 +1,26 @@ +const toString = Object.prototype.toString; + +export default function isPlainObject(value: unknown): value is object { + // The base prototype's toString deals with Argument objects and native namespaces like Math + if ( + !value || + typeof value !== 'object' || + toString.call(value) !== '[object Object]' + ) { + return false; + } + + const proto = Object.getPrototypeOf(value); + if (proto === null) { + return true; + } + + // Iteratively going up the prototype chain is needed for cross-realm environments (differing contexts, iframes, etc) + let parentProto = proto; + let nextProto = Object.getPrototypeOf(proto); + while (nextProto !== null) { + parentProto = nextProto; + nextProto = Object.getPrototypeOf(parentProto); + } + return parentProto === proto; +} diff --git a/src/utils/mixin.ts b/src/utils/mixin.ts new file mode 100644 index 0000000000..3d4cee5fc6 --- /dev/null +++ b/src/utils/mixin.ts @@ -0,0 +1,20 @@ +type Constructor = new (...args: unknown[]) => T; + +/** + * Contributes additional methods to a constructor + */ +export default function mixin( + ctor: C, + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + methods: Record +): C { + const keyCopier = (key: string | symbol): void => { + // @ts-expect-error how to handle symbol ? + ctor.prototype[key] = methods[key]; + }; + Object.keys(methods).forEach(keyCopier); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- TODO enable eslint here + Object.getOwnPropertySymbols && + Object.getOwnPropertySymbols(methods).forEach(keyCopier); + return ctor; +} diff --git a/src/utils/quoteString.ts b/src/utils/quoteString.ts new file mode 100644 index 0000000000..8d9b825a38 --- /dev/null +++ b/src/utils/quoteString.ts @@ -0,0 +1,11 @@ +/** + * Converts a value to a string, adding quotes if a string was provided. + */ +export default function quoteString(value: unknown): string { + try { + return typeof value === 'string' ? JSON.stringify(value) : String(value); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (_ignoreError) { + return JSON.stringify(value); + } +} diff --git a/src/utils/shallowCopy.ts b/src/utils/shallowCopy.ts new file mode 100644 index 0000000000..37aad28015 --- /dev/null +++ b/src/utils/shallowCopy.ts @@ -0,0 +1,19 @@ +import arrCopy from './arrCopy'; +import hasOwnProperty from './hasOwnProperty'; + +export default function shallowCopy(from: Array): Array; +export default function shallowCopy(from: O): O; +export default function shallowCopy( + from: Array | O +): Array | O { + if (Array.isArray(from)) { + return arrCopy(from); + } + const to: Partial = {}; + for (const key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + return to as O; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..b0fa1baad1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + /* Base Options: */ + "esModuleInterop": true, + "skipLibCheck": true, + "target": "es2022", + "allowJs": true, + "resolveJsonModule": true, + "moduleDetection": "force", + "isolatedModules": true, + "verbatimModuleSyntax": true, + /* Strictness */ + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + /* If NOT transpiling with TypeScript: */ + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + /* If your code runs in the DOM: */ + "lib": ["es2022", "dom", "dom.iterable"] + } +} diff --git a/tsconfig.src.json b/tsconfig.src.json new file mode 100644 index 0000000000..ae550d9ff2 --- /dev/null +++ b/tsconfig.src.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/Immutable.js"] +} diff --git a/tstyche.config.json b/tstyche.config.json new file mode 100644 index 0000000000..903317e015 --- /dev/null +++ b/tstyche.config.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://tstyche.org/schemas/config.json", + "testFileMatch": [ + "type-definitions/ts-tests/*.ts" + ] +} diff --git a/type-definitions/Immutable.d.ts b/type-definitions/Immutable.d.ts deleted file mode 100644 index 1d62f96114..0000000000 --- a/type-definitions/Immutable.d.ts +++ /dev/null @@ -1,1864 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/** - * Immutable Data - * ============== - * - * Immutable data encourages pure functions (data-in, data-out) and lends itself - * to much simpler application development and enabling techniques from - * functional programming such as lazy evaluation. - * - * While designed to bring these powerful functional concepts to JavaScript, it - * presents an Object-Oriented API familiar to Javascript engineers and closely - * mirroring that of Array, Map, and Set. It is easy and efficient to convert to - * and from plain Javascript types. - */ - -declare module 'immutable' { - - /** - * `Immutable.is()` has the same semantics as Object.is(), but treats immutable - * sequences as data, equal if the second immutable sequences contains - * equivalent data. It's used throughout when checking for equality. - * - * var map1 = Immutable.Map({a:1, b:1, c:1}); - * var map2 = Immutable.Map({a:1, b:1, c:1}); - * assert(map1 !== map2); - * assert(Object.is(map1, map2) === false); - * assert(Immutable.is(map1, map2) === true); - * - */ - export function is(first: any, second: any): boolean; - - /** - * `Immutable.fromJS()` deeply converts plain JS objects and arrays to - * Immutable sequences. - * - * If a `converter` is optionally provided, it will be called with every - * sequence (beginning with the most nested sequences and proceeding to the - * original sequence itself), along with the key refering to this Sequence - * and the parent JS object provided as `this`. For the top level, object, - * the key will be "". This `converter` is expected to return a new Sequence, - * allowing for custom convertions from deep JS objects. - * - * This example converts JSON to Vector and OrderedMap: - * - * Immutable.fromJS({a: {b: [10, 20, 30]}, c: 40}, function (value, key) { - * var isIndexed = value instanceof IndexedSequence; - * console.log(isIndexed, key, this); - * return isIndexed ? value.toVector() : value.toOrderedMap(); - * }); - * - * // true, "b", {b: [10, 20, 30]} - * // false, "a", {a: {b: [10, 20, 30]}, c: 40} - * // false, "", {"": {a: {b: [10, 20, 30]}, c: 40}} - * - * If `converter` is not provided, the default behavior will convert Arrays into - * Vectors and Objects into Maps. - * - * Note: `converter` acts similarly to [`reviver`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter) - * in `JSON.parse`. - */ - export function fromJS( - json: any, - converter?: (k: any, v: Sequence) => any - ): any; - - - - /** - * Sequence - * -------- - * - * The `Sequence` is a set of (key, value) entries which can be iterated, and - * is the base class for all collections in `immutable`, allowing them to - * make use of all the Sequence methods (such as `map` and `filter`). - * - * **Sequences are immutable** — Once a sequence is created, it cannot be - * changed, appended to, rearranged or otherwise modified. Instead, any mutative - * method called on a sequence will return a new immutable sequence. - * - * **Sequences are lazy** — Sequences do as little work as necessary to respond - * to any method call. - * - * For example, the following does no work, because the resulting sequence is - * never used: - * - * var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8) - * .filter(x => x % 2).map(x => x * x); - * - * Once the sequence is used, it performs only the work necessary. In this - * example, no intermediate arrays are ever created, filter is only called - * twice, and map is only called once: - * - * console.log(evenSquares.last()); // 49 - * - * Lazy Sequences allow for the efficient chaining of sequence operations, - * allowing for the expression of logic that can otherwise be very tedious: - * - * Immutable.Sequence({a:1, b:1, c:1}) - * .flip().map(key => key.toUpperCase()).flip().toObject(); - * // Map { A: 1, B: 1, C: 1 } - * - * As well as expressing logic that would otherwise seem memory-limited: - * - * Immutable.Range(1, Infinity) - * .skip(1000) - * .map(n => -n) - * .filter(n => n % 2 === 0) - * .take(2) - * .reduce((r, n) => r * n, 1); - * // 1006008 - * - * Note: A sequence is always iterated in the same order, however that order may - * not always be well defined, as is the case for the `Map`. - */ - - /** - * `Immutable.Sequence()` returns a sequence of its parameters. - * - * * If provided a single argument: - * * If a Sequence, that same Sequence is returned. - * * If an Array, an `IndexedSequence` is returned. - * * If a plain Object, a `Sequence` is returned, iterated in the same order - * as the for-in would iterate through the Object itself. - * * An `IndexedSequence` of all arguments is returned. - * - * Note: if a Sequence is created from a JavaScript Array or Object, then it can - * still possibly mutated if the underlying Array or Object is ever mutated. - */ - export function Sequence(seq: IndexedSequence): IndexedSequence; - export function Sequence(array: Array): IndexedSequence; - export function Sequence(seq: Sequence): Sequence; - export function Sequence(obj: {[key: string]: V}): Sequence; - export function Sequence(iterable: Object/*Iterable*/): IndexedSequence; - export function Sequence(...values: T[]): IndexedSequence; - export function Sequence(): Sequence; - - /** - * Like `Immutable.Sequence()`, `Immutable.Sequence.from()` returns a sequence, - * but always expects a single argument. - */ - export module Sequence { - function from(seq: IndexedSequence): IndexedSequence; - function from(array: Array): IndexedSequence; - function from(seq: Sequence): Sequence; - function from(obj: {[key: string]: V}): Sequence; - } - - - export interface Sequence { - - // ### Conversion to other types - - /** - * Converts this sequence to an Array, discarding keys. - */ - toArray(): Array; - - /** - * Deeply converts this sequence to equivalent JS. - * - * IndexedSequences, Vectors, Ranges, Repeats and Sets become Arrays, while - * other Sequences become Objects. - */ - toJS(): any; - - /** - * Converts this sequence to a Map, Throws if keys are not hashable. - * - * Note: This is equivalent to `Map.from(this)`, but provided to allow for - * chained expressions. - */ - toMap(): Map; - - /** - * Converts this sequence to an Object. Throws if keys are not strings. - */ - toObject(): Object; - - /** - * Converts this sequence to a Map, maintaining the order of iteration. - * - * Note: This is equivalent to `OrderedMap.from(this)`, but provided to - * allow for chained expressions. - */ - toOrderedMap(): Map; - - /** - * Converts this sequence to a Set, discarding keys. Throws if values - * are not hashable. - * - * Note: This is equivalent to `Set.from(this)`, but provided to allow for - * chained expressions. - */ - toSet(): Set; - - /** - * Converts this sequence to a Vector, discarding keys. - * - * Note: This is equivalent to `Vector.from(this)`, but provided to allow - * for chained expressions. - */ - toVector(): Vector; - - - // ### Common JavaScript methods and properties - - /** - * Deeply converts this sequence to a string. - */ - toString(): string; - - /** - * Some sequences can describe their length lazily. When this is the case, - * length will be an integer. Otherwise it will be undefined. - * - * For example, the new Sequences returned from map() or reverse() - * preserve the length of the original sequence while filter() does not. - * - * Note: All original collections will have a length, including Maps, - * Vectors, Sets, Ranges, Repeats and Sequences made from - * Arrays and Objects. - */ - length: number; - - - // ### Sequential methods mirring those found on Array and Map (ES6) - - /** - * Returns a new sequence with other values and sequences concatenated to - * this one. All entries will be present in the resulting sequence, even if - * they have the same key. - */ - concat(...valuesOrSequences: any[]): Sequence; - - /** - * True if a value exists within this Sequence. - */ - contains(value: V): boolean; - - /** - * An iterator of this Map's entries as [key, value] tuples. - */ - entries(): Iterator>; - - /** - * True if `predicate` returns true for all entries in the sequence. - */ - every( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): boolean; - - /** - * Returns a new sequence with only the entries for which the `predicate` - * function returns true. - * - * Sequence({a:1,b:2,c:3,d:4}).filter(x => x % 2 === 0) // { b: 2, d: 4 } - * - */ - filter( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns the value for which the `predicate` returns true. - */ - find( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any, - notSetValue?: V - ): V; - - /** - * The `sideEffect` is executed for every entry in the sequence. - * - * Unlike `Array.prototype.forEach`, if any call of `sideEffect` returns - * `false`, the iteration will stop. Returns the length of the sequence which - * was iterated (including the last iteration which returned false). - */ - forEach( - sideEffect: (value?: V, key?: K, seq?: Sequence) => any, - context?: any - ): number; - - /** - * Joins values together as a string, inserting a separator between each. - * The default separator is ",". - */ - join(separator?: string): string; - - /** - * An iterator of this Map's keys. - */ - keys(): Iterator; - - /** - * Returns a new sequence with values passed through a `mapper` function. - * - * Sequence({ a: 1, b: 2 }).map(x => 10 * x) // { a: 10, b: 20 } - * - */ - map( - mapper: (value?: V, key?: K, seq?: Sequence) => M, - context?: any - ): Sequence; - - /** - * Reduces the sequence to a value by calling the `reducer` for every entry - * in the sequence and passing along the reduced value. - * - * If `initialReduction` is not provided, or is null, the first item in the - * sequence will be used. - * - * @see `Array.prototype.reduce`. - */ - reduce( - reducer: (reduction?: R, value?: V, key?: K, seq?: Sequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Reduces the sequence in reverse (from the right side). - * - * Note: Equivalent to this.reverse().reduce(), but provided for parity - * with `Array.prototype.reduceRight`. - */ - reduceRight( - reducer: (reduction?: R, value?: V, key?: K, seq?: Sequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Returns a new sequence which iterates in reverse order of this sequence. - */ - reverse(): Sequence; - - /** - * Returns a new sequence representing a portion of this sequence from start - * up to but not including end. - * - * If begin is negative, it is offset from the end of the sequence. e.g. - * `slice(-2)` returns a sequence of the last two entries. If it is not - * provided the new sequence will begin at the beginning of this sequence. - * - * If end is negative, it is offset from the end of the sequence. e.g. - * `slice(0, -1)` returns a sequence of everything but the last entry. If it - * is not provided, the new sequence will continue through the end of - * this sequence. - * - * If the requested slice is equivalent to the current Sequence, then it will - * return itself. - * - * Note: unlike `Array.prototype.slice`, this function is O(1) and copies - * no data. The resulting sequence is also lazy, and a copy is only made when - * it is converted such as via `toArray()` or `toVector()`. - */ - slice(begin?: number, end?: number): Sequence; - - /** - * True if `predicate` returns true for any entry in the sequence. - */ - some( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): boolean; - - /** - * Returns a new Sequence which contains the same [key, value] entries, - * (stable) sorted by using a comparator. - * - * If a comparator is not provided, a default comparator uses `a < b`. - * - * `comparator(valueA, valueB)`: - * - * * Returns `0` if the elements should not be swapped. - * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` - * * Returns `1` (or any positive number) if `valueA` comes after `valueB` - * * Is pure, i.e. it must always return the same value for the same pair - * of values. - */ - sort(comparator?: (valueA: V, valueB: V) => number): Sequence; - - /** - * An iterator of this Map's values. - */ - values(): Iterator; - - - // ### More sequential methods - - /** - * Returns a new Sequence containing all entries except the last. - */ - butLast(): Sequence; - - /** - * Regardless of if this sequence can describe its length lazily, this method - * will always return the correct length. E.g. it evaluates the full sequence - * if necessary. - * - * If `predicate` is provided, then this returns the count of entries in the - * sequence for which the `predicate` returns true. - */ - count(): number; - count( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): number; - - /** - * Returns a `Sequence` of counts, grouped by the return value of the - * `grouper` function. - * - * Note: This is not a lazy operation. - */ - countBy( - grouper: (value?: V, key?: K, seq?: Sequence) => G, - context?: any - ): Sequence; - - /** - * True if this and the other sequence have value equality, as defined - * by `Immutable.is()`. - * - * Note: This is equivalent to `Immutable.is(this, other)`, but provided to - * allow for chained expressions. - */ - equals(other: Sequence): boolean; - - /** - * Returns a new indexed sequence of [key, value] tuples. - */ - entrySeq(): IndexedSequence>; - - /** - * Returns the key for which the `predicate` returns true. - */ - findKey( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): K; - - /** - * Returns the last value for which the `predicate` returns true. - * - * Note: `predicate` will be called for each entry in reverse. - */ - findLast( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any, - notSetValue?: V - ): V; - - /** - * Returns the last key for which the `predicate` returns true. - * - * Note: `predicate` will be called for each entry in reverse. - */ - findLastKey( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): K; - - /** - * The first value in the sequence. - */ - first(): V; - - /** - * Flat-maps the Sequence. - */ - flatMap( - mapper: (value?: V, key?: K, seq?: Sequence) => Sequence, - context?: any - ): Sequence; - - /** - * Flattens nested Sequences by one level. - * - * Note: `flatten` operates on Sequence> and - * returns Sequence - */ - flatten(): Sequence; - - /** - * Returns a new sequence with this sequences's keys as it's values, and this - * sequences's values as it's keys. - * - * Sequence({ a: 'z', b: 'y' }).flip() // { z: 'a', y: 'b' } - * - */ - flip(): Sequence; - - /** - * Returns the value associated with the provided key, or notSetValue if - * the Sequence does not contain this key. - * - * Note: it is possible a key may be associated with an `undefined` value, so - * if `notSetValue` is not provided and this method returns `undefined`, - * that does not guarantee the key was not found. - */ - get(key: K, notSetValue?: V): V; - - /** - * Returns the value found by following a key path through nested sequences. - */ - getIn(searchKeyPath: Array, notSetValue?: V): V; - - /** - * Returns a `Sequence` of `Sequences`, grouped by the return value of the - * `grouper` function. - * - * Note: This is not a lazy operation. - */ - groupBy( - grouper: (value?: V, key?: K, seq?: Sequence) => G, - context?: any - ): Sequence>; - - /** - * True if a key exists within this Sequence. - */ - has(key: K): boolean; - - /** - * Returns a new indexed sequence of the keys of this sequence, - * discarding values. - */ - keySeq(): IndexedSequence; - - /** - * The last value in the sequence. - */ - last(): V; - - /** - * Returns a new sequence with entries ([key, value] tuples) passed through - * a `mapper` function. - * - * Sequence({ a: 1, b: 2 }) - * .mapEntries(([k, v]) => [k.toUpperCase(), v * 2]) - * // { A: 2, B: 4 } - * - */ - mapEntries( - mapper: (entry?: /*(K, V)*/Array, index?: number, seq?: Sequence) => /*(KM, VM)*/Array, - context?: any - ): Sequence; - - /** - * Returns a new sequence with keys passed through a `mapper` function. - * - * Sequence({ a: 1, b: 2 }).mapKeys(x => x.toUpperCase()) // { A: 1, B: 2 } - * - */ - mapKeys( - mapper: (key?: K, value?: V, seq?: Sequence) => M, - context?: any - ): Sequence; - - /** - * Returns a new Sequence containing all entries except the first. - */ - rest(): Sequence - - /** - * Returns a new sequence which excludes the first `amount` entries from - * this sequence. - */ - skip(amount: number): Sequence; - - /** - * Returns a new sequence which excludes the last `amount` entries from - * this sequence. - */ - skipLast(amount: number): Sequence; - - /** - * Returns a new sequence which contains entries starting from when - * `predicate` first returns false. - * - * Sequence('dog','frog','cat','hat','god').skipWhile(x => x.match(/g/)) - * // ['cat', 'hat', 'god'] - * - */ - skipWhile( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns a new sequence which contains entries starting from when - * `predicate` first returns true. - * - * Sequence('dog','frog','cat','hat','god').skipUntil(x => x.match(/hat/)) - * // ['hat', 'god'] - * - */ - skipUntil( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Like `sort`, but also accepts a `sortValueMapper` which allows for - * sorting by more sophisticated means: - * - * hitters.sortBy(hitter => hitter.avgHits); - * - */ - sortBy( - sortValueMapper: (value?: V, key?: K, seq?: Sequence) => S, - comparator?: (valueA: S, valueB: S) => number - ): Sequence; - - /** - * Returns a new sequence which contains the first `amount` entries from - * this sequence. - */ - take(amount: number): Sequence; - - /** - * Returns a new sequence which contains the last `amount` entries from - * this sequence. - */ - takeLast(amount: number): Sequence; - - /** - * Returns a new sequence which contains entries from this sequence as long - * as the `predicate` returns true. - * - * Sequence('dog','frog','cat','hat','god').takeWhile(x => x.match(/o/)) - * // ['dog', 'frog'] - * - */ - takeWhile( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns a new sequence which contains entries from this sequence as long - * as the `predicate` returns false. - * - * Sequence('dog','frog','cat','hat','god').takeUntil(x => x.match(/at/)) - * // ['dog', 'frog'] - * - */ - takeUntil( - predicate: (value?: V, key?: K, seq?: Sequence) => boolean, - context?: any - ): Sequence; - - /** - * Returns a new Sequence identical to this one, but does not behave as - * indexed. Instead the indices are treated as keys. This is useful if you - * want to operate on an IndexedSequence and preserve the index, value - * pairs. - * - * This is the generalized (and lazy) form of converting a Vector to Map. - * - * The returned Sequence will have identical iteration order as - * this Sequence. - * - * For already Keyed sequences, simply returns itself. - * - * Example: - * - * var indexedSeq = Immutable.Sequence('A', 'B', 'C'); - * indexedSeq.filter(v => v === 'B').toString() // Seq [ 'B' ] - * var keyedSeq = indexedSeq.toKeyedSeq(); - * keyedSeq.filter(v => v === 'B').toString() // Seq { 1: 'B' } - * - */ - toKeyedSeq(): Sequence; - - /** - * Returns a new indexed sequence of the values of this sequence, - * discarding keys. - */ - valueSeq(): IndexedSequence; - - - // ### Lazy Sequence methods - - /** - * Because Sequences are lazy and designed to be chained together, they do - * not cache their results. For example, this map function is called 6 times: - * - * var squares = Sequence(1,2,3).map(x => x * x); - * squares.join() + squares.join(); - * - * If you know a derived sequence will be used multiple times, it may be more - * efficient to first cache it. Here, map is called 3 times: - * - * var squares = Sequence(1,2,3).map(x => x * x).cacheResult(); - * squares.join() + squares.join(); - * - * Use this method judiciously, as it must fully evaluate a lazy Sequence. - * - * Note: after calling `cacheResult()`, a Sequence will always have a length. - */ - cacheResult(): Sequence; - } - - - /** - * Indexed Sequence - * ---------------- - * - * Indexed Sequences have incrementing numeric keys. They exhibit - * slightly different behavior than `Sequence` for some methods in order to - * better mirror the behavior of JavaScript's `Array`, and add others which do - * not make sense on non-indexed sequences such as `indexOf`. - * - * Unlike JavaScript arrays, `IndexedSequence`s are always dense. "Unset" - * indices and `undefined` indices are indistinguishable, and all indices from - * 0 to `length` are visited when iterated. - * - * All IndexedSequence methods return re-indexed Sequences. In other words, - * indices always start at 0 and increment until length. If you wish to - * preserve indices, using them as keys, use `toKeyedSeq()`. - * - */ - - export interface IndexedSequence extends Sequence { - - // ### Sequential methods mirring those found on Array (ES6) - - /** - * This new behavior will iterate through the values and sequences with - * increasing indices. - * @override - */ - concat(...valuesOrSequences: any[]): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - every( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): boolean; - - /** - * Returns IndexedSequence. - * @override - */ - filter( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - find( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any, - notSetValue?: T - ): T; - - /** - * Returns the first index in the sequence where a value satisfies the - * provided predicate function. Otherwise -1 is returned. - */ - findIndex( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Side effect takes IndexedSequence. - * @override - */ - forEach( - sideEffect: (value?: T, index?: number, seq?: IndexedSequence) => any, - context?: any - ): number; - - /** - * Returns the first index at which a given value can be found in the - * sequence, or -1 if it is not present. - */ - indexOf(searchValue: T): number; - - /** - * Returns the last index at which a given value can be found in the - * sequence, or -1 if it is not present. - */ - lastIndexOf(searchValue: T): number; - - /** - * Returns an IndexedSequence - * @override - */ - map( - mapper: (value?: T, index?: number, seq?: IndexedSequence) => M, - context?: any - ): IndexedSequence; - - /** - * Reducer takes IndexedSequence. - * @override - */ - reduce( - reducer: (reduction?: R, value?: T, index?: number, seq?: IndexedSequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Reducer takes IndexedSequence. - * @override - */ - reduceRight( - reducer: (reduction?: R, value?: T, index?: number, seq?: IndexedSequence) => R, - initialReduction?: R, - context?: any - ): R; - - /** - * Returns a new IndexedSequence with this sequences values in the - * reversed order. - * @override - */ - reverse(): IndexedSequence; - - /** - * Returns IndexedSequence. - * @override - */ - slice(begin?: number, end?: number): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - some( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): boolean; - - /** - * Returns an IndexedSequence - * @override - */ - sort( - comparator?: (valueA: T, valueB: T) => number - ): IndexedSequence; - - /** - * Splice returns a new indexed sequence by replacing a region of this sequence - * with new values. If values are not provided, it only skips the region to - * be removed. - * - * `index` may be a negative number, which indexes back from the end of the - * Sequence. `s.splice(-2)` splices after the second to last item. - * - * Sequence(['a','b','c','d']).splice(1, 2, 'q', 'r', 's') - * // ['a', 'q', 'r', 's', 'd'] - * - */ - splice(index: number, removeNum: number, ...values: any[]): IndexedSequence; - - - // ### More sequential methods - - /** - * Returns an IndexedSequence - * @override - */ - butLast(): IndexedSequence; - - /** - * Predicate takes IndexedSequence. - * @override - */ - count(): number; - count( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Predicate takes IndexedSequence. - * @override - */ - findKey( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Predicate takes IndexedSequence. - * @override - */ - findLast( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any, - notSetValue?: T - ): T; - - /** - * Returns the last index in the sequence where a value satisfies the - * provided predicate function. Otherwise -1 is returned. - */ - findLastIndex( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Predicate takes IndexedSequence. - * @override - */ - findLastKey( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): number; - - /** - * Returns IndexedSequence - * @override - */ - flatMap( - mapper: (value?: T, index?: number, seq?: IndexedSequence) => IndexedSequence, - context?: any - ): IndexedSequence; - flatMap( - mapper: (value?: T, index?: number, seq?: IndexedSequence) => M[], - context?: any - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - flatten(): IndexedSequence; - - /** - * If this is a sequence of entries (key-value tuples), it will return a - * sequence of those entries. - */ - fromEntrySeq(): Sequence; - - /** - * Returns the value associated with the provided index, or notSetValue if - * the index is beyond the bounds of the sequence. - * - * `index` may be a negative number, which indexes back from the end of the - * Sequence. `s.get(-1)` gets the last item in the Sequence. - */ - get(index: number, notSetValue?: T): T; - - /** - * Returns Sequence> - * @override - */ - groupBy( - grouper: (value?: T, index?: number, seq?: IndexedSequence) => G, - context?: any - ): Sequence*/>; // Bug: exposing this causes the type checker to implode. - - /** - * Mapper takes IndexedSequence. - * @override - */ - mapEntries( - mapper: (entry?: /*(K, V)*/Array, index?: number, seq?: IndexedSequence) => /*(KM, VM)*/Array, - context?: any - ): Sequence; - - /** - * Mapper takes IndexedSequence. - * @override - */ - mapKeys( - mapper: (index?: number, value?: T, seq?: IndexedSequence) => M, - context?: any - ): Sequence; - - /** - * Returns IndexedSequence - * @override - */ - rest(): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skip(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skipLast(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skipWhile( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - skipUntil( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Returns an IndexedSequence - * @override - */ - sortBy( - sortValueMapper: (value?: T, index?: number, seq?: IndexedSequence) => S, - comparator?: (valueA: S, valueB: S) => number - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - take(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - takeLast(amount: number): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - takeWhile( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - /** - * Returns IndexedSequence - * @override - */ - takeUntil( - predicate: (value?: T, index?: number, seq?: IndexedSequence) => boolean, - context?: any - ): IndexedSequence; - - - // ### Lazy Sequence methods - - /** - * Returns an IndexedSequence - * @override - */ - cacheResult(): IndexedSequence; - } - - - /** - * Range - * ----- - * - * Returns a lazy indexed sequence of numbers from `start` (inclusive) to `end` - * (exclusive), by `step`, where `start` defaults to 0, `step` to 1, and `end` to - * infinity. When `start` is equal to `end`, returns empty range. - * - * Range() // [0,1,2,3,...] - * Range(10) // [10,11,12,13,...] - * Range(10,15) // [10,11,12,13,14] - * Range(10,30,5) // [10,15,20,25] - * Range(30,10,5) // [30,25,20,15] - * Range(30,30,5) // [] - * - */ - export function Range(start?: number, end?: number, step?: number): IndexedSequence; - - - /** - * Repeat - * ------ - * - * Returns a lazy sequence of `value` repeated `times` times. When `times` is - * not defined, returns an infinite sequence of `value`. - * - * Repeat('foo') // ['foo','foo','foo',...] - * Repeat('bar',4) // ['bar','bar','bar','bar'] - * - */ - export function Repeat(value: T, times?: number): IndexedSequence; - - - /** - * Map - * --- - * - * A Map is a Sequence of (key, value) pairs with `O(log32 N)` gets and sets. - * - * Map is a hash map and requires keys that are hashable, either a primitive - * (string or number) or an object with a `hashCode(): number` method. - * - * Iteration order of a Map is undefined, however is stable. Multiple iterations - * of the same Map will iterate in the same order. - */ - - export module Map { - - /** - * `Map.empty()` creates a new immutable map of length 0. - */ - function empty(): Map; - - /** - * `Map.from()` creates a new immutable Map with the same key value pairs as - * the provided Sequence or JavaScript Object or Array. - * - * var newMap = Map.from({key: "value"}); - * var newMap = Map.from([["key", "value"]]); - * - */ - function from(sequence: Sequence): Map; - function from(object: {[key: string]: V}): Map; - function from(entries: Array>): Map; - } - - /** - * Alias for `Map.empty()`. - */ - export function Map(): Map; - - /** - * Alias for `Map.from()`. - */ - export function Map(sequence: Sequence): Map; - export function Map(object: {[key: string]: V}): Map; - export function Map(entries: Array>): Map; - - - export interface Map extends Sequence { - - /** - * Returns a new Map also containing the new key, value pair. If an equivalent - * key already exists in this Map, it will be replaced. - */ - set(key: K, value: V): Map; - - /** - * Returns a new Map which excludes this `key`. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(key: K): Map; - delete(key: K): Map; - - /** - * Returns a new Map containing no keys or values. - */ - clear(): Map; - - /** - * When this cursor's (or any of its sub-cursors') `update` method is called, - * the resulting new data structure will be provided to the `onChange` - * function. Use this callback to keep track of the most current value or - * update the rest of your application. - */ - cursor( - onChange?: (newValue: Map, oldValue?: Map, keyPath?: Array) => void - ): Cursor>; - cursor( - keyPath: Array, - onChange?: (newValue: Map, oldValue?: Map, keyPath?: Array) => void - ): Cursor; - cursor( - key: K, - onChange?: (newValue: Map, oldValue?: Map, keyPath?: Array) => void - ): Cursor; - - /** - * Returns a new Map having updated the value at this `key` with the return - * value of calling `updater` with the existing value, or `notSetValue` if - * the key was not set. If called with only a single argument, `updater` is - * called with the Map itself. - * - * Equivalent to: `map.set(key, updater(map.get(key, notSetValue)))`. - */ - update(updater: (value: Map) => Map): Map; - update(key: K, updater: (value: V) => V): Map; - update(key: K, notSetValue: V, updater: (value: V) => V): Map; - - /** - * Returns a new Map having applied the `updater` to the entry found at the - * keyPath. If any keys in `keyPath` do not exist, a new immutable Map will - * be created at that key. If the `keyPath` was not previously set, - * `updater` is called with `notSetValue` (if provided). - * - * var data = Immutable.fromJS({ a: { b: { c: 10 } } }); - * data.updateIn(['a', 'b'], map => map.set('d', 20)); - * // { a: { b: { c: 10, d: 20 } } } - * - */ - updateIn( - keyPath: Array, - updater: (value: any) => any - ): Map; - updateIn( - keyPath: Array, - notSetValue: any, - updater: (value: any) => any - ): Map; - - /** - * Returns a new Map resulting from merging the provided Sequences - * (or JS objects) into this Map. In other words, this takes each entry of - * each sequence and sets it on this Map. - * - * var x = Immutable.Map({a: 10, b: 20, c: 30}); - * var y = Immutable.Map({b: 40, a: 50, d: 60}); - * x.merge(y) // { a: 50, b: 40, c: 30, d: 60 } - * y.merge(x) // { b: 20, a: 10, d: 60, c: 30 } - * - */ - merge(...sequences: Sequence[]): Map; - merge(...sequences: {[key: string]: V}[]): Map; - - /** - * Like `merge()`, `mergeWith()` returns a new Map resulting from merging the - * provided Sequences (or JS objects) into this Map, but uses the `merger` - * function for dealing with conflicts. - * - * var x = Immutable.Map({a: 10, b: 20, c: 30}); - * var y = Immutable.Map({b: 40, a: 50, d: 60}); - * x.mergeWith((prev, next) => prev / next, y) // { a: 0.2, b: 0.5, c: 30, d: 60 } - * y.mergeWith((prev, next) => prev / next, x) // { b: 2, a: 5, d: 60, c: 30 } - * - */ - mergeWith( - merger: (previous?: V, next?: V) => V, - ...sequences: Sequence[] - ): Map; - mergeWith( - merger: (previous?: V, next?: V) => V, - ...sequences: {[key: string]: V}[] - ): Map; - - /** - * Like `merge()`, but when two Sequences conflict, it merges them as well, - * recursing deeply through the nested data. - * - * var x = Immutable.fromJS({a: { x: 10, y: 10 }, b: { x: 20, y: 50 } }); - * var y = Immutable.fromJS({a: { x: 2 }, b: { y: 5 }, c: { z: 3 } }); - * x.mergeDeep(y) // {a: { x: 2, y: 10 }, b: { x: 20, y: 5 }, c: { z: 3 } } - * - */ - mergeDeep(...sequences: Sequence[]): Map; - mergeDeep(...sequences: {[key: string]: V}[]): Map; - - /** - * Like `mergeDeep()`, but when two non-Sequences conflict, it uses the - * `merger` function to determine the resulting value. - * - * var x = Immutable.fromJS({a: { x: 10, y: 10 }, b: { x: 20, y: 50 } }); - * var y = Immutable.fromJS({a: { x: 2 }, b: { y: 5 }, c: { z: 3 } }); - * x.mergeDeepWith((prev, next) => prev / next, y) - * // {a: { x: 5, y: 10 }, b: { x: 20, y: 10 }, c: { z: 3 } } - * - */ - mergeDeepWith( - merger: (previous?: V, next?: V) => V, - ...sequences: Sequence[] - ): Map; - mergeDeepWith( - merger: (previous?: V, next?: V) => V, - ...sequences: {[key: string]: V}[] - ): Map; - - /** - * Every time you call one of the above functions, a new immutable Map is - * created. If a pure function calls a number of these to produce a final - * return value, then a penalty on performance and memory has been paid by - * creating all of the intermediate immutable Maps. - * - * If you need to apply a series of mutations to produce a new immutable - * Map, `withMutations()` creates a temporary mutable copy of the Map which - * can apply mutations in a highly performant manner. In fact, this is - * exactly how complex mutations like `merge` are done. - * - * As an example, this results in the creation of 2, not 4, new Maps: - * - * var map1 = Immutable.Map(); - * var map2 = map1.withMutations(map => { - * map.set('a', 1).set('b', 2).set('c', 3); - * }); - * assert(map1.length === 0); - * assert(map2.length === 3); - * - */ - withMutations(mutator: (mutable: Map) => any): Map; - - /** - * Another way to avoid creation of intermediate Immutable maps is to create - * a mutable copy of this collection. Mutable copies *always* return `this`, - * and thus shouldn't be used for equality. Your function should never return - * a mutable copy of a collection, only use it internally to create a new - * collection. If possible, use `withMutations` as it provides an easier to - * use API. - * - * Note: if the collection is already mutable, `asMutable` returns itself. - */ - asMutable(): Map; - - /** - * The yin to `asMutable`'s yang. Because it applies to mutable collections, - * this operation is *mutable* and returns itself. Once performed, the mutable - * copy has become immutable and can be safely returned from a function. - */ - asImmutable(): Map; - } - - - /** - * Ordered Map - * ----------- - * - * OrderedMap constructors return a Map which has the additional guarantee of - * the iteration order of entries to match the order in which they were set(). - * This makes OrderedMap behave similarly to native JS objects. - */ - - export module OrderedMap { - - /** - * `OrderedMap.empty()` creates a new immutable ordered Map of length 0. - */ - function empty(): Map; - - /** - * `OrderedMap.from()` creates a new immutable ordered Map with the same key - * value pairs as the provided Sequence or JavaScript Object or Array. - * - * var newMap = OrderedMap.from({key: "value"}); - * - */ - function from(sequence: Sequence): Map; - function from(object: {[key: string]: V}): Map; - function from(array: Array): Map; - } - - /** - * Alias for `OrderedMap.empty()`. - */ - export function OrderedMap(): Map; - - /** - * Alias for `OrderedMap.from()`. - */ - export function OrderedMap(sequence: Sequence): Map; - export function OrderedMap(object: {[key: string]: V}): Map; - export function OrderedMap(array: Array): Map; - - - /** - * Record - * ------ - * - * Creates a new Class which produces maps with a specific set of allowed string - * keys and have default values. - * - * var ABRecord = Record({a:1, b:2}) - * var myRecord = new ABRecord({b:3}) - * - * Records always have a value for the keys they define. `remove`ing a key - * from a record simply resets it to the default value for that key. - * - * myRecord.length // 2 - * myRecordWithoutB = myRecord.remove('b') - * myRecordWithoutB.get('b') // 2 - * myRecordWithoutB.length // 2 - * - * Because Records have a known set of string keys, property get access works as - * expected, however property sets will throw an Error. - * - * myRecord.b // 3 - * myRecord.b = 5 // throws Error - * - * Record Classes can be extended as well, allowing for custom methods on your - * Record. This isn't how things are done in functional environments, but is a - * common pattern in many JS programs. - * - * class ABRecord extends Record({a:1,b:2}) { - * getAB() { - * return this.a + this.b; - * } - * } - * - * var myRecord = new ABRecord(b:3) - * myRecord.getAB() // 4 - * - */ - export function Record(defaultValues: Sequence, name?: string): RecordClass; - export function Record(defaultValues: {[key: string]: any}, name?: string): RecordClass; - - export interface RecordClass { - new (): Map; - new (values: Sequence): Map; - new (values: {[key: string]: any}): Map; - } - - - /** - * Set - * --- - * - * A Set is a Sequence of unique values with `O(log32 N)` gets and sets. - * - * Sets, like Maps, require that their values are hashable, either a primitive - * (string or number) or an object with a `hashCode(): number` method. - * - * When iterating a Set, the entries will be (value, value) pairs. Iteration - * order of a Set is undefined, however is stable. Multiple iterations of the - * same Set will iterate in the same order. - */ - - export module Set { - - /** - * `Set.empty()` creates a new immutable set of length 0. - */ - function empty(): Set; - - /** - * `Set.from()` creates a new immutable Set containing the values from this - * Sequence or JavaScript Array. - */ - function from(sequence: Sequence): Set; - function from(array: Array): Set; - - /** - * `Set.fromkeySeq()` creates a new immutable Set containing the keys from - * this Sequence or JavaScript Object. - */ - function fromKeys(sequence: Sequence): Set; - function fromKeys(object: {[key: string]: any}): Set; - } - - /** - * Alias for `Set.empty()` - */ - export function Set(): Set; - - /** - * Like `Set.from()`, but accepts variable arguments instead of an Array. - */ - export function Set(...values: T[]): Set; - - - export interface Set extends Sequence { - - /** - * Returns a new Set which also includes this value. - */ - add(value: T): Set; - - /** - * Returns a new Set which excludes this value. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(value: T): Set; - delete(value: T): Set; - - /** - * Returns a new Set containing no values. - */ - clear(): Set; - - /** - * Alias for `union`. - * @see `Map.prototype.merge` - */ - merge(...sequences: Sequence[]): Set; - merge(...sequences: Array[]): Set; - - /** - * Returns a Set including any value from `sequences` that does not already - * exist in this Set. - */ - union(...sequences: Sequence[]): Set; - union(...sequences: Array[]): Set; - - /** - * Returns a Set which has removed any values not also contained - * within `sequences`. - */ - intersect(...sequences: Sequence[]): Set; - intersect(...sequences: Array[]): Set; - - /** - * Returns a Set excluding any values contained within `sequences`. - */ - subtract(...sequences: Sequence[]): Set; - subtract(...sequences: Array[]): Set; - - /** - * True if `sequence` contains every value in this Set. - */ - isSubset(sequence: Sequence): boolean; - isSubset(sequence: Array): boolean; - - /** - * True if this Set contains every value in `sequence`. - */ - isSuperset(sequence: Sequence): boolean; - isSuperset(sequence: Array): boolean; - - /** - * @see `Map.prototype.withMutations` - */ - withMutations(mutator: (mutable: Set) => any): Set; - - /** - * @see `Map.prototype.asMutable` - */ - asMutable(): Set; - - /** - * @see `Map.prototype.asImmutable` - */ - asImmutable(): Set; - } - - - /** - * Vector - * ------ - * - * Vectors are ordered indexed dense collections, much like a JavaScript - * Array. Unlike a JavaScript Array, there is no distinction between an - * "unset" index and an index set to `undefined`. `Vector#forEach` visits all - * indices from 0 to length, regardless of if they are defined. - */ - - export module Vector { - - /** - * `Vector.empty()` returns a Vector of length 0. - */ - function empty(): Vector; - - /** - * `Vector.from()` returns a Vector of the same length of the provided - * `values` JavaScript Array or Sequence, containing the values at the - * same indices. - * - * If a non-indexed Sequence is provided, its keys will be discarded and - * its values will be used to fill the returned Vector. - */ - function from(array: Array): Vector; - function from(sequence: Sequence): Vector; - } - - /** - * Alias for `Vector.empty()` - */ - export function Vector(): Vector; - - /** - * Like `Vector.from()`, but accepts variable arguments instead of an Array. - */ - export function Vector(...values: T[]): Vector; - - - export interface Vector extends IndexedSequence { - - /** - * Returns a new Vector which includes `value` at `index`. If `index` already - * exists in this Vector, it will be replaced. - * - * `index` may be a negative number, which indexes back from the end of the - * Vector. `v.set(-1, "value")` sets the last item in the Vector. - */ - set(index: number, value: T): Vector; - - /** - * Returns a new Vector which excludes this `index`. It will not affect the - * length of the Vector, instead leaving an undefined value. - * - * `index` may be a negative number, which indexes back from the end of the - * Vector. `v.delete(-1)` deletes the last item in the Vector. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(index: number): Vector; - delete(index: number): Vector; - - /** - * Returns a new Vector with 0 length and no values. - */ - clear(): Vector; - - /** - * Returns a new Vector with the provided `values` appended, starting at this - * Vector's `length`. - */ - push(...values: T[]): Vector; - - /** - * Returns a new Vector with a length ones less than this Vector, excluding - * the last index in this Vector. - * - * Note: this differs from `Array.prototype.pop` because it returns a new - * Vector rather than the removed value. Use `last()` to get the last value - * in this Vector. - */ - pop(): Vector; - - /** - * Returns a new Vector with the provided `values` prepended, pushing other - * values ahead to higher indices. - */ - unshift(...values: T[]): Vector; - - /** - * Returns a new Vector with a length ones less than this Vector, excluding - * the first index in this Vector, shifting all other values to a lower index. - * - * Note: this differs from `Array.prototype.shift` because it returns a new - * Vector rather than the removed value. Use `first()` to get the last value - * in this Vector. - */ - shift(): Vector; - - /** - * @see Map.cursor - */ - cursor( - onChange?: (newValue: Vector, oldValue?: Vector, keyPath?: Array) => void - ): Cursor>; - cursor( - keyPath: Array, - onChange?: (newValue: Vector, oldValue?: Vector, keyPath?: Array) => void - ): Cursor; - cursor( - key: number, - onChange?: (newValue: Vector, oldValue?: Vector, keyPath?: Array) => void - ): Cursor; - - - /** - * Returns a new Vector with an updated value at `index` with the return - * value of calling `updater` with the existing value, or `notSetValue` if - * `index` was not set. If called with a single argument, `updater` is - * called with the Vector itself. - * - * `index` may be a negative number, which indexes back from the end of the - * Vector. `v.update(-1)` updates the last item in the Vector. - * - * @see Map.update - */ - update(updater: (value: Vector) => Vector): Vector; - update(index: number, updater: (value: T) => T): Vector; - update(index: number, notSetValue: T, updater: (value: T) => T): Vector; - - /** - * @see `Map.prototype.updateIn` - */ - updateIn( - keyPath: Array, - updater: (value: any) => any - ): Vector; - updateIn( - keyPath: Array, - notSetValue: any, - updater: (value: any) => any - ): Vector; - - /** - * @see `Map.prototype.merge` - */ - merge(...sequences: IndexedSequence[]): Vector; - merge(...sequences: Array[]): Vector; - - /** - * @see `Map.prototype.mergeWith` - */ - mergeWith( - merger: (previous?: T, next?: T) => T, - ...sequences: IndexedSequence[] - ): Vector; - mergeWith( - merger: (previous?: T, next?: T) => T, - ...sequences: Array[] - ): Vector; - - /** - * @see `Map.prototype.mergeDeep` - */ - mergeDeep(...sequences: IndexedSequence[]): Vector; - mergeDeep(...sequences: Array[]): Vector; - - /** - * @see `Map.prototype.mergeDeepWith` - */ - mergeDeepWith( - merger: (previous?: T, next?: T) => T, - ...sequences: IndexedSequence[] - ): Vector; - mergeDeepWith( - merger: (previous?: T, next?: T) => T, - ...sequences: Array[] - ): Vector; - - /** - * Returns a new Vector with length `length`. If `length` is less than this - * Vector's length, the new Vector will exclude values at the higher indices. - * If `length` is greater than this Vector's length, the new Vector will have - * undefined values for the newly available indices. - */ - setLength(length: number): Vector; - - /** - * @see `Map.prototype.withMutations` - */ - withMutations(mutator: (mutable: Vector) => any): Vector; - - /** - * @see `Map.prototype.asMutable` - */ - asMutable(): Vector; - - /** - * @see `Map.prototype.asImmutable` - */ - asImmutable(): Vector; - } - - - /** - * Cursors - * ------- - * - * Cursors allow you to hold a reference to a path in a nested immutable data - * structure, allowing you to pass smaller sections of a larger nested - * collection to portions of your application while maintaining a central point - * aware of changes to the entire data structure. - * - * This is particularly useful when used in conjuction with component-based UI - * libraries like [React](http://facebook.github.io/react/) or to simulate - * "state" throughout an application while maintaining a single flow of logic. - * - * Cursors provide a simple API for getting the value at that path - * (the equivalent of `this.getIn(keyPath)`), updating the value at that path - * (the equivalent of `this.updateIn(keyPath)`), and getting a sub-cursor - * starting from that path. - * - * When updated, a new root collection is created and provided to the `onChange` - * function provided to the first call to `map.cursor(...)`. - * - * @see Map.cursor - */ - - export interface Cursor extends Sequence { - - /** - * Returns a sub-cursor following the key-path starting from this cursor. - */ - cursor(subKeyPath: Array): Cursor; - cursor(subKey: any): Cursor; - - /** - * Returns the value at the cursor, if the cursor path does not yet exist, - * returns `notSetValue`. - */ - deref(notSetValue?: T): T; - - /** - * Returns the value at the `key` in the cursor, or `notSetValue` if it - * does not exist. - * - * If the key would return a collection, a new Cursor is returned. - */ - get(key: any, notSetValue?: any): any; - - /** - * Returns the value at the `keyPath` in the cursor, or `notSetValue` if it - * does not exist. - * - * If the keyPath would return a collection, a new Cursor is returned. - */ - getIn(keyPath: Array, notSetValue?: any): any; - - /** - * Sets `value` at `key` in the cursor, returning a new cursor to the same - * point in the new data. - */ - set(key: any, value: any): Cursor; - - /** - * Deletes `key` from the cursor, returning a new cursor to the same - * point in the new data. - * - * Note: `delete` cannot be safely used in IE8 - * @alias delete - */ - remove(key: any): Cursor; - delete(key: any): Cursor; - - /** - * Clears the value at this cursor, returning a new cursor to the same - * point in the new data. - */ - clear(): Cursor; - - /** - * Updates the value in the data this cursor points to, triggering the - * callback for the root cursor and returning a new cursor pointing to the - * new data. - */ - update(updater: (value: T) => T): Cursor; - update(key: any, updater: (value: any) => any): Cursor; - update(key: any, notSetValue: any, updater: (value: any) => any): Cursor; - - - /** - * Every time you call one of the above functions, a new immutable value is - * created and the callback is triggered. If you need to apply a series of - * mutations to a Cursor without triggering the callback repeatedly, - * `withMutations()` creates a temporary mutable copy of the value which - * can apply mutations in a highly performant manner. Afterwards the - * callback is triggered with the final value. - */ - withMutations(mutator: (mutable: T) => T): Cursor; - } - - // ES6 Iterator - export interface Iterator { - next(): { value: T; done: boolean; } - } - -} diff --git a/type-definitions/flow-tests/.flowconfig b/type-definitions/flow-tests/.flowconfig new file mode 100644 index 0000000000..8bacb74638 --- /dev/null +++ b/type-definitions/flow-tests/.flowconfig @@ -0,0 +1,9 @@ +[include] +../../ + +[options] +module.name_mapper='^immutable$' -> '../../type-definitions/immutable.js.flow' + +[ignore] +Ÿ’İ Only interested in testing these files directly in this repo. +.*/node_modules/.* diff --git a/type-definitions/flow-tests/covariance.js b/type-definitions/flow-tests/covariance.js new file mode 100644 index 0000000000..6f325f4bae --- /dev/null +++ b/type-definitions/flow-tests/covariance.js @@ -0,0 +1,55 @@ +//@flow + +import { List, Map, Set, Stack, OrderedMap, OrderedSet } from 'immutable'; + +class A { + x: number; +} +class B extends A { + y: string; +} +class C { + z: string; +} + +// List covariance +declare var listOfB: List; +var listOfA: List = listOfB; +listOfA = List([new B()]); +// $FlowExpectedError[incompatible-type-arg] +var listOfC: List = listOfB; + +// Map covariance +declare var mapOfB: Map; +var mapOfA: Map = mapOfB; +mapOfA = Map({ b: new B() }); +// $FlowExpectedError[incompatible-type-arg] +var mapOfC: Map = mapOfB; + +// Set covariance +declare var setOfB: Set; +var setOfA: Set = setOfB; +setOfA = Set([new B()]); +// $FlowExpectedError[incompatible-type-arg] +var setOfC: Set = setOfB; + +// Stack covariance +declare var stackOfB: Stack; +var stackOfA: Stack = stackOfB; +stackOfA = Stack([new B()]); +// $FlowExpectedError[incompatible-type-arg] +var stackOfC: Stack = stackOfB; + +// OrderedMap covariance +declare var orderedMapOfB: OrderedMap; +var orderedMapOfA: OrderedMap = orderedMapOfB; +orderedMapOfA = OrderedMap({ b: new B() }); +// $FlowExpectedError[incompatible-type-arg] +var orderedMapOfC: OrderedMap = orderedMapOfB; + +// OrderedSet covariance +declare var orderedSetOfB: OrderedSet; +var orderedSetOfA: OrderedSet = orderedSetOfB; +orderedSetOfA = OrderedSet([new B()]); +// $FlowExpectedError[incompatible-type-arg] +var orderedSetOfC: OrderedSet = orderedSetOfB; diff --git a/type-definitions/flow-tests/es6-collections.js b/type-definitions/flow-tests/es6-collections.js new file mode 100644 index 0000000000..a763d6bf75 --- /dev/null +++ b/type-definitions/flow-tests/es6-collections.js @@ -0,0 +1,15 @@ +// @flow + +import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable'; + +// Immutable.js collections +var mapImmutable: ImmutableMap = ImmutableMap(); +var setImmutable: ImmutableSet = ImmutableSet(); +var deleteResultImmutable: ImmutableMap = mapImmutable.delete( + 'foo' +); + +// ES6 collections +var mapES6: Map = new Map(); +var setES6: Set = new Set(); +var deleteResultES6: boolean = mapES6.delete('foo'); diff --git a/type-definitions/flow-tests/immutable-flow.js b/type-definitions/flow-tests/immutable-flow.js new file mode 100644 index 0000000000..c203962052 --- /dev/null +++ b/type-definitions/flow-tests/immutable-flow.js @@ -0,0 +1,1341 @@ +// @flow +// Some tests look like they are repeated in order to avoid false positives. +// Flow might not complain about an instance of (what it thinks is) T to be assigned to T + +import Immutable, { + List, + Map, + Stack, + Set, + Seq, + Range, + Repeat, + Record, + OrderedMap, + OrderedSet, + get, + getIn, + has, + hasIn, + merge, + mergeDeep, + mergeWith, + mergeDeepWith, + remove, + removeIn, + set, + setIn, + update, + updateIn, +} from 'immutable'; +import * as Immutable2 from 'immutable'; + +import type { + KeyedCollection, + IndexedCollection, + SetCollection, + KeyedSeq, + IndexedSeq, + SetSeq, + RecordFactory, + RecordOf, +} from 'immutable'; + +/** + * Although this looks like dead code, importing `Immutable` and + * `Immutable2` tests: + * + * 1. that default import works -- `import Immutable, {...} from 'immutable' + * 2. that importing everything works -- `import * as X from 'immutable'` + * 3. that individual imports are supported + */ +const ImmutableList = Immutable.List; +const ImmutableMap = Immutable.Map; +const ImmutableStack = Immutable.Stack; +const ImmutableSet = Immutable.Set; +const ImmutableKeyedCollection: KeyedCollection< + *, + * +> = Immutable.Collection.Keyed(); +const ImmutableRange = Immutable.Range; +const ImmutableRepeat = Immutable.Repeat; +const ImmutableIndexedSeq: IndexedSeq<*> = Immutable.Seq.Indexed(); + +const Immutable2List = Immutable2.List; +const Immutable2Map = Immutable2.Map; +const Immutable2Stack = Immutable2.Stack; +const Immutable2Set = Immutable2.Set; +const Immutable2KeyedCollection: Immutable2.KeyedCollection< + *, + * +> = Immutable2.Collection.Keyed(); +const Immutable2Range = Immutable2.Range; +const Immutable2Repeat = Immutable2.Repeat; +const Immutable2IndexedSeq: Immutable2.IndexedSeq<*> = Immutable2.Seq.Indexed(); + +var defaultExport: List<*> = Immutable.List(); +var moduleExport: List<*> = Immutable2.List(); + +var numberList: List = List(); +var numberOrStringList: List = List(); +var nullableNumberList: List = List(); +var stringToNumber: Map = Map(); +var orderedStringToNumber: OrderedMap = OrderedMap(); +var orderedStringToString: OrderedMap = OrderedMap(); +var orderedStringToNumberOrString: OrderedMap< + string, + string | number +> = OrderedMap(); +var orderedNumberToString: OrderedMap = OrderedMap(); +var orderedNumberToNumber: OrderedMap = OrderedMap(); +var stringToNumberOrString: Map = Map(); +var numberToString: Map = Map(); +var stringOrNumberToNumberOrString: Map< + string | number, + string | number +> = Map(); +var anyMap: Map = Map(); +var numberSet: Set = Set(); +var orderedStringSet: OrderedSet = OrderedSet(); +var orderedNumberSet: OrderedSet = OrderedSet(); +var orderedNumberOrStringSet: OrderedSet = OrderedSet(); +var numberOrStringSet: Set = Set(); +var stringSet: Set = Set(); +var numberStack: Stack = Stack(); +var numberOrStringStack: Stack = Stack(); +var number: number = 0; +var stringToNumberCollection: KeyedCollection = stringToNumber; +var numberToStringCollection: KeyedCollection = numberToString; +var partitions: [List, List]; + +numberList = List([1, 2]); +var numberListSize: number = numberList.size; +numberOrStringList = List(['a', 1]); +// $FlowExpectedError[incompatible-call] +numberList = List(['a', 'b']); + +numberList = List.of(1, 2); +numberOrStringList = List.of('a', 1); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a', 1); + +numberList = List().set(0, 0); +numberOrStringList = List.of(0).set(1, 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List().set(0, 'a'); + +numberList = List.of(1, 2, 3); +// $FlowExpectedError[incompatible-type] +var item: number = numberList.get(4); +var nullableItem: ?number = numberList.get(4); +var itemOrDefault: number = numberList.get(4, 10); + +// $FlowExpectedError[incompatible-type] +var item: number = numberList.first(); +// $FlowExpectedError[incompatible-type] +var func: () => number = () => numberList.first(); + +// $FlowExpectedError[incompatible-type] +var item: number = numberList.last(); +// $FlowExpectedError[incompatible-type] +var func: () => number = () => numberList.last(); + +numberList = List().insert(0, 0); +numberOrStringList = List.of(0).insert(1, 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List().insert(0, 'a'); + +numberList = List().push(1, 1); +numberOrStringList = List().push(1, 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List().push(0, 'a'); + +numberList = List().unshift(1, 1); +numberOrStringList = List().unshift(1, 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List().unshift(0, 'a'); + +numberList = List.of(1).delete(0); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a').delete(0); + +numberList = List.of(1).remove(0); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a').remove(0); + +numberList = List.of(1).clear(); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a').clear(); + +numberList = List.of(1).pop(); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a').pop(); + +numberList = List.of(1).shift(); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a').shift(); + +numberList = List.of('a').update((value) => List.of(1)); +// $FlowExpectedError[incompatible-call] +numberList = List.of(1).update((value) => List.of('a')); + +numberOrStringList = List.of('a').update(0, (value) => 1); +// $FlowExpectedError[incompatible-call] +numberList = List.of(1).update(0, (value) => 'a'); + +numberOrStringList = List.of(1).update(1, 0, (value) => 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List.of(1).update(1, 0, (value) => 'a'); + +numberList = List.of(1).merge(List.of(2)); +numberOrStringList = List.of('a').merge(List.of(1)); +// $FlowExpectedError[incompatible-call] +numberList = List.of('a').merge(List.of(1)); + +// Functional API + +numberList = merge(List([1]), List([2])); +numberOrStringList = merge>(List(['a']), List([1])); +// $FlowExpectedError[incompatible-call] +numberList = merge(List(['a']), List([1])); + +nullableNumberList = List.of(1).setSize(2); + +// $FlowExpectedError[incompatible-type] setIn [] replaces the top-most value. number ~> List +numberList = List([1]).setIn([], 0); +{ + const x: number = List([1]).setIn([], 0); +} +// $FlowExpectedError[incompatible-call] "a" is not a valid key for List. +numberList = List([1]).setIn(['a'], 0); +// $FlowExpectedError[incompatible-type-arg] "a" is not a valid value for List of number. +numberList = List([1]).setIn([0], 'a'); +numberList = List([1]).setIn([0], 0); + +// $FlowExpectedError[incompatible-call] "a" is not a valid key for List. +List([List([List([1])])]).setIn([0, 0, 'a'], 'a'); +// $FlowExpectedError[incompatible-call] "a" is not a valid value for List of number. +List([List([List([1])])]).setIn([0, 0, 0], 'a'); +List([List([List([1])])]).setIn([0, 0, 0], 123); + +// $FlowExpectedError[incompatible-type] deleteIn [] replaces the top-most value. void ~> List +numberList = List([1]).deleteIn([]); +{ + const x: void = List([1]).deleteIn([]); +} +// $FlowExpectedError[incompatible-type] +numberList = List([1]).removeIn([]); +// $FlowExpectedError[incompatible-call] "a" is not a valid key for List. +numberList = List([1]).deleteIn(['a']); +// $FlowExpectedError[incompatible-call] +numberList = List([1]).removeIn(['a']); +numberList = List([1]).deleteIn([0]); +numberList = List([1]).removeIn([0]); + +// Functional API + +// $FlowExpectedError[incompatible-type] deleteIn [] replaces the top-most value. void ~> List +numberList = removeIn(List([1]), []); +{ + const x: void = removeIn(List([1]), []); +} +// $FlowExpectedError[incompatible-call] "a" is not a valid key for List. +numberList = removeIn(List([1]), ['a']); +numberList = removeIn(List([1]), [0]); + +// $FlowExpectedError[incompatible-type] updateIn [] replaces the top-most value. number ~> List +numberList = List([1]).updateIn([], () => 123); +{ + const x: number = List([1]).updateIn([], () => 123); +} +// $FlowExpectedError[incompatible-call] - 'a' is not a number +numberList = List([1]).updateIn([0], (val) => 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List([1]).updateIn([0], 0, (val) => 'a'); +// $FlowExpectedError[incompatible-call] - 'a' in an invalid argument +numberList = List([1]).updateIn([0], 'a'); +// $FlowExpectedError[incompatible-call] +numberList = List([1]).updateIn([0], 0, 'a'); +numberList = List([1]).updateIn([0], (val) => val + 1); +numberList = List([1]).updateIn([0], 0, (val) => val + 1); + +numberList = List.of(1).mergeIn([], []); +numberList = List.of(1).mergeDeepIn([], []); + +numberList = List.of(1).withMutations((mutable) => mutable); + +numberList = List.of(1).asMutable(); +numberList = List.of(1).asImmutable(); + +numberList = List.of(1).map((value, index, iter) => 1); +// $FlowExpectedError[incompatible-call] +numberList = List.of(1).map((value, index, iter) => 'a'); + +numberList = List.of(1).flatMap((value, index, iter) => [1]); +// $FlowExpectedError[incompatible-call] +numberList = List.of(1).flatMap((value, index, iter) => ['a']); + +numberList = List.of(1).flatten(); + +// Specific type for filter(Boolean) which removes nullability. +numberList = nullableNumberList.filter(Boolean); + +partitions = List([1,2,3]).partition(value => value % 2); + +/* Map */ + +stringToNumber = Map(); +let stringToNumberSize: number = stringToNumber.size; +stringToNumberOrString = Map(); +numberToString = Map(); + +stringToNumber = Map({ a: 1 }); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 'a' }); + +stringToNumber = Map([['a', 1]]); +stringToNumber = Map(List([['a', 1]])); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map([['a', 'b']]); +// $FlowExpectedError[incompatible-call] -- this is actually a Map +stringToNumber = Map(List([['a', 'a']])); +// $FlowFixMe[incompatible-call] - This is Iterable>, ideally it could be interpreted as Iterable<[string, string]> +stringToNumber = Map(List([List(['a', 'a'])])); + +stringOrNumberToNumberOrString = Map({ a: 'a' }).set('b', 1).set(2, 'c'); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 0 }).set('b', ''); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map().set(1, ''); + +// Functional API + +stringToNumber = set(set(Map({ a: 0 }), 'b', 1), 'c', 2); +// $FlowExpectedError[incompatible-call] - Functional API currently requires arguments to have the same value types. +stringOrNumberToNumberOrString = set(set(Map({ a: 'a' }), 'b', 1), 2, 'c'); +// $FlowExpectedError[incompatible-call] +stringToNumber = set(Map({ a: 0 }), 'b', ''); +// $FlowExpectedError[incompatible-call] +stringToNumber = set(Map(), 1, ''); + +stringToNumber = Map({ a: 0 }).delete('a'); +stringToNumber = Map({ a: 0 }).remove('a'); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 0 }).delete(1); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 0 }).remove(1); + +stringToNumber = Map({ a: 0 }).deleteAll(['a']); +stringToNumber = Map({ a: 0 }).removeAll(['a']); +// $FlowExpectedError[prop-missing] +stringToNumber = Map({ a: 0 }).deleteAll(1); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 0 }).deleteAll([1]); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 0 }).removeAll([1]); + +stringToNumber = Map({ a: 0 }).clear(); + +stringToNumber = Map({ a: 1 }).update((value) => Map({ a: 1 })); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).update((value) => Map({ '1': 'a' })); + +stringToNumberOrString = Map({ a: 1 }).update('a', (value) => 'a'); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).update('a', (value) => 'a'); + +stringToNumberOrString = Map({ a: 1 }).update('a', 'b', (value) => 'a'); +// $FlowExpectedError[incompatible-type-arg] +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).update('a', 'b', (value) => 'a'); +// $FlowExpectedError[incompatible-type-arg] +stringToNumberOrString = Map({ a: 1 }).merge({ a: { a: '1' } }); +// $FlowExpectedError[incompatible-type-arg] +stringToNumberOrString = Map({ a: 1 }).update('a', 'b', (value) => { + a: '1'; +}); + +stringToNumber = Map({ a: 1 }).merge(Map({ a: 1 })); +stringToNumberOrString = Map({ a: 1 }).merge({ a: 'b' }); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).merge({ a: 'b' }); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).merge([[1, 'a']]); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).merge(numberToString); + +// Functional API +stringToNumber = merge(Map({ a: 1 }), Map({ a: 1 })); +// $FlowExpectedError[incompatible-call] - Functional API currently requires arguments to have the same value types. +stringToNumberOrString = merge(Map({ a: 1 }), { a: 'b' }); +// $FlowExpectedError[incompatible-call] +stringToNumber = merge(Map({ a: 1 }), { a: 'b' }); +// $FlowExpectedError[incompatible-call] +stringToNumber = merge(Map({ a: 1 }), [[1, 'a']]); +// $FlowExpectedError[incompatible-call] +stringToNumber = merge(Map({ a: 1 }), numberToString); + +stringToNumber = Map({ a: 1 }).mergeWith((previous, next, key) => 1, { + a: 2, + b: 2, +}); +stringToNumber = Map({ a: 1 }).mergeWith( + // $FlowExpectedError[incompatible-call] + (previous, next, key) => previous + next, + // $FlowExpectedError[incompatible-type-arg] + { a: '2', b: '2' } +); +stringToNumberOrString = Map({ a: 1 }).mergeWith( + (previous, next, key) => previous + next, + { a: '2', b: '2' } +); +// $FlowExpectedError[incompatible-call] - the array [1] is not a valid argument +stringToNumber = Map({ a: 1 }).mergeWith((previous, next, key) => 1, [1]); + +stringToNumberOrString = Map({ a: 1 }).mergeDeep({ a: 'b' }); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).mergeDeep({ a: 'b' }); + +stringToNumber = Map({ a: 1 }).mergeDeepWith((previous, next, key) => 1, { + a: 2, + b: 2, +}); +stringToNumber = Map({ a: 1 }).mergeDeepWith( + (previous, next, key) => 1, + // $FlowExpectedError[incompatible-type-arg] + { a: '2', b: '2' } +); +stringToNumberOrString = Map({ a: 1 }).mergeDeepWith( + (previous, next, key) => 1, + { a: '2', b: '2' } +); +// $FlowExpectedError[incompatible-call] - the array [1] is not a valid argument +stringToNumber = Map({ a: 1 }).mergeDeepWith((previous, next, key) => 1, [1]); + +// KeyedSeq can merge into Map +var stringToStringSeq: KeyedSeq = Seq({ b: 'B' }); +stringToNumberOrString = Map({ a: 1 }).merge(stringToStringSeq); + +// $FlowExpectedError[incompatible-type] +stringToNumber = Map({ a: 1 }).setIn([], 0); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).setIn(['a'], 'a'); +stringToNumber = Map({ a: 1 }).setIn(['a'], 0); + +// $FlowExpectedError[incompatible-type] +stringToNumber = Map({ a: 1 }).deleteIn([]); +// $FlowExpectedError[incompatible-type] +stringToNumber = Map({ a: 1 }).removeIn([]); +stringToNumber = Map({ a: 1 }).deleteIn(['a']); +stringToNumber = Map({ a: 1 }).removeIn(['a']); + +// $FlowExpectedError[incompatible-type] +Map({ a: 1 }).updateIn([], (v) => v + 1); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).updateIn(['a'], (v) => 'a'); +stringToNumber = Map({ a: 1 }).updateIn(['a'], (v) => v + 1); +stringToNumber = Map({ a: 1 }).updateIn(['a'], 0, (v) => v + 1); + +Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn(['x', 'y', 'z'], (v) => v + 1); +Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn( + ['x', 'y', 'z'], + 0, + (v) => v + 1 +); + +// $FlowExpectedError[incompatible-call] +Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn(['x', 'y', 1], (v) => v + 1); +// $FlowExpectedError[incompatible-call] +Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn(['x', 'y', 'z'], (v) => 'a'); + +stringToNumber = Map({ a: 1 }).mergeIn([], []); +stringToNumber = Map({ a: 1 }).mergeDeepIn([], []); + +anyMap = Map({ a: {} }).mergeIn(['a'], Map({ b: 2 })); +anyMap = Map({ a: {} }).mergeDeepIn(['a'], Map({ b: 2 })); +anyMap = Map({ a: {} }).mergeIn(['a'], List([1, 2])); +anyMap = Map({ a: {} }).mergeDeepIn(['a'], List([1, 2])); +anyMap = Map({ a: {} }).mergeIn(['a'], { b: 2 }); +anyMap = Map({ a: {} }).mergeDeepIn(['a'], { b: 2 }); +// $FlowExpectedError[incompatible-call]: not iterable / object +anyMap = Map({ a: {} }).mergeIn(['a'], 1); +// $FlowExpectedError[incompatible-call]: not iterable / object +anyMap = Map({ a: {} }).mergeDeepIn(['a'], 1); +// $FlowExpectedError[incompatible-type-arg]: bad key type +stringToNumber = Map({ a: {} }).mergeIn([1], { b: 2 }); +// $FlowExpectedError[incompatible-type-arg]: bad key type +stringToNumber = Map({ a: {} }).mergeDeepIn([1], { b: 2 }); + +stringToNumber = Map({ a: 1 }).withMutations((mutable) => mutable); + +stringToNumber = Map({ a: 1 }).asMutable(); +stringToNumber = Map({ a: 1 }).asImmutable(); + +stringToNumber = Map({ a: 1 }).map((value, index, iter) => 1); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).map((value, index, iter) => 'a'); + +stringToNumber = Map({ a: 1 }).flatMap((value, index, iter) => [['b', 1]]); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).flatMap((value, index, iter) => [['a', 'a']]); +// $FlowExpectedError[incompatible-call] +stringToNumber = Map({ a: 1 }).flatMap((value, index, iter) => Map({ a: 'a' })); + +numberToString = Map({ a: 1 }).flip(); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).flip(); + +numberToString = Map({ a: 'a' }).mapKeys((key, value, iter) => 1); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = Map({ a: 1 }).mapKeys((key, value, iter) => 1); + +anyMap = Map({ a: 1 }).flatten(); + +var stringToNullableNumber = Map({ a: 1, b: null }); +// $FlowExpectedError[incompatible-type-arg] +stringToNumber = stringToNullableNumber; +// Specific type for filter(Boolean) which removes nullability. +stringToNumber = stringToNullableNumber.filter(Boolean); + +[anyMap, ] = Map({ "a": 1, "b": 2}).partition((key, index, iter) => key % 2) + +/* OrderedMap */ + +orderedStringToNumber = Map({ a: 1 }).toOrderedMap(); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap +orderedStringToNumber = Map({ a: 'b' }).toOrderedMap(); +orderedStringToString = Map({ a: 'b' }).toOrderedMap(); + +orderedStringToNumber = OrderedMap({ a: 1 }); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: '1' }); +orderedStringToString = OrderedMap({ a: '1' }); + +orderedStringToNumber = OrderedMap(Map({ a: 1 })); +// $FlowExpectedError[incompatible-type-arg] - it's actually an OrderedMap +orderedStringToNumber = OrderedMap(Map({ a: '1' })); + +orderedStringToNumber = OrderedMap(); + +orderedStringToNumber = OrderedMap().set('b', 2); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap().set('b', '2'); +orderedStringToString = OrderedMap().set('b', '2'); + +orderedStringToNumber = OrderedMap({ a: 1 }).delete('a'); +orderedStringToNumber = OrderedMap({ a: 1 }).remove('a'); +orderedStringToNumber = OrderedMap({ a: 1 }).clear(); + +orderedStringToNumber = OrderedMap({ a: 1 }).update(() => OrderedMap({ b: 1 })); +/** + * TODO: the following is valid but I question if it should be valid: + * + * ``` + * const x: OrderedMap = OrderedMap({'a': 1}) + * .update(() => OrderedMap({'b': '1'})) + * ``` + * + * In the above example, `update` is changing an OrderedMap to an OrderedMap + * This seems inconsistent with the typescript signature of + * + * ``` + * update(updater: (value: Map) => Map): Map + * ``` + */ +orderedStringToNumber = OrderedMap({ a: 1 }).update(() => + // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap + OrderedMap({ b: '1' }) +); +orderedStringToString = OrderedMap({ a: 1 }).update(() => + OrderedMap({ b: '1' }) +); + +orderedStringToNumber = OrderedMap({ a: 1 }).update('a', (value) => value + 1); +/** + * TODO: is the below the intended functionality? The typescript signature looks like + * + * ``` + * update(key: K, updater: (value: V) => V): Map; + * ``` + * + * so it seems like in this case the updater should only be able to return numbers. + * This comment applies to all of the update / merge functions in Map and OrderedMap + */ +// $FlowExpectedError[incompatible-call] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).update('a', () => 'b'); +orderedStringToNumberOrString = OrderedMap({ a: 1 }).update('a', () => 'b'); + +orderedStringToNumber = OrderedMap({ a: 1 }).update( + 'a', + 0, + (value) => value + 1 +); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).update('a', 0, () => 'b'); +orderedStringToNumberOrString = OrderedMap({ a: 1 }).update('a', 0, () => 'b'); + +orderedStringToNumber = OrderedMap({ a: 1 }).merge({ b: 2 }); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).merge({ b: '2' }); +orderedStringToNumberOrString = OrderedMap({ a: 1 }).merge({ b: '2' }); + +orderedStringToNumber = OrderedMap({ a: 1 }).mergeWith( + (prev, next) => next, + { a: 2, b: 3 } +); +orderedStringToNumber = OrderedMap({ a: 1 }).mergeWith( + // $FlowExpectedError[incompatible-call] + (prev, next) => next, + // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap + { a: '2', b: '3' } +); +orderedStringToNumberOrString = OrderedMap({ a: 1 }).mergeWith( + (prev, next) => next, + { a: '2', b: '3' } +); +// $FlowExpectedError[incompatible-call] - the array [1] is not a valid argument +orderedStringToNumber = OrderedMap({ a: 1 }).mergeWith((prev, next) => next, [ + 1, +]); + +orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeep({ a: 2 }); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeep({ a: '2' }); +orderedStringToNumberOrString = OrderedMap({ a: 1 }).mergeDeep({ a: '2' }); + +orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepWith( + (prev, next) => next, + { a: 2, b: 3 } +); +orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepWith( + (prev, next) => next, + // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap + { a: '2', b: '3' } +); +orderedStringToNumberOrString = OrderedMap({ a: 1 }).mergeDeepWith( + (prev, next) => next, + { a: '2', b: '3' } +); +orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepWith( + (prev, next) => next, + // $FlowExpectedError[incompatible-call] - the array [1] is an invalid argument + [1] +); + +// $FlowExpectedError[incompatible-type] +orderedStringToNumber = OrderedMap({ a: 1 }).setIn([], 3); +// $FlowExpectedError[incompatible-type-arg] +orderedStringToNumber = OrderedMap({ a: 1 }).setIn([1], 3); +orderedStringToNumber = OrderedMap({ a: 1 }).setIn(['a'], 3); +// $FlowExpectedError[incompatible-type] +orderedStringToNumber = OrderedMap({ a: 1 }).deleteIn([]); +// $FlowExpectedError[incompatible-type] +orderedStringToNumber = OrderedMap({ a: 1 }).removeIn([]); +// $FlowExpectedError[incompatible-type-arg] +orderedStringToNumber = OrderedMap({ a: 1 }).deleteIn([1]); +// $FlowExpectedError[incompatible-type-arg] +orderedStringToNumber = OrderedMap({ a: 1 }).removeIn([1]); +orderedStringToNumber = OrderedMap({ a: 1 }).deleteIn(['b']); +orderedStringToNumber = OrderedMap({ a: 1 }).removeIn(['b']); + +// $FlowExpectedError[incompatible-type] +orderedStringToNumber = OrderedMap({ a: 1 }).updateIn([], (v) => v + 1); +// $FlowExpectedError[incompatible-type-arg] +orderedStringToNumber = OrderedMap({ a: 1 }).updateIn([1], (v) => v + 1); +// $FlowExpectedError[incompatible-call] +orderedStringToNumber = OrderedMap({ a: 1 }).updateIn(['a'], (v) => 'a'); +orderedStringToNumber = OrderedMap({ a: 1 }).updateIn(['a'], (v) => v + 1); +orderedStringToNumber = OrderedMap({ a: 1 }).updateIn(['a'], 0, (v) => v + 1); + +// $FlowExpectedError[incompatible-call] +OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 1], (v) => v + 1); +// $FlowExpectedError[incompatible-call] +OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 'y'], (v) => 'a'); +OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 'y'], (v) => v + 1); +OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 'y'], 0, (v) => v + 1); + +orderedStringToNumber = OrderedMap({ a: 1 }).mergeIn([], { b: 2 }); +orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepIn([], { b: 2 }); +orderedStringToNumber = OrderedMap({ a: 1 }).withMutations((mutable) => + mutable.set('b', 2) +); +orderedStringToNumber = OrderedMap({ a: 1 }).asMutable(); +orderedStringToNumber = OrderedMap({ a: 1 }).asImmutable(); + +orderedStringToNumber = OrderedMap({ a: 1 }).map((v) => v + 1); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).map(() => 'a'); +orderedStringToString = OrderedMap({ a: 1 }).map(() => 'a'); + +orderedStringToNumber = OrderedMap({ a: 1 }).flatMap((v, k) => + OrderedMap({ [k]: v + 1 }) +); +orderedStringToNumber = OrderedMap({ a: 1 }).flatMap((v, k) => + // $FlowExpectedError[incompatible-call] - string "a" is not a number + OrderedMap({ [k]: 'a' }) +); + +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).flip(); +orderedNumberToString = OrderedMap({ a: 1 }).flip(); + +orderedStringToNumber = OrderedMap({ a: 1 }).mapKeys((x) => x); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap +orderedStringToNumber = OrderedMap({ a: 1 }).mapKeys((x) => 1); +orderedNumberToNumber = OrderedMap({ a: 1 }).mapKeys((x) => 1); + +orderedStringToNumber = OrderedMap({ a: 1 }).flatten(); +orderedStringToNumber = OrderedMap({ a: 1 }).flatten(1); +orderedStringToNumber = OrderedMap({ a: 1 }).flatten(true); +// $FlowExpectedError[incompatible-call] - 'a' is an invalid argument +orderedStringToNumber = OrderedMap({ a: 1 }).flatten('a'); + +/* Set */ + +numberSet = Set(); +numberOrStringSet = Set(); +stringSet = Set(); + +numberSet = Set([1, 2, 3]); +// $FlowExpectedError[incompatible-call] +numberSet = Set(['a', 'b']); + +numberSet = Set.of(1, 2); +// $FlowExpectedError[incompatible-call] +numberSet = Set.of('a', 'b'); + +numberSet = Set.fromKeys(Map().set(1, '')); +stringSet = Set.fromKeys({ a: '' }); +// $FlowExpectedError[incompatible-type-arg] +numberSet = Set.fromKeys(Map({ a: 1 })); +// $FlowExpectedError[incompatible-type-arg] +numberSet = Set.fromKeys({ a: 1 }); + +numberOrStringSet = Set([1]).add('a'); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).add('s'); + +numberSet = Set([1]).delete(1); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).delete('a'); +// $FlowExpectedError[incompatible-call] +numberSet = Set(['a']).delete('a'); + +numberSet = Set([1]).remove(1); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).remove('a'); +// $FlowExpectedError[incompatible-call] +numberSet = Set(['a']).remove('a'); + +numberSet = Set([1]).clear(); +// $FlowExpectedError[incompatible-call] +numberSet = Set(['a']).clear(); + +numberOrStringSet = Set(['a']).union([1]); +numberOrStringSet = Set(['a']).union(Set([1])); +numberSet = Set([1]).union([1]); +numberSet = Set([1]).union(Set([1])); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).union(['a']); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).union(Set(['a'])); + +numberOrStringSet = Set(['a']).merge([1]); +numberOrStringSet = Set(['a']).merge(Set([1])); +numberSet = Set([1]).merge([1]); +numberSet = Set([1]).merge(Set([1])); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).merge(['a']); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).merge(Set(['a'])); + +numberSet = Set([1]).intersect(Set([1])); +numberSet = Set([1]).intersect([1]); +numberSet = Set([1]).intersect(Set(['a'])); +numberSet = Set([1]).intersect(['a']); + +numberSet = Set([1]).subtract(Set([1])); +numberSet = Set([1]).subtract([1]); +numberSet = Set([1]).subtract(Set(['a'])); +numberSet = Set([1]).subtract(['a']); + +numberSet = Set([1]).withMutations((mutable) => mutable); +// $FlowExpectedError[incompatible-call] +stringSet = Set([1]).withMutations((mutable) => mutable); + +numberSet = Set([1]).asMutable(); +// $FlowExpectedError[incompatible-call] +stringSet = Set([1]).asMutable(); + +numberSet = Set([1]).asImmutable(); +// $FlowExpectedError[incompatible-call] +stringSet = Set([1]).asImmutable(); + +stringSet = Set([1]).map((value, index, iter) => 'a'); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).map((value, index, iter) => 'a'); + +stringSet = Set([1]).flatMap((value, index, iter) => ['a']); +// $FlowExpectedError[incompatible-call] +numberSet = Set([1]).flatMap((value, index, iter) => ['a']); + +numberSet = Set([1]).flatten(); + +/* OrderedSet */ + +orderedStringSet = Set(['a']).toOrderedSet(); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = Set([1]).toOrderedSet(); +orderedNumberSet = Set([1]).toOrderedSet(); + +orderedStringSet = OrderedSet(['a']); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = OrderedSet([1]); +orderedNumberSet = OrderedSet([1]); + +orderedStringSet = OrderedSet(List.of('a')); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = OrderedSet(List.of(1)); +orderedNumberSet = OrderedSet(List.of(1)); + +orderedStringSet = OrderedSet.of('a', 'b', 'c'); +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = OrderedSet.of(1); +orderedNumberSet = OrderedSet.of(1); + +orderedStringSet = OrderedSet.fromKeys(Map({ a: 1 })); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedSet +orderedNumberSet = OrderedSet.fromKeys(Map({ a: 1 })); + +orderedStringSet = OrderedSet.fromKeys({ a: 1 }); +// $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedSet +orderedNumberSet = OrderedSet.fromKeys({ a: 1 }); + +orderedStringSet = OrderedSet(); + +orderedStringSet = OrderedSet.of('a').add('b'); +/** + * TODO: in typescript definitions, add looks like + * + * ``` + * add(value: T): Set + * ``` + * + * so we shouldn't be able to add a number to a set of strings + */ +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = OrderedSet('a').add(1); +orderedNumberOrStringSet = OrderedSet('a').add(1); + +orderedStringSet = OrderedSet.of('a').delete('a'); +// $FlowExpectedError[incompatible-call] - 1 is an invalid arg +orderedStringSet = OrderedSet.of('a').delete(1); + +orderedStringSet = OrderedSet.of('a').remove('a'); +// $FlowExpectedError[incompatible-call] - 1 is an invalid arg +orderedStringSet = OrderedSet.of('a').remove(1); + +orderedStringSet = OrderedSet.of('a').clear(); + +orderedStringSet = OrderedSet.of('a').union(OrderedSet.of('b')); +/** + * TODO: typescript def looks like + * + * ``` + * union(...iterables: Array[]): Set + * ``` + * + * so we shouldn't be able to merge strings and numbers + */ +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = OrderedSet.of('a').union(OrderedSet.of(1)); +orderedNumberOrStringSet = OrderedSet.of('a').union(OrderedSet.of(1)); + +orderedStringSet = OrderedSet.of('a').merge(OrderedSet.of('b')); +/** + * TODO: typescript def looks like + * + * ``` + * merge(...iterables: Array[]): Set + * ``` + * + * so we shouldn't be able to merge strings and numbers + */ +// $FlowExpectedError[incompatible-call] - this is actually an OrderedSet +orderedStringSet = OrderedSet.of('a').merge(OrderedSet.of(1)); +orderedNumberOrStringSet = OrderedSet.of('a').merge(OrderedSet.of(1)); + +orderedStringSet = OrderedSet.of('a', 'b').intersect(OrderedSet.of('a')); +/** + * TODO: typescript def looks like + * + * ``` + * intersect(...iterables: Array[]): Set + * ``` + * + * so we shouldn't be able to intersect strings and numbers + */ +orderedStringSet = OrderedSet.of('a', 'b').intersect(OrderedSet.of(1)); + +orderedStringSet = OrderedSet.of('a', 'b').subtract(OrderedSet.of('a')); +/** + * TODO: typescript def looks like + * + * ``` + * subtract(...iterables: Array[]): Set + * ``` + * + * so we shouldn't be able to intersect strings and numbers + */ +orderedStringSet = OrderedSet.of('a', 'b').subtract(OrderedSet.of(1)); + +orderedStringSet = OrderedSet().withMutations((mutable) => mutable.add('a')); +orderedStringSet = OrderedSet.of('a').asMutable(); +orderedStringSet = OrderedSet.of('a').asImmutable(); + +orderedStringSet = OrderedSet.of('a', 'b').map((m) => m); +// $FlowExpectedError[incompatible-call] - this is an OrderedSet +orderedStringSet = OrderedSet.of('a', 'b').map(() => 1); +orderedNumberSet = OrderedSet.of('a', 'b').map(() => 1); + +orderedStringSet = OrderedSet.of('a', 'b').flatMap((m) => [m]); +// $FlowExpectedError[incompatible-call] - this is an OrderedSet +orderedStringSet = OrderedSet.of('a', 'b').flatMap((m) => [1]); +orderedNumberSet = OrderedSet.of('a', 'b').flatMap((m) => [1]); + +orderedStringSet = OrderedSet.of('a', 'b').flatten(1); +orderedStringSet = OrderedSet.of('a', 'b').flatten(false); +// $FlowExpectedError[incompatible-call] - invalid arg for flatten +orderedStringSet = OrderedSet.of('a', 'b').flatten('a'); + +/* Stack */ + +numberStack = Stack([1, 2]); +let numberStackSize: number = numberStack.size; +numberOrStringStack = Stack(['a', 1]); +// $FlowExpectedError[incompatible-call] +numberStack = Stack(['a', 'b']); + +numberStack = Stack.of(1, 2); +numberOrStringStack = Stack.of('a', 1); +// $FlowExpectedError[incompatible-call] +numberStack = Stack.of('a', 1); + +number = Stack([1]).peek(); +// $FlowExpectedError[incompatible-type] +number = Stack(['a']).peek(); + +numberStack = Stack([1]).unshift(1); +numberOrStringStack = Stack([1]).unshift('a'); +// $FlowExpectedError[incompatible-call] +numberStack = Stack([1]).unshift('a'); + +numberStack = Stack([1]).unshiftAll([1]); +numberOrStringStack = Stack([1]).unshiftAll(['a']); +// $FlowExpectedError[incompatible-call] +numberStack = Stack([1]).unshiftAll(['a']); + +numberStack = Stack.of(1).shift(); +// $FlowExpectedError[incompatible-call] +numberStack = Stack.of('a').shift(); + +numberStack = Stack().push(1); +numberOrStringStack = Stack([1]).push('a'); +// $FlowExpectedError[incompatible-call] +numberStack = Stack().push('a'); + +numberStack = Stack().pushAll([1]); +numberOrStringStack = Stack([1]).pushAll(['a']); +// $FlowExpectedError[incompatible-call] +numberStack = Stack().push(['a']); + +numberStack = Stack.of(1).pop(); +// $FlowExpectedError[incompatible-call] +numberStack = Stack.of('a').pop(); + +numberStack = Stack([1]).withMutations((mutable) => mutable); +// $FlowExpectedError[incompatible-call] +numberStack = Stack(['a']).withMutations((mutable) => mutable); + +numberStack = Stack([1]).asMutable(); +// $FlowExpectedError[incompatible-call] +numberStack = Stack(['a']).asMutable(); + +numberStack = Stack([1]).asImmutable(); +// $FlowExpectedError[incompatible-call] +numberStack = Stack(['a']).asImmutable(); + +numberStack = Stack([1]).map((value, index, iter) => 1); +// $FlowExpectedError[incompatible-call] +numberStack = Stack([1]).map((value, index, iter) => 'a'); + +numberStack = Stack([1]).flatMap((value, index, iter) => [1]); +// $FlowExpectedError[incompatible-call] +numberStack = Stack([1]).flatMap((value, index, iter) => ['a']); + +numberStack = Stack([1]).flatten(); +numberStack = Stack(['a']).flatten(); + +/* Range & Repeat */ + +// `{}` provide namespaces +{ + const numberSequence: IndexedSeq = Range(0, 0, 0); +} +{ + const numberSequence: IndexedSeq = Repeat(1, 5); +} + +{ + const stringSequence: IndexedSeq = Repeat('a', 5); +} +{ + // $FlowExpectedError[incompatible-call] + const stringSequence: IndexedSeq = Repeat(0, 1); +} +{ + // $FlowExpectedError[incompatible-type-arg] + const stringSequence: IndexedSeq = Range(0, 0, 0); +} + +/* Seq */ + +let numberSeq = Seq([1, 2, 3]); +// $FlowExpectedError[incompatible-type] +let numberSeqSize: number = numberSeq.size; +let maybeNumberSeqSize: ?number = numberSeq.size; + +/* Record */ + +type PersonRecordFields = { age: number, name: string }; +type PersonRecord = RecordOf; +const makePersonRecord: RecordFactory = Record({ + age: 900, + name: 'Yoda', +}); + +const personRecordInstance: PersonRecord = makePersonRecord({ age: 25 }); + +{ + // $FlowExpectedError[incompatible-type] + const age: string = personRecordInstance.get('age'); +} +{ + // $FlowExpectedError[incompatible-type] + const age: string = personRecordInstance.age; +} +{ + const age: number = personRecordInstance.get('age'); +} +{ + const age: number = personRecordInstance.age; +} + +// $FlowExpectedError[incompatible-call] +personRecordInstance.set('invalid', 25); +personRecordInstance.set('name', '25'); +personRecordInstance.set('age', 33); + +// FixMe: The first should be FlowExpectedError[incompatible-call], and the second two should be correct, +// however all three produce a hard to understand error because there is a bug +// with Flow's $Call utility type. +// set(personRecordInstance, 'invalid', 25) +// set(personRecordInstance, 'name', '25') +// set(personRecordInstance, 'age', 33) + +// Create a Map from a non-prototype "plain" Object +let someObj = Object.create(null); +someObj.x = 1; +someObj.y = 2; +let mapOfSomeObj: Map = Map(someObj); +// $FlowExpectedError[incompatible-call] - someObj is string -> number +let mapOfSomeObjMistake: Map = Map(someObj); + +// getIn() type + +// Deep nested +const deepData1: List> = List([Map([['apple', 'sauce']])]); +const deepNestedString1 = deepData1.getIn([0, 'apple']); +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = deepNestedString1; +} +{ + // $FlowExpectedError[incompatible-type] getIn can return undefined + const fail: string = deepNestedString1; +} +{ + const success: ?string = deepNestedString1; +} + +const listOfListOfNumber: List> = List([List([1, 2, 3])]); +const nestedNum = listOfListOfNumber.getIn([0, 1]); +{ + // $FlowExpectedError[incompatible-type] number is not string + const fail: ?string = nestedNum; +} +{ + // $FlowExpectedError[incompatible-type] getIn can return undefined + const fail: number = nestedNum; +} +{ + const success: ?number = nestedNum; +} +// $FlowExpectedError[incompatible-call] expected a number 1st key +listOfListOfNumber.getIn(['whoops', 1]); +// $FlowExpectedError[incompatible-call] expected a number 2nd key +listOfListOfNumber.getIn([0, 'whoops']); +// $FlowExpectedError[incompatible-call] too many keys! +listOfListOfNumber.getIn([0, 0, 'whoops']); + +// Deep nested +const deepData: List>> = List([ + Map([['apple', List(['sauce'])]]), +]); +const deepNestedString = deepData.getIn([0, 'apple', 0]); +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = deepNestedString; +} +{ + // $FlowExpectedError[incompatible-type] getIn can return undefined + const fail: string = deepNestedString; +} +{ + const success: ?string = deepNestedString; +} +// $FlowExpectedError[incompatible-call] expected a string 2nd key +deepData.getIn([0, 0, 0]); +// $FlowExpectedError[incompatible-call] expected a number 3rd key +deepData.getIn([0, 'apple', 'whoops']); + +// Containing Records +const listOfPersonRecord: List = List([personRecordInstance]); +const firstAge = listOfPersonRecord.getIn([0, 'age']); +{ + // $FlowExpectedError[incompatible-type] expected a string key + const age: string = firstAge; +} +{ + // $FlowExpectedError[incompatible-type] getIn can return undefined + const age: number = firstAge; +} +{ + const age: ?number = firstAge; +} +// $FlowExpectedError[incompatible-call] - the first key is not an index +listOfPersonRecord.getIn(['wrong', 'age']); +// $FlowExpectedError[incompatible-call] - the second key is not an record key +listOfPersonRecord.getIn([0, 'mispeld']); +// $FlowExpectedError[incompatible-call] - the second key is not an record key +listOfPersonRecord.getIn([0, 0]); +// $FlowExpectedError[incompatible-call] +listOfPersonRecord.setIn([0, 'age'], 'Thirteen'); +listOfPersonRecord.setIn([0, 'age'], 13); +// $FlowExpectedError[prop-missing] +listOfPersonRecord.updateIn([0, 'age'], (value) => value.unknownFunction()); +listOfPersonRecord.updateIn([0, 'age'], (value) => value + 1); +listOfPersonRecord.updateIn([0, 'age'], 0, (value) => value + 1); + +// Recursive Records +type PersonRecord2Fields = { name: string, friends: List }; +type PersonRecord2 = RecordOf; +const makePersonRecord2: RecordFactory = Record({ + name: 'Adam', + friends: List(), +}); +const friendly: PersonRecord2 = makePersonRecord2(); +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = friendly.getIn(['friends', 0, 'name']); +} +// notSetValue provided +{ + const success: string = friendly.getIn(['friends', 0, 'name'], 'Abbie'); +} +{ + const success: ?string = friendly.getIn(['friends', 0, 'name']); +} + +// Functional API + +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = getIn(friendly, ['friends', 0, 'name']); +} +// notSetValue provided +{ + const success: string = getIn(friendly, ['friends', 0, 'name'], 'Abbie'); +} +{ + const success: ?string = getIn(friendly, ['friends', 0, 'name']); +} + +// Deep nested containing recursive Records +const friendlies: List = List([makePersonRecord2()]); +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = friendlies.getIn([0, 'friends', 0, 'name']); +} +// notSetValue provided +{ + const success: string = friendlies.getIn([0, 'friends', 0, 'name'], 'Abbie'); +} +{ + const success: ?string = friendlies.getIn([0, 'friends', 0, 'name']); +} +// $FlowExpectedError[incompatible-call] +friendlies.setIn([0, 'friends', 0, 'name'], 123); +friendlies.setIn([0, 'friends', 0, 'name'], 'Sally'); +friendlies.updateIn([0, 'friends', 0, 'name'], (value) => + // $FlowExpectedError[prop-missing] + value.unknownFunction() +); +friendlies.updateIn([0, 'friends', 0, 'name'], (value) => value.toUpperCase()); +friendlies.updateIn([0, 'friends', 0, 'name'], 'Unknown Name', (value) => + value.toUpperCase() +); + +// Nested plain JS values +type PlainPerson = { name: string, friends: Array }; +const plainFriendly: PlainPerson = { name: 'Bobbie', friends: [] }; +const plainFriendlies: List = List([plainFriendly]); + +{ + // $FlowExpectedError[incompatible-call] 'fraaands' is an unknown key in PlainPerson + const fail: ?number = plainFriendlies.getIn([0, 'fraaands', 0, 'name']); +} +{ + // $FlowExpectedError[incompatible-call] 0 is an unknown key in PlainPerson + const fail: ?number = plainFriendlies.getIn([0, 'fraaands', 0, 0]); +} +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = plainFriendlies.getIn([0, 'friends', 0, 'name']); +} +{ + // $FlowExpectedError[incompatible-type] can return undefined + const fail: string = plainFriendlies.getIn([0, 'friends', 0, 'name']); +} +{ + const success: ?string = plainFriendlies.getIn([0, 'friends', 0, 'name']); +} + +// $FlowExpectedError[incompatible-call] number is not a string +plainFriendlies.setIn([0, 'friends', 0, 'name'], 123); +plainFriendlies.setIn([0, 'friends', 0, 'name'], 'Morgan'); + +plainFriendlies.updateIn([0, 'friends', 0, 'name'], (value) => + // $FlowExpectedError[prop-missing] value is a string, this is an unknown function + value.unknownFunction() +); +plainFriendlies.updateIn([0, 'friends', 0, 'name'], (value) => + value.toUpperCase() +); + +// $FlowExpectedError[incompatible-call] number is not a string +plainFriendlies.updateIn([0, 'friends', 0, 'name'], () => 123); +plainFriendlies.updateIn([0, 'friends', 0, 'name'], () => 'Whitney'); + +// Functional API + +{ + // $FlowExpectedError[incompatible-call] 'fraaands' is an unknown key in PlainPerson + const fail: ?number = getIn(plainFriendlies, [0, 'fraaands', 0, 'name']); +} +{ + // $FlowExpectedError[incompatible-call] 0 is an unknown key in PlainPerson + const fail: ?number = getIn(plainFriendlies, [0, 'fraaands', 0, 0]); +} +{ + // $FlowExpectedError[incompatible-type] string is not a number + const fail: ?number = getIn(plainFriendlies, [0, 'friends', 0, 'name']); +} +{ + // $FlowExpectedError[incompatible-type] can return undefined + const fail: string = getIn(plainFriendlies, [0, 'friends', 0, 'name']); +} +{ + const success: ?string = getIn(plainFriendlies, [0, 'friends', 0, 'name']); +} + +// $FlowExpectedError[incompatible-call] number is not a string +setIn(plainFriendlies, [0, 'friends', 0, 'name'], 123); +setIn(plainFriendlies, [0, 'friends', 0, 'name'], 'Morgan'); + +updateIn(plainFriendlies, [0, 'friends', 0, 'name'], (value) => + // $FlowExpectedError[prop-missing] value is a string, this is an unknown function + value.unknownFunction() +); +updateIn(plainFriendlies, [0, 'friends', 0, 'name'], (value) => + value.toUpperCase() +); + +// $FlowExpectedError[incompatible-call] number is not a string +updateIn(plainFriendlies, [0, 'friends', 0, 'name'], () => 123); +updateIn(plainFriendlies, [0, 'friends', 0, 'name'], () => 'Whitney'); + +// Plain JS values + +{ + const success: number | void = get([1, 2, 3], 0); +} +{ + const success: number | string = get([1, 2, 3], 0, 'missing'); +} +{ + // $FlowExpectedError[incompatible-call] - string is not an array index + const success: number = get([1, 2, 3], 'z'); +} +// Note: does not return null since x is known to exist in {x,y} +{ + const success: number = get({ x: 10, y: 10 }, 'x'); +} +{ + // $FlowExpectedError[incompatible-call] - z is not in {x,y} + const success: number | void = get({ x: 10, y: 10 }, 'z'); +} +{ + const objMap: { [string]: number } = { x: 10, y: 10 }; + const success: number | void = get(objMap, 'z'); +} +{ + const success: number = get({ x: 10, y: 10 }, 'x', 'missing'); +} +{ + const objMap: { [string]: number } = { x: 10, y: 10 }; + const success: number | string = get(objMap, 'z', 'missing'); +} + +// Deeply nested records + +type DeepNestFields = { + foo: number, +}; +type DeepNest = RecordOf; +const deepNest: RecordFactory = Record({ + foo: 0, +}); + +type NestFields = { + deepNest: DeepNest, +}; +type Nest = RecordOf; +const nest: RecordFactory = Record({ + deepNest: deepNest(), +}); + +type StateFields = { + nest: Nest, +}; +type State = RecordOf; +const initialState: RecordFactory = Record({ + nest: nest(), +}); + +const state = initialState(); +(state.setIn(['nest', 'deepNest', 'foo'], 5): State); +// $FlowExpectedError[incompatible-call] +(state.setIn(['nest', 'deepNest', 'foo'], 'string'): State); +// $FlowExpectedError[incompatible-call] +(state.setIn(['nest', 'deepNest', 'unknownField'], 5): State); diff --git a/type-definitions/flow-tests/merge.js b/type-definitions/flow-tests/merge.js new file mode 100644 index 0000000000..ad4cc4b21f --- /dev/null +++ b/type-definitions/flow-tests/merge.js @@ -0,0 +1,138 @@ +// @flow +import { + List, + Map, + Record, + type RecordOf, + type RecordFactory, + get, + getIn, + has, + hasIn, + merge, + mergeDeep, + mergeWith, + mergeDeepWith, + remove, + removeIn, + set, + setIn, + update, + updateIn, +} from 'immutable'; + +// merge: Objects as Maps + +type ObjMap = { [key: string]: T }; +const objMap: ObjMap = { x: 12, y: 34 }; +(merge(objMap, { x: 321 }): ObjMap); +(merge(objMap, { z: 321 }): ObjMap); +// $FlowExpectedError[incompatible-call] +(merge(objMap, { x: 'abc' }): ObjMap); +(merge(objMap, [['x', 321]]): ObjMap); +(merge(objMap, [['z', 321]]): ObjMap); +// $FlowExpectedError[incompatible-call] +(merge(objMap, [['x', 'abc']]): ObjMap); +// $FlowExpectedError[incompatible-call] +(merge(objMap, [321]): ObjMap); +(merge(objMap, Map({ x: 123 })): ObjMap); +(merge(objMap, Map({ z: 123 })): ObjMap); +(merge(objMap, Map([['x', 123]])): ObjMap); +(merge(objMap, Map([['z', 123]])): ObjMap); +// $FlowExpectedError[incompatible-call] +(merge(objMap, List([123])): ObjMap); + +// merge: Maps + +const map = Map({ key: 'value' }); +(merge(map, { key: 'alternate' }): Map); +(merge(map, { otherKey: 'value' }): Map); +(merge(map, Map({ key: 'alternate' })): Map); +(merge(map, Map({ otherKey: 'value' })): Map); +(merge(map, [['otherKey', 'value']]): Map); +// $FlowExpectedError[incompatible-call] (functional merge cannot return union value types) +(merge(map, Map({ otherKey: 123 })): Map); +// $FlowExpectedError[incompatible-call] +(merge(map, [4, 5, 6]): Map); +// $FlowExpectedError[incompatible-call] +(merge(map, 123): Map); +// $FlowExpectedError[incompatible-call] +(merge(map, { '0': 123 }): Map); +// $FlowExpectedError[incompatible-call] +(merge(map, [ + [0, 4], + [1, 5], + [1, 6], +]): Map); + +// merge: Lists + +const list = List([1, 2, 3]); +(merge(list, [4, 5, 6]): List); +(merge(list, List([4, 5, 6])): List); +// $FlowExpectedError[incompatible-call] (functional merge cannot return union value types) +(merge(list, ['a', 'b', 'c']): List); +// $FlowExpectedError[incompatible-call] (functional merge cannot return union value types) +(merge(list, List(['a', 'b', 'c'])): List); +// $FlowExpectedError[incompatible-call] +(merge(list, 123): List); +// $FlowExpectedError[incompatible-call] +(merge(list, { '0': 123 }): List); +// $FlowExpectedError[incompatible-call] +(merge(list, Map({ '0': 123 })): List); +// $FlowExpectedError[incompatible-call] +(merge(list, [ + [0, 4], + [1, 5], + [1, 6], +]): List); + +// merge: Objects as Records + +type XYPoint = { x: number, y: number }; +const objRecord: XYPoint = { x: 12, y: 34 }; +(merge(objRecord, { x: 321 }): XYPoint); +(merge(objRecord, [['x', 321]]): XYPoint); +(merge(objRecord, Map({ x: 123 })): XYPoint); +(merge(objRecord, Map([['x', 123]])): XYPoint); +const xyPointRecord = Record({ x: 0, y: 0 }); +(merge(objRecord, xyPointRecord({ x: 321 })): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge(objRecord, { x: 'abc' }): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge({ x: 12, y: 34 }, [['x', 'abc']]): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge(objRecord, { z: 321 }): XYPoint); +// $FlowExpectedError[prop-missing]] +// $FlowExpectedError[invalid-call-util]] +(merge(objRecord, [['z', 321]]): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge(objRecord, Map({ z: 123 })): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge(objRecord, Map([['z', 123]])): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge(objRecord, [321]): XYPoint); +// $FlowExpectedError[incompatible-call] +(merge(objRecord, List([123])): XYPoint); + +// merge: Arrays + +const arr = [1, 2, 3]; +(merge(arr, [4, 5, 6]): Array); +(merge(arr, List([4, 5, 6])): Array); +// $FlowExpectedError[incompatible-call] (functional merge cannot return union value types) +(merge(arr, ['a', 'b', 'c']): Array); +// $FlowExpectedError[incompatible-call] (functional merge cannot return union value types) +(merge(arr, List(['a', 'b', 'c'])): Array); +// $FlowExpectedError[incompatible-call] +(merge(arr, 123): Array); +// $FlowExpectedError[incompatible-call] +(merge(arr, { '0': 123 }): Array); +// $FlowExpectedError[incompatible-call] +(merge(arr, Map({ '0': 123 })): Array); +// $FlowExpectedError[incompatible-call] +(merge(arr, [ + [0, 4], + [1, 5], + [1, 6], +]): Array); diff --git a/type-definitions/flow-tests/predicates.js b/type-definitions/flow-tests/predicates.js new file mode 100644 index 0000000000..a72072bb96 --- /dev/null +++ b/type-definitions/flow-tests/predicates.js @@ -0,0 +1,17 @@ +// @flow +import { List } from 'immutable'; + +declare var mystery: mixed; + +// $FlowExpectedError[cannot-resolve-name] +maybe.push('3'); + +if (mystery instanceof List) { + maybe.push('3'); +} + +// Note: Flow's support for %checks is still experimental. +// Support this in the future. +// if (List.isList(mystery)) { +// mystery.push('3'); +// } diff --git a/type-definitions/flow-tests/record.js b/type-definitions/flow-tests/record.js new file mode 100644 index 0000000000..d820608d92 --- /dev/null +++ b/type-definitions/flow-tests/record.js @@ -0,0 +1,217 @@ +// @flow +// Some tests look like they are repeated in order to avoid false positives. +// Flow might not complain about an instance of (what it thinks is) T to be assigned to T + +import { Record, type RecordFactory, type RecordOf, Map, List, merge } from 'immutable'; + +// Use the RecordFactory type to annotate +const Point2: RecordFactory<{ x: number, y: number }> = Record({ x: 0, y: 0 }); +const Point3: RecordFactory<{ x: number, y: number, z: number }> = Record({ + x: 0, + y: 0, + z: 0, +}); +type TGeoPoint = { lat: ?number, lon: ?number }; +const GeoPoint: RecordFactory = Record({ lat: null, lon: null }); + +// TODO: this should be FlowExpectedError - 'abc' is not a number +// However, due to support for the brittle support for subclassing, Flow +// cannot also type check default values in this position. +const PointWhoops: RecordFactory<{ x: number, y: number }> = Record({ + x: 0, + y: 'abc', +}); + +let origin2 = Point2({}); +let origin3 = Point3({}); +let geo = GeoPoint({ lat: 34 }); +// $FlowExpectedError[incompatible-call] +const mistake = Point2({ x: 'string' }); +origin3 = GeoPoint({ lat: 34 }); +geo = Point3({}); + +// Use RecordOf to type the return value of a Record factory function. +let geoPointExpected1: RecordOf = GeoPoint({}); + +// $FlowExpectedError[prop-missing] - Point2 does not return GeoPoint. +let geoPointExpected2: RecordOf = Point2({}); + +const px = origin2.get('x'); +const px2: number = origin2.x; +// $FlowExpectedError[incompatible-type] +const px3: number = origin2.get('x', 'not set value'); +const px4: number | string = origin2.get('x', 'not set value'); +// $FlowExpectedError[incompatible-call] +const pz = origin2.get('z'); +// $FlowExpectedError[incompatible-use] +const pz2 = origin2.z; + +origin2.set('x', 4); +// $FlowExpectedError[incompatible-call] +origin2.set('x', 'not-a-number'); +// $FlowExpectedError[incompatible-call] +origin2.set('z', 3); + +const name: string = Record.getDescriptiveName(origin2); +// $FlowExpectedError[incompatible-call] +const name2: string = Record.getDescriptiveName({}); + +// Note: need to cast through any when extending Records as if they ere classes +class ABClass extends (Record({ a: 1, b: 2 }): any) { + setA(a: number) { + return this.set('a', a); + } + + setB(b: number) { + return this.set('b', b); + } +} + +var t1 = new ABClass({ a: 1 }); +var t2 = t1.setA(3); +var t3 = t2.setB(10); +// Note: flow does not check extended Record classes yet +var t4 = t2.setC(10); + +// Note: flow does not check extended Record classes yet +var t1a: string = t1.a; +// Note: flow does not check extended Record classes yet +var t1c = t1.c; + +// Use of new to create record factories (supported, but discouraged) +type TPointNew = { x: number, y: number }; +type PointNew = RecordOf; +const MakePointNew: RecordFactory = new Record({ x: 0, y: 0 }); +// Not using new allows returning a record. +const origin: PointNew = MakePointNew(); +// Both get and prop access are supported with RecordOf +{ + const x: number = origin.get('x'); +} +{ + const x: number = origin.x; +} +{ + // $FlowExpectedError[incompatible-type] number is not a string + const x: string = origin.x; +} +// Can use the Record constructor type as an alternative, +// it just doesn't support property access. +const originAlt1: MakePointNew = MakePointNew(); +// Both get and prop access are supported with RecordOf +{ + const x: number = originAlt1.get('x'); +} +{ + // $FlowExpectedError[prop-missing] cannot use property access for this alternative annotation + const x: number = originAlt1.x; +} +// Can also sort of use the inner Record values type as an alternative, +// however it does not have the immutable record API, though useful for flowing +// immutable Records where plain objects are expected. +// Remember that Records are *read only*, and using the $ReadOnly helper type +// can ensure correct types. +const originAlt2: $ReadOnly = MakePointNew(); +{ + // $FlowExpectedError[prop-missing] cannot use Record API for this alternative annotation + const x: number = originAlt2.get('x'); +} +{ + const x: number = originAlt2.x; +} + +// Use of new may only return a class instance, not a record +// (supported but discouraged) +// $FlowExpectedError[class-object-subtyping] +// $FlowExpectedError[prop-missing] +const mistakeOriginNew: PointNew = new MakePointNew(); +// An alternative type strategy is instance based +const originNew: MakePointNew = new MakePointNew(); +// Only get, but not prop access are supported with class instances +{ + const x: number = originNew.get('x'); +} +{ + // $FlowExpectedError[prop-missing] property `x`. Property not found in RecordInstance + const x: number = originNew.x; +} + +// $FlowExpectedError[incompatible-call] instantiated with invalid type +const mistakeNewRecord = MakePointNew({ x: 'string' }); +// $FlowExpectedError[incompatible-call] instantiated with invalid type +const mistakeNewInstance = new MakePointNew({ x: 'string' }); + +// Subclassing + +// Note use of + for Read Only. +type TPerson = { +name: string, +age: number }; +const defaultValues: TPerson = { name: 'Aristotle', age: 2400 }; +const PersonRecord = Record(defaultValues); + +class Person extends PersonRecord { + getName(): string { + return this.get('name'); + } + + setName(name: string): this & TPerson { + return this.set('name', name); + } +} + +const person = new Person(); +(person.setName('Thales'): Person); +(person.getName(): string); +(person.setName('Thales').getName(): string); +(person.setName('Thales').name: string); +person.get('name'); +person.set('name', 'Thales'); +// $FlowExpectedError[incompatible-call] +person.get('unknown'); +// $FlowExpectedError[prop-missing] +person.set('unknown', 'Thales'); + +// Note: not +class PersonWithoutTypes extends PersonRecord { + getName(): string { + return this.get('name'); + } + + setName(name: string): this & TPerson { + return this.set('name', name); + } +} + +const person2 = new PersonWithoutTypes(); + +person2.get('name'); +// Note: no error +person2.get('unknown'); + + +// Functional Merge + +type XYPoint = { x: number, y: number }; +type XYPointRecord = RecordOf; +const xyRecord: RecordFactory = Record({ x: 0, y: 0 }); +const record = xyRecord(); +(merge(record, { x: 321 }): XYPointRecord); +(merge(record, xyRecord({ x: 321 })): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, { z: 321 }): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, { x: 'abc' }): XYPointRecord); +(merge(record, [['x', 321]]): XYPointRecord); +// $FlowExpectedError[prop-missing]] +(merge(record, [['z', 321]]): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, [['x', 'abc']]): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, [321]): XYPointRecord); +(merge(record, Map({ x: 123 })): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, Map({ z: 123 })): XYPointRecord); +(merge(record, Map([['x', 123]])): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, Map([['z', 123]])): XYPointRecord); +// $FlowExpectedError[incompatible-call] +(merge(record, List([123])): XYPointRecord); diff --git a/type-definitions/immutable.d.ts b/type-definitions/immutable.d.ts new file mode 100644 index 0000000000..331dc2c6a8 --- /dev/null +++ b/type-definitions/immutable.d.ts @@ -0,0 +1,6249 @@ +/** @ignore we should disable this rules, but let's activate it to enable eslint first */ +/** + * Immutable data encourages pure functions (data-in, data-out) and lends itself + * to much simpler application development and enabling techniques from + * functional programming such as lazy evaluation. + * + * While designed to bring these powerful functional concepts to JavaScript, it + * presents an Object-Oriented API familiar to Javascript engineers and closely + * mirroring that of Array, Map, and Set. It is easy and efficient to convert to + * and from plain Javascript types. + * + * ## How to read these docs + * + * In order to better explain what kinds of values the Immutable.js API expects + * and produces, this documentation is presented in a statically typed dialect of + * JavaScript (like [Flow][] or [TypeScript][]). You *don't need* to use these + * type checking tools in order to use Immutable.js, however becoming familiar + * with their syntax will help you get a deeper understanding of this API. + * + * **A few examples and how to read them.** + * + * All methods describe the kinds of data they accept and the kinds of data + * they return. For example a function which accepts two numbers and returns + * a number would look like this: + * + * ```js + * sum(first: number, second: number): number + * ``` + * + * Sometimes, methods can accept different kinds of data or return different + * kinds of data, and this is described with a *type variable*, which is + * typically in all-caps. For example, a function which always returns the same + * kind of data it was provided would look like this: + * + * ```js + * identity(value: T): T + * ``` + * + * Type variables are defined with classes and referred to in methods. For + * example, a class that holds onto a value for you might look like this: + * + * ```js + * class Box { + * constructor(value: T) + * getValue(): T + * } + * ``` + * + * In order to manipulate Immutable data, methods that we're used to affecting + * a Collection instead return a new Collection of the same type. The type + * `this` refers to the same kind of class. For example, a List which returns + * new Lists when you `push` a value onto it might look like: + * + * ```js + * class List { + * push(value: T): this + * } + * ``` + * + * Many methods in Immutable.js accept values which implement the JavaScript + * [Iterable][] protocol, and might appear like `Iterable` for something + * which represents sequence of strings. Typically in JavaScript we use plain + * Arrays (`[]`) when an Iterable is expected, but also all of the Immutable.js + * collections are iterable themselves! + * + * For example, to get a value deep within a structure of data, we might use + * `getIn` which expects an `Iterable` path: + * + * ``` + * getIn(path: Iterable): unknown + * ``` + * + * To use this method, we could pass an array: `data.getIn([ "key", 2 ])`. + * + * + * Note: All examples are presented in the modern [ES2015][] version of + * JavaScript. Use tools like Babel to support older browsers. + * + * For example: + * + * ```js + * // ES2015 + * const mappedFoo = foo.map(x => x * x); + * // ES5 + * var mappedFoo = foo.map(function (x) { return x * x; }); + * ``` + * + * [ES2015]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla + * [TypeScript]: https://www.typescriptlang.org/ + * [Flow]: https://flowtype.org/ + * [Iterable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + */ + +declare namespace Immutable { + /** @ignore */ + type OnlyObject = Extract; + + /** @ignore */ + type ContainObject = + OnlyObject extends object + ? OnlyObject extends never + ? false + : true + : false; + + /** + * @ignore + * + * Used to convert deeply all immutable types to a plain TS type. + * Using `unknown` on object instead of recursive call as we have a circular reference issue + */ + export type DeepCopy = + T extends Record + ? // convert Record to DeepCopy plain JS object + { + [key in keyof R]: ContainObject extends true + ? unknown + : R[key]; + } + : T extends MapOf + ? // convert MapOf to DeepCopy plain JS object + { + [key in keyof R]: ContainObject extends true + ? unknown + : R[key]; + } + : T extends Collection.Keyed + ? // convert KeyedCollection to DeepCopy plain JS object + { + [key in KeyedKey extends PropertyKey + ? KeyedKey + : string]: V extends object ? unknown : V; + } + : // convert IndexedCollection or Immutable.Set to DeepCopy plain JS array + // eslint-disable-next-line @typescript-eslint/no-unused-vars + T extends Collection + ? Array> + : T extends string | number // Iterable scalar types : should be kept as is + ? T + : T extends Iterable // Iterable are converted to plain JS array + ? Array> + : T extends object // plain JS object are converted deeply + ? { + [ObjectKey in keyof T]: ContainObject< + T[ObjectKey] + > extends true + ? unknown + : T[ObjectKey]; + } + : // other case : should be kept as is + T; + + /** + * Describes which item in a pair should be placed first when sorting + * + * @ignore + */ + export enum PairSorting { + LeftThenRight = -1, + RightThenLeft = +1, + } + + /** + * Function comparing two items of the same type. It can return: + * + * * a PairSorting value, to indicate whether the left-hand item or the right-hand item should be placed before the other + * + * * the traditional numeric return value - especially -1, 0, or 1 + * + * @ignore + */ + export type Comparator = (left: T, right: T) => PairSorting | number; + + /** + * @ignore + * + * KeyPath allowed for `xxxIn` methods + */ + export type KeyPath = OrderedCollection | ArrayLike; + + /** + * Lists are ordered indexed dense collections, much like a JavaScript + * Array. + * + * Lists are immutable and fully persistent with O(log32 N) gets and sets, + * and O(1) push and pop. + * + * Lists implement Deque, with efficient addition and removal from both the + * end (`push`, `pop`) and beginning (`unshift`, `shift`). + * + * Unlike a JavaScript Array, there is no distinction between an + * "unset" index and an index set to `undefined`. `List#forEach` visits all + * indices from 0 to size, regardless of whether they were explicitly defined. + */ + namespace List { + /** + * True if the provided value is a List + * + * + * ```js + * const { List } = require('immutable'); + * List.isList([]); // false + * List.isList(List()); // true + * ``` + */ + function isList(maybeList: unknown): maybeList is List; + + /** + * Creates a new List containing `values`. + * + * + * ```js + * const { List } = require('immutable'); + * List.of(1, 2, 3, 4) + * // List [ 1, 2, 3, 4 ] + * ``` + * + * Note: Values are not altered or converted in any way. + * + * + * ```js + * const { List } = require('immutable'); + * List.of({x:1}, 2, [3], 4) + * // List [ { x: 1 }, 2, [ 3 ], 4 ] + * ``` + */ + function of(...values: Array): List; + } + + /** + * Create a new immutable List containing the values of the provided + * collection-like. + * + * Note: `List` is a factory function and not a class, and does not use the + * `new` keyword during construction. + * + * + * ```js + * const { List, Set } = require('immutable') + * + * const emptyList = List() + * // List [] + * + * const plainArray = [ 1, 2, 3, 4 ] + * const listFromPlainArray = List(plainArray) + * // List [ 1, 2, 3, 4 ] + * + * const plainSet = Set([ 1, 2, 3, 4 ]) + * const listFromPlainSet = List(plainSet) + * // List [ 1, 2, 3, 4 ] + * + * const arrayIterator = plainArray[Symbol.iterator]() + * const listFromCollectionArray = List(arrayIterator) + * // List [ 1, 2, 3, 4 ] + * + * listFromPlainArray.equals(listFromCollectionArray) // true + * listFromPlainSet.equals(listFromCollectionArray) // true + * listFromPlainSet.equals(listFromPlainArray) // true + * ``` + */ + function List(collection?: Iterable | ArrayLike): List; + + interface List extends Collection.Indexed { + /** + * The number of items in this List. + */ + readonly size: number; + + // Persistent changes + + /** + * Returns a new List which includes `value` at `index`. If `index` already + * exists in this List, it will be replaced. + * + * `index` may be a negative number, which indexes back from the end of the + * List. `v.set(-1, "value")` sets the last item in the List. + * + * If `index` larger than `size`, the returned List's `size` will be large + * enough to include the `index`. + * + * + * ```js + * const originalList = List([ 0 ]); + * // List [ 0 ] + * originalList.set(1, 1); + * // List [ 0, 1 ] + * originalList.set(0, 'overwritten'); + * // List [ "overwritten" ] + * originalList.set(2, 2); + * // List [ 0, undefined, 2 ] + * + * List().set(50000, 'value').size; + * // 50001 + * ``` + * + * Note: `set` can be used in `withMutations`. + */ + set(index: number, value: T): List; + + /** + * Returns a new List which excludes this `index` and with a size 1 less + * than this List. Values at indices above `index` are shifted down by 1 to + * fill the position. + * + * This is synonymous with `list.splice(index, 1)`. + * + * `index` may be a negative number, which indexes back from the end of the + * List. `v.delete(-1)` deletes the last item in the List. + * + * Note: `delete` cannot be safely used in IE8 + * + * + * ```js + * List([ 0, 1, 2, 3, 4 ]).delete(0); + * // List [ 1, 2, 3, 4 ] + * ``` + * + * Since `delete()` re-indexes values, it produces a complete copy, which + * has `O(N)` complexity. + * + * Note: `delete` *cannot* be used in `withMutations`. + * + * @alias remove + */ + delete(index: number): List; + remove(index: number): List; + + /** + * Returns a new List with `value` at `index` with a size 1 more than this + * List. Values at indices above `index` are shifted over by 1. + * + * This is synonymous with `list.splice(index, 0, value)`. + * + * + * ```js + * List([ 0, 1, 2, 3, 4 ]).insert(6, 5) + * // List [ 0, 1, 2, 3, 4, 5 ] + * ``` + * + * Since `insert()` re-indexes values, it produces a complete copy, which + * has `O(N)` complexity. + * + * Note: `insert` *cannot* be used in `withMutations`. + */ + insert(index: number, value: T): List; + + /** + * Returns a new List with 0 size and no values in constant time. + * + * + * ```js + * List([ 1, 2, 3, 4 ]).clear() + * // List [] + * ``` + * + * Note: `clear` can be used in `withMutations`. + */ + clear(): List; + + /** + * Returns a new List with the provided `values` appended, starting at this + * List's `size`. + * + * + * ```js + * List([ 1, 2, 3, 4 ]).push(5) + * // List [ 1, 2, 3, 4, 5 ] + * ``` + * + * Note: `push` can be used in `withMutations`. + */ + push(...values: Array): List; + + /** + * Returns a new List with a size ones less than this List, excluding + * the last index in this List. + * + * Note: this differs from `Array#pop` because it returns a new + * List rather than the removed value. Use `last()` to get the last value + * in this List. + * + * ```js + * List([ 1, 2, 3, 4 ]).pop() + * // List[ 1, 2, 3 ] + * ``` + * + * Note: `pop` can be used in `withMutations`. + */ + pop(): List; + + /** + * Returns a new List with the provided `values` prepended, shifting other + * values ahead to higher indices. + * + * + * ```js + * List([ 2, 3, 4]).unshift(1); + * // List [ 1, 2, 3, 4 ] + * ``` + * + * Note: `unshift` can be used in `withMutations`. + */ + unshift(...values: Array): List; + + /** + * Returns a new List with a size ones less than this List, excluding + * the first index in this List, shifting all other values to a lower index. + * + * Note: this differs from `Array#shift` because it returns a new + * List rather than the removed value. Use `first()` to get the first + * value in this List. + * + * + * ```js + * List([ 0, 1, 2, 3, 4 ]).shift(); + * // List [ 1, 2, 3, 4 ] + * ``` + * + * Note: `shift` can be used in `withMutations`. + */ + shift(): List; + + /** + * Returns a new List with an updated value at `index` with the return + * value of calling `updater` with the existing value, or `notSetValue` if + * `index` was not set. If called with a single argument, `updater` is + * called with the List itself. + * + * `index` may be a negative number, which indexes back from the end of the + * List. `v.update(-1)` updates the last item in the List. + * + * + * ```js + * const list = List([ 'a', 'b', 'c' ]) + * const result = list.update(2, val => val.toUpperCase()) + * // List [ "a", "b", "C" ] + * ``` + * + * This can be very useful as a way to "chain" a normal function into a + * sequence of methods. RxJS calls this "let" and lodash calls it "thru". + * + * For example, to sum a List after mapping and filtering: + * + * + * ```js + * function sum(collection) { + * return collection.reduce((sum, x) => sum + x, 0) + * } + * + * List([ 1, 2, 3 ]) + * .map(x => x + 1) + * .filter(x => x % 2 === 0) + * .update(sum) + * // 6 + * ``` + * + * Note: `update(index)` can be used in `withMutations`. + * + * @see `Map#update` + */ + update(index: number, notSetValue: T, updater: (value: T) => T): this; + update( + index: number, + updater: (value: T | undefined) => T | undefined + ): this; + update(updater: (value: this) => R): R; + + /** + * Returns a new List with size `size`. If `size` is less than this + * List's size, the new List will exclude values at the higher indices. + * If `size` is greater than this List's size, the new List will have + * undefined values for the newly available indices. + * + * When building a new List and the final size is known up front, `setSize` + * used in conjunction with `withMutations` may result in the more + * performant construction. + */ + setSize(size: number): List; + + // Deep persistent changes + + /** + * Returns a new List having set `value` at this `keyPath`. If any keys in + * `keyPath` do not exist, a new immutable Map will be created at that key. + * + * Index numbers are used as keys to determine the path to follow in + * the List. + * + * + * ```js + * const { List } = require('immutable') + * const list = List([ 0, 1, 2, List([ 3, 4 ])]) + * list.setIn([3, 0], 999); + * // List [ 0, 1, 2, List [ 999, 4 ] ] + * ``` + * + * Plain JavaScript Object or Arrays may be nested within an Immutable.js + * Collection, and setIn() can update those values as well, treating them + * immutably by creating new copies of those values with the changes applied. + * + * + * ```js + * const { List } = require('immutable') + * const list = List([ 0, 1, 2, { plain: 'object' }]) + * list.setIn([3, 'plain'], 'value'); + * // List([ 0, 1, 2, { plain: 'value' }]) + * ``` + * + * Note: `setIn` can be used in `withMutations`. + */ + setIn(keyPath: Iterable, value: unknown): this; + + /** + * Returns a new List having removed the value at this `keyPath`. If any + * keys in `keyPath` do not exist, no change will occur. + * + * + * ```js + * const { List } = require('immutable') + * const list = List([ 0, 1, 2, List([ 3, 4 ])]) + * list.deleteIn([3, 0]); + * // List [ 0, 1, 2, List [ 4 ] ] + * ``` + * + * Plain JavaScript Object or Arrays may be nested within an Immutable.js + * Collection, and removeIn() can update those values as well, treating them + * immutably by creating new copies of those values with the changes applied. + * + * + * ```js + * const { List } = require('immutable') + * const list = List([ 0, 1, 2, { plain: 'object' }]) + * list.removeIn([3, 'plain']); + * // List([ 0, 1, 2, {}]) + * ``` + * + * Note: `deleteIn` *cannot* be safely used in `withMutations`. + * + * @alias removeIn + */ + deleteIn(keyPath: Iterable): this; + removeIn(keyPath: Iterable): this; + + /** + * Note: `updateIn` can be used in `withMutations`. + * + * @see `Map#updateIn` + */ + updateIn( + keyPath: Iterable, + notSetValue: unknown, + updater: (value: unknown) => unknown + ): this; + updateIn( + keyPath: Iterable, + updater: (value: unknown) => unknown + ): this; + + /** + * Note: `mergeIn` can be used in `withMutations`. + * + * @see `Map#mergeIn` + */ + mergeIn(keyPath: Iterable, ...collections: Array): this; + + /** + * Note: `mergeDeepIn` can be used in `withMutations`. + * + * @see `Map#mergeDeepIn` + */ + mergeDeepIn( + keyPath: Iterable, + ...collections: Array + ): this; + + // Transient changes + + /** + * Note: Not all methods can be safely used on a mutable collection or within + * `withMutations`! Check the documentation for each method to see if it + * allows being used in `withMutations`. + * + * @see `Map#withMutations` + */ + withMutations(mutator: (mutable: this) => unknown): this; + + /** + * An alternative API for withMutations() + * + * Note: Not all methods can be safely used on a mutable collection or within + * `withMutations`! Check the documentation for each method to see if it + * allows being used in `withMutations`. + * + * @see `Map#asMutable` + */ + asMutable(): this; + + /** + * @see `Map#wasAltered` + */ + wasAltered(): boolean; + + /** + * @see `Map#asImmutable` + */ + asImmutable(): this; + + // Sequence algorithms + + /** + * Returns a new List with other values or collections concatenated to this one. + * + * Note: `concat` can be used in `withMutations`. + * + * @alias merge + */ + concat(...valuesOrCollections: Array | C>): List; + merge(...collections: Array>): List; + + /** + * Returns a new List with values passed through a + * `mapper` function. + * + * + * ```js + * List([ 1, 2 ]).map(x => 10 * x) + * // List [ 10, 20 ] + * ``` + */ + map( + mapper: (value: T, key: number, iter: this) => M, + context?: unknown + ): List; + + /** + * Flat-maps the List, returning a new List. + * + * Similar to `list.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: number, iter: this) => Iterable, + context?: unknown + ): List; + + /** + * Returns a new List with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, index: number, iter: this) => value is F, + context?: unknown + ): List; + filter( + predicate: (value: T, index: number, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new List with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: T, index: number, iter: this) => value is F, + context?: C + ): [List, List]; + partition( + predicate: (this: C, value: T, index: number, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * Returns a List "zipped" with the provided collection. + * + * Like `zipWith`, but using the default `zipper`: creating an `Array`. + * + * + * ```js + * const a = List([ 1, 2, 3 ]); + * const b = List([ 4, 5, 6 ]); + * const c = a.zip(b); // List [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] + * ``` + */ + zip(other: Collection): List<[T, U]>; + zip( + other: Collection, + other2: Collection + ): List<[T, U, V]>; + zip(...collections: Array>): List; + + /** + * Returns a List "zipped" with the provided collections. + * + * Unlike `zip`, `zipAll` continues zipping until the longest collection is + * exhausted. Missing values from shorter collections are filled with `undefined`. + * + * + * ```js + * const a = List([ 1, 2 ]); + * const b = List([ 3, 4, 5 ]); + * const c = a.zipAll(b); // List [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ] + * ``` + * + * Note: Since zipAll will return a collection as large as the largest + * input, some results may contain undefined values. TypeScript cannot + * account for these without cases (as of v2.5). + */ + zipAll(other: Collection): List<[T, U]>; + zipAll( + other: Collection, + other2: Collection + ): List<[T, U, V]>; + zipAll(...collections: Array>): List; + + /** + * Returns a List "zipped" with the provided collections by using a + * custom `zipper` function. + * + * + * ```js + * const a = List([ 1, 2, 3 ]); + * const b = List([ 4, 5, 6 ]); + * const c = a.zipWith((a, b) => a + b, b); + * // List [ 5, 7, 9 ] + * ``` + */ + zipWith( + zipper: (value: T, otherValue: U) => Z, + otherCollection: Collection + ): List; + zipWith( + zipper: (value: T, otherValue: U, thirdValue: V) => Z, + otherCollection: Collection, + thirdCollection: Collection + ): List; + zipWith( + zipper: (...values: Array) => Z, + ...collections: Array> + ): List; + + /** + * Returns a new List with its values shuffled thanks to the + * [Fisher–Yates](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) + * algorithm. + * It uses Math.random, but you can provide your own random number generator. + */ + shuffle(random?: () => number): this; + } + + /** + * Immutable Map is an unordered Collection.Keyed of (key, value) pairs with + * `O(log32 N)` gets and `O(log32 N)` persistent sets. + * + * Iteration order of a Map is undefined, however is stable. Multiple + * iterations of the same Map will iterate in the same order. + * + * Map's keys can be of any type, and use `Immutable.is` to determine key + * equality. This allows the use of any value (including NaN) as a key. + * + * Because `Immutable.is` returns equality based on value semantics, and + * Immutable collections are treated as values, any Immutable collection may + * be used as a key. + * + * + * ```js + * const { Map, List } = require('immutable'); + * Map().set(List([ 1 ]), 'listofone').get(List([ 1 ])); + * // 'listofone' + * ``` + * + * Any JavaScript object may be used as a key, however strict identity is used + * to evaluate key equality. Two similar looking objects will represent two + * different keys. + * + * Implemented by a hash-array mapped trie. + */ + namespace Map { + /** + * True if the provided value is a Map + * + * + * ```js + * const { Map } = require('immutable') + * Map.isMap({}) // false + * Map.isMap(Map()) // true + * ``` + */ + function isMap(maybeMap: unknown): maybeMap is Map; + } + + /** + * Creates a new Immutable Map. + * + * Created with the same key value pairs as the provided Collection.Keyed or + * JavaScript Object or expects a Collection of [K, V] tuple entries. + * + * Note: `Map` is a factory function and not a class, and does not use the + * `new` keyword during construction. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ key: "value" }) + * Map([ [ "key", "value" ] ]) + * ``` + * + * Keep in mind, when using JS objects to construct Immutable Maps, that + * JavaScript Object properties are always strings, even if written in a + * quote-less shorthand, while Immutable Maps accept keys of any type. + * + * + * ```js + * let obj = { 1: "one" } + * Object.keys(obj) // [ "1" ] + * assert.equal(obj["1"], obj[1]) // "one" === "one" + * + * let map = Map(obj) + * assert.notEqual(map.get("1"), map.get(1)) // "one" !== undefined + * ``` + * + * Property access for JavaScript Objects first converts the key to a string, + * but since Immutable Map keys can be of any type the argument to `get()` is + * not altered. + */ + function Map(collection?: Iterable<[K, V]>): Map; + function Map(obj: R): MapOf; + function Map(obj: { [key: string]: V }): Map; + function Map(obj: { [P in K]?: V }): Map; + + /** + * Represent a Map constructed by an object + * + * @ignore + */ + interface MapOf + extends Map { + /** + * Returns the value associated with the provided key, or notSetValue if + * the Collection does not contain this key. + * + * Note: it is possible a key may be associated with an `undefined` value, + * so if `notSetValue` is not provided and this method returns `undefined`, + * that does not guarantee the key was not found. + */ + get(key: K, notSetValue?: unknown): R[K]; + get(key: unknown, notSetValue: NSV): NSV; + + // TODO `` can be used after dropping support for TypeScript 4.x + // reference: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#const-type-parameters + // after this change, `as const` assertions can be remove from the type tests + getIn

>( + searchKeyPath: [...P], + notSetValue?: unknown + ): RetrievePath; + + set(key: K, value: R[K]): this; + + update(updater: (value: this) => this): this; + update(key: K, updater: (value: R[K]) => R[K]): this; + update( + key: K, + notSetValue: NSV, + updater: (value: R[K]) => R[K] + ): this; + + // Possible best type is MapOf> but Omit seems to broke other function calls + // and generate recursion error with other methods (update, merge, etc.) until those functions are defined in MapOf + delete( + key: K + ): Extract extends never ? never : this; + remove( + key: K + ): Extract extends never ? never : this; + + toJS(): { [K in keyof R]: DeepCopy }; + + toJSON(): { [K in keyof R]: R[K] }; + } + + // Loosely based off of this work. + // https://github.com/immutable-js/immutable-js/issues/1462#issuecomment-584123268 + + /** + * @ignore + * Convert an immutable type to the equivalent plain TS type + * - MapOf -> object + * - List -> Array + */ + type GetNativeType = + S extends MapOf ? T : S extends List ? Array : S; + + /** @ignore */ + type Head> = T extends [ + infer H, + ...Array, + ] + ? H + : never; + /** @ignore */ + type Tail> = T extends [unknown, ...infer I] + ? I + : Array; + /** @ignore */ + type RetrievePathReducer< + T, + C, + L extends ReadonlyArray, + NT = GetNativeType, + > = + // we can not retrieve a path from a primitive type + T extends string | number | boolean | null | undefined + ? never + : C extends keyof NT + ? L extends [] // L extends [] means we are at the end of the path, lets return the current type + ? NT[C] + : // we are not at the end of the path, lets continue with the next key + RetrievePathReducer, Tail> + : // C is not a "key" of NT, so the path is invalid + never; + + /** @ignore */ + type RetrievePath> = P extends [] + ? P + : RetrievePathReducer, Tail

>; + + interface Map extends Collection.Keyed { + /** + * The number of entries in this Map. + */ + readonly size: number; + + // Persistent changes + + /** + * Returns a new Map also containing the new key, value pair. If an equivalent + * key already exists in this Map, it will be replaced. + * + * + * ```js + * const { Map } = require('immutable') + * const originalMap = Map() + * const newerMap = originalMap.set('key', 'value') + * const newestMap = newerMap.set('key', 'newer value') + * + * originalMap + * // Map {} + * newerMap + * // Map { "key": "value" } + * newestMap + * // Map { "key": "newer value" } + * ``` + * + * Note: `set` can be used in `withMutations`. + */ + set(key: K, value: V): this; + + /** + * Returns a new Map which excludes this `key`. + * + * Note: `delete` cannot be safely used in IE8, but is provided to mirror + * the ES6 collection API. + * + * + * ```js + * const { Map } = require('immutable') + * const originalMap = Map({ + * key: 'value', + * otherKey: 'other value' + * }) + * // Map { "key": "value", "otherKey": "other value" } + * originalMap.delete('otherKey') + * // Map { "key": "value" } + * ``` + * + * Note: `delete` can be used in `withMutations`. + * + * @alias remove + */ + delete(key: K): this; + remove(key: K): this; + + /** + * Returns a new Map which excludes the provided `keys`. + * + * + * ```js + * const { Map } = require('immutable') + * const names = Map({ a: "Aaron", b: "Barry", c: "Connor" }) + * names.deleteAll([ 'a', 'c' ]) + * // Map { "b": "Barry" } + * ``` + * + * Note: `deleteAll` can be used in `withMutations`. + * + * @alias removeAll + */ + deleteAll(keys: Iterable): this; + removeAll(keys: Iterable): this; + + /** + * Returns a new Map containing no keys or values. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ key: 'value' }).clear() + * // Map {} + * ``` + * + * Note: `clear` can be used in `withMutations`. + */ + clear(): this; + + /** + * Returns a new Map having updated the value at this `key` with the return + * value of calling `updater` with the existing value. + * + * Similar to: `map.set(key, updater(map.get(key)))`. + * + * + * ```js + * const { Map } = require('immutable') + * const aMap = Map({ key: 'value' }) + * const newMap = aMap.update('key', value => value + value) + * // Map { "key": "valuevalue" } + * ``` + * + * This is most commonly used to call methods on collections within a + * structure of data. For example, in order to `.push()` onto a nested `List`, + * `update` and `push` can be used together: + * + * + * ```js + * const aMap = Map({ nestedList: List([ 1, 2, 3 ]) }) + * const newMap = aMap.update('nestedList', list => list.push(4)) + * // Map { "nestedList": List [ 1, 2, 3, 4 ] } + * ``` + * + * When a `notSetValue` is provided, it is provided to the `updater` + * function when the value at the key does not exist in the Map. + * + * + * ```js + * const aMap = Map({ key: 'value' }) + * const newMap = aMap.update('noKey', 'no value', value => value + value) + * // Map { "key": "value", "noKey": "no valueno value" } + * ``` + * + * However, if the `updater` function returns the same value it was called + * with, then no change will occur. This is still true if `notSetValue` + * is provided. + * + * + * ```js + * const aMap = Map({ apples: 10 }) + * const newMap = aMap.update('oranges', 0, val => val) + * // Map { "apples": 10 } + * assert.strictEqual(newMap, map); + * ``` + * + * For code using ES2015 or later, using `notSetValue` is discourged in + * favor of function parameter default values. This helps to avoid any + * potential confusion with identify functions as described above. + * + * The previous example behaves differently when written with default values: + * + * + * ```js + * const aMap = Map({ apples: 10 }) + * const newMap = aMap.update('oranges', (val = 0) => val) + * // Map { "apples": 10, "oranges": 0 } + * ``` + * + * If no key is provided, then the `updater` function return value is + * returned as well. + * + * + * ```js + * const aMap = Map({ key: 'value' }) + * const result = aMap.update(aMap => aMap.get('key')) + * // "value" + * ``` + * + * This can be very useful as a way to "chain" a normal function into a + * sequence of methods. RxJS calls this "let" and lodash calls it "thru". + * + * For example, to sum the values in a Map + * + * + * ```js + * function sum(collection) { + * return collection.reduce((sum, x) => sum + x, 0) + * } + * + * Map({ x: 1, y: 2, z: 3 }) + * .map(x => x + 1) + * .filter(x => x % 2 === 0) + * .update(sum) + * // 6 + * ``` + * + * Note: `update(key)` can be used in `withMutations`. + */ + update(key: K, notSetValue: V, updater: (value: V) => V): this; + update(key: K, updater: (value: V | undefined) => V | undefined): this; + update(updater: (value: this) => R): R; + + /** + * Returns a new Map resulting from merging the provided Collections + * (or JS objects) into this Map. In other words, this takes each entry of + * each collection and sets it on this Map. + * + * Note: Values provided to `merge` are shallowly converted before being + * merged. No nested values are altered. + * + * + * ```js + * const { Map } = require('immutable') + * const one = Map({ a: 10, b: 20, c: 30 }) + * const two = Map({ b: 40, a: 50, d: 60 }) + * one.merge(two) // Map { "a": 50, "b": 40, "c": 30, "d": 60 } + * two.merge(one) // Map { "b": 20, "a": 10, "d": 60, "c": 30 } + * ``` + * + * Note: `merge` can be used in `withMutations`. + * + * @alias concat + */ + merge( + ...collections: Array> + ): Map | VC>; + merge( + ...collections: Array<{ [key: string]: C }> + ): Map | C>; + + concat( + ...collections: Array> + ): Map | VC>; + concat( + ...collections: Array<{ [key: string]: C }> + ): Map | C>; + + /** + * Like `merge()`, `mergeWith()` returns a new Map resulting from merging + * the provided Collections (or JS objects) into this Map, but uses the + * `merger` function for dealing with conflicts. + * + * + * ```js + * const { Map } = require('immutable') + * const one = Map({ a: 10, b: 20, c: 30 }) + * const two = Map({ b: 40, a: 50, d: 60 }) + * one.mergeWith((oldVal, newVal) => oldVal / newVal, two) + * // { "a": 0.2, "b": 0.5, "c": 30, "d": 60 } + * two.mergeWith((oldVal, newVal) => oldVal / newVal, one) + * // { "b": 2, "a": 5, "d": 60, "c": 30 } + * ``` + * + * Note: `mergeWith` can be used in `withMutations`. + */ + mergeWith( + merger: (oldVal: V, newVal: VC, key: K) => VCC, + ...collections: Array> + ): Map; + mergeWith( + merger: (oldVal: V, newVal: C, key: string) => CC, + ...collections: Array<{ [key: string]: C }> + ): Map; + + /** + * Like `merge()`, but when two compatible collections are encountered with + * the same key, it merges them as well, recursing deeply through the nested + * data. Two collections are considered to be compatible (and thus will be + * merged together) if they both fall into one of three categories: keyed + * (e.g., `Map`s, `Record`s, and objects), indexed (e.g., `List`s and + * arrays), or set-like (e.g., `Set`s). If they fall into separate + * categories, `mergeDeep` will replace the existing collection with the + * collection being merged in. This behavior can be customized by using + * `mergeDeepWith()`. + * + * Note: Indexed and set-like collections are merged using + * `concat()`/`union()` and therefore do not recurse. + * + * + * ```js + * const { Map } = require('immutable') + * const one = Map({ a: Map({ x: 10, y: 10 }), b: Map({ x: 20, y: 50 }) }) + * const two = Map({ a: Map({ x: 2 }), b: Map({ y: 5 }), c: Map({ z: 3 }) }) + * one.mergeDeep(two) + * // Map { + * // "a": Map { "x": 2, "y": 10 }, + * // "b": Map { "x": 20, "y": 5 }, + * // "c": Map { "z": 3 } + * // } + * ``` + * + * Note: `mergeDeep` can be used in `withMutations`. + */ + mergeDeep( + ...collections: Array> + ): Map; + mergeDeep( + ...collections: Array<{ [key: string]: C }> + ): Map; + + /** + * Like `mergeDeep()`, but when two non-collections or incompatible + * collections are encountered at the same key, it uses the `merger` + * function to determine the resulting value. Collections are considered + * incompatible if they fall into separate categories between keyed, + * indexed, and set-like. + * + * + * ```js + * const { Map } = require('immutable') + * const one = Map({ a: Map({ x: 10, y: 10 }), b: Map({ x: 20, y: 50 }) }) + * const two = Map({ a: Map({ x: 2 }), b: Map({ y: 5 }), c: Map({ z: 3 }) }) + * one.mergeDeepWith((oldVal, newVal) => oldVal / newVal, two) + * // Map { + * // "a": Map { "x": 5, "y": 10 }, + * // "b": Map { "x": 20, "y": 10 }, + * // "c": Map { "z": 3 } + * // } + * ``` + * + * Note: `mergeDeepWith` can be used in `withMutations`. + */ + mergeDeepWith( + merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown, + ...collections: Array | { [key: string]: V }> + ): this; + + // Deep persistent changes + + /** + * Returns a new Map having set `value` at this `keyPath`. If any keys in + * `keyPath` do not exist, a new immutable Map will be created at that key. + * + * + * ```js + * const { Map } = require('immutable') + * const originalMap = Map({ + * subObject: Map({ + * subKey: 'subvalue', + * subSubObject: Map({ + * subSubKey: 'subSubValue' + * }) + * }) + * }) + * + * const newMap = originalMap.setIn(['subObject', 'subKey'], 'ha ha!') + * // Map { + * // "subObject": Map { + * // "subKey": "ha ha!", + * // "subSubObject": Map { "subSubKey": "subSubValue" } + * // } + * // } + * + * const newerMap = originalMap.setIn( + * ['subObject', 'subSubObject', 'subSubKey'], + * 'ha ha ha!' + * ) + * // Map { + * // "subObject": Map { + * // "subKey": "subvalue", + * // "subSubObject": Map { "subSubKey": "ha ha ha!" } + * // } + * // } + * ``` + * + * Plain JavaScript Object or Arrays may be nested within an Immutable.js + * Collection, and setIn() can update those values as well, treating them + * immutably by creating new copies of those values with the changes applied. + * + * + * ```js + * const { Map } = require('immutable') + * const originalMap = Map({ + * subObject: { + * subKey: 'subvalue', + * subSubObject: { + * subSubKey: 'subSubValue' + * } + * } + * }) + * + * originalMap.setIn(['subObject', 'subKey'], 'ha ha!') + * // Map { + * // "subObject": { + * // subKey: "ha ha!", + * // subSubObject: { subSubKey: "subSubValue" } + * // } + * // } + * ``` + * + * If any key in the path exists but cannot be updated (such as a primitive + * like number or a custom Object like Date), an error will be thrown. + * + * Note: `setIn` can be used in `withMutations`. + */ + setIn(keyPath: Iterable, value: unknown): this; + + /** + * Returns a new Map having removed the value at this `keyPath`. If any keys + * in `keyPath` do not exist, no change will occur. + * + * Note: `deleteIn` can be used in `withMutations`. + * + * @alias removeIn + */ + deleteIn(keyPath: Iterable): this; + removeIn(keyPath: Iterable): this; + + /** + * Returns a new Map having applied the `updater` to the entry found at the + * keyPath. + * + * This is most commonly used to call methods on collections nested within a + * structure of data. For example, in order to `.push()` onto a nested `List`, + * `updateIn` and `push` can be used together: + * + * + * ```js + * const { Map, List } = require('immutable') + * const map = Map({ inMap: Map({ inList: List([ 1, 2, 3 ]) }) }) + * const newMap = map.updateIn(['inMap', 'inList'], list => list.push(4)) + * // Map { "inMap": Map { "inList": List [ 1, 2, 3, 4 ] } } + * ``` + * + * If any keys in `keyPath` do not exist, new Immutable `Map`s will + * be created at those keys. If the `keyPath` does not already contain a + * value, the `updater` function will be called with `notSetValue`, if + * provided, otherwise `undefined`. + * + * + * ```js + * const map = Map({ a: Map({ b: Map({ c: 10 }) }) }) + * const newMap = map.updateIn(['a', 'b', 'c'], val => val * 2) + * // Map { "a": Map { "b": Map { "c": 20 } } } + * ``` + * + * If the `updater` function returns the same value it was called with, then + * no change will occur. This is still true if `notSetValue` is provided. + * + * + * ```js + * const map = Map({ a: Map({ b: Map({ c: 10 }) }) }) + * const newMap = map.updateIn(['a', 'b', 'x'], 100, val => val) + * // Map { "a": Map { "b": Map { "c": 10 } } } + * assert.strictEqual(newMap, aMap) + * ``` + * + * For code using ES2015 or later, using `notSetValue` is discourged in + * favor of function parameter default values. This helps to avoid any + * potential confusion with identify functions as described above. + * + * The previous example behaves differently when written with default values: + * + * + * ```js + * const map = Map({ a: Map({ b: Map({ c: 10 }) }) }) + * const newMap = map.updateIn(['a', 'b', 'x'], (val = 100) => val) + * // Map { "a": Map { "b": Map { "c": 10, "x": 100 } } } + * ``` + * + * Plain JavaScript Object or Arrays may be nested within an Immutable.js + * Collection, and updateIn() can update those values as well, treating them + * immutably by creating new copies of those values with the changes applied. + * + * + * ```js + * const map = Map({ a: { b: { c: 10 } } }) + * const newMap = map.updateIn(['a', 'b', 'c'], val => val * 2) + * // Map { "a": { b: { c: 20 } } } + * ``` + * + * If any key in the path exists but cannot be updated (such as a primitive + * like number or a custom Object like Date), an error will be thrown. + * + * Note: `updateIn` can be used in `withMutations`. + */ + updateIn( + keyPath: Iterable, + notSetValue: unknown, + updater: (value: unknown) => unknown + ): this; + updateIn( + keyPath: Iterable, + updater: (value: unknown) => unknown + ): this; + + /** + * A combination of `updateIn` and `merge`, returning a new Map, but + * performing the merge at a point arrived at by following the keyPath. + * In other words, these two lines are equivalent: + * + * ```js + * map.updateIn(['a', 'b', 'c'], abc => abc.merge(y)) + * map.mergeIn(['a', 'b', 'c'], y) + * ``` + * + * Note: `mergeIn` can be used in `withMutations`. + */ + mergeIn(keyPath: Iterable, ...collections: Array): this; + + /** + * A combination of `updateIn` and `mergeDeep`, returning a new Map, but + * performing the deep merge at a point arrived at by following the keyPath. + * In other words, these two lines are equivalent: + * + * ```js + * map.updateIn(['a', 'b', 'c'], abc => abc.mergeDeep(y)) + * map.mergeDeepIn(['a', 'b', 'c'], y) + * ``` + * + * Note: `mergeDeepIn` can be used in `withMutations`. + */ + mergeDeepIn( + keyPath: Iterable, + ...collections: Array + ): this; + + // Transient changes + + /** + * Every time you call one of the above functions, a new immutable Map is + * created. If a pure function calls a number of these to produce a final + * return value, then a penalty on performance and memory has been paid by + * creating all of the intermediate immutable Maps. + * + * If you need to apply a series of mutations to produce a new immutable + * Map, `withMutations()` creates a temporary mutable copy of the Map which + * can apply mutations in a highly performant manner. In fact, this is + * exactly how complex mutations like `merge` are done. + * + * As an example, this results in the creation of 2, not 4, new Maps: + * + * + * ```js + * const { Map } = require('immutable') + * const map1 = Map() + * const map2 = map1.withMutations(map => { + * map.set('a', 1).set('b', 2).set('c', 3) + * }) + * assert.equal(map1.size, 0) + * assert.equal(map2.size, 3) + * ``` + * + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Read the documentation for each method to see if it + * is safe to use in `withMutations`. + */ + withMutations(mutator: (mutable: this) => unknown): this; + + /** + * Another way to avoid creation of intermediate Immutable maps is to create + * a mutable copy of this collection. Mutable copies *always* return `this`, + * and thus shouldn't be used for equality. Your function should never return + * a mutable copy of a collection, only use it internally to create a new + * collection. + * + * If possible, use `withMutations` to work with temporary mutable copies as + * it provides an easier to use API and considers many common optimizations. + * + * Note: if the collection is already mutable, `asMutable` returns itself. + * + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Read the documentation for each method to see if it + * is safe to use in `withMutations`. + * + * @see `Map#asImmutable` + */ + asMutable(): this; + + /** + * Returns true if this is a mutable copy (see `asMutable()`) and mutative + * alterations have been applied. + * + * @see `Map#asMutable` + */ + wasAltered(): boolean; + + /** + * The yin to `asMutable`'s yang. Because it applies to mutable collections, + * this operation is *mutable* and may return itself (though may not + * return itself, i.e. if the result is an empty collection). Once + * performed, the original mutable copy must no longer be mutated since it + * may be the immutable result. + * + * If possible, use `withMutations` to work with temporary mutable copies as + * it provides an easier to use API and considers many common optimizations. + * + * @see `Map#asMutable` + */ + asImmutable(): this; + + // Sequence algorithms + + /** + * Returns a new Map with values passed through a + * `mapper` function. + * + * Map({ a: 1, b: 2 }).map(x => 10 * x) + * // Map { a: 10, b: 20 } + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): Map; + + /** + * @see Collection.Keyed.mapKeys + */ + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: unknown + ): Map; + + /** + * @see Collection.Keyed.mapEntries + */ + mapEntries( + mapper: ( + entry: [K, V], + index: number, + iter: this + ) => [KM, VM] | undefined, + context?: unknown + ): Map; + + /** + * Flat-maps the Map, returning a new Map. + * + * Similar to `data.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: unknown + ): Map; + + /** + * Returns a new Map with only the entries for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: V, key: K, iter: this) => value is F, + context?: unknown + ): Map; + filter( + predicate: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new Map with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: V, key: K, iter: this) => value is F, + context?: C + ): [Map, Map]; + partition( + predicate: (this: C, value: V, key: K, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * @see Collection.Keyed.flip + */ + flip(): Map; + + /** + * Returns an OrderedMap of the same type which includes the same entries, + * stably sorted by using a `comparator`. + * + * If a `comparator` is not provided, a default comparator uses `<` and `>`. + * + * `comparator(valueA, valueB)`: + * + * * Returns `0` if the elements should not be swapped. + * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` + * * Returns `1` (or any positive number) if `valueA` comes after `valueB` + * * Alternatively, can return a value of the `PairSorting` enum type + * * Is pure, i.e. it must always return the same value for the same pair + * of values. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ "c": 3, "a": 1, "b": 2 }).sort((a, b) => { + * if (a < b) { return -1; } + * if (a > b) { return 1; } + * if (a === b) { return 0; } + * }); + * // OrderedMap { "a": 1, "b": 2, "c": 3 } + * ``` + * + * Note: `sort()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sort(comparator?: Comparator): this & OrderedMap; + + /** + * Like `sort`, but also accepts a `comparatorValueMapper` which allows for + * sorting by more sophisticated means: + * + * + * ```js + * const { Map } = require('immutable') + * const beattles = Map({ + * John: { name: "Lennon" }, + * Paul: { name: "McCartney" }, + * George: { name: "Harrison" }, + * Ringo: { name: "Starr" }, + * }); + * beattles.sortBy(member => member.name); + * ``` + * + * Note: `sortBy()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sortBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: (valueA: C, valueB: C) => number + ): this & OrderedMap; + } + + /** + * A type of Map that has the additional guarantee that the iteration order of + * entries will be the order in which they were set(). + * + * The iteration behavior of OrderedMap is the same as native ES6 Map and + * JavaScript Object. + * + * Note that `OrderedMap` are more expensive than non-ordered `Map` and may + * consume more memory. `OrderedMap#set` is amortized O(log32 N), but not + * stable. + */ + namespace OrderedMap { + /** + * True if the provided value is an OrderedMap. + */ + function isOrderedMap( + maybeOrderedMap: unknown + ): maybeOrderedMap is OrderedMap; + } + + /** + * Creates a new Immutable OrderedMap. + * + * Created with the same key value pairs as the provided Collection.Keyed or + * JavaScript Object or expects a Collection of [K, V] tuple entries. + * + * The iteration order of key-value pairs provided to this constructor will + * be preserved in the OrderedMap. + * + * let newOrderedMap = OrderedMap({key: "value"}) + * let newOrderedMap = OrderedMap([["key", "value"]]) + * + * Note: `OrderedMap` is a factory function and not a class, and does not use + * the `new` keyword during construction. + */ + function OrderedMap(collection?: Iterable<[K, V]>): OrderedMap; + function OrderedMap(obj: { [key: string]: V }): OrderedMap; + + interface OrderedMap extends Map, OrderedCollection<[K, V]> { + /** + * The number of entries in this OrderedMap. + */ + readonly size: number; + + /** + * Returns a new OrderedMap also containing the new key, value pair. If an + * equivalent key already exists in this OrderedMap, it will be replaced + * while maintaining the existing order. + * + * + * ```js + * const { OrderedMap } = require('immutable') + * const originalMap = OrderedMap({a:1, b:1, c:1}) + * const updatedMap = originalMap.set('b', 2) + * + * originalMap + * // OrderedMap {a: 1, b: 1, c: 1} + * updatedMap + * // OrderedMap {a: 1, b: 2, c: 1} + * ``` + * + * Note: `set` can be used in `withMutations`. + */ + set(key: K, value: V): this; + + /** + * Returns a new OrderedMap resulting from merging the provided Collections + * (or JS objects) into this OrderedMap. In other words, this takes each + * entry of each collection and sets it on this OrderedMap. + * + * Note: Values provided to `merge` are shallowly converted before being + * merged. No nested values are altered. + * + * + * ```js + * const { OrderedMap } = require('immutable') + * const one = OrderedMap({ a: 10, b: 20, c: 30 }) + * const two = OrderedMap({ b: 40, a: 50, d: 60 }) + * one.merge(two) // OrderedMap { "a": 50, "b": 40, "c": 30, "d": 60 } + * two.merge(one) // OrderedMap { "b": 20, "a": 10, "d": 60, "c": 30 } + * ``` + * + * Note: `merge` can be used in `withMutations`. + * + * @alias concat + */ + merge( + ...collections: Array> + ): OrderedMap | VC>; + merge( + ...collections: Array<{ [key: string]: C }> + ): OrderedMap | C>; + + concat( + ...collections: Array> + ): OrderedMap | VC>; + concat( + ...collections: Array<{ [key: string]: C }> + ): OrderedMap | C>; + + mergeWith( + merger: (oldVal: V, newVal: VC, key: K) => VCC, + ...collections: Array> + ): OrderedMap; + mergeWith( + merger: (oldVal: V, newVal: C, key: string) => CC, + ...collections: Array<{ [key: string]: C }> + ): OrderedMap; + + mergeDeep( + ...collections: Array> + ): OrderedMap; + mergeDeep( + ...collections: Array<{ [key: string]: C }> + ): OrderedMap; + + // Sequence algorithms + + /** + * Returns a new OrderedMap with values passed through a + * `mapper` function. + * + * OrderedMap({ a: 1, b: 2 }).map(x => 10 * x) + * // OrderedMap { "a": 10, "b": 20 } + * + * Note: `map()` always returns a new instance, even if it produced the same + * value at every step. + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): OrderedMap; + + /** + * @see Collection.Keyed.mapKeys + */ + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: unknown + ): OrderedMap; + + /** + * @see Collection.Keyed.mapEntries + */ + mapEntries( + mapper: ( + entry: [K, V], + index: number, + iter: this + ) => [KM, VM] | undefined, + context?: unknown + ): OrderedMap; + + /** + * Flat-maps the OrderedMap, returning a new OrderedMap. + * + * Similar to `data.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: unknown + ): OrderedMap; + + /** + * Returns a new OrderedMap with only the entries for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: V, key: K, iter: this) => value is F, + context?: unknown + ): OrderedMap; + filter( + predicate: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new OrderedMap with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: V, key: K, iter: this) => value is F, + context?: C + ): [OrderedMap, OrderedMap]; + partition( + predicate: (this: C, value: V, key: K, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * @see Collection.Keyed.flip + */ + flip(): OrderedMap; + } + + /** + * A Collection of unique values with `O(log32 N)` adds and has. + * + * When iterating a Set, the entries will be (value, value) pairs. Iteration + * order of a Set is undefined, however is stable. Multiple iterations of the + * same Set will iterate in the same order. + * + * Set values, like Map keys, may be of any type. Equality is determined using + * `Immutable.is`, enabling Sets to uniquely include other Immutable + * collections, custom value types, and NaN. + */ + namespace Set { + /** + * True if the provided value is a Set + */ + function isSet(maybeSet: unknown): maybeSet is Set; + + /** + * Creates a new Set containing `values`. + */ + function of(...values: Array): Set; + + /** + * `Set.fromKeys()` creates a new immutable Set containing the keys from + * this Collection or JavaScript Object. + */ + function fromKeys(iter: Collection.Keyed): Set; + function fromKeys(iter: Collection): Set; + function fromKeys(obj: { [key: string]: unknown }): Set; + + /** + * `Set.intersect()` creates a new immutable Set that is the intersection of + * a collection of other sets. + * + * ```js + * const { Set } = require('immutable') + * const intersected = Set.intersect([ + * Set([ 'a', 'b', 'c' ]) + * Set([ 'c', 'a', 't' ]) + * ]) + * // Set [ "a", "c" ] + * ``` + */ + function intersect(sets: Iterable>): Set; + + /** + * `Set.union()` creates a new immutable Set that is the union of a + * collection of other sets. + * + * ```js + * const { Set } = require('immutable') + * const unioned = Set.union([ + * Set([ 'a', 'b', 'c' ]) + * Set([ 'c', 'a', 't' ]) + * ]) + * // Set [ "a", "b", "c", "t" ] + * ``` + */ + function union(sets: Iterable>): Set; + } + + /** + * Create a new immutable Set containing the values of the provided + * collection-like. + * + * Note: `Set` is a factory function and not a class, and does not use the + * `new` keyword during construction. + */ + function Set(collection?: Iterable | ArrayLike): Set; + + interface Set extends Collection.Set { + /** + * The number of items in this Set. + */ + readonly size: number; + + // Persistent changes + + /** + * Returns a new Set which also includes this value. + * + * Note: `add` can be used in `withMutations`. + */ + add(value: T): this; + + /** + * Returns a new Set which excludes this value. + * + * Note: `delete` can be used in `withMutations`. + * + * Note: `delete` **cannot** be safely used in IE8, use `remove` if + * supporting old browsers. + * + * @alias remove + */ + delete(value: T): this; + remove(value: T): this; + + /** + * Returns a new Set containing no values. + * + * Note: `clear` can be used in `withMutations`. + */ + clear(): this; + + /** + * Returns a Set including any value from `collections` that does not already + * exist in this Set. + * + * Note: `union` can be used in `withMutations`. + * @alias merge + * @alias concat + */ + union(...collections: Array>): Set; + merge(...collections: Array>): Set; + concat(...collections: Array>): Set; + + /** + * Returns a Set which has removed any values not also contained + * within `collections`. + * + * Note: `intersect` can be used in `withMutations`. + */ + intersect(...collections: Array>): this; + + /** + * Returns a Set excluding any values contained within `collections`. + * + * + * ```js + * const { OrderedSet } = require('immutable') + * OrderedSet([ 1, 2, 3 ]).subtract([1, 3]) + * // OrderedSet [2] + * ``` + * + * Note: `subtract` can be used in `withMutations`. + */ + subtract(...collections: Array>): this; + + // Transient changes + + /** + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Check the documentation for each method to see if it + * mentions being safe to use in `withMutations`. + * + * @see `Map#withMutations` + */ + withMutations(mutator: (mutable: this) => unknown): this; + + /** + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Check the documentation for each method to see if it + * mentions being safe to use in `withMutations`. + * + * @see `Map#asMutable` + */ + asMutable(): this; + + /** + * @see `Map#wasAltered` + */ + wasAltered(): boolean; + + /** + * @see `Map#asImmutable` + */ + asImmutable(): this; + + // Sequence algorithms + + /** + * Returns a new Set with values passed through a + * `mapper` function. + * + * Set([1,2]).map(x => 10 * x) + * // Set [10,20] + */ + map( + mapper: (value: T, key: T, iter: this) => M, + context?: unknown + ): Set; + + /** + * Flat-maps the Set, returning a new Set. + * + * Similar to `set.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: T, iter: this) => Iterable, + context?: unknown + ): Set; + + /** + * Returns a new Set with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, key: T, iter: this) => value is F, + context?: unknown + ): Set; + filter( + predicate: (value: T, key: T, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new Set with the values for which the `predicate` function + * returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: T, key: T, iter: this) => value is F, + context?: C + ): [Set, Set]; + partition( + predicate: (this: C, value: T, key: T, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * Returns an OrderedSet of the same type which includes the same entries, + * stably sorted by using a `comparator`. + * + * If a `comparator` is not provided, a default comparator uses `<` and `>`. + * + * `comparator(valueA, valueB)`: + * + * * Returns `0` if the elements should not be swapped. + * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` + * * Returns `1` (or any positive number) if `valueA` comes after `valueB` + * * Alternatively, can return a value of the `PairSorting` enum type + * * Is pure, i.e. it must always return the same value for the same pair + * of values. + * + * + * ```js + * const { Set } = require('immutable') + * Set(['b', 'a', 'c']).sort((a, b) => { + * if (a < b) { return -1; } + * if (a > b) { return 1; } + * if (a === b) { return 0; } + * }); + * // OrderedSet { "a":, "b", "c" } + * ``` + * + * Note: `sort()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sort(comparator?: Comparator): this & OrderedSet; + + /** + * Like `sort`, but also accepts a `comparatorValueMapper` which allows for + * sorting by more sophisticated means: + * + * + * ```js + * const { Set } = require('immutable') + * const beattles = Set([ + * { name: "Lennon" }, + * { name: "McCartney" }, + * { name: "Harrison" }, + * { name: "Starr" }, + * ]); + * beattles.sortBy(member => member.name); + * ``` + * + * Note: `sortBy()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sortBy( + comparatorValueMapper: (value: T, key: T, iter: this) => C, + comparator?: (valueA: C, valueB: C) => number + ): this & OrderedSet; + } + + /** + * A type of Set that has the additional guarantee that the iteration order of + * values will be the order in which they were `add`ed. + * + * The iteration behavior of OrderedSet is the same as native ES6 Set. + * + * Note that `OrderedSet` are more expensive than non-ordered `Set` and may + * consume more memory. `OrderedSet#add` is amortized O(log32 N), but not + * stable. + */ + namespace OrderedSet { + /** + * True if the provided value is an OrderedSet. + */ + function isOrderedSet( + maybeOrderedSet: unknown + ): maybeOrderedSet is OrderedSet; + + /** + * Creates a new OrderedSet containing `values`. + */ + function of(...values: Array): OrderedSet; + + /** + * `OrderedSet.fromKeys()` creates a new immutable OrderedSet containing + * the keys from this Collection or JavaScript Object. + */ + function fromKeys(iter: Collection.Keyed): OrderedSet; + function fromKeys(iter: Collection): OrderedSet; + function fromKeys(obj: { [key: string]: unknown }): OrderedSet; + } + + /** + * Create a new immutable OrderedSet containing the values of the provided + * collection-like. + * + * Note: `OrderedSet` is a factory function and not a class, and does not use + * the `new` keyword during construction. + */ + function OrderedSet( + collection?: Iterable | ArrayLike + ): OrderedSet; + + interface OrderedSet extends Set, OrderedCollection { + /** + * The number of items in this OrderedSet. + */ + readonly size: number; + + /** + * Returns an OrderedSet including any value from `collections` that does + * not already exist in this OrderedSet. + * + * Note: `union` can be used in `withMutations`. + * @alias merge + * @alias concat + */ + union(...collections: Array>): OrderedSet; + merge(...collections: Array>): OrderedSet; + concat(...collections: Array>): OrderedSet; + + // Sequence algorithms + + /** + * Returns a new Set with values passed through a + * `mapper` function. + * + * OrderedSet([ 1, 2 ]).map(x => 10 * x) + * // OrderedSet [10, 20] + */ + map( + mapper: (value: T, key: T, iter: this) => M, + context?: unknown + ): OrderedSet; + + /** + * Flat-maps the OrderedSet, returning a new OrderedSet. + * + * Similar to `set.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: T, iter: this) => Iterable, + context?: unknown + ): OrderedSet; + + /** + * Returns a new OrderedSet with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, key: T, iter: this) => value is F, + context?: unknown + ): OrderedSet; + filter( + predicate: (value: T, key: T, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new OrderedSet with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: T, key: T, iter: this) => value is F, + context?: C + ): [OrderedSet, OrderedSet]; + partition( + predicate: (this: C, value: T, key: T, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * Returns an OrderedSet of the same type "zipped" with the provided + * collections. + * + * Like `zipWith`, but using the default `zipper`: creating an `Array`. + * + * ```js + * const a = OrderedSet([ 1, 2, 3 ]) + * const b = OrderedSet([ 4, 5, 6 ]) + * const c = a.zip(b) + * // OrderedSet [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] + * ``` + */ + zip(other: Collection): OrderedSet<[T, U]>; + zip( + other1: Collection, + other2: Collection + ): OrderedSet<[T, U, V]>; + zip( + ...collections: Array> + ): OrderedSet; + + /** + * Returns a OrderedSet of the same type "zipped" with the provided + * collections. + * + * Unlike `zip`, `zipAll` continues zipping until the longest collection is + * exhausted. Missing values from shorter collections are filled with `undefined`. + * + * ```js + * const a = OrderedSet([ 1, 2 ]); + * const b = OrderedSet([ 3, 4, 5 ]); + * const c = a.zipAll(b); // OrderedSet [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ] + * ``` + * + * Note: Since zipAll will return a collection as large as the largest + * input, some results may contain undefined values. TypeScript cannot + * account for these without cases (as of v2.5). + */ + zipAll(other: Collection): OrderedSet<[T, U]>; + zipAll( + other1: Collection, + other2: Collection + ): OrderedSet<[T, U, V]>; + zipAll( + ...collections: Array> + ): OrderedSet; + + /** + * Returns an OrderedSet of the same type "zipped" with the provided + * collections by using a custom `zipper` function. + * + * @see Seq.Indexed.zipWith + */ + zipWith( + zipper: (value: T, otherValue: U) => Z, + otherCollection: Collection + ): OrderedSet; + zipWith( + zipper: (value: T, otherValue: U, thirdValue: V) => Z, + otherCollection: Collection, + thirdCollection: Collection + ): OrderedSet; + zipWith( + zipper: (...values: Array) => Z, + ...collections: Array> + ): OrderedSet; + } + + /** + * Stacks are indexed collections which support very efficient O(1) addition + * and removal from the front using `unshift(v)` and `shift()`. + * + * For familiarity, Stack also provides `push(v)`, `pop()`, and `peek()`, but + * be aware that they also operate on the front of the list, unlike List or + * a JavaScript Array. + * + * Note: `reverse()` or any inherent reverse traversal (`reduceRight`, + * `lastIndexOf`, etc.) is not efficient with a Stack. + * + * Stack is implemented with a Single-Linked List. + */ + namespace Stack { + /** + * True if the provided value is a Stack + */ + function isStack(maybeStack: unknown): maybeStack is Stack; + + /** + * Creates a new Stack containing `values`. + */ + function of(...values: Array): Stack; + } + + /** + * Create a new immutable Stack containing the values of the provided + * collection-like. + * + * The iteration order of the provided collection is preserved in the + * resulting `Stack`. + * + * Note: `Stack` is a factory function and not a class, and does not use the + * `new` keyword during construction. + */ + function Stack(collection?: Iterable | ArrayLike): Stack; + + interface Stack extends Collection.Indexed { + /** + * The number of items in this Stack. + */ + readonly size: number; + + // Reading values + + /** + * Alias for `Stack.first()`. + */ + peek(): T | undefined; + + // Persistent changes + + /** + * Returns a new Stack with 0 size and no values. + * + * Note: `clear` can be used in `withMutations`. + */ + clear(): Stack; + + /** + * Returns a new Stack with the provided `values` prepended, shifting other + * values ahead to higher indices. + * + * This is very efficient for Stack. + * + * Note: `unshift` can be used in `withMutations`. + */ + unshift(...values: Array): Stack; + + /** + * Like `Stack#unshift`, but accepts a collection rather than varargs. + * + * Note: `unshiftAll` can be used in `withMutations`. + */ + unshiftAll(iter: Iterable): Stack; + + /** + * Returns a new Stack with a size ones less than this Stack, excluding + * the first item in this Stack, shifting all other values to a lower index. + * + * Note: this differs from `Array#shift` because it returns a new + * Stack rather than the removed value. Use `first()` or `peek()` to get the + * first value in this Stack. + * + * Note: `shift` can be used in `withMutations`. + */ + shift(): Stack; + + /** + * Alias for `Stack#unshift` and is not equivalent to `List#push`. + */ + push(...values: Array): Stack; + + /** + * Alias for `Stack#unshiftAll`. + */ + pushAll(iter: Iterable): Stack; + + /** + * Alias for `Stack#shift` and is not equivalent to `List#pop`. + */ + pop(): Stack; + + // Transient changes + + /** + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Check the documentation for each method to see if it + * mentions being safe to use in `withMutations`. + * + * @see `Map#withMutations` + */ + withMutations(mutator: (mutable: this) => unknown): this; + + /** + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Check the documentation for each method to see if it + * mentions being safe to use in `withMutations`. + * + * @see `Map#asMutable` + */ + asMutable(): this; + + /** + * @see `Map#wasAltered` + */ + wasAltered(): boolean; + + /** + * @see `Map#asImmutable` + */ + asImmutable(): this; + + // Sequence algorithms + + /** + * Returns a new Stack with other collections concatenated to this one. + */ + concat(...valuesOrCollections: Array | C>): Stack; + + /** + * Returns a new Stack with values passed through a + * `mapper` function. + * + * Stack([ 1, 2 ]).map(x => 10 * x) + * // Stack [ 10, 20 ] + * + * Note: `map()` always returns a new instance, even if it produced the same + * value at every step. + */ + map( + mapper: (value: T, key: number, iter: this) => M, + context?: unknown + ): Stack; + + /** + * Flat-maps the Stack, returning a new Stack. + * + * Similar to `stack.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: number, iter: this) => Iterable, + context?: unknown + ): Stack; + + /** + * Returns a new Set with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, index: number, iter: this) => value is F, + context?: unknown + ): Set; + filter( + predicate: (value: T, index: number, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a Stack "zipped" with the provided collections. + * + * Like `zipWith`, but using the default `zipper`: creating an `Array`. + * + * ```js + * const a = Stack([ 1, 2, 3 ]); + * const b = Stack([ 4, 5, 6 ]); + * const c = a.zip(b); // Stack [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] + * ``` + */ + zip(other: Collection): Stack<[T, U]>; + zip( + other: Collection, + other2: Collection + ): Stack<[T, U, V]>; + zip(...collections: Array>): Stack; + + /** + * Returns a Stack "zipped" with the provided collections. + * + * Unlike `zip`, `zipAll` continues zipping until the longest collection is + * exhausted. Missing values from shorter collections are filled with `undefined`. + * + * ```js + * const a = Stack([ 1, 2 ]); + * const b = Stack([ 3, 4, 5 ]); + * const c = a.zipAll(b); // Stack [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ] + * ``` + * + * Note: Since zipAll will return a collection as large as the largest + * input, some results may contain undefined values. TypeScript cannot + * account for these without cases (as of v2.5). + */ + zipAll(other: Collection): Stack<[T, U]>; + zipAll( + other: Collection, + other2: Collection + ): Stack<[T, U, V]>; + zipAll(...collections: Array>): Stack; + + /** + * Returns a Stack "zipped" with the provided collections by using a + * custom `zipper` function. + * + * ```js + * const a = Stack([ 1, 2, 3 ]); + * const b = Stack([ 4, 5, 6 ]); + * const c = a.zipWith((a, b) => a + b, b); + * // Stack [ 5, 7, 9 ] + * ``` + */ + zipWith( + zipper: (value: T, otherValue: U) => Z, + otherCollection: Collection + ): Stack; + zipWith( + zipper: (value: T, otherValue: U, thirdValue: V) => Z, + otherCollection: Collection, + thirdCollection: Collection + ): Stack; + zipWith( + zipper: (...values: Array) => Z, + ...collections: Array> + ): Stack; + } + + /** + * Returns a Seq.Indexed of numbers from `start` (inclusive) to `end` + * (exclusive), by `step`, where `start` defaults to 0, `step` to 1, and `end` to + * infinity. When `start` is equal to `end`, returns empty range. + * + * Note: `Range` is a factory function and not a class, and does not use the + * `new` keyword during construction. + * + * ```js + * const { Range } = require('immutable') + * Range() // [ 0, 1, 2, 3, ... ] + * Range(10) // [ 10, 11, 12, 13, ... ] + * Range(10, 15) // [ 10, 11, 12, 13, 14 ] + * Range(10, 30, 5) // [ 10, 15, 20, 25 ] + * Range(30, 10, 5) // [ 30, 25, 20, 15 ] + * Range(30, 30, 5) // [] + * ``` + */ + function Range( + start: number, + end: number, + step?: number + ): Seq.Indexed; + + /** + * Returns a Seq.Indexed of `value` repeated `times` times. When `times` is + * not defined, returns an infinite `Seq` of `value`. + * + * Note: `Repeat` is a factory function and not a class, and does not use the + * `new` keyword during construction. + * + * ```js + * const { Repeat } = require('immutable') + * Repeat('foo') // [ 'foo', 'foo', 'foo', ... ] + * Repeat('bar', 4) // [ 'bar', 'bar', 'bar', 'bar' ] + * ``` + */ + function Repeat(value: T, times?: number): Seq.Indexed; + + /** + * A record is similar to a JS object, but enforces a specific set of allowed + * string keys, and has default values. + * + * The `Record()` function produces new Record Factories, which when called + * create Record instances. + * + * ```js + * const { Record } = require('immutable') + * const ABRecord = Record({ a: 1, b: 2 }) + * const myRecord = ABRecord({ b: 3 }) + * ``` + * + * Records always have a value for the keys they define. `remove`ing a key + * from a record simply resets it to the default value for that key. + * + * ```js + * myRecord.get('a') // 1 + * myRecord.get('b') // 3 + * const myRecordWithoutB = myRecord.remove('b') + * myRecordWithoutB.get('b') // 2 + * ``` + * + * Values provided to the constructor not found in the Record type will + * be ignored. For example, in this case, ABRecord is provided a key "x" even + * though only "a" and "b" have been defined. The value for "x" will be + * ignored for this record. + * + * ```js + * const myRecord = ABRecord({ b: 3, x: 10 }) + * myRecord.get('x') // undefined + * ``` + * + * Because Records have a known set of string keys, property get access works + * as expected, however property sets will throw an Error. + * + * Note: IE8 does not support property access. Only use `get()` when + * supporting IE8. + * + * ```js + * myRecord.b // 3 + * myRecord.b = 5 // throws Error + * ``` + * + * Record Types can be extended as well, allowing for custom methods on your + * Record. This is not a common pattern in functional environments, but is in + * many JS programs. + * + * However Record Types are more restricted than typical JavaScript classes. + * They do not use a class constructor, which also means they cannot use + * class properties (since those are technically part of a constructor). + * + * While Record Types can be syntactically created with the JavaScript `class` + * form, the resulting Record function is actually a factory function, not a + * class constructor. Even though Record Types are not classes, JavaScript + * currently requires the use of `new` when creating new Record instances if + * they are defined as a `class`. + * + * ``` + * class ABRecord extends Record({ a: 1, b: 2 }) { + * getAB() { + * return this.a + this.b; + * } + * } + * + * var myRecord = new ABRecord({b: 3}) + * myRecord.getAB() // 4 + * ``` + * + * + * **Flow Typing Records:** + * + * Immutable.js exports two Flow types designed to make it easier to use + * Records with flow typed code, `RecordOf` and `RecordFactory`. + * + * When defining a new kind of Record factory function, use a flow type that + * describes the values the record contains along with `RecordFactory`. + * To type instances of the Record (which the factory function returns), + * use `RecordOf`. + * + * Typically, new Record definitions will export both the Record factory + * function as well as the Record instance type for use in other code. + * + * ```js + * import type { RecordFactory, RecordOf } from 'immutable'; + * + * // Use RecordFactory for defining new Record factory functions. + * type Point3DProps = { x: number, y: number, z: number }; + * const defaultValues: Point3DProps = { x: 0, y: 0, z: 0 }; + * const makePoint3D: RecordFactory = Record(defaultValues); + * export makePoint3D; + * + * // Use RecordOf for defining new instances of that Record. + * export type Point3D = RecordOf; + * const some3DPoint: Point3D = makePoint3D({ x: 10, y: 20, z: 30 }); + * ``` + * + * **Flow Typing Record Subclasses:** + * + * Records can be subclassed as a means to add additional methods to Record + * instances. This is generally discouraged in favor of a more functional API, + * since Subclasses have some minor overhead. However the ability to create + * a rich API on Record types can be quite valuable. + * + * When using Flow to type Subclasses, do not use `RecordFactory`, + * instead apply the props type when subclassing: + * + * ```js + * type PersonProps = {name: string, age: number}; + * const defaultValues: PersonProps = {name: 'Aristotle', age: 2400}; + * const PersonRecord = Record(defaultValues); + * class Person extends PersonRecord { + * getName(): string { + * return this.get('name') + * } + * + * setName(name: string): this { + * return this.set('name', name); + * } + * } + * ``` + * + * **Choosing Records vs plain JavaScript objects** + * + * Records offer a persistently immutable alternative to plain JavaScript + * objects, however they're not required to be used within Immutable.js + * collections. In fact, the deep-access and deep-updating functions + * like `getIn()` and `setIn()` work with plain JavaScript Objects as well. + * + * Deciding to use Records or Objects in your application should be informed + * by the tradeoffs and relative benefits of each: + * + * - *Runtime immutability*: plain JS objects may be carefully treated as + * immutable, however Record instances will *throw* if attempted to be + * mutated directly. Records provide this additional guarantee, however at + * some marginal runtime cost. While JS objects are mutable by nature, the + * use of type-checking tools like [Flow](https://medium.com/@gcanti/immutability-with-flow-faa050a1aef4) + * can help gain confidence in code written to favor immutability. + * + * - *Value equality*: Records use value equality when compared with `is()` + * or `record.equals()`. That is, two Records with the same keys and values + * are equal. Plain objects use *reference equality*. Two objects with the + * same keys and values are not equal since they are different objects. + * This is important to consider when using objects as keys in a `Map` or + * values in a `Set`, which use equality when retrieving values. + * + * - *API methods*: Records have a full featured API, with methods like + * `.getIn()`, and `.equals()`. These can make working with these values + * easier, but comes at the cost of not allowing keys with those names. + * + * - *Default values*: Records provide default values for every key, which + * can be useful when constructing Records with often unchanging values. + * However default values can make using Flow and TypeScript more laborious. + * + * - *Serialization*: Records use a custom internal representation to + * efficiently store and update their values. Converting to and from this + * form isn't free. If converting Records to plain objects is common, + * consider sticking with plain objects to begin with. + */ + namespace Record { + /** + * True if `maybeRecord` is an instance of a Record. + */ + function isRecord(maybeRecord: unknown): maybeRecord is Record; + + /** + * Records allow passing a second parameter to supply a descriptive name + * that appears when converting a Record to a string or in any error + * messages. A descriptive name for any record can be accessed by using this + * method. If one was not provided, the string "Record" is returned. + * + * ```js + * const { Record } = require('immutable') + * const Person = Record({ + * name: null + * }, 'Person') + * + * var me = Person({ name: 'My Name' }) + * me.toString() // "Person { "name": "My Name" }" + * Record.getDescriptiveName(me) // "Person" + * ``` + */ + function getDescriptiveName( + record: RecordOf + ): string; + + /** + * A Record.Factory is created by the `Record()` function. Record instances + * are created by passing it some of the accepted values for that Record + * type: + * + * + * ```js + * // makePerson is a Record Factory function + * const makePerson = Record({ name: null, favoriteColor: 'unknown' }); + * + * // alan is a Record instance + * const alan = makePerson({ name: 'Alan' }); + * ``` + * + * Note that Record Factories return `Record & Readonly`, + * this allows use of both the Record instance API, and direct property + * access on the resulting instances: + * + * + * ```js + * // Use the Record API + * console.log('Record API: ' + alan.get('name')) + * + * // Or direct property access (Readonly) + * console.log('property access: ' + alan.name) + * ``` + * + * **Flow Typing Records:** + * + * Use the `RecordFactory` Flow type to get high quality type checking of + * Records: + * + * ```js + * import type { RecordFactory, RecordOf } from 'immutable'; + * + * // Use RecordFactory for defining new Record factory functions. + * type PersonProps = { name: ?string, favoriteColor: string }; + * const makePerson: RecordFactory = Record({ name: null, favoriteColor: 'unknown' }); + * + * // Use RecordOf for defining new instances of that Record. + * type Person = RecordOf; + * const alan: Person = makePerson({ name: 'Alan' }); + * ``` + */ + namespace Factory {} + + interface Factory { + ( + values?: Partial | Iterable<[string, unknown]> + ): RecordOf; + new ( + values?: Partial | Iterable<[string, unknown]> + ): RecordOf; + + /** + * The name provided to `Record(values, name)` can be accessed with + * `displayName`. + */ + displayName: string; + } + + function Factory( + values?: Partial | Iterable<[string, unknown]> + ): RecordOf; + } + + /** + * Unlike other types in Immutable.js, the `Record()` function creates a new + * Record Factory, which is a function that creates Record instances. + * + * See above for examples of using `Record()`. + * + * Note: `Record` is a factory function and not a class, and does not use the + * `new` keyword during construction. + */ + function Record( + defaultValues: TProps, + name?: string + ): Record.Factory; + + interface Record { + // Reading values + + has(key: string): key is keyof TProps & string; + + /** + * Returns the value associated with the provided key, which may be the + * default value defined when creating the Record factory function. + * + * If the requested key is not defined by this Record type, then + * notSetValue will be returned if provided. Note that this scenario would + * produce an error when using Flow or TypeScript. + */ + get(key: K, notSetValue?: unknown): TProps[K]; + get(key: string, notSetValue: T): T; + + // Reading deep values + + hasIn(keyPath: Iterable): boolean; + getIn(keyPath: Iterable): unknown; + + // Value equality + + equals(other: unknown): boolean; + hashCode(): number; + + // Persistent changes + + set(key: K, value: TProps[K]): this; + update( + key: K, + updater: (value: TProps[K]) => TProps[K] + ): this; + merge( + ...collections: Array | Iterable<[string, unknown]>> + ): this; + mergeDeep( + ...collections: Array | Iterable<[string, unknown]>> + ): this; + + mergeWith( + merger: (oldVal: unknown, newVal: unknown, key: keyof TProps) => unknown, + ...collections: Array | Iterable<[string, unknown]>> + ): this; + mergeDeepWith( + merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown, + ...collections: Array | Iterable<[string, unknown]>> + ): this; + + /** + * Returns a new instance of this Record type with the value for the + * specific key set to its default value. + * + * @alias remove + */ + delete(key: K): this; + remove(key: K): this; + + /** + * Returns a new instance of this Record type with all values set + * to their default values. + */ + clear(): this; + + // Deep persistent changes + + setIn(keyPath: Iterable, value: unknown): this; + updateIn( + keyPath: Iterable, + updater: (value: unknown) => unknown + ): this; + mergeIn(keyPath: Iterable, ...collections: Array): this; + mergeDeepIn( + keyPath: Iterable, + ...collections: Array + ): this; + + /** + * @alias removeIn + */ + deleteIn(keyPath: Iterable): this; + removeIn(keyPath: Iterable): this; + + // Conversion to JavaScript types + + /** + * Deeply converts this Record to equivalent native JavaScript Object. + * + * Note: This method may not be overridden. Objects with custom + * serialization to plain JS may override toJSON() instead. + */ + toJS(): DeepCopy; + + /** + * Shallowly converts this Record to equivalent native JavaScript Object. + */ + toJSON(): TProps; + + /** + * Shallowly converts this Record to equivalent JavaScript Object. + */ + toObject(): TProps; + + // Transient changes + + /** + * Note: Not all methods can be used on a mutable collection or within + * `withMutations`! Only `set` may be used mutatively. + * + * @see `Map#withMutations` + */ + withMutations(mutator: (mutable: this) => unknown): this; + + /** + * @see `Map#asMutable` + */ + asMutable(): this; + + /** + * @see `Map#wasAltered` + */ + wasAltered(): boolean; + + /** + * @see `Map#asImmutable` + */ + asImmutable(): this; + + // Sequence algorithms + + toSeq(): Seq.Keyed; + + [Symbol.iterator](): IterableIterator<[keyof TProps, TProps[keyof TProps]]>; + } + + /** + * RecordOf is used in TypeScript to define interfaces expecting an + * instance of record with type T. + * + * This is equivalent to an instance of a record created by a Record Factory. + */ + type RecordOf = Record & Readonly; + + /** + * `Seq` describes a lazy operation, allowing them to efficiently chain + * use of all the higher-order collection methods (such as `map` and `filter`) + * by not creating intermediate collections. + * + * **Seq is immutable** — Once a Seq is created, it cannot be + * changed, appended to, rearranged or otherwise modified. Instead, any + * mutative method called on a `Seq` will return a new `Seq`. + * + * **Seq is lazy** — `Seq` does as little work as necessary to respond to any + * method call. Values are often created during iteration, including implicit + * iteration when reducing or converting to a concrete data structure such as + * a `List` or JavaScript `Array`. + * + * For example, the following performs no work, because the resulting + * `Seq`'s values are never iterated: + * + * ```js + * const { Seq } = require('immutable') + * const oddSquares = Seq([ 1, 2, 3, 4, 5, 6, 7, 8 ]) + * .filter(x => x % 2 !== 0) + * .map(x => x * x) + * ``` + * + * Once the `Seq` is used, it performs only the work necessary. In this + * example, no intermediate arrays are ever created, filter is called three + * times, and map is only called once: + * + * ```js + * oddSquares.get(1); // 9 + * ``` + * + * Any collection can be converted to a lazy Seq with `Seq()`. + * + * + * ```js + * const { Map } = require('immutable') + * const map = Map({ a: 1, b: 2, c: 3 }) + * const lazySeq = Seq(map) + * ``` + * + * `Seq` allows for the efficient chaining of operations, allowing for the + * expression of logic that can otherwise be very tedious: + * + * ```js + * lazySeq + * .flip() + * .map(key => key.toUpperCase()) + * .flip() + * // Seq { A: 1, B: 1, C: 1 } + * ``` + * + * As well as expressing logic that would otherwise seem memory or time + * limited, for example `Range` is a special kind of Lazy sequence. + * + * + * ```js + * const { Range } = require('immutable') + * Range(1, Infinity) + * .skip(1000) + * .map(n => -n) + * .filter(n => n % 2 === 0) + * .take(2) + * .reduce((r, n) => r * n, 1) + * // 1006008 + * ``` + * + * Seq is often used to provide a rich collection API to JavaScript Object. + * + * ```js + * Seq({ x: 0, y: 1, z: 2 }).map(v => v * 2).toObject(); + * // { x: 0, y: 2, z: 4 } + * ``` + */ + + namespace Seq { + /** + * True if `maybeSeq` is a Seq, it is not backed by a concrete + * structure such as Map, List, or Set. + */ + function isSeq( + maybeSeq: unknown + ): maybeSeq is + | Seq.Indexed + | Seq.Keyed + | Seq.Set; + + /** + * `Seq` which represents key-value pairs. + */ + namespace Keyed {} + + /** + * Always returns a Seq.Keyed, if input is not keyed, expects an + * collection of [K, V] tuples. + * + * Note: `Seq.Keyed` is a conversion function and not a class, and does not + * use the `new` keyword during construction. + */ + function Keyed(collection?: Iterable<[K, V]>): Seq.Keyed; + function Keyed(obj: { [key: string]: V }): Seq.Keyed; + + interface Keyed extends Seq, Collection.Keyed { + /** + * Deeply converts this Keyed Seq to equivalent native JavaScript Object. + * + * Converts keys to Strings. + */ + toJS(): { [key in PropertyKey]: DeepCopy }; + + /** + * Shallowly converts this Keyed Seq to equivalent native JavaScript Object. + * + * Converts keys to Strings. + */ + toJSON(): { [key in PropertyKey]: V }; + + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array<[K, V]>; + + /** + * Returns itself + */ + toSeq(): this; + + /** + * Returns a new Seq with other collections concatenated to this one. + * + * All entries will be present in the resulting Seq, even if they + * have the same key. + */ + concat( + ...collections: Array> + ): Seq.Keyed; + concat( + ...collections: Array<{ [key: string]: C }> + ): Seq.Keyed; + + /** + * Returns a new Seq.Keyed with values passed through a + * `mapper` function. + * + * ```js + * const { Seq } = require('immutable') + * Seq.Keyed({ a: 1, b: 2 }).map(x => 10 * x) + * // Seq { "a": 10, "b": 20 } + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the + * same value at every step. + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): Seq.Keyed; + + /** + * @see Collection.Keyed.mapKeys + */ + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: unknown + ): Seq.Keyed; + + /** + * @see Collection.Keyed.mapEntries + */ + mapEntries( + mapper: ( + entry: [K, V], + index: number, + iter: this + ) => [KM, VM] | undefined, + context?: unknown + ): Seq.Keyed; + + /** + * Flat-maps the Seq, returning a Seq of the same type. + * + * Similar to `seq.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: unknown + ): Seq.Keyed; + + /** + * Returns a new Seq with only the entries for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: V, key: K, iter: this) => value is F, + context?: unknown + ): Seq.Keyed; + filter( + predicate: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new keyed Seq with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: V, key: K, iter: this) => value is F, + context?: C + ): [Seq.Keyed, Seq.Keyed]; + partition( + predicate: (this: C, value: V, key: K, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * @see Collection.Keyed.flip + */ + flip(): Seq.Keyed; + + [Symbol.iterator](): IterableIterator<[K, V]>; + } + + /** + * `Seq` which represents an ordered indexed list of values. + */ + namespace Indexed { + /** + * Provides an Seq.Indexed of the values provided. + */ + function of(...values: Array): Seq.Indexed; + } + + /** + * Always returns Seq.Indexed, discarding associated keys and + * supplying incrementing indices. + * + * Note: `Seq.Indexed` is a conversion function and not a class, and does + * not use the `new` keyword during construction. + */ + function Indexed( + collection?: Iterable | ArrayLike + ): Seq.Indexed; + + interface Indexed extends Seq, Collection.Indexed { + /** + * Deeply converts this Indexed Seq to equivalent native JavaScript Array. + */ + toJS(): Array>; + + /** + * Shallowly converts this Indexed Seq to equivalent native JavaScript Array. + */ + toJSON(): Array; + + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array; + + /** + * Returns itself + */ + toSeq(): this; + + /** + * Returns a new Seq with other collections concatenated to this one. + */ + concat( + ...valuesOrCollections: Array | C> + ): Seq.Indexed; + + /** + * Returns a new Seq.Indexed with values passed through a + * `mapper` function. + * + * ```js + * const { Seq } = require('immutable') + * Seq.Indexed([ 1, 2 ]).map(x => 10 * x) + * // Seq [ 10, 20 ] + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the + * same value at every step. + */ + map( + mapper: (value: T, key: number, iter: this) => M, + context?: unknown + ): Seq.Indexed; + + /** + * Flat-maps the Seq, returning a a Seq of the same type. + * + * Similar to `seq.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: number, iter: this) => Iterable, + context?: unknown + ): Seq.Indexed; + + /** + * Returns a new Seq with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, index: number, iter: this) => value is F, + context?: unknown + ): Seq.Indexed; + filter( + predicate: (value: T, index: number, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new indexed Seq with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: T, index: number, iter: this) => value is F, + context?: C + ): [Seq.Indexed, Seq.Indexed]; + partition( + predicate: (this: C, value: T, index: number, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * Returns a Seq "zipped" with the provided collections. + * + * Like `zipWith`, but using the default `zipper`: creating an `Array`. + * + * ```js + * const a = Seq([ 1, 2, 3 ]); + * const b = Seq([ 4, 5, 6 ]); + * const c = a.zip(b); // Seq [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] + * ``` + */ + zip(other: Collection): Seq.Indexed<[T, U]>; + zip( + other: Collection, + other2: Collection + ): Seq.Indexed<[T, U, V]>; + zip( + ...collections: Array> + ): Seq.Indexed; + + /** + * Returns a Seq "zipped" with the provided collections. + * + * Unlike `zip`, `zipAll` continues zipping until the longest collection is + * exhausted. Missing values from shorter collections are filled with `undefined`. + * + * ```js + * const a = Seq([ 1, 2 ]); + * const b = Seq([ 3, 4, 5 ]); + * const c = a.zipAll(b); // Seq [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ] + * ``` + */ + zipAll(other: Collection): Seq.Indexed<[T, U]>; + zipAll( + other: Collection, + other2: Collection + ): Seq.Indexed<[T, U, V]>; + zipAll( + ...collections: Array> + ): Seq.Indexed; + + /** + * Returns a Seq "zipped" with the provided collections by using a + * custom `zipper` function. + * + * ```js + * const a = Seq([ 1, 2, 3 ]); + * const b = Seq([ 4, 5, 6 ]); + * const c = a.zipWith((a, b) => a + b, b); + * // Seq [ 5, 7, 9 ] + * ``` + */ + zipWith( + zipper: (value: T, otherValue: U) => Z, + otherCollection: Collection + ): Seq.Indexed; + zipWith( + zipper: (value: T, otherValue: U, thirdValue: V) => Z, + otherCollection: Collection, + thirdCollection: Collection + ): Seq.Indexed; + zipWith( + zipper: (...values: Array) => Z, + ...collections: Array> + ): Seq.Indexed; + + [Symbol.iterator](): IterableIterator; + } + + /** + * `Seq` which represents a set of values. + * + * Because `Seq` are often lazy, `Seq.Set` does not provide the same guarantee + * of value uniqueness as the concrete `Set`. + */ + namespace Set { + /** + * Returns a Seq.Set of the provided values + */ + function of(...values: Array): Seq.Set; + } + + /** + * Always returns a Seq.Set, discarding associated indices or keys. + * + * Note: `Seq.Set` is a conversion function and not a class, and does not + * use the `new` keyword during construction. + */ + function Set(collection?: Iterable | ArrayLike): Seq.Set; + + interface Set extends Seq, Collection.Set { + /** + * Deeply converts this Set Seq to equivalent native JavaScript Array. + */ + toJS(): Array>; + + /** + * Shallowly converts this Set Seq to equivalent native JavaScript Array. + */ + toJSON(): Array; + + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array; + + /** + * Returns itself + */ + toSeq(): this; + + /** + * Returns a new Seq with other collections concatenated to this one. + * + * All entries will be present in the resulting Seq, even if they + * are duplicates. + */ + concat(...collections: Array>): Seq.Set; + + /** + * Returns a new Seq.Set with values passed through a + * `mapper` function. + * + * ```js + * Seq.Set([ 1, 2 ]).map(x => 10 * x) + * // Seq { 10, 20 } + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the + * same value at every step. + */ + map( + mapper: (value: T, key: T, iter: this) => M, + context?: unknown + ): Seq.Set; + + /** + * Flat-maps the Seq, returning a Seq of the same type. + * + * Similar to `seq.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: T, iter: this) => Iterable, + context?: unknown + ): Seq.Set; + + /** + * Returns a new Seq with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, key: T, iter: this) => value is F, + context?: unknown + ): Seq.Set; + filter( + predicate: (value: T, key: T, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new set Seq with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: T, key: T, iter: this) => value is F, + context?: C + ): [Seq.Set, Seq.Set]; + partition( + predicate: (this: C, value: T, key: T, iter: this) => unknown, + context?: C + ): [this, this]; + + [Symbol.iterator](): IterableIterator; + } + } + + /** + * Creates a Seq. + * + * Returns a particular kind of `Seq` based on the input. + * + * * If a `Seq`, that same `Seq`. + * * If an `Collection`, a `Seq` of the same kind (Keyed, Indexed, or Set). + * * If an Array-like, an `Seq.Indexed`. + * * If an Iterable Object, an `Seq.Indexed`. + * * If an Object, a `Seq.Keyed`. + * + * Note: An Iterator itself will be treated as an object, becoming a `Seq.Keyed`, + * which is usually not what you want. You should turn your Iterator Object into + * an iterable object by defining a Symbol.iterator (or @@iterator) method which + * returns `this`. + * + * Note: `Seq` is a conversion function and not a class, and does not use the + * `new` keyword during construction. + */ + function Seq>(seq: S): S; + function Seq(collection: Collection.Keyed): Seq.Keyed; + function Seq(collection: Collection.Set): Seq.Set; + function Seq( + collection: Collection.Indexed | Iterable | ArrayLike + ): Seq.Indexed; + function Seq(obj: { [key: string]: V }): Seq.Keyed; + function Seq(): Seq; + + interface Seq extends Collection { + /** + * Some Seqs can describe their size lazily. When this is the case, + * size will be an integer. Otherwise it will be undefined. + * + * For example, Seqs returned from `map()` or `reverse()` + * preserve the size of the original `Seq` while `filter()` does not. + * + * Note: `Range`, `Repeat` and `Seq`s made from `Array`s and `Object`s will + * always have a size. + */ + readonly size: number | undefined; + + // Force evaluation + + /** + * Because Sequences are lazy and designed to be chained together, they do + * not cache their results. For example, this map function is called a total + * of 6 times, as each `join` iterates the Seq of three values. + * + * var squares = Seq([ 1, 2, 3 ]).map(x => x * x) + * squares.join() + squares.join() + * + * If you know a `Seq` will be used multiple times, it may be more + * efficient to first cache it in memory. Here, the map function is called + * only 3 times. + * + * var squares = Seq([ 1, 2, 3 ]).map(x => x * x).cacheResult() + * squares.join() + squares.join() + * + * Use this method judiciously, as it must fully evaluate a Seq which can be + * a burden on memory and possibly performance. + * + * Note: after calling `cacheResult`, a Seq will always have a `size`. + */ + cacheResult(): this; + + // Sequence algorithms + + /** + * Returns a new Seq with values passed through a + * `mapper` function. + * + * ```js + * const { Seq } = require('immutable') + * Seq([ 1, 2 ]).map(x => 10 * x) + * // Seq [ 10, 20 ] + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the same + * value at every step. + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): Seq; + + /** + * Returns a new Seq with values passed through a + * `mapper` function. + * + * ```js + * const { Seq } = require('immutable') + * Seq([ 1, 2 ]).map(x => 10 * x) + * // Seq [ 10, 20 ] + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the same + * value at every step. + * Note: used only for sets. + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): Seq; + + /** + * Flat-maps the Seq, returning a Seq of the same type. + * + * Similar to `seq.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable, + context?: unknown + ): Seq; + + /** + * Flat-maps the Seq, returning a Seq of the same type. + * + * Similar to `seq.map(...).flatten(true)`. + * Note: Used only for sets. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable, + context?: unknown + ): Seq; + + /** + * Returns a new Seq with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: V, key: K, iter: this) => value is F, + context?: unknown + ): Seq; + filter( + predicate: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new Seq with the values for which the `predicate` function + * returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: V, key: K, iter: this) => value is F, + context?: C + ): [Seq, Seq]; + partition( + predicate: (this: C, value: V, key: K, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * Returns a new Sequence of the same type with other values and + * collection-like concatenated to this one. + * + * All entries will be present in the resulting Seq, even if they + * have the same key. + */ + concat(...valuesOrCollections: Array): Seq; + } + + /** + * The `Collection` is a set of (key, value) entries which can be iterated, and + * is the base class for all collections in `immutable`, allowing them to + * make use of all the Collection methods (such as `map` and `filter`). + * + * Note: A collection is always iterated in the same order, however that order + * may not always be well defined, as is the case for the `Map` and `Set`. + * + * Collection is the abstract base class for concrete data structures. It + * cannot be constructed directly. + * + * Implementations should extend one of the subclasses, `Collection.Keyed`, + * `Collection.Indexed`, or `Collection.Set`. + */ + namespace Collection { + /** + * Keyed Collections have discrete keys tied to each value. + * + * When iterating `Collection.Keyed`, each iteration will yield a `[K, V]` + * tuple, in other words, `Collection#entries` is the default iterator for + * Keyed Collections. + */ + namespace Keyed {} + + /** + * Creates a Collection.Keyed + * + * Similar to `Collection()`, however it expects collection-likes of [K, V] + * tuples if not constructed from a Collection.Keyed or JS Object. + * + * Note: `Collection.Keyed` is a conversion function and not a class, and + * does not use the `new` keyword during construction. + */ + function Keyed(collection?: Iterable<[K, V]>): Collection.Keyed; + function Keyed(obj: { [key: string]: V }): Collection.Keyed; + + interface Keyed extends Collection { + /** + * Deeply converts this Keyed collection to equivalent native JavaScript Object. + * + * Converts keys to Strings. + */ + toJS(): { [key in PropertyKey]: DeepCopy }; + + /** + * Shallowly converts this Keyed collection to equivalent native JavaScript Object. + * + * Converts keys to Strings. + */ + toJSON(): { [key in PropertyKey]: V }; + + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array<[K, V]>; + + /** + * Returns Seq.Keyed. + * @override + */ + toSeq(): Seq.Keyed; + + // Sequence functions + + /** + * Returns a new Collection.Keyed of the same type where the keys and values + * have been flipped. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ a: 'z', b: 'y' }).flip() + * // Map { "z": "a", "y": "b" } + * ``` + */ + flip(): Collection.Keyed; + + /** + * Returns a new Collection with other collections concatenated to this one. + */ + concat( + ...collections: Array> + ): Collection.Keyed; + concat( + ...collections: Array<{ [key: string]: C }> + ): Collection.Keyed; + + /** + * Returns a new Collection.Keyed with values passed through a + * `mapper` function. + * + * ```js + * const { Collection } = require('immutable') + * Collection.Keyed({ a: 1, b: 2 }).map(x => 10 * x) + * // Seq { "a": 10, "b": 20 } + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the + * same value at every step. + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): Collection.Keyed; + + /** + * Returns a new Collection.Keyed of the same type with keys passed through + * a `mapper` function. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ a: 1, b: 2 }).mapKeys(x => x.toUpperCase()) + * // Map { "A": 1, "B": 2 } + * ``` + * + * Note: `mapKeys()` always returns a new instance, even if it produced + * the same key at every step. + */ + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: unknown + ): Collection.Keyed; + + /** + * Returns a new Collection.Keyed of the same type with entries + * ([key, value] tuples) passed through a `mapper` function. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ a: 1, b: 2 }) + * .mapEntries(([ k, v ]) => [ k.toUpperCase(), v * 2 ]) + * // Map { "A": 2, "B": 4 } + * ``` + * + * Note: `mapEntries()` always returns a new instance, even if it produced + * the same entry at every step. + * + * If the mapper function returns `undefined`, then the entry will be filtered + */ + mapEntries( + mapper: ( + entry: [K, V], + index: number, + iter: this + ) => [KM, VM] | undefined, + context?: unknown + ): Collection.Keyed; + + /** + * Flat-maps the Collection, returning a Collection of the same type. + * + * Similar to `collection.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: unknown + ): Collection.Keyed; + + /** + * Returns a new Collection with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: V, key: K, iter: this) => value is F, + context?: unknown + ): Collection.Keyed; + filter( + predicate: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new keyed Collection with the values for which the + * `predicate` function returns false and another for which is returns + * true. + */ + partition( + predicate: (this: C, value: V, key: K, iter: this) => value is F, + context?: C + ): [Collection.Keyed, Collection.Keyed]; + partition( + predicate: (this: C, value: V, key: K, iter: this) => unknown, + context?: C + ): [this, this]; + + [Symbol.iterator](): IterableIterator<[K, V]>; + } + + /** + * Indexed Collections have incrementing numeric keys. They exhibit + * slightly different behavior than `Collection.Keyed` for some methods in order + * to better mirror the behavior of JavaScript's `Array`, and add methods + * which do not make sense on non-indexed Collections such as `indexOf`. + * + * Unlike JavaScript arrays, `Collection.Indexed`s are always dense. "Unset" + * indices and `undefined` indices are indistinguishable, and all indices from + * 0 to `size` are visited when iterated. + * + * All Collection.Indexed methods return re-indexed Collections. In other words, + * indices always start at 0 and increment until size. If you wish to + * preserve indices, using them as keys, convert to a Collection.Keyed by + * calling `toKeyedSeq`. + */ + namespace Indexed {} + + /** + * Creates a new Collection.Indexed. + * + * Note: `Collection.Indexed` is a conversion function and not a class, and + * does not use the `new` keyword during construction. + */ + function Indexed( + collection?: Iterable | ArrayLike + ): Collection.Indexed; + + interface Indexed extends Collection, OrderedCollection { + /** + * Deeply converts this Indexed collection to equivalent native JavaScript Array. + */ + toJS(): Array>; + + /** + * Shallowly converts this Indexed collection to equivalent native JavaScript Array. + */ + toJSON(): Array; + + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array; + + // Reading values + + /** + * Returns the value associated with the provided index, or notSetValue if + * the index is beyond the bounds of the Collection. + * + * `index` may be a negative number, which indexes back from the end of the + * Collection. `s.get(-1)` gets the last item in the Collection. + */ + get(index: number, notSetValue: NSV): T | NSV; + get(index: number): T | undefined; + + // Conversion to Seq + + /** + * Returns Seq.Indexed. + * @override + */ + toSeq(): Seq.Indexed; + + /** + * If this is a collection of [key, value] entry tuples, it will return a + * Seq.Keyed of those entries. + */ + fromEntrySeq(): Seq.Keyed; + + // Combination + + /** + * Returns a Collection of the same type with `separator` between each item + * in this Collection. + */ + interpose(separator: T): this; + + /** + * Returns a Collection of the same type with the provided `collections` + * interleaved into this collection. + * + * The resulting Collection includes the first item from each, then the + * second from each, etc. + * + * + * ```js + * const { List } = require('immutable') + * List([ 1, 2, 3 ]).interleave(List([ 'A', 'B', 'C' ])) + * // List [ 1, "A", 2, "B", 3, "C" ] + * ``` + * + * The shortest Collection stops interleave. + * + * + * ```js + * List([ 1, 2, 3 ]).interleave( + * List([ 'A', 'B' ]), + * List([ 'X', 'Y', 'Z' ]) + * ) + * // List [ 1, "A", "X", 2, "B", "Y" ] + * ``` + * + * Since `interleave()` re-indexes values, it produces a complete copy, + * which has `O(N)` complexity. + * + * Note: `interleave` *cannot* be used in `withMutations`. + */ + interleave(...collections: Array>): this; + + /** + * Splice returns a new indexed Collection by replacing a region of this + * Collection with new values. If values are not provided, it only skips the + * region to be removed. + * + * `index` may be a negative number, which indexes back from the end of the + * Collection. `s.splice(-2)` splices after the second to last item. + * + * + * ```js + * const { List } = require('immutable') + * List([ 'a', 'b', 'c', 'd' ]).splice(1, 2, 'q', 'r', 's') + * // List [ "a", "q", "r", "s", "d" ] + * ``` + * + * Since `splice()` re-indexes values, it produces a complete copy, which + * has `O(N)` complexity. + * + * Note: `splice` *cannot* be used in `withMutations`. + */ + splice(index: number, removeNum: number, ...values: Array): this; + + /** + * Returns a Collection of the same type "zipped" with the provided + * collections. + * + * Like `zipWith`, but using the default `zipper`: creating an `Array`. + * + * + * + * ```js + * const a = List([ 1, 2, 3 ]); + * const b = List([ 4, 5, 6 ]); + * const c = a.zip(b); // List [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] + * ``` + */ + zip(other: Collection): Collection.Indexed<[T, U]>; + zip( + other: Collection, + other2: Collection + ): Collection.Indexed<[T, U, V]>; + zip( + ...collections: Array> + ): Collection.Indexed; + + /** + * Returns a Collection "zipped" with the provided collections. + * + * Unlike `zip`, `zipAll` continues zipping until the longest collection is + * exhausted. Missing values from shorter collections are filled with `undefined`. + * + * ```js + * const a = List([ 1, 2 ]); + * const b = List([ 3, 4, 5 ]); + * const c = a.zipAll(b); // List [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ] + * ``` + */ + zipAll(other: Collection): Collection.Indexed<[T, U]>; + zipAll( + other: Collection, + other2: Collection + ): Collection.Indexed<[T, U, V]>; + zipAll( + ...collections: Array> + ): Collection.Indexed; + + /** + * Returns a Collection of the same type "zipped" with the provided + * collections by using a custom `zipper` function. + * + * + * ```js + * const a = List([ 1, 2, 3 ]); + * const b = List([ 4, 5, 6 ]); + * const c = a.zipWith((a, b) => a + b, b); + * // List [ 5, 7, 9 ] + * ``` + */ + zipWith( + zipper: (value: T, otherValue: U) => Z, + otherCollection: Collection + ): Collection.Indexed; + zipWith( + zipper: (value: T, otherValue: U, thirdValue: V) => Z, + otherCollection: Collection, + thirdCollection: Collection + ): Collection.Indexed; + zipWith( + zipper: (...values: Array) => Z, + ...collections: Array> + ): Collection.Indexed; + + // Search for value + + /** + * Returns the first index at which a given value can be found in the + * Collection, or -1 if it is not present. + */ + indexOf(searchValue: T): number; + + /** + * Returns the last index at which a given value can be found in the + * Collection, or -1 if it is not present. + */ + lastIndexOf(searchValue: T): number; + + /** + * Returns the first index in the Collection where a value satisfies the + * provided predicate function. Otherwise -1 is returned. + */ + findIndex( + predicate: (value: T, index: number, iter: this) => boolean, + context?: unknown + ): number; + + /** + * Returns the last index in the Collection where a value satisfies the + * provided predicate function. Otherwise -1 is returned. + */ + findLastIndex( + predicate: (value: T, index: number, iter: this) => boolean, + context?: unknown + ): number; + + // Sequence algorithms + + /** + * Returns a new Collection with other collections concatenated to this one. + */ + concat( + ...valuesOrCollections: Array | C> + ): Collection.Indexed; + + /** + * Returns a new Collection.Indexed with values passed through a + * `mapper` function. + * + * ```js + * const { Collection } = require('immutable') + * Collection.Indexed([1,2]).map(x => 10 * x) + * // Seq [ 1, 2 ] + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the + * same value at every step. + */ + map( + mapper: (value: T, key: number, iter: this) => M, + context?: unknown + ): Collection.Indexed; + + /** + * Flat-maps the Collection, returning a Collection of the same type. + * + * Similar to `collection.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: number, iter: this) => Iterable, + context?: unknown + ): Collection.Indexed; + + /** + * Returns a new Collection with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, index: number, iter: this) => value is F, + context?: unknown + ): Collection.Indexed; + filter( + predicate: (value: T, index: number, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new indexed Collection with the values for which the + * `predicate` function returns false and another for which is returns + * true. + */ + partition( + predicate: (this: C, value: T, index: number, iter: this) => value is F, + context?: C + ): [Collection.Indexed, Collection.Indexed]; + partition( + predicate: (this: C, value: T, index: number, iter: this) => unknown, + context?: C + ): [this, this]; + + [Symbol.iterator](): IterableIterator; + } + + /** + * Set Collections only represent values. They have no associated keys or + * indices. Duplicate values are possible in the lazy `Seq.Set`s, however + * the concrete `Set` Collection does not allow duplicate values. + * + * Collection methods on Collection.Set such as `map` and `forEach` will provide + * the value as both the first and second arguments to the provided function. + * + * ```js + * const { Collection } = require('immutable') + * const seq = Collection.Set([ 'A', 'B', 'C' ]) + * // Seq { "A", "B", "C" } + * seq.forEach((v, k) => + * assert.equal(v, k) + * ) + * ``` + */ + namespace Set {} + + /** + * Similar to `Collection()`, but always returns a Collection.Set. + * + * Note: `Collection.Set` is a factory function and not a class, and does + * not use the `new` keyword during construction. + */ + function Set(collection?: Iterable | ArrayLike): Collection.Set; + + interface Set extends Collection { + /** + * Deeply converts this Set collection to equivalent native JavaScript Array. + */ + toJS(): Array>; + + /** + * Shallowly converts this Set collection to equivalent native JavaScript Array. + */ + toJSON(): Array; + + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array; + + /** + * Returns Seq.Set. + * @override + */ + toSeq(): Seq.Set; + + // Sequence algorithms + + /** + * Returns a new Collection with other collections concatenated to this one. + */ + concat(...collections: Array>): Collection.Set; + + /** + * Returns a new Collection.Set with values passed through a + * `mapper` function. + * + * ``` + * Collection.Set([ 1, 2 ]).map(x => 10 * x) + * // Seq { 1, 2 } + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the + * same value at every step. + */ + map( + mapper: (value: T, key: T, iter: this) => M, + context?: unknown + ): Collection.Set; + + /** + * Flat-maps the Collection, returning a Collection of the same type. + * + * Similar to `collection.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: T, key: T, iter: this) => Iterable, + context?: unknown + ): Collection.Set; + + /** + * Returns a new Collection with only the values for which the `predicate` + * function returns true. + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: T, key: T, iter: this) => value is F, + context?: unknown + ): Collection.Set; + filter( + predicate: (value: T, key: T, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new set Collection with the values for which the + * `predicate` function returns false and another for which is returns + * true. + */ + partition( + predicate: (this: C, value: T, key: T, iter: this) => value is F, + context?: C + ): [Collection.Set, Collection.Set]; + partition( + predicate: (this: C, value: T, key: T, iter: this) => unknown, + context?: C + ): [this, this]; + + [Symbol.iterator](): IterableIterator; + } + } + + /** + * Creates a Collection. + * + * The type of Collection created is based on the input. + * + * * If an `Collection`, that same `Collection`. + * * If an Array-like, an `Collection.Indexed`. + * * If an Object with an Iterator defined, an `Collection.Indexed`. + * * If an Object, an `Collection.Keyed`. + * + * This methods forces the conversion of Objects and Strings to Collections. + * If you want to ensure that a Collection of one item is returned, use + * `Seq.of`. + * + * Note: An Iterator itself will be treated as an object, becoming a `Seq.Keyed`, + * which is usually not what you want. You should turn your Iterator Object into + * an iterable object by defining a Symbol.iterator (or @@iterator) method which + * returns `this`. + * + * Note: `Collection` is a conversion function and not a class, and does not + * use the `new` keyword during construction. + */ + function Collection>(collection: I): I; + function Collection( + collection: Iterable | ArrayLike + ): Collection.Indexed; + function Collection(obj: { + [key: string]: V; + }): Collection.Keyed; + function Collection(): Collection; + + interface Collection extends ValueObject { + // Value equality + + /** + * True if this and the other Collection have value equality, as defined + * by `Immutable.is()`. + * + * Note: This is equivalent to `Immutable.is(this, other)`, but provided to + * allow for chained expressions. + */ + equals(other: unknown): boolean; + + /** + * Computes and returns the hashed identity for this Collection. + * + * The `hashCode` of a Collection is used to determine potential equality, + * and is used when adding this to a `Set` or as a key in a `Map`, enabling + * lookup via a different instance. + * + * + * ```js + * const a = List([ 1, 2, 3 ]); + * const b = List([ 1, 2, 3 ]); + * assert.notStrictEqual(a, b); // different instances + * const set = Set([ a ]); + * assert.equal(set.has(b), true); + * ``` + * + * If two values have the same `hashCode`, they are [not guaranteed + * to be equal][Hash Collision]. If two values have different `hashCode`s, + * they must not be equal. + * + * [Hash Collision]: https://en.wikipedia.org/wiki/Collision_(computer_science) + */ + hashCode(): number; + + // Reading values + + /** + * Returns the value associated with the provided key, or notSetValue if + * the Collection does not contain this key. + * + * Note: it is possible a key may be associated with an `undefined` value, + * so if `notSetValue` is not provided and this method returns `undefined`, + * that does not guarantee the key was not found. + */ + get(key: K, notSetValue: NSV): V | NSV; + get(key: K): V | undefined; + + /** + * True if a key exists within this `Collection`, using `Immutable.is` + * to determine equality + */ + has(key: K): boolean; + + /** + * True if a value exists within this `Collection`, using `Immutable.is` + * to determine equality + * @alias contains + */ + includes(value: V): boolean; + contains(value: V): boolean; + + /** + * In case the `Collection` is not empty returns the first element of the + * `Collection`. + * In case the `Collection` is empty returns the optional default + * value if provided, if no default value is provided returns undefined. + */ + first(notSetValue: NSV): V | NSV; + first(): V | undefined; + + /** + * In case the `Collection` is not empty returns the last element of the + * `Collection`. + * In case the `Collection` is empty returns the optional default + * value if provided, if no default value is provided returns undefined. + */ + last(notSetValue: NSV): V | NSV; + last(): V | undefined; + + // Reading deep values + + /** + * Returns the value found by following a path of keys or indices through + * nested Collections. + * + * + * ```js + * const { Map, List } = require('immutable') + * const deepData = Map({ x: List([ Map({ y: 123 }) ]) }); + * deepData.getIn(['x', 0, 'y']) // 123 + * ``` + * + * Plain JavaScript Object or Arrays may be nested within an Immutable.js + * Collection, and getIn() can access those values as well: + * + * + * ```js + * const { Map, List } = require('immutable') + * const deepData = Map({ x: [ { y: 123 } ] }); + * deepData.getIn(['x', 0, 'y']) // 123 + * ``` + */ + getIn(searchKeyPath: Iterable, notSetValue?: unknown): unknown; + + /** + * True if the result of following a path of keys or indices through nested + * Collections results in a set value. + */ + hasIn(searchKeyPath: Iterable): boolean; + + // Persistent changes + + /** + * This can be very useful as a way to "chain" a normal function into a + * sequence of methods. RxJS calls this "let" and lodash calls it "thru". + * + * For example, to sum a Seq after mapping and filtering: + * + * + * ```js + * const { Seq } = require('immutable') + * + * function sum(collection) { + * return collection.reduce((sum, x) => sum + x, 0) + * } + * + * Seq([ 1, 2, 3 ]) + * .map(x => x + 1) + * .filter(x => x % 2 === 0) + * .update(sum) + * // 6 + * ``` + */ + update(updater: (value: this) => R): R; + + // Conversion to JavaScript types + + /** + * Deeply converts this Collection to equivalent native JavaScript Array or Object. + * + * `Collection.Indexed`, and `Collection.Set` become `Array`, while + * `Collection.Keyed` become `Object`, converting keys to Strings. + */ + toJS(): Array> | { [key in PropertyKey]: DeepCopy }; + + /** + * Shallowly converts this Collection to equivalent native JavaScript Array or Object. + * + * `Collection.Indexed`, and `Collection.Set` become `Array`, while + * `Collection.Keyed` become `Object`, converting keys to Strings. + */ + toJSON(): Array | { [key in PropertyKey]: V }; + + /** + * Shallowly converts this collection to an Array. + * + * `Collection.Indexed`, and `Collection.Set` produce an Array of values. + * `Collection.Keyed` produce an Array of [key, value] tuples. + */ + toArray(): Array | Array<[K, V]>; + + /** + * Shallowly converts this Collection to an Object. + * + * Converts keys to Strings. + */ + toObject(): { [key: string]: V }; + + // Conversion to Collections + + /** + * Converts this Collection to a Map, Throws if keys are not hashable. + * + * Note: This is equivalent to `Map(this.toKeyedSeq())`, but provided + * for convenience and to allow for chained expressions. + */ + toMap(): Map; + + /** + * Converts this Collection to a Map, maintaining the order of iteration. + * + * Note: This is equivalent to `OrderedMap(this.toKeyedSeq())`, but + * provided for convenience and to allow for chained expressions. + */ + toOrderedMap(): OrderedMap; + + /** + * Converts this Collection to a Set, discarding keys. Throws if values + * are not hashable. + * + * Note: This is equivalent to `Set(this)`, but provided to allow for + * chained expressions. + */ + toSet(): Set; + + /** + * Converts this Collection to a Set, maintaining the order of iteration and + * discarding keys. + * + * Note: This is equivalent to `OrderedSet(this.valueSeq())`, but provided + * for convenience and to allow for chained expressions. + */ + toOrderedSet(): OrderedSet; + + /** + * Converts this Collection to a List, discarding keys. + * + * This is similar to `List(collection)`, but provided to allow for chained + * expressions. However, when called on `Map` or other keyed collections, + * `collection.toList()` discards the keys and creates a list of only the + * values, whereas `List(collection)` creates a list of entry tuples. + * + * + * ```js + * const { Map, List } = require('immutable') + * var myMap = Map({ a: 'Apple', b: 'Banana' }) + * List(myMap) // List [ [ "a", "Apple" ], [ "b", "Banana" ] ] + * myMap.toList() // List [ "Apple", "Banana" ] + * ``` + */ + toList(): List; + + /** + * Converts this Collection to a Stack, discarding keys. Throws if values + * are not hashable. + * + * Note: This is equivalent to `Stack(this)`, but provided to allow for + * chained expressions. + */ + toStack(): Stack; + + // Conversion to Seq + + /** + * Converts this Collection to a Seq of the same kind (indexed, + * keyed, or set). + */ + toSeq(): Seq; + + /** + * Returns a Seq.Keyed from this Collection where indices are treated as keys. + * + * This is useful if you want to operate on an + * Collection.Indexed and preserve the [index, value] pairs. + * + * The returned Seq will have identical iteration order as + * this Collection. + * + * + * ```js + * const { Seq } = require('immutable') + * const indexedSeq = Seq([ 'A', 'B', 'C' ]) + * // Seq [ "A", "B", "C" ] + * indexedSeq.filter(v => v === 'B') + * // Seq [ "B" ] + * const keyedSeq = indexedSeq.toKeyedSeq() + * // Seq { 0: "A", 1: "B", 2: "C" } + * keyedSeq.filter(v => v === 'B') + * // Seq { 1: "B" } + * ``` + */ + toKeyedSeq(): Seq.Keyed; + + /** + * Returns an Seq.Indexed of the values of this Collection, discarding keys. + */ + toIndexedSeq(): Seq.Indexed; + + /** + * Returns a Seq.Set of the values of this Collection, discarding keys. + */ + toSetSeq(): Seq.Set; + + // Iterators + + /** + * An iterator of this `Collection`'s keys. + * + * Note: this will return an ES6 iterator which does not support + * Immutable.js sequence algorithms. Use `keySeq` instead, if this is + * what you want. + */ + keys(): IterableIterator; + + /** + * An iterator of this `Collection`'s values. + * + * Note: this will return an ES6 iterator which does not support + * Immutable.js sequence algorithms. Use `valueSeq` instead, if this is + * what you want. + */ + values(): IterableIterator; + + /** + * An iterator of this `Collection`'s entries as `[ key, value ]` tuples. + * + * Note: this will return an ES6 iterator which does not support + * Immutable.js sequence algorithms. Use `entrySeq` instead, if this is + * what you want. + */ + entries(): IterableIterator<[K, V]>; + + [Symbol.iterator](): IterableIterator; + + // Collections (Seq) + + /** + * Returns a new Seq.Indexed of the keys of this Collection, + * discarding values. + */ + keySeq(): Seq.Indexed; + + /** + * Returns an Seq.Indexed of the values of this Collection, discarding keys. + */ + valueSeq(): Seq.Indexed; + + /** + * Returns a new Seq.Indexed of [key, value] tuples. + */ + entrySeq(): Seq.Indexed<[K, V]>; + + // Sequence algorithms + + /** + * Returns a new Collection of the same type with values passed through a + * `mapper` function. + * + * + * ```js + * const { Collection } = require('immutable') + * Collection({ a: 1, b: 2 }).map(x => 10 * x) + * // Seq { "a": 10, "b": 20 } + * ``` + * + * Note: `map()` always returns a new instance, even if it produced the same + * value at every step. + */ + map( + mapper: (value: V, key: K, iter: this) => M, + context?: unknown + ): Collection; + + /** + * Note: used only for sets, which return Collection but are otherwise + * identical to normal `map()`. + * + * @ignore + */ + map(...args: Array): unknown; + + /** + * Returns a new Collection of the same type with only the entries for which + * the `predicate` function returns true. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ a: 1, b: 2, c: 3, d: 4}).filter(x => x % 2 === 0) + * // Map { "b": 2, "d": 4 } + * ``` + * + * Note: `filter()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filter( + predicate: (value: V, key: K, iter: this) => value is F, + context?: unknown + ): Collection; + filter( + predicate: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): this; + + /** + * Returns a new Collection of the same type with only the entries for which + * the `predicate` function returns false. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ a: 1, b: 2, c: 3, d: 4}).filterNot(x => x % 2 === 0) + * // Map { "a": 1, "c": 3 } + * ``` + * + * Note: `filterNot()` always returns a new instance, even if it results in + * not filtering out any values. + */ + filterNot( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): this; + + /** + * Returns a new Collection with the values for which the `predicate` + * function returns false and another for which is returns true. + */ + partition( + predicate: (this: C, value: V, key: K, iter: this) => value is F, + context?: C + ): [Collection, Collection]; + partition( + predicate: (this: C, value: V, key: K, iter: this) => unknown, + context?: C + ): [this, this]; + + /** + * Returns a new Collection of the same type in reverse order. + */ + reverse(): this; + + /** + * Returns a new Collection of the same type which includes the same entries, + * stably sorted by using a `comparator`. + * + * If a `comparator` is not provided, a default comparator uses `<` and `>`. + * + * `comparator(valueA, valueB)`: + * + * * Returns `0` if the elements should not be swapped. + * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` + * * Returns `1` (or any positive number) if `valueA` comes after `valueB` + * * Alternatively, can return a value of the `PairSorting` enum type + * * Is pure, i.e. it must always return the same value for the same pair + * of values. + * + * When sorting collections which have no defined order, their ordered + * equivalents will be returned. e.g. `map.sort()` returns OrderedMap. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ "c": 3, "a": 1, "b": 2 }).sort((a, b) => { + * if (a < b) { return -1; } + * if (a > b) { return 1; } + * if (a === b) { return 0; } + * }); + * // OrderedMap { "a": 1, "b": 2, "c": 3 } + * ``` + * + * Note: `sort()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sort(comparator?: Comparator): this; + + /** + * Like `sort`, but also accepts a `comparatorValueMapper` which allows for + * sorting by more sophisticated means: + * + * + * ```js + * const { Map } = require('immutable') + * const beattles = Map({ + * John: { name: "Lennon" }, + * Paul: { name: "McCartney" }, + * George: { name: "Harrison" }, + * Ringo: { name: "Starr" }, + * }); + * beattles.sortBy(member => member.name); + * ``` + * + * Note: `sortBy()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sortBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: Comparator + ): this; + + /** + * Returns a `Map` of `Collection`, grouped by the return + * value of the `grouper` function. + * + * Note: This is always an eager operation. + * + * + * ```js + * const { List, Map } = require('immutable') + * const listOfMaps = List([ + * Map({ v: 0 }), + * Map({ v: 1 }), + * Map({ v: 1 }), + * Map({ v: 0 }), + * Map({ v: 2 }) + * ]) + * const groupsOfMaps = listOfMaps.groupBy(x => x.get('v')) + * // Map { + * // 0: List [ Map{ "v": 0 }, Map { "v": 0 } ], + * // 1: List [ Map{ "v": 1 }, Map { "v": 1 } ], + * // 2: List [ Map{ "v": 2 } ], + * // } + * ``` + */ + groupBy( + grouper: (value: V, key: K, iter: this) => G, + context?: unknown + ): Map; + + // Side effects + + /** + * The `sideEffect` is executed for every entry in the Collection. + * + * Unlike `Array#forEach`, if any call of `sideEffect` returns + * `false`, the iteration will stop. Returns the number of entries iterated + * (including the last iteration which returned false). + */ + forEach( + sideEffect: (value: V, key: K, iter: this) => unknown, + context?: unknown + ): number; + + // Creating subsets + + /** + * Returns a new Collection of the same type representing a portion of this + * Collection from start up to but not including end. + * + * If begin is negative, it is offset from the end of the Collection. e.g. + * `slice(-2)` returns a Collection of the last two entries. If it is not + * provided the new Collection will begin at the beginning of this Collection. + * + * If end is negative, it is offset from the end of the Collection. e.g. + * `slice(0, -1)` returns a Collection of everything but the last entry. If + * it is not provided, the new Collection will continue through the end of + * this Collection. + * + * If the requested slice is equivalent to the current Collection, then it + * will return itself. + */ + slice(begin?: number, end?: number): this; + + /** + * Returns a new Collection of the same type containing all entries except + * the first. + */ + rest(): this; + + /** + * Returns a new Collection of the same type containing all entries except + * the last. + */ + butLast(): this; + + /** + * Returns a new Collection of the same type which excludes the first `amount` + * entries from this Collection. + */ + skip(amount: number): this; + + /** + * Returns a new Collection of the same type which excludes the last `amount` + * entries from this Collection. + */ + skipLast(amount: number): this; + + /** + * Returns a new Collection of the same type which includes entries starting + * from when `predicate` first returns false. + * + * + * ```js + * const { List } = require('immutable') + * List([ 'dog', 'frog', 'cat', 'hat', 'god' ]) + * .skipWhile(x => x.match(/g/)) + * // List [ "cat", "hat", "god" ] + * ``` + */ + skipWhile( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): this; + + /** + * Returns a new Collection of the same type which includes entries starting + * from when `predicate` first returns true. + * + * + * ```js + * const { List } = require('immutable') + * List([ 'dog', 'frog', 'cat', 'hat', 'god' ]) + * .skipUntil(x => x.match(/hat/)) + * // List [ "hat", "god" ] + * ``` + */ + skipUntil( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): this; + + /** + * Returns a new Collection of the same type which includes the first `amount` + * entries from this Collection. + */ + take(amount: number): this; + + /** + * Returns a new Collection of the same type which includes the last `amount` + * entries from this Collection. + */ + takeLast(amount: number): this; + + /** + * Returns a new Collection of the same type which includes entries from this + * Collection as long as the `predicate` returns true. + * + * + * ```js + * const { List } = require('immutable') + * List([ 'dog', 'frog', 'cat', 'hat', 'god' ]) + * .takeWhile(x => x.match(/o/)) + * // List [ "dog", "frog" ] + * ``` + */ + takeWhile( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): this; + + /** + * Returns a new Collection of the same type which includes entries from this + * Collection as long as the `predicate` returns false. + * + * + * ```js + * const { List } = require('immutable') + * List([ 'dog', 'frog', 'cat', 'hat', 'god' ]) + * .takeUntil(x => x.match(/at/)) + * // List [ "dog", "frog" ] + * ``` + */ + takeUntil( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): this; + + // Combination + + /** + * Returns a new Collection of the same type with other values and + * collection-like concatenated to this one. + * + * For Seqs, all entries will be present in the resulting Seq, even if they + * have the same key. + */ + concat( + ...valuesOrCollections: Array + ): Collection; + + /** + * Flattens nested Collections. + * + * Will deeply flatten the Collection by default, returning a Collection of the + * same type, but a `depth` can be provided in the form of a number or + * boolean (where true means to shallowly flatten one level). A depth of 0 + * (or shallow: false) will deeply flatten. + * + * Flattens only others Collection, not Arrays or Objects. + * + * Note: `flatten(true)` operates on Collection> and + * returns Collection + */ + flatten(depth?: number): Collection; + flatten(shallow?: boolean): Collection; + + /** + * Flat-maps the Collection, returning a Collection of the same type. + * + * Similar to `collection.map(...).flatten(true)`. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable, + context?: unknown + ): Collection; + + /** + * Flat-maps the Collection, returning a Collection of the same type. + * + * Similar to `collection.map(...).flatten(true)`. + * Used for Dictionaries only. + */ + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: unknown + ): Collection; + + // Reducing a value + + /** + * Reduces the Collection to a value by calling the `reducer` for every entry + * in the Collection and passing along the reduced value. + * + * If `initialReduction` is not provided, the first item in the + * Collection will be used. + * + * @see `Array#reduce`. + */ + reduce( + reducer: (reduction: R, value: V, key: K, iter: this) => R, + initialReduction: R, + context?: unknown + ): R; + reduce( + reducer: (reduction: V | R, value: V, key: K, iter: this) => R + ): R; + + /** + * Reduces the Collection in reverse (from the right side). + * + * Note: Similar to this.reverse().reduce(), and provided for parity + * with `Array#reduceRight`. + */ + reduceRight( + reducer: (reduction: R, value: V, key: K, iter: this) => R, + initialReduction: R, + context?: unknown + ): R; + reduceRight( + reducer: (reduction: V | R, value: V, key: K, iter: this) => R + ): R; + + /** + * True if `predicate` returns true for all entries in the Collection. + */ + every( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): boolean; + + /** + * True if `predicate` returns true for any entry in the Collection. + */ + some( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): boolean; + + /** + * Joins values together as a string, inserting a separator between each. + * The default separator is `","`. + */ + join(separator?: string): string; + + /** + * Returns true if this Collection includes no values. + * + * For some lazy `Seq`, `isEmpty` might need to iterate to determine + * emptiness. At most one iteration will occur. + */ + isEmpty(): boolean; + + /** + * Returns the size of this Collection. + * + * Regardless of if this Collection can describe its size lazily (some Seqs + * cannot), this method will always return the correct size. E.g. it + * evaluates a lazy `Seq` if necessary. + * + * If `predicate` is provided, then this returns the count of entries in the + * Collection for which the `predicate` returns true. + */ + count(): number; + count( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): number; + + /** + * Returns a `Seq.Keyed` of counts, grouped by the return value of + * the `grouper` function. + * + * Note: This is not a lazy operation. + */ + countBy( + grouper: (value: V, key: K, iter: this) => G, + context?: unknown + ): Map; + + // Search for value + + /** + * Returns the first value for which the `predicate` returns true. + */ + find( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown, + notSetValue?: V + ): V | undefined; + + /** + * Returns the last value for which the `predicate` returns true. + * + * Note: `predicate` will be called for each entry in reverse. + */ + findLast( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown, + notSetValue?: V + ): V | undefined; + + /** + * Returns the first [key, value] entry for which the `predicate` returns true. + */ + findEntry( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown, + notSetValue?: V + ): [K, V] | undefined; + + /** + * Returns the last [key, value] entry for which the `predicate` + * returns true. + * + * Note: `predicate` will be called for each entry in reverse. + */ + findLastEntry( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown, + notSetValue?: V + ): [K, V] | undefined; + + /** + * Returns the key for which the `predicate` returns true. + */ + findKey( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): K | undefined; + + /** + * Returns the last key for which the `predicate` returns true. + * + * Note: `predicate` will be called for each entry in reverse. + */ + findLastKey( + predicate: (value: V, key: K, iter: this) => boolean, + context?: unknown + ): K | undefined; + + /** + * Returns the key associated with the search value, or undefined. + */ + keyOf(searchValue: V): K | undefined; + + /** + * Returns the last key associated with the search value, or undefined. + */ + lastKeyOf(searchValue: V): K | undefined; + + /** + * Returns the maximum value in this collection. If any values are + * comparatively equivalent, the first one found will be returned. + * + * The `comparator` is used in the same way as `Collection#sort`. If it is not + * provided, the default comparator is `>`. + * + * When two values are considered equivalent, the first encountered will be + * returned. Otherwise, `max` will operate independent of the order of input + * as long as the comparator is commutative. The default comparator `>` is + * commutative *only* when types do not differ. + * + * If `comparator` returns 0 and either value is NaN, undefined, or null, + * that value will be returned. + */ + max(comparator?: Comparator): V | undefined; + + /** + * Like `max`, but also accepts a `comparatorValueMapper` which allows for + * comparing by more sophisticated means: + * + * + * ```js + * const { List, } = require('immutable'); + * const l = List([ + * { name: 'Bob', avgHit: 1 }, + * { name: 'Max', avgHit: 3 }, + * { name: 'Lili', avgHit: 2 } , + * ]); + * l.maxBy(i => i.avgHit); // will output { name: 'Max', avgHit: 3 } + * ``` + */ + maxBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: Comparator + ): V | undefined; + + /** + * Returns the minimum value in this collection. If any values are + * comparatively equivalent, the first one found will be returned. + * + * The `comparator` is used in the same way as `Collection#sort`. If it is not + * provided, the default comparator is `<`. + * + * When two values are considered equivalent, the first encountered will be + * returned. Otherwise, `min` will operate independent of the order of input + * as long as the comparator is commutative. The default comparator `<` is + * commutative *only* when types do not differ. + * + * If `comparator` returns 0 and either value is NaN, undefined, or null, + * that value will be returned. + */ + min(comparator?: Comparator): V | undefined; + + /** + * Like `min`, but also accepts a `comparatorValueMapper` which allows for + * comparing by more sophisticated means: + * + * + * ```js + * const { List, } = require('immutable'); + * const l = List([ + * { name: 'Bob', avgHit: 1 }, + * { name: 'Max', avgHit: 3 }, + * { name: 'Lili', avgHit: 2 } , + * ]); + * l.minBy(i => i.avgHit); // will output { name: 'Bob', avgHit: 1 } + * ``` + */ + minBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: Comparator + ): V | undefined; + + // Comparison + + /** + * True if `iter` includes every value in this Collection. + */ + isSubset(iter: Iterable): boolean; + + /** + * True if this Collection includes every value in `iter`. + */ + isSuperset(iter: Iterable): boolean; + } + + /** + * The interface to fulfill to qualify as a Value Object. + */ + interface ValueObject { + /** + * True if this and the other Collection have value equality, as defined + * by `Immutable.is()`. + * + * Note: This is equivalent to `Immutable.is(this, other)`, but provided to + * allow for chained expressions. + */ + equals(other: unknown): boolean; + + /** + * Computes and returns the hashed identity for this Collection. + * + * The `hashCode` of a Collection is used to determine potential equality, + * and is used when adding this to a `Set` or as a key in a `Map`, enabling + * lookup via a different instance. + * + * + * ```js + * const { List, Set } = require('immutable'); + * const a = List([ 1, 2, 3 ]); + * const b = List([ 1, 2, 3 ]); + * assert.notStrictEqual(a, b); // different instances + * const set = Set([ a ]); + * assert.equal(set.has(b), true); + * ``` + * + * Note: hashCode() MUST return a Uint32 number. The easiest way to + * guarantee this is to return `myHash | 0` from a custom implementation. + * + * If two values have the same `hashCode`, they are [not guaranteed + * to be equal][Hash Collision]. If two values have different `hashCode`s, + * they must not be equal. + * + * Note: `hashCode()` is not guaranteed to always be called before + * `equals()`. Most but not all Immutable.js collections use hash codes to + * organize their internal data structures, while all Immutable.js + * collections use equality during lookups. + * + * [Hash Collision]: https://en.wikipedia.org/wiki/Collision_(computer_science) + */ + hashCode(): number; + } + + /** + * Interface representing all oredered collections. + * This includes `List`, `Stack`, `Map`, `OrderedMap`, `Set`, and `OrderedSet`. + * return of `isOrdered()` return true in that case. + */ + interface OrderedCollection { + /** + * Shallowly converts this collection to an Array. + */ + toArray(): Array; + + [Symbol.iterator](): IterableIterator; + } + + /** + * Deeply converts plain JS objects and arrays to Immutable Maps and Lists. + * + * `fromJS` will convert Arrays and [array-like objects][2] to a List, and + * plain objects (without a custom prototype) to a Map. [Iterable objects][3] + * may be converted to List, Map, or Set. + * + * If a `reviver` is optionally provided, it will be called with every + * collection as a Seq (beginning with the most nested collections + * and proceeding to the top-level collection itself), along with the key + * referring to each collection and the parent JS object provided as `this`. + * For the top level, object, the key will be `""`. This `reviver` is expected + * to return a new Immutable Collection, allowing for custom conversions from + * deep JS objects. Finally, a `path` is provided which is the sequence of + * keys to this value from the starting value. + * + * `reviver` acts similarly to the [same parameter in `JSON.parse`][1]. + * + * If `reviver` is not provided, the default behavior will convert Objects + * into Maps and Arrays into Lists like so: + * + * + * ```js + * const { fromJS, isKeyed } = require('immutable') + * function (key, value) { + * return isKeyed(value) ? value.toMap() : value.toList() + * } + * ``` + * + * Accordingly, this example converts native JS data to OrderedMap and List: + * + * + * ```js + * const { fromJS, isKeyed } = require('immutable') + * fromJS({ a: {b: [10, 20, 30]}, c: 40}, function (key, value, path) { + * console.log(key, value, path) + * return isKeyed(value) ? value.toOrderedMap() : value.toList() + * }) + * + * > "b", [ 10, 20, 30 ], [ "a", "b" ] + * > "a", {b: [10, 20, 30]}, [ "a" ] + * > "", {a: {b: [10, 20, 30]}, c: 40}, [] + * ``` + * + * Keep in mind, when using JS objects to construct Immutable Maps, that + * JavaScript Object properties are always strings, even if written in a + * quote-less shorthand, while Immutable Maps accept keys of any type. + * + * + * ```js + * const { Map } = require('immutable') + * let obj = { 1: "one" }; + * Object.keys(obj); // [ "1" ] + * assert.equal(obj["1"], obj[1]); // "one" === "one" + * + * let map = Map(obj); + * assert.notEqual(map.get("1"), map.get(1)); // "one" !== undefined + * ``` + * + * Property access for JavaScript Objects first converts the key to a string, + * but since Immutable Map keys can be of any type the argument to `get()` is + * not altered. + * + * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter + * "Using the reviver parameter" + * [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects + * "Working with array-like objects" + * [3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol + * "The iterable protocol" + */ + function fromJS( + jsValue: JSValue, + reviver?: undefined + ): FromJS; + function fromJS( + jsValue: unknown, + reviver?: ( + key: string | number, + sequence: Collection.Keyed | Collection.Indexed, + path?: Array + ) => unknown + ): Collection; + + type FromJS = JSValue extends FromJSNoTransform + ? JSValue + : JSValue extends Array + ? FromJSArray + : JSValue extends object + ? FromJSObject + : unknown; + + type FromJSNoTransform = + | Collection + | number + | string + | null + | undefined; + + type FromJSArray = + JSValue extends Array ? List> : never; + + type FromJSObject = JSValue extends object + ? Map> + : never; + + /** + * Value equality check with semantics similar to `Object.is`, but treats + * Immutable `Collection`s as values, equal if the second `Collection` includes + * equivalent values. + * + * It's used throughout Immutable when checking for equality, including `Map` + * key equality and `Set` membership. + * + * + * ```js + * const { Map, is } = require('immutable') + * const map1 = Map({ a: 1, b: 1, c: 1 }) + * const map2 = Map({ a: 1, b: 1, c: 1 }) + * assert.equal(map1 !== map2, true) + * assert.equal(Object.is(map1, map2), false) + * assert.equal(is(map1, map2), true) + * ``` + * + * `is()` compares primitive types like strings and numbers, Immutable.js + * collections like `Map` and `List`, but also any custom object which + * implements `ValueObject` by providing `equals()` and `hashCode()` methods. + * + * Note: Unlike `Object.is`, `Immutable.is` assumes `0` and `-0` are the same + * value, matching the behavior of ES6 Map key equality. + */ + function is(first: unknown, second: unknown): boolean; + + /** + * The `hash()` function is an important part of how Immutable determines if + * two values are equivalent and is used to determine how to store those + * values. Provided with any value, `hash()` will return a 31-bit integer. + * + * When designing Objects which may be equal, it's important that when a + * `.equals()` method returns true, that both values `.hashCode()` method + * return the same value. `hash()` may be used to produce those values. + * + * For non-Immutable Objects that do not provide a `.hashCode()` functions + * (including plain Objects, plain Arrays, Date objects, etc), a unique hash + * value will be created for each *instance*. That is, the create hash + * represents referential equality, and not value equality for Objects. This + * ensures that if that Object is mutated over time that its hash code will + * remain consistent, allowing Objects to be used as keys and values in + * Immutable.js collections. + * + * Note that `hash()` attempts to balance between speed and avoiding + * collisions, however it makes no attempt to produce secure hashes. + * + * *New in Version 4.0* + */ + function hash(value: unknown): number; + + /** + * True if `maybeImmutable` is an Immutable Collection or Record. + * + * Note: Still returns true even if the collections is within a `withMutations()`. + * + * + * ```js + * const { isImmutable, Map, List, Stack } = require('immutable'); + * isImmutable([]); // false + * isImmutable({}); // false + * isImmutable(Map()); // true + * isImmutable(List()); // true + * isImmutable(Stack()); // true + * isImmutable(Map().asMutable()); // true + * ``` + */ + function isImmutable( + maybeImmutable: unknown + ): maybeImmutable is Collection; + + /** + * True if `maybeCollection` is a Collection, or any of its subclasses. + * + * + * ```js + * const { isCollection, Map, List, Stack } = require('immutable'); + * isCollection([]); // false + * isCollection({}); // false + * isCollection(Map()); // true + * isCollection(List()); // true + * isCollection(Stack()); // true + * ``` + */ + function isCollection( + maybeCollection: unknown + ): maybeCollection is Collection; + + /** + * True if `maybeKeyed` is a Collection.Keyed, or any of its subclasses. + * + * + * ```js + * const { isKeyed, Map, List, Stack } = require('immutable'); + * isKeyed([]); // false + * isKeyed({}); // false + * isKeyed(Map()); // true + * isKeyed(List()); // false + * isKeyed(Stack()); // false + * ``` + */ + function isKeyed( + maybeKeyed: unknown + ): maybeKeyed is Collection.Keyed; + + /** + * True if `maybeIndexed` is a Collection.Indexed, or any of its subclasses. + * + * + * ```js + * const { isIndexed, Map, List, Stack, Set } = require('immutable'); + * isIndexed([]); // false + * isIndexed({}); // false + * isIndexed(Map()); // false + * isIndexed(List()); // true + * isIndexed(Stack()); // true + * isIndexed(Set()); // false + * ``` + */ + function isIndexed( + maybeIndexed: unknown + ): maybeIndexed is Collection.Indexed; + + /** + * True if `maybeAssociative` is either a Keyed or Indexed Collection. + * + * + * ```js + * const { isAssociative, Map, List, Stack, Set } = require('immutable'); + * isAssociative([]); // false + * isAssociative({}); // false + * isAssociative(Map()); // true + * isAssociative(List()); // true + * isAssociative(Stack()); // true + * isAssociative(Set()); // false + * ``` + */ + function isAssociative( + maybeAssociative: unknown + ): maybeAssociative is + | Collection.Keyed + | Collection.Indexed; + + /** + * True if `maybeOrdered` is a Collection where iteration order is well + * defined. True for Collection.Indexed as well as OrderedMap and OrderedSet. + * + * + * ```js + * const { isOrdered, Map, OrderedMap, List, Set } = require('immutable'); + * isOrdered([]); // false + * isOrdered({}); // false + * isOrdered(Map()); // false + * isOrdered(OrderedMap()); // true + * isOrdered(List()); // true + * isOrdered(Set()); // false + * ``` + */ + function isOrdered( + maybeOrdered: Iterable + ): maybeOrdered is OrderedCollection; + function isOrdered( + maybeOrdered: unknown + ): maybeOrdered is OrderedCollection; + + /** + * True if `maybeValue` is a JavaScript Object which has *both* `equals()` + * and `hashCode()` methods. + * + * Any two instances of *value objects* can be compared for value equality with + * `Immutable.is()` and can be used as keys in a `Map` or members in a `Set`. + */ + function isValueObject(maybeValue: unknown): maybeValue is ValueObject; + + /** + * True if `maybeSeq` is a Seq. + */ + function isSeq( + maybeSeq: unknown + ): maybeSeq is + | Seq.Indexed + | Seq.Keyed + | Seq.Set; + + /** + * True if `maybeList` is a List. + */ + function isList(maybeList: unknown): maybeList is List; + + /** + * True if `maybeMap` is a Map. + * + * Also true for OrderedMaps. + */ + function isMap(maybeMap: unknown): maybeMap is Map; + + /** + * True if `maybeOrderedMap` is an OrderedMap. + */ + function isOrderedMap( + maybeOrderedMap: unknown + ): maybeOrderedMap is OrderedMap; + + /** + * True if `maybeStack` is a Stack. + */ + function isStack(maybeStack: unknown): maybeStack is Stack; + + /** + * True if `maybeSet` is a Set. + * + * Also true for OrderedSets. + */ + function isSet(maybeSet: unknown): maybeSet is Set; + + /** + * True if `maybeOrderedSet` is an OrderedSet. + */ + function isOrderedSet( + maybeOrderedSet: unknown + ): maybeOrderedSet is OrderedSet; + + /** + * True if `maybeRecord` is a Record. + */ + function isRecord(maybeRecord: unknown): maybeRecord is Record; + + /** + * Returns the value within the provided collection associated with the + * provided key, or notSetValue if the key is not defined in the collection. + * + * A functional alternative to `collection.get(key)` which will also work on + * plain Objects and Arrays as an alternative for `collection[key]`. + * + * + * ```js + * const { get } = require('immutable') + * get([ 'dog', 'frog', 'cat' ], 2) // 'frog' + * get({ x: 123, y: 456 }, 'x') // 123 + * get({ x: 123, y: 456 }, 'z', 'ifNotSet') // 'ifNotSet' + * ``` + */ + function get(collection: Collection, key: K): V | undefined; + function get( + collection: Collection, + key: K, + notSetValue: NSV + ): V | NSV; + function get( + record: Record, + key: K, + notSetValue: unknown + ): TProps[K]; + function get(collection: Array, key: number): V | undefined; + function get( + collection: Array, + key: number, + notSetValue: NSV + ): V | NSV; + function get( + object: C, + key: K, + notSetValue: unknown + ): C[K]; + function get( + collection: { [key: PropertyKey]: V }, + key: string + ): V | undefined; + function get( + collection: { [key: PropertyKey]: V }, + key: string, + notSetValue: NSV + ): V | NSV; + + /** + * Returns true if the key is defined in the provided collection. + * + * A functional alternative to `collection.has(key)` which will also work with + * plain Objects and Arrays as an alternative for + * `collection.hasOwnProperty(key)`. + * + * + * ```js + * const { has } = require('immutable') + * has([ 'dog', 'frog', 'cat' ], 2) // true + * has([ 'dog', 'frog', 'cat' ], 5) // false + * has({ x: 123, y: 456 }, 'x') // true + * has({ x: 123, y: 456 }, 'z') // false + * ``` + */ + function has(collection: object, key: unknown): boolean; + + /** + * Returns a copy of the collection with the value at key removed. + * + * A functional alternative to `collection.remove(key)` which will also work + * with plain Objects and Arrays as an alternative for + * `delete collectionCopy[key]`. + * + * + * ```js + * const { remove } = require('immutable') + * const originalArray = [ 'dog', 'frog', 'cat' ] + * remove(originalArray, 1) // [ 'dog', 'cat' ] + * console.log(originalArray) // [ 'dog', 'frog', 'cat' ] + * const originalObject = { x: 123, y: 456 } + * remove(originalObject, 'x') // { y: 456 } + * console.log(originalObject) // { x: 123, y: 456 } + * ``` + */ + function remove>( + collection: C, + key: K + ): C; + function remove< + TProps extends object, + C extends Record, + K extends keyof TProps, + >(collection: C, key: K): C; + function remove>(collection: C, key: number): C; + function remove(collection: C, key: K): C; + function remove( + collection: C, + key: K + ): C; + + /** + * Returns a copy of the collection with the value at key set to the provided + * value. + * + * A functional alternative to `collection.set(key, value)` which will also + * work with plain Objects and Arrays as an alternative for + * `collectionCopy[key] = value`. + * + * + * ```js + * const { set } = require('immutable') + * const originalArray = [ 'dog', 'frog', 'cat' ] + * set(originalArray, 1, 'cow') // [ 'dog', 'cow', 'cat' ] + * console.log(originalArray) // [ 'dog', 'frog', 'cat' ] + * const originalObject = { x: 123, y: 456 } + * set(originalObject, 'x', 789) // { x: 789, y: 456 } + * console.log(originalObject) // { x: 123, y: 456 } + * ``` + */ + function set>( + collection: C, + key: K, + value: V + ): C; + function set< + TProps extends object, + C extends Record, + K extends keyof TProps, + >(record: C, key: K, value: TProps[K]): C; + function set>(collection: C, key: number, value: V): C; + function set(object: C, key: K, value: C[K]): C; + function set( + collection: C, + key: string, + value: V + ): C; + + /** + * Returns a copy of the collection with the value at key set to the result of + * providing the existing value to the updating function. + * + * A functional alternative to `collection.update(key, fn)` which will also + * work with plain Objects and Arrays as an alternative for + * `collectionCopy[key] = fn(collection[key])`. + * + * + * ```js + * const { update } = require('immutable') + * const originalArray = [ 'dog', 'frog', 'cat' ] + * update(originalArray, 1, val => val.toUpperCase()) // [ 'dog', 'FROG', 'cat' ] + * console.log(originalArray) // [ 'dog', 'frog', 'cat' ] + * const originalObject = { x: 123, y: 456 } + * update(originalObject, 'x', val => val * 6) // { x: 738, y: 456 } + * console.log(originalObject) // { x: 123, y: 456 } + * ``` + */ + function update>( + collection: C, + key: K, + updater: (value: V | undefined) => V | undefined + ): C; + function update, NSV>( + collection: C, + key: K, + notSetValue: NSV, + updater: (value: V | NSV) => V + ): C; + function update< + TProps extends object, + C extends Record, + K extends keyof TProps, + >(record: C, key: K, updater: (value: TProps[K]) => TProps[K]): C; + function update< + TProps extends object, + C extends Record, + K extends keyof TProps, + NSV, + >( + record: C, + key: K, + notSetValue: NSV, + updater: (value: TProps[K] | NSV) => TProps[K] + ): C; + function update( + collection: Array, + key: number, + updater: (value: V | undefined) => V | undefined + ): Array; + function update( + collection: Array, + key: number, + notSetValue: NSV, + updater: (value: V | NSV) => V + ): Array; + function update( + object: C, + key: K, + updater: (value: C[K]) => C[K] + ): C; + function update( + object: C, + key: K, + notSetValue: NSV, + updater: (value: C[K] | NSV) => C[K] + ): C; + function update( + collection: C, + key: K, + updater: (value: V) => V + ): { [key: string]: V }; + function update( + collection: C, + key: K, + notSetValue: NSV, + updater: (value: V | NSV) => V + ): { [key: string]: V }; + + // TODO `` can be used after dropping support for TypeScript 4.x + // reference: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#const-type-parameters + // after this change, `as const` assertions can be remove from the type tests + /** + * Returns the value at the provided key path starting at the provided + * collection, or notSetValue if the key path is not defined. + * + * A functional alternative to `collection.getIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * const { getIn } = require('immutable') + * getIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // 123 + * getIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p'], 'ifNotSet') // 'ifNotSet' + * ``` + */ + function getIn>( + object: C, + keyPath: [...P] + ): RetrievePath; + function getIn>(object: C, keyPath: P): unknown; + function getIn, NSV>( + collection: C, + keyPath: [...P], + notSetValue: NSV + ): RetrievePath extends never ? NSV : RetrievePath; + function getIn, NSV>( + object: C, + keyPath: P, + notSetValue: NSV + ): unknown; + + /** + * Returns true if the key path is defined in the provided collection. + * + * A functional alternative to `collection.hasIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * const { hasIn } = require('immutable') + * hasIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // true + * hasIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p']) // false + * ``` + */ + function hasIn( + collection: string | boolean | number, + keyPath: KeyPath + ): never; + function hasIn(collection: unknown, keyPath: KeyPath): boolean; + + /** + * Returns a copy of the collection with the value at the key path removed. + * + * A functional alternative to `collection.removeIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * const { removeIn } = require('immutable') + * const original = { x: { y: { z: 123 }}} + * removeIn(original, ['x', 'y', 'z']) // { x: { y: {}}} + * console.log(original) // { x: { y: { z: 123 }}} + * ``` + */ + function removeIn(collection: C, keyPath: Iterable): C; + + /** + * Returns a copy of the collection with the value at the key path set to the + * provided value. + * + * A functional alternative to `collection.setIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * const { setIn } = require('immutable') + * const original = { x: { y: { z: 123 }}} + * setIn(original, ['x', 'y', 'z'], 456) // { x: { y: { z: 456 }}} + * console.log(original) // { x: { y: { z: 123 }}} + * ``` + */ + function setIn( + collection: C, + keyPath: Iterable, + value: unknown + ): C; + + /** + * Returns a copy of the collection with the value at key path set to the + * result of providing the existing value to the updating function. + * + * A functional alternative to `collection.updateIn(keypath)` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * const { updateIn } = require('immutable') + * const original = { x: { y: { z: 123 }}} + * updateIn(original, ['x', 'y', 'z'], val => val * 6) // { x: { y: { z: 738 }}} + * console.log(original) // { x: { y: { z: 123 }}} + * ``` + */ + function updateIn>( + collection: C, + keyPath: KeyPath, + updater: ( + value: RetrievePath> | undefined + ) => unknown | undefined + ): C; + function updateIn, NSV>( + collection: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: (value: RetrievePath> | NSV) => unknown + ): C; + function updateIn< + TProps extends object, + C extends Record, + K extends keyof TProps, + >( + record: C, + keyPath: KeyPath, + updater: (value: RetrievePath>) => unknown + ): C; + function updateIn< + TProps extends object, + C extends Record, + K extends keyof TProps, + NSV, + >( + record: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: (value: RetrievePath> | NSV) => unknown + ): C; + function updateIn>( + collection: Array, + keyPath: KeyPath, + updater: ( + value: RetrievePath> | undefined + ) => unknown | undefined + ): Array; + function updateIn, NSV>( + collection: Array, + keyPath: KeyPath, + notSetValue: NSV, + updater: (value: RetrievePath> | NSV) => unknown + ): Array; + function updateIn( + object: C, + keyPath: KeyPath, + updater: (value: RetrievePath>) => unknown + ): C; + function updateIn( + object: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: (value: RetrievePath> | NSV) => unknown + ): C; + function updateIn< + K extends PropertyKey, + V, + C extends { [key: PropertyKey]: V }, + >( + collection: C, + keyPath: KeyPath, + updater: (value: RetrievePath>) => unknown + ): { [key: PropertyKey]: V }; + function updateIn< + K extends PropertyKey, + V, + C extends { [key: PropertyKey]: V }, + NSV, + >( + collection: C, + keyPath: KeyPath, + notSetValue: NSV, + updater: (value: RetrievePath> | NSV) => unknown + ): { [key: PropertyKey]: V }; + + /** + * Returns a copy of the collection with the remaining collections merged in. + * + * A functional alternative to `collection.merge()` which will also work with + * plain Objects and Arrays. + * + * + * ```js + * const { merge } = require('immutable') + * const original = { x: 123, y: 456 } + * merge(original, { y: 789, z: 'abc' }) // { x: 123, y: 789, z: 'abc' } + * console.log(original) // { x: 123, y: 456 } + * ``` + */ + function merge( + collection: C, + ...collections: Array< + | Iterable + | Iterable<[unknown, unknown]> + | { [key: string]: unknown } + > + ): C; + + /** + * Returns a copy of the collection with the remaining collections merged in, + * calling the `merger` function whenever an existing value is encountered. + * + * A functional alternative to `collection.mergeWith()` which will also work + * with plain Objects and Arrays. + * + * + * ```js + * const { mergeWith } = require('immutable') + * const original = { x: 123, y: 456 } + * mergeWith( + * (oldVal, newVal) => oldVal + newVal, + * original, + * { y: 789, z: 'abc' } + * ) // { x: 123, y: 1245, z: 'abc' } + * console.log(original) // { x: 123, y: 456 } + * ``` + */ + function mergeWith( + merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown, + collection: C, + ...collections: Array< + | Iterable + | Iterable<[unknown, unknown]> + | { [key: string]: unknown } + > + ): C; + + /** + * Like `merge()`, but when two compatible collections are encountered with + * the same key, it merges them as well, recursing deeply through the nested + * data. Two collections are considered to be compatible (and thus will be + * merged together) if they both fall into one of three categories: keyed + * (e.g., `Map`s, `Record`s, and objects), indexed (e.g., `List`s and + * arrays), or set-like (e.g., `Set`s). If they fall into separate + * categories, `mergeDeep` will replace the existing collection with the + * collection being merged in. This behavior can be customized by using + * `mergeDeepWith()`. + * + * Note: Indexed and set-like collections are merged using + * `concat()`/`union()` and therefore do not recurse. + * + * A functional alternative to `collection.mergeDeep()` which will also work + * with plain Objects and Arrays. + * + * + * ```js + * const { mergeDeep } = require('immutable') + * const original = { x: { y: 123 }} + * mergeDeep(original, { x: { z: 456 }}) // { x: { y: 123, z: 456 }} + * console.log(original) // { x: { y: 123 }} + * ``` + */ + function mergeDeep( + collection: C, + ...collections: Array< + | Iterable + | Iterable<[unknown, unknown]> + | { [key: string]: unknown } + > + ): C; + + /** + * Like `mergeDeep()`, but when two non-collections or incompatible + * collections are encountered at the same key, it uses the `merger` function + * to determine the resulting value. Collections are considered incompatible + * if they fall into separate categories between keyed, indexed, and set-like. + * + * A functional alternative to `collection.mergeDeepWith()` which will also + * work with plain Objects and Arrays. + * + * + * ```js + * const { mergeDeepWith } = require('immutable') + * const original = { x: { y: 123 }} + * mergeDeepWith( + * (oldVal, newVal) => oldVal + newVal, + * original, + * { x: { y: 456 }} + * ) // { x: { y: 579 }} + * console.log(original) // { x: { y: 123 }} + * ``` + */ + function mergeDeepWith( + merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown, + collection: C, + ...collections: Array< + | Iterable + | Iterable<[unknown, unknown]> + | { [key: string]: unknown } + > + ): C; +} + +/** + * Defines the main export of the immutable module to be the Immutable namespace + * This supports many common module import patterns: + * + * const Immutable = require("immutable"); + * const { List } = require("immutable"); + * import Immutable from "immutable"; + * import * as Immutable from "immutable"; + * import { List } from "immutable"; + * + */ +export = Immutable; + +/** + * A global "Immutable" namespace used by UMD modules which allows the use of + * the full Immutable API. + * + * If using Immutable as an imported module, prefer using: + * + * import Immutable from 'immutable' + * + */ +export as namespace Immutable; diff --git a/type-definitions/immutable.js.flow b/type-definitions/immutable.js.flow new file mode 100644 index 0000000000..9ab444d234 --- /dev/null +++ b/type-definitions/immutable.js.flow @@ -0,0 +1,2414 @@ +/** + * This file provides type definitions for use with the Flow type checker. + * + * An important caveat when using these definitions is that the types for + * `Collection.Keyed`, `Collection.Indexed`, `Seq.Keyed`, and so on are stubs. + * When referring to those types, you can get the proper definitions by + * importing the types `KeyedCollection`, `IndexedCollection`, `KeyedSeq`, etc. + * For example, + * + * import { Seq } from 'immutable' + * import type { IndexedCollection, IndexedSeq } from 'immutable' + * + * const someSeq: IndexedSeq = Seq.Indexed.of(1, 2, 3) + * + * function takesASeq>(iter: TS): TS { + * return iter.butLast() + * } + * + * takesASeq(someSeq) + * + * @flow strict + */ + +// Helper type that represents plain objects allowed as arguments to +// some constructors and functions. +type PlainObjInput = { +[key: K]: V, __proto__: null }; + +type K = $Keys; + +// Helper types to extract the "keys" and "values" use by the *In() methods. +type $KeyOf = $Call< + ((?_Collection) => K) & + ((?$ReadOnlyArray) => number) & + ((?RecordInstance | T) => $Keys) & + ((T) => $Keys), + C, +>; + +type $ValOf> = $Call< + ((?_Collection) => V) & + ((?$ReadOnlyArray) => T) & + (>(?RecordInstance | T, K) => $ElementType) & + ((T) => $Values), + C, + K, +>; + +type $IterableOf = $Call< + ( | IndexedCollection | SetCollection>( + V + ) => Iterable<$ValOf>) & + (< + V: + | KeyedCollection + | RecordInstance + | PlainObjInput, + >( + V + ) => Iterable<[$KeyOf, $ValOf]>), + C, +>; + +const PairSorting: $ReadOnly<{ LeftThenRight: number, RightThenLeft: number }> = + { + LeftThenRight: -1, + RightThenLeft: +1, + }; + +type Comparator = (left: T, right: T) => number; + +declare class _Collection implements ValueObject { + equals(other: mixed): boolean; + hashCode(): number; + get(key: K, ..._: []): V | void; + get(key: K, notSetValue: NSV): V | NSV; + has(key: K): boolean; + includes(value: V): boolean; + contains(value: V): boolean; + first(): V | void; + first(notSetValue: NSV): V | NSV; + last(): V | void; + last(notSetValue: NSV): V | NSV; + + hasIn(keyPath: Iterable): boolean; + + getIn(keyPath: [], notSetValue?: mixed): this; + getIn(keyPath: [K], notSetValue: NSV): V | NSV; + getIn>( + keyPath: [K, K2], + notSetValue: NSV + ): $ValOf | NSV; + getIn, K3: $KeyOf<$ValOf>>( + keyPath: [K, K2, K3], + notSetValue: NSV + ): $ValOf<$ValOf, K3> | NSV; + getIn< + NSV, + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + >( + keyPath: [K, K2, K3, K4], + notSetValue: NSV + ): $ValOf<$ValOf<$ValOf, K3>, K4> | NSV; + getIn< + NSV, + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf, K3>, K4>>, + >( + keyPath: [K, K2, K3, K4, K5], + notSetValue: NSV + ): $ValOf<$ValOf<$ValOf<$ValOf, K3>, K4>, K5> | NSV; + + update(updater: (value: this) => U): U; + + toJS(): Array | { [key: string]: mixed }; + toJSON(): Array | { [key: string]: V }; + toArray(): Array | Array<[K, V]>; + toObject(): { [key: string]: V }; + toMap(): Map; + toOrderedMap(): OrderedMap; + toSet(): Set; + toOrderedSet(): OrderedSet; + toList(): List; + toStack(): Stack; + toSeq(): Seq; + toKeyedSeq(): KeyedSeq; + toIndexedSeq(): IndexedSeq; + toSetSeq(): SetSeq; + + keys(): Iterator; + values(): Iterator; + entries(): Iterator<[K, V]>; + + keySeq(): IndexedSeq; + valueSeq(): IndexedSeq; + entrySeq(): IndexedSeq<[K, V]>; + + reverse(): this; + sort(comparator?: Comparator): this; + + sortBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: Comparator + ): this; + + groupBy( + grouper: (value: V, key: K, iter: this) => G, + context?: mixed + ): KeyedSeq; + + forEach( + sideEffect: (value: V, key: K, iter: this) => any, + context?: mixed + ): number; + + slice(begin?: number, end?: number): this; + rest(): this; + butLast(): this; + skip(amount: number): this; + skipLast(amount: number): this; + skipWhile( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): this; + skipUntil( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): this; + take(amount: number): this; + takeLast(amount: number): this; + takeWhile( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): this; + takeUntil( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): this; + + filterNot( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): this; + + reduce( + reducer: (reduction: R, value: V, key: K, iter: this) => R, + initialReduction: R, + context?: mixed + ): R; + reduce(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + + reduceRight( + reducer: (reduction: R, value: V, key: K, iter: this) => R, + initialReduction: R, + context?: mixed + ): R; + reduceRight( + reducer: (reduction: V | R, value: V, key: K, iter: this) => R + ): R; + + every( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): boolean; + some( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): boolean; + join(separator?: string): string; + isEmpty(): boolean; + count( + predicate?: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): number; + countBy( + grouper: (value: V, key: K, iter: this) => G, + context?: mixed + ): Map; + + find( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed, + notSetValue?: V + ): V | void; + findLast( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed, + notSetValue?: V + ): V | void; + + findEntry(predicate: (value: V, key: K, iter: this) => mixed): [K, V] | void; + findLastEntry( + predicate: (value: V, key: K, iter: this) => mixed + ): [K, V] | void; + + findKey( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): K | void; + findLastKey( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): K | void; + + keyOf(searchValue: V): K | void; + lastKeyOf(searchValue: V): K | void; + + max(comparator?: Comparator): V; + maxBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: Comparator + ): V; + min(comparator?: Comparator): V; + minBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: Comparator + ): V; + + isSubset(iter: Iterable): boolean; + isSuperset(iter: Iterable): boolean; +} + +declare function isImmutable( + maybeImmutable: mixed +): boolean %checks(maybeImmutable instanceof Collection); +declare function isCollection( + maybeCollection: mixed +): boolean %checks(maybeCollection instanceof Collection); +declare function isKeyed( + maybeKeyed: mixed +): boolean %checks(maybeKeyed instanceof KeyedCollection); +declare function isIndexed( + maybeIndexed: mixed +): boolean %checks(maybeIndexed instanceof IndexedCollection); +declare function isAssociative( + maybeAssociative: mixed +): boolean %checks(maybeAssociative instanceof KeyedCollection || + maybeAssociative instanceof IndexedCollection); +declare function isOrdered( + maybeOrdered: mixed +): boolean %checks(maybeOrdered instanceof IndexedCollection || + maybeOrdered instanceof OrderedMap || + maybeOrdered instanceof OrderedSet); +declare function isValueObject(maybeValue: mixed): boolean; + +declare function isSeq(maybeSeq: any): boolean %checks(maybeSeq instanceof Seq); +declare function isList(maybeList: any): boolean %checks(maybeList instanceof + List); +declare function isMap(maybeMap: any): boolean %checks(maybeMap instanceof Map); +declare function isOrderedMap( + maybeOrderedMap: any +): boolean %checks(maybeOrderedMap instanceof OrderedMap); +declare function isStack(maybeStack: any): boolean %checks(maybeStack instanceof + Stack); +declare function isSet(maybeSet: any): boolean %checks(maybeSet instanceof Set); +declare function isOrderedSet( + maybeOrderedSet: any +): boolean %checks(maybeOrderedSet instanceof OrderedSet); +declare function isRecord( + maybeRecord: any +): boolean %checks(maybeRecord instanceof Record); + +declare interface ValueObject { + equals(other: mixed): boolean; + hashCode(): number; +} + +declare class Collection extends _Collection { + static Keyed: typeof KeyedCollection; + static Indexed: typeof IndexedCollection; + static Set: typeof SetCollection; + + static isCollection: typeof isCollection; + static isKeyed: typeof isKeyed; + static isIndexed: typeof isIndexed; + static isAssociative: typeof isAssociative; + static isOrdered: typeof isOrdered; +} + +declare class KeyedCollection extends Collection { + static ( + values?: Iterable<[K, V]> | PlainObjInput + ): KeyedCollection; + + toJS(): { [key: string]: mixed }; + toJSON(): { [key: string]: V }; + toArray(): Array<[K, V]>; + @@iterator(): Iterator<[K, V]>; + toSeq(): KeyedSeq; + flip(): KeyedCollection; + + concat( + ...iters: Array | PlainObjInput> + ): KeyedCollection; + + filter(predicate: typeof Boolean): KeyedCollection>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): KeyedCollection; + + partition( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: V, key: K, iter: this) => M, + context?: mixed + ): KeyedCollection; + + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: mixed + ): KeyedCollection; + + mapEntries( + mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], + context?: mixed + ): KeyedCollection; + + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: mixed + ): KeyedCollection; + + flatten(depth?: number): KeyedCollection; + flatten(shallow?: boolean): KeyedCollection; +} + +Collection.Keyed = KeyedCollection; + +declare class IndexedCollection<+T> extends Collection { + static (iter?: Iterable): IndexedCollection; + + toJS(): Array; + toJSON(): Array; + toArray(): Array; + @@iterator(): Iterator; + toSeq(): IndexedSeq; + fromEntrySeq(): KeyedSeq; + interpose(separator: T): this; + interleave(...collections: Iterable[]): this; + splice(index: number, removeNum: number, ...values: T[]): this; + + zip(a: Iterable, ..._: []): IndexedCollection<[T, A]>; + zip( + a: Iterable, + b: Iterable, + ..._: [] + ): IndexedCollection<[T, A, B]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): IndexedCollection<[T, A, B, C]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): IndexedCollection<[T, A, B, C, D]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): IndexedCollection<[T, A, B, C, D, E]>; + + zipAll(a: Iterable, ..._: []): IndexedCollection<[T | void, A | void]>; + zipAll( + a: Iterable, + b: Iterable, + ..._: [] + ): IndexedCollection<[T | void, A | void, B | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): IndexedCollection<[T | void, A | void, B | void, C | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): IndexedCollection<[T | void, A | void, B | void, C | void, D | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): IndexedCollection< + [T | void, A | void, B | void, C | void, D | void, E | void], + >; + + zipWith( + zipper: (value: T, a: A) => R, + a: Iterable, + ..._: [] + ): IndexedCollection; + zipWith( + zipper: (value: T, a: A, b: B) => R, + a: Iterable, + b: Iterable, + ..._: [] + ): IndexedCollection; + zipWith( + zipper: (value: T, a: A, b: B, c: C) => R, + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): IndexedCollection; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): IndexedCollection; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): IndexedCollection; + + indexOf(searchValue: T): number; + lastIndexOf(searchValue: T): number; + findIndex( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): number; + findLastIndex( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): number; + + concat(...iters: Array | C>): IndexedCollection; + + filter(predicate: typeof Boolean): IndexedCollection<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): IndexedCollection; + + partition( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, index: number, iter: this) => M, + context?: mixed + ): IndexedCollection; + + flatMap( + mapper: (value: T, index: number, iter: this) => Iterable, + context?: mixed + ): IndexedCollection; + + flatten(depth?: number): IndexedCollection; + flatten(shallow?: boolean): IndexedCollection; +} + +declare class SetCollection<+T> extends Collection { + static (iter?: Iterable): SetCollection; + + toJS(): Array; + toJSON(): Array; + toArray(): Array; + @@iterator(): Iterator; + toSeq(): SetSeq; + + concat(...collections: Iterable[]): SetCollection; + + // `filter`, `map` and `flatMap` cannot be defined further up the hierarchy, + // because the implementation for `KeyedCollection` allows the value type to + // change without constraining the key type. That does not work for + // `SetCollection` - the value and key types *must* match. + filter(predicate: typeof Boolean): SetCollection<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): SetCollection; + + partition( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, value: T, iter: this) => M, + context?: mixed + ): SetCollection; + + flatMap( + mapper: (value: T, value: T, iter: this) => Iterable, + context?: mixed + ): SetCollection; + + flatten(depth?: number): SetCollection; + flatten(shallow?: boolean): SetCollection; +} + +declare function isSeq(maybeSeq: mixed): boolean %checks(maybeSeq instanceof + Seq); +declare class Seq extends _Collection { + static Keyed: typeof KeyedSeq; + static Indexed: typeof IndexedSeq; + static Set: typeof SetSeq; + + static (values: KeyedSeq): KeyedSeq; + static (values: SetSeq): SetSeq; + static (values: Iterable): IndexedSeq; + static (values?: PlainObjInput): KeyedSeq; + + static isSeq: typeof isSeq; + + size: number | void; + cacheResult(): this; + toSeq(): this; +} + +declare class KeyedSeq extends Seq mixins KeyedCollection { + static ( + values?: Iterable<[K, V]> | PlainObjInput + ): KeyedSeq; + + // Override specialized return types + flip(): KeyedSeq; + + concat( + ...iters: Array | PlainObjInput> + ): KeyedSeq; + + filter(predicate: typeof Boolean): KeyedSeq>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): KeyedSeq; + + partition( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: V, key: K, iter: this) => M, + context?: mixed + ): KeyedSeq; + + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: mixed + ): KeyedSeq; + + mapEntries( + mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], + context?: mixed + ): KeyedSeq; + + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: mixed + ): KeyedSeq; + + flatten(depth?: number): KeyedSeq; + flatten(shallow?: boolean): KeyedSeq; +} + +declare class IndexedSeq<+T> + extends Seq + mixins IndexedCollection +{ + static (values?: Iterable): IndexedSeq; + + static of(...values: T[]): IndexedSeq; + + // Override specialized return types + + concat(...iters: Array | C>): IndexedSeq; + + filter(predicate: typeof Boolean): IndexedSeq<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): IndexedSeq; + + partition( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, index: number, iter: this) => M, + context?: mixed + ): IndexedSeq; + + flatMap( + mapper: (value: T, index: number, iter: this) => Iterable, + context?: mixed + ): IndexedSeq; + + flatten(depth?: number): IndexedSeq; + flatten(shallow?: boolean): IndexedSeq; + + zip(a: Iterable, ..._: []): IndexedSeq<[T, A]>; + zip(a: Iterable, b: Iterable, ..._: []): IndexedSeq<[T, A, B]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): IndexedSeq<[T, A, B, C]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): IndexedSeq<[T, A, B, C, D]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): IndexedSeq<[T, A, B, C, D, E]>; + + zipAll(a: Iterable, ..._: []): IndexedSeq<[T | void, A | void]>; + zipAll( + a: Iterable, + b: Iterable, + ..._: [] + ): IndexedSeq<[T | void, A | void, B | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): IndexedSeq<[T | void, A | void, B | void, C | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): IndexedSeq<[T | void, A | void, B | void, C | void, D | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): IndexedSeq<[T | void, A | void, B | void, C | void, D | void, E | void]>; + + zipWith( + zipper: (value: T, a: A) => R, + a: Iterable, + ..._: [] + ): IndexedSeq; + zipWith( + zipper: (value: T, a: A, b: B) => R, + a: Iterable, + b: Iterable, + ..._: [] + ): IndexedSeq; + zipWith( + zipper: (value: T, a: A, b: B, c: C) => R, + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): IndexedSeq; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): IndexedSeq; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): IndexedSeq; +} + +declare class SetSeq<+T> extends Seq mixins SetCollection { + static (values?: Iterable): SetSeq; + + static of(...values: T[]): SetSeq; + + // Override specialized return types + + concat(...collections: Iterable[]): SetSeq; + + filter(predicate: typeof Boolean): SetSeq<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): SetSeq; + + partition( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, value: T, iter: this) => M, + context?: mixed + ): SetSeq; + + flatMap( + mapper: (value: T, value: T, iter: this) => Iterable, + context?: mixed + ): SetSeq; + + flatten(depth?: number): SetSeq; + flatten(shallow?: boolean): SetSeq; +} + +declare class UpdatableInCollection { + setIn(keyPath: [], value: S): S; + setIn(keyPath: [K], value: V): this; + setIn, S: $ValOf>(keyPath: [K, K2], value: S): this; + setIn, K3: $KeyOf<$ValOf>, S: $ValOf<$ValOf, K3>>( + keyPath: [K, K2, K3], + value: S + ): this; + setIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + S: $ValOf<$ValOf<$ValOf, K3>, K4>, + >( + keyPath: [K, K2, K3, K4], + value: S + ): this; + setIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K3>, K4>, K5>, + >( + keyPath: [K, K2, K3, K4, K5], + value: S + ): this; + + deleteIn(keyPath: []): void; + deleteIn(keyPath: [K]): this; + deleteIn>(keyPath: [K, K2]): this; + deleteIn, K3: $KeyOf<$ValOf>>( + keyPath: [K, K2, K3] + ): this; + deleteIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + >( + keyPath: [K, K2, K3, K4] + ): this; + deleteIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf, K3>, K4>>, + >( + keyPath: [K, K2, K3, K4, K5] + ): this; + + removeIn(keyPath: []): void; + removeIn(keyPath: [K]): this; + removeIn>(keyPath: [K, K2]): this; + removeIn, K3: $KeyOf<$ValOf>>( + keyPath: [K, K2, K3] + ): this; + removeIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + >( + keyPath: [K, K2, K3, K4] + ): this; + removeIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf, K3>, K4>>, + >( + keyPath: [K, K2, K3, K4, K5] + ): this; + + updateIn(keyPath: [], notSetValue: mixed, updater: (value: this) => U): U; + updateIn(keyPath: [], updater: (value: this) => U): U; + updateIn(keyPath: [K], notSetValue: NSV, updater: (value: V) => V): this; + updateIn(keyPath: [K], updater: (value: V) => V): this; + updateIn, S: $ValOf>( + keyPath: [K, K2], + notSetValue: NSV, + updater: (value: $ValOf | NSV) => S + ): this; + updateIn, S: $ValOf>( + keyPath: [K, K2], + updater: (value: $ValOf) => S + ): this; + updateIn< + NSV, + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + S: $ValOf<$ValOf, K3>, + >( + keyPath: [K, K2, K3], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf, K3> | NSV) => S + ): this; + updateIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + S: $ValOf<$ValOf, K3>, + >( + keyPath: [K, K2, K3], + updater: (value: $ValOf<$ValOf, K3>) => S + ): this; + updateIn< + NSV, + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + S: $ValOf<$ValOf<$ValOf, K3>, K4>, + >( + keyPath: [K, K2, K3, K4], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf<$ValOf, K3>, K4> | NSV) => S + ): this; + updateIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + S: $ValOf<$ValOf<$ValOf, K3>, K4>, + >( + keyPath: [K, K2, K3, K4], + updater: (value: $ValOf<$ValOf<$ValOf, K3>, K4>) => S + ): this; + updateIn< + NSV, + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K3>, K4>, K5>, + >( + keyPath: [K, K2, K3, K4, K5], + notSetValue: NSV, + updater: ( + value: $ValOf<$ValOf<$ValOf<$ValOf, K3>, K4>, K5> | NSV + ) => S + ): this; + updateIn< + K2: $KeyOf, + K3: $KeyOf<$ValOf>, + K4: $KeyOf<$ValOf<$ValOf, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K3>, K4>, K5>, + >( + keyPath: [K, K2, K3, K4, K5], + updater: (value: $ValOf<$ValOf<$ValOf<$ValOf, K3>, K4>, K5>) => S + ): this; +} + +declare function isList(maybeList: mixed): boolean %checks(maybeList instanceof + List); +declare class List<+T> + extends IndexedCollection + mixins UpdatableInCollection +{ + static (collection?: Iterable): List; + + static of(...values: T[]): List; + + static isList: typeof isList; + + size: number; + + set(index: number, value: U): List; + delete(index: number): this; + remove(index: number): this; + insert(index: number, value: U): List; + clear(): this; + push(...values: U[]): List; + pop(): this; + unshift(...values: U[]): List; + shift(): this; + + update(updater: (value: this) => U): U; + update(index: number, updater: (value: T) => U): List; + update( + index: number, + notSetValue: U, + updater: (value: T) => U + ): List; + + merge(...collections: Iterable[]): List; + + setSize(size: number): this; + + mergeIn(keyPath: Iterable, ...collections: Iterable[]): this; + mergeDeepIn( + keyPath: Iterable, + ...collections: Iterable[] + ): this; + + withMutations(mutator: (mutable: this) => mixed): this; + asMutable(): this; + wasAltered(): boolean; + asImmutable(): this; + + // Override specialized return types + + concat(...iters: Array | C>): List; + + filter(predicate: typeof Boolean): List<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): List; + + partition( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, index: number, iter: this) => M, + context?: mixed + ): List; + + flatMap( + mapper: (value: T, index: number, iter: this) => Iterable, + context?: mixed + ): List; + + flatten(depth?: number): List; + flatten(shallow?: boolean): List; + + zip(a: Iterable, ..._: []): List<[T, A]>; + zip(a: Iterable, b: Iterable, ..._: []): List<[T, A, B]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): List<[T, A, B, C]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): List<[T, A, B, C, D]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): List<[T, A, B, C, D, E]>; + + zipAll(a: Iterable, ..._: []): List<[T | void, A | void]>; + zipAll( + a: Iterable, + b: Iterable, + ..._: [] + ): List<[T | void, A | void, B | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): List<[T | void, A | void, B | void, C | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): List<[T | void, A | void, B | void, C | void, D | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): List<[T | void, A | void, B | void, C | void, D | void, E | void]>; + + zipWith( + zipper: (value: T, a: A) => R, + a: Iterable, + ..._: [] + ): List; + zipWith( + zipper: (value: T, a: A, b: B) => R, + a: Iterable, + b: Iterable, + ..._: [] + ): List; + zipWith( + zipper: (value: T, a: A, b: B, c: C) => R, + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): List; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): List; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): List; +} + +declare function isMap(maybeMap: mixed): boolean %checks(maybeMap instanceof + Map); +declare class Map + extends KeyedCollection + mixins UpdatableInCollection +{ + static (values?: Iterable<[K, V]> | PlainObjInput): Map; + + static isMap: typeof isMap; + + size: number; + + set(key: K_, value: V_): Map; + delete(key: K): this; + remove(key: K): this; + clear(): this; + + deleteAll(keys: Iterable): Map; + removeAll(keys: Iterable): Map; + + update(updater: (value: this) => U): U; + update(key: K, updater: (value: V) => V_): Map; + update( + key: K, + notSetValue: V_, + updater: (value: V) => V_ + ): Map; + + merge( + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): Map; + concat( + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): Map; + + mergeWith( + merger: (oldVal: V, newVal: W, key: K) => X, + ...collections: (Iterable<[K_, W]> | PlainObjInput)[] + ): Map; + + mergeDeep( + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): Map; + + mergeDeepWith( + merger: (oldVal: any, newVal: any, key: any) => mixed, + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): Map; + + mergeIn( + keyPath: Iterable, + ...collections: (Iterable | PlainObjInput)[] + ): this; + mergeDeepIn( + keyPath: Iterable, + ...collections: (Iterable | PlainObjInput)[] + ): this; + + withMutations(mutator: (mutable: this) => mixed): this; + asMutable(): this; + wasAltered(): boolean; + asImmutable(): this; + + // Override specialized return types + + flip(): Map; + + filter(predicate: typeof Boolean): Map>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): Map; + + partition( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: V, key: K, iter: this) => M, + context?: mixed + ): Map; + + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: mixed + ): Map; + + mapEntries( + mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], + context?: mixed + ): Map; + + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: mixed + ): Map; + + flatten(depth?: number): Map; + flatten(shallow?: boolean): Map; +} + +declare function isOrderedMap( + maybeOrderedMap: mixed +): boolean %checks(maybeOrderedMap instanceof OrderedMap); +declare class OrderedMap + extends Map + mixins UpdatableInCollection +{ + static ( + values?: Iterable<[K, V]> | PlainObjInput + ): OrderedMap; + + static isOrderedMap: typeof isOrderedMap; + + size: number; + + set(key: K_, value: V_): OrderedMap; + delete(key: K): this; + remove(key: K): this; + clear(): this; + + update(updater: (value: this) => U): U; + update(key: K, updater: (value: V) => V_): OrderedMap; + update( + key: K, + notSetValue: V_, + updater: (value: V) => V_ + ): OrderedMap; + + merge( + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): OrderedMap; + concat( + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): OrderedMap; + + mergeWith( + merger: (oldVal: V, newVal: W, key: K) => X, + ...collections: (Iterable<[K_, W]> | PlainObjInput)[] + ): OrderedMap; + + mergeDeep( + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): OrderedMap; + + mergeDeepWith( + merger: (oldVal: any, newVal: any, key: any) => mixed, + ...collections: (Iterable<[K_, V_]> | PlainObjInput)[] + ): OrderedMap; + + mergeIn( + keyPath: Iterable, + ...collections: (Iterable | PlainObjInput)[] + ): this; + mergeDeepIn( + keyPath: Iterable, + ...collections: (Iterable | PlainObjInput)[] + ): this; + + withMutations(mutator: (mutable: this) => mixed): this; + asMutable(): this; + wasAltered(): boolean; + asImmutable(): this; + + // Override specialized return types + + flip(): OrderedMap; + + filter(predicate: typeof Boolean): OrderedMap>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): OrderedMap; + + partition( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: V, key: K, iter: this) => M, + context?: mixed + ): OrderedMap; + + mapKeys( + mapper: (key: K, value: V, iter: this) => M, + context?: mixed + ): OrderedMap; + + mapEntries( + mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], + context?: mixed + ): OrderedMap; + + flatMap( + mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, + context?: mixed + ): OrderedMap; + + flatten(depth?: number): OrderedMap; + flatten(shallow?: boolean): OrderedMap; +} + +declare function isSet(maybeSet: mixed): boolean %checks(maybeSet instanceof + Set); +declare class Set<+T> extends SetCollection { + static (values?: Iterable): Set; + + static of(...values: T[]): Set; + static fromKeys( + values: Iterable<[T, mixed]> | PlainObjInput + ): Set; + + static intersect(sets: Iterable>): Set; + static union(sets: Iterable>): Set; + + static isSet: typeof isSet; + + size: number; + + add(value: U): Set; + delete(value: T): this; + remove(value: T): this; + clear(): this; + union(...collections: Iterable[]): Set; + merge(...collections: Iterable[]): Set; + concat(...collections: Iterable[]): Set; + intersect(...collections: Iterable[]): Set; + subtract(...collections: Iterable[]): this; + + withMutations(mutator: (mutable: this) => mixed): this; + asMutable(): this; + wasAltered(): boolean; + asImmutable(): this; + + // Override specialized return types + + filter(predicate: typeof Boolean): Set<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): Set; + + partition( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, value: T, iter: this) => M, + context?: mixed + ): Set; + + flatMap( + mapper: (value: T, value: T, iter: this) => Iterable, + context?: mixed + ): Set; + + flatten(depth?: number): Set; + flatten(shallow?: boolean): Set; +} + +// Overrides except for `isOrderedSet` are for specialized return types +declare function isOrderedSet( + maybeOrderedSet: mixed +): boolean %checks(maybeOrderedSet instanceof OrderedSet); +declare class OrderedSet<+T> extends Set { + static (values?: Iterable): OrderedSet; + + static of(...values: T[]): OrderedSet; + static fromKeys( + values: Iterable<[T, mixed]> | PlainObjInput + ): OrderedSet; + + static isOrderedSet: typeof isOrderedSet; + + size: number; + + add(value: U): OrderedSet; + union(...collections: Iterable[]): OrderedSet; + merge(...collections: Iterable[]): OrderedSet; + concat(...collections: Iterable[]): OrderedSet; + intersect(...collections: Iterable[]): OrderedSet; + + filter(predicate: typeof Boolean): OrderedSet<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): OrderedSet; + + partition( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): [this, this]; + + map( + mapper: (value: T, value: T, iter: this) => M, + context?: mixed + ): OrderedSet; + + flatMap( + mapper: (value: T, value: T, iter: this) => Iterable, + context?: mixed + ): OrderedSet; + + flatten(depth?: number): OrderedSet; + flatten(shallow?: boolean): OrderedSet; + + zip(a: Iterable, ..._: []): OrderedSet<[T, A]>; + zip(a: Iterable, b: Iterable, ..._: []): OrderedSet<[T, A, B]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): OrderedSet<[T, A, B, C]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): OrderedSet<[T, A, B, C, D]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): OrderedSet<[T, A, B, C, D, E]>; + + zipAll(a: Iterable, ..._: []): OrderedSet<[T | void, A | void]>; + zipAll( + a: Iterable, + b: Iterable, + ..._: [] + ): OrderedSet<[T | void, A | void, B | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): OrderedSet<[T | void, A | void, B | void, C | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): OrderedSet<[T | void, A | void, B | void, C | void, D | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): OrderedSet<[T | void, A | void, B | void, C | void, D | void, E | void]>; + + zipWith( + zipper: (value: T, a: A) => R, + a: Iterable, + ..._: [] + ): OrderedSet; + zipWith( + zipper: (value: T, a: A, b: B) => R, + a: Iterable, + b: Iterable, + ..._: [] + ): OrderedSet; + zipWith( + zipper: (value: T, a: A, b: B, c: C) => R, + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): OrderedSet; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): OrderedSet; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): OrderedSet; +} + +declare function isStack( + maybeStack: mixed +): boolean %checks(maybeStack instanceof Stack); +declare class Stack<+T> extends IndexedCollection { + static (collection?: Iterable): Stack; + + static isStack(maybeStack: mixed): boolean; + static of(...values: T[]): Stack; + + static isStack: typeof isStack; + + size: number; + + peek(): T; + clear(): this; + unshift(...values: U[]): Stack; + unshiftAll(iter: Iterable): Stack; + shift(): this; + push(...values: U[]): Stack; + pushAll(iter: Iterable): Stack; + pop(): this; + + withMutations(mutator: (mutable: this) => mixed): this; + asMutable(): this; + wasAltered(): boolean; + asImmutable(): this; + + // Override specialized return types + + concat(...iters: Array | C>): Stack; + + filter(predicate: typeof Boolean): Stack<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): Stack; + + map( + mapper: (value: T, index: number, iter: this) => M, + context?: mixed + ): Stack; + + flatMap( + mapper: (value: T, index: number, iter: this) => Iterable, + context?: mixed + ): Stack; + + flatten(depth?: number): Stack; + flatten(shallow?: boolean): Stack; + + zip(a: Iterable, ..._: []): Stack<[T, A]>; + zip(a: Iterable, b: Iterable, ..._: []): Stack<[T, A, B]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): Stack<[T, A, B, C]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): Stack<[T, A, B, C, D]>; + zip( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): Stack<[T, A, B, C, D, E]>; + + zipAll(a: Iterable, ..._: []): Stack<[T | void, A | void]>; + zipAll( + a: Iterable, + b: Iterable, + ..._: [] + ): Stack<[T | void, A | void, B | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): Stack<[T | void, A | void, B | void, C | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): Stack<[T | void, A | void, B | void, C | void, D | void]>; + zipAll( + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): Stack<[T | void, A | void, B | void, C | void, D | void, E | void]>; + + zipWith( + zipper: (value: T, a: A) => R, + a: Iterable, + ..._: [] + ): Stack; + zipWith( + zipper: (value: T, a: A, b: B) => R, + a: Iterable, + b: Iterable, + ..._: [] + ): Stack; + zipWith( + zipper: (value: T, a: A, b: B, c: C) => R, + a: Iterable, + b: Iterable, + c: Iterable, + ..._: [] + ): Stack; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + ..._: [] + ): Stack; + zipWith( + zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R, + a: Iterable, + b: Iterable, + c: Iterable, + d: Iterable, + e: Iterable, + ..._: [] + ): Stack; +} + +declare function Range( + start?: number, + end?: number, + step?: number +): IndexedSeq; +declare function Repeat(value: T, times?: number): IndexedSeq; + +// The type of a Record factory function. +type RecordFactory = Class>; + +// The type of runtime Record instances. +type RecordOf = RecordInstance & $ReadOnly; + +// The values of a Record instance. +type _RecordValues | T> = R; +type RecordValues = _RecordValues<*, R>; + +declare function isRecord( + maybeRecord: any +): boolean %checks(maybeRecord instanceof RecordInstance); +declare class Record { + static (spec: Values, name?: string): typeof RecordInstance; + constructor( + spec: Values, + name?: string + ): typeof RecordInstance; + + static isRecord: typeof isRecord; + + static getDescriptiveName(record: RecordInstance): string; +} + +declare class RecordInstance { + static (values?: Iterable<[$Keys, $ValOf]> | $Shape): RecordOf; + // Note: a constructor can only create an instance of RecordInstance, + // it's encouraged to not use `new` when creating Records. + constructor(values?: Iterable<[$Keys, $ValOf]> | $Shape): void; + + size: number; + + has(key: string): boolean; + + get>(key: K, ..._: []): $ElementType; + get, NSV>(key: K, notSetValue: NSV): $ElementType | NSV; + + hasIn(keyPath: Iterable): boolean; + + getIn(keyPath: [], notSetValue?: mixed): this & $ReadOnly; + getIn>(keyPath: [K], notSetValue?: mixed): $ElementType; + getIn, K2: $KeyOf<$ValOf>>( + keyPath: [K, K2], + notSetValue: NSV + ): $ValOf<$ValOf, K2> | NSV; + getIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + >( + keyPath: [K, K2, K3], + notSetValue: NSV + ): $ValOf<$ValOf<$ValOf, K2>, K3> | NSV; + getIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + >( + keyPath: [K, K2, K3, K4], + notSetValue: NSV + ): $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4> | NSV; + getIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + >( + keyPath: [K, K2, K3, K4, K5], + notSetValue: NSV + ): $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5> | NSV; + + equals(other: any): boolean; + hashCode(): number; + + set>(key: K, value: $ElementType): this & $ReadOnly; + update>( + key: K, + updater: (value: $ElementType) => $ElementType + ): this & $ReadOnly; + merge( + ...collections: Array, $ValOf]> | $Shape> + ): this & $ReadOnly; + mergeDeep( + ...collections: Array, $ValOf]> | $Shape> + ): this & $ReadOnly; + + mergeWith( + merger: (oldVal: $ValOf, newVal: $ValOf, key: $Keys) => $ValOf, + ...collections: Array, $ValOf]> | $Shape> + ): this & $ReadOnly; + mergeDeepWith( + merger: (oldVal: any, newVal: any, key: any) => any, + ...collections: Array, $ValOf]> | $Shape> + ): this & $ReadOnly; + + delete>(key: K): this & $ReadOnly; + remove>(key: K): this & $ReadOnly; + clear(): this & $ReadOnly; + + setIn(keyPath: [], value: S): S; + setIn, S: $ValOf>( + keyPath: [K], + value: S + ): this & $ReadOnly; + setIn, K2: $KeyOf<$ValOf>, S: $ValOf<$ValOf, K2>>( + keyPath: [K, K2], + value: S + ): this & $ReadOnly; + setIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + S: $ValOf<$ValOf<$ValOf, K2>, K3>, + >( + keyPath: [K, K2, K3], + value: S + ): this & $ReadOnly; + setIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, + >( + keyPath: [K, K2, K3, K4], + value: S + ): this & $ReadOnly; + setIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5>, + >( + keyPath: [K, K2, K3, K4, K5], + value: S + ): this & $ReadOnly; + + deleteIn(keyPath: []): void; + deleteIn>(keyPath: [K]): this & $ReadOnly; + deleteIn, K2: $KeyOf<$ValOf>>( + keyPath: [K, K2] + ): this & $ReadOnly; + deleteIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + >( + keyPath: [K, K2, K3] + ): this & $ReadOnly; + deleteIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + >( + keyPath: [K, K2, K3, K4] + ): this & $ReadOnly; + deleteIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + >( + keyPath: [K, K2, K3, K4, K5] + ): this & $ReadOnly; + + removeIn(keyPath: []): void; + removeIn>(keyPath: [K]): this & $ReadOnly; + removeIn, K2: $KeyOf<$ValOf>>( + keyPath: [K, K2] + ): this & $ReadOnly; + removeIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + >( + keyPath: [K, K2, K3] + ): this & $ReadOnly; + removeIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + >( + keyPath: [K, K2, K3, K4] + ): this & $ReadOnly; + removeIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + >( + keyPath: [K, K2, K3, K4, K5] + ): this & $ReadOnly; + + updateIn( + keyPath: [], + notSetValue: mixed, + updater: (value: this & T) => U + ): U; + updateIn(keyPath: [], updater: (value: this & T) => U): U; + updateIn, S: $ValOf>( + keyPath: [K], + notSetValue: NSV, + updater: (value: $ValOf) => S + ): this & $ReadOnly; + updateIn, S: $ValOf>( + keyPath: [K], + updater: (value: $ValOf) => S + ): this & $ReadOnly; + updateIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + S: $ValOf<$ValOf, K2>, + >( + keyPath: [K, K2], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf, K2> | NSV) => S + ): this & $ReadOnly; + updateIn, K2: $KeyOf<$ValOf>, S: $ValOf<$ValOf, K2>>( + keyPath: [K, K2], + updater: (value: $ValOf<$ValOf, K2>) => S + ): this & $ReadOnly; + updateIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + S: $ValOf<$ValOf<$ValOf, K2>, K3>, + >( + keyPath: [K, K2, K3], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf<$ValOf, K2>, K3> | NSV) => S + ): this & $ReadOnly; + updateIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + S: $ValOf<$ValOf<$ValOf, K2>, K3>, + >( + keyPath: [K, K2, K3], + updater: (value: $ValOf<$ValOf<$ValOf, K2>, K3>) => S + ): this & $ReadOnly; + updateIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, + >( + keyPath: [K, K2, K3, K4], + notSetValue: NSV, + updater: ( + value: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4> | NSV + ) => S + ): this & $ReadOnly; + updateIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, + >( + keyPath: [K, K2, K3, K4], + updater: (value: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>) => S + ): this & $ReadOnly; + updateIn< + NSV, + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5>, + >( + keyPath: [K, K2, K3, K4, K5], + notSetValue: NSV, + updater: ( + value: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5> | NSV + ) => S + ): this & $ReadOnly; + updateIn< + K: $Keys, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5>, + >( + keyPath: [K, K2, K3, K4, K5], + updater: ( + value: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5> + ) => S + ): this & $ReadOnly; + + mergeIn( + keyPath: Iterable, + ...collections: Array + ): this & $ReadOnly; + mergeDeepIn( + keyPath: Iterable, + ...collections: Array + ): this & $ReadOnly; + + toSeq(): KeyedSeq<$Keys, any>; + + toJS(): { [key: $Keys]: mixed }; + toJSON(): T; + toObject(): T; + + withMutations(mutator: (mutable: this & T) => mixed): this & $ReadOnly; + asMutable(): this & $ReadOnly; + wasAltered(): boolean; + asImmutable(): this & $ReadOnly; + + @@iterator(): Iterator<[$Keys, $ValOf]>; +} + +declare function fromJS( + jsValue: mixed, + reviver?: ( + key: string | number, + sequence: KeyedCollection | IndexedCollection, + path?: Array + ) => mixed +): Collection; + +declare function is(first: mixed, second: mixed): boolean; +declare function hash(value: mixed): number; + +declare function get>( + collection: C, + key: K, + notSetValue: mixed +): $ValOf; +declare function get, NSV>( + collection: C, + key: K, + notSetValue: NSV +): $ValOf | NSV; + +declare function has(collection: Object, key: mixed): boolean; +declare function remove(collection: C, key: $KeyOf): C; +declare function set, V: $ValOf>( + collection: C, + key: K, + value: V +): C; +declare function update, V: $ValOf, NSV>( + collection: C, + key: K, + notSetValue: NSV, + updater: ($ValOf | NSV) => V +): C; +declare function update, V: $ValOf>( + collection: C, + key: K, + updater: ($ValOf) => V +): C; + +declare function getIn(collection: C, keyPath: [], notSetValue?: mixed): C; +declare function getIn, NSV>( + collection: C, + keyPath: [K], + notSetValue: NSV +): $ValOf | NSV; +declare function getIn, K2: $KeyOf<$ValOf>, NSV>( + collection: C, + keyPath: [K, K2], + notSetValue: NSV +): $ValOf<$ValOf, K2> | NSV; +declare function getIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + NSV, +>( + collection: C, + keyPath: [K, K2, K3], + notSetValue: NSV +): $ValOf<$ValOf<$ValOf, K2>, K3> | NSV; +declare function getIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + NSV, +>( + collection: C, + keyPath: [K, K2, K3, K4], + notSetValue: NSV +): $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4> | NSV; +declare function getIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + NSV, +>( + collection: C, + keyPath: [K, K2, K3, K4, K5], + notSetValue: NSV +): $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5> | NSV; + +declare function hasIn(collection: Object, keyPath: Iterable): boolean; + +declare function removeIn(collection: C, keyPath: []): void; +declare function removeIn>(collection: C, keyPath: [K]): C; +declare function removeIn, K2: $KeyOf<$ValOf>>( + collection: C, + keyPath: [K, K2] +): C; +declare function removeIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, +>( + collection: C, + keyPath: [K, K2, K3] +): C; +declare function removeIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, +>( + collection: C, + keyPath: [K, K2, K3, K4] +): C; +declare function removeIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, +>( + collection: C, + keyPath: [K, K2, K3, K4, K5] +): C; + +declare function setIn(collection: Object, keyPath: [], value: S): S; +declare function setIn, S: $ValOf>( + collection: C, + keyPath: [K], + value: S +): C; +declare function setIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + S: $ValOf<$ValOf, K2>, +>( + collection: C, + keyPath: [K, K2], + value: S +): C; +declare function setIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + S: $ValOf<$ValOf<$ValOf, K2>, K3>, +>( + collection: C, + keyPath: [K, K2, K3], + value: S +): C; +declare function setIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, +>( + collection: C, + keyPath: [K, K2, K3, K4], + value: S +): C; +declare function setIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5>, +>( + collection: C, + keyPath: [K, K2, K3, K4, K5], + value: S +): C; + +declare function updateIn( + collection: C, + keyPath: [], + notSetValue: mixed, + updater: (value: C) => S +): S; +declare function updateIn( + collection: C, + keyPath: [], + updater: (value: C) => S +): S; +declare function updateIn, S: $ValOf, NSV>( + collection: C, + keyPath: [K], + notSetValue: NSV, + updater: (value: $ValOf | NSV) => S +): C; +declare function updateIn, S: $ValOf>( + collection: C, + keyPath: [K], + updater: (value: $ValOf) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + S: $ValOf<$ValOf, K2>, + NSV, +>( + collection: C, + keyPath: [K, K2], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf, K2> | NSV) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + S: $ValOf<$ValOf, K2>, +>( + collection: C, + keyPath: [K, K2], + updater: (value: $ValOf<$ValOf, K2>) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + S: $ValOf<$ValOf<$ValOf, K2>, K3>, + NSV, +>( + collection: C, + keyPath: [K, K2, K3], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf<$ValOf, K2>, K3> | NSV) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + S: $ValOf<$ValOf<$ValOf, K2>, K3>, +>( + collection: C, + keyPath: [K, K2, K3], + updater: (value: $ValOf<$ValOf<$ValOf, K2>, K3>) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, + NSV, +>( + collection: C, + keyPath: [K, K2, K3, K4], + notSetValue: NSV, + updater: (value: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4> | NSV) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + S: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, +>( + collection: C, + keyPath: [K, K2, K3, K4], + updater: (value: $ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5>, + NSV, +>( + collection: C, + keyPath: [K, K2, K3, K4, K5], + notSetValue: NSV, + updater: ( + value: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5> | NSV + ) => S +): C; +declare function updateIn< + C, + K: $KeyOf, + K2: $KeyOf<$ValOf>, + K3: $KeyOf<$ValOf<$ValOf, K2>>, + K4: $KeyOf<$ValOf<$ValOf<$ValOf, K2>, K3>>, + K5: $KeyOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>>, + S: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5>, +>( + collection: C, + keyPath: [K, K2, K3, K4, K5], + updater: ( + value: $ValOf<$ValOf<$ValOf<$ValOf<$ValOf, K2>, K3>, K4>, K5> + ) => S +): C; + +declare function merge( + collection: C, + ...collections: Array< + | $IterableOf + | $Shape> + | PlainObjInput<$KeyOf, $ValOf>, + > +): C; +declare function mergeWith( + merger: (oldVal: $ValOf, newVal: $ValOf, key: $KeyOf) => $ValOf, + collection: C, + ...collections: Array< + | $IterableOf + | $Shape> + | PlainObjInput<$KeyOf, $ValOf>, + > +): C; +declare function mergeDeep( + collection: C, + ...collections: Array< + | $IterableOf + | $Shape> + | PlainObjInput<$KeyOf, $ValOf>, + > +): C; +declare function mergeDeepWith( + merger: (oldVal: any, newVal: any, key: any) => mixed, + collection: C, + ...collections: Array< + | $IterableOf + | $Shape> + | PlainObjInput<$KeyOf, $ValOf>, + > +): C; + +export { + Collection, + Seq, + List, + Map, + OrderedMap, + OrderedSet, + Range, + Repeat, + Record, + Set, + Stack, + fromJS, + is, + hash, + isImmutable, + isCollection, + isKeyed, + isIndexed, + isAssociative, + isOrdered, + isRecord, + isValueObject, + get, + has, + remove, + set, + update, + getIn, + hasIn, + removeIn, + setIn, + updateIn, + merge, + mergeWith, + mergeDeep, + mergeDeepWith, +}; + +export default { + Collection, + Seq, + + List, + Map, + OrderedMap, + OrderedSet, + PairSorting, + Range, + Repeat, + Record, + Set, + Stack, + + fromJS, + is, + hash, + + isImmutable, + isCollection, + isKeyed, + isIndexed, + isAssociative, + isOrdered, + isRecord, + isValueObject, + + get, + has, + remove, + set, + update, + getIn, + hasIn, + removeIn, + setIn, + updateIn, + merge, + mergeWith, + mergeDeep, + mergeDeepWith, +}; + +export type { + Comparator, + KeyedCollection, + IndexedCollection, + SetCollection, + KeyedSeq, + IndexedSeq, + SetSeq, + RecordFactory, + RecordOf, + RecordInstance, + ValueObject, + $KeyOf, + $ValOf, +}; diff --git a/type-definitions/ts-tests/covariance.ts b/type-definitions/ts-tests/covariance.ts new file mode 100644 index 0000000000..b4c01e50e9 --- /dev/null +++ b/type-definitions/ts-tests/covariance.ts @@ -0,0 +1,87 @@ +import { expect, test } from 'tstyche'; +import { + List, + Map, + MapOf, + OrderedMap, + OrderedSet, + Set, + Stack, +} from 'immutable'; + +class A { + x: number; + + constructor() { + this.x = 1; + } +} + +class B extends A { + y: string; + + constructor() { + super(); + this.y = 'B'; + } +} + +class C { + z: string; + + constructor() { + this.z = 'C'; + } +} + +test('List covariance', () => { + expect>().type.toBeAssignableWith(List()); + + expect(List([new B()])).type.toBe>(); + + expect>().type.not.toBeAssignableWith(List()); +}); + +test('Map covariance', () => { + expect>().type.toBeAssignableWith>(); + + expect(Map({ b: new B() })).type.toBe>(); + + expect>().type.not.toBeAssignableWith>(); +}); + +test('Set covariance', () => { + expect>().type.toBeAssignableWith>(); + + expect(Set([new B()])).type.toBe>(); + + expect>().type.not.toBeAssignableWith>(); +}); + +test('Stack covariance', () => { + expect>().type.toBeAssignableWith>(); + + expect(Stack([new B()])).type.toBe>(); + + expect>().type.not.toBeAssignableWith>(); +}); + +test('OrderedMap covariance', () => { + expect>().type.toBeAssignableWith< + OrderedMap + >(); + + expect(OrderedMap({ b: new B() })).type.toBe>(); + + expect>().type.not.toBeAssignableWith< + OrderedMap + >(); +}); + +test('OrderedSet covariance', () => { + expect>().type.toBeAssignableWith>(); + + expect(OrderedSet([new B()])).type.toBe>(); + + expect>().type.not.toBeAssignableWith>(); +}); diff --git a/type-definitions/ts-tests/deepCopy.ts b/type-definitions/ts-tests/deepCopy.ts new file mode 100644 index 0000000000..25e262fd81 --- /dev/null +++ b/type-definitions/ts-tests/deepCopy.ts @@ -0,0 +1,112 @@ +import { describe, expect, test } from 'tstyche'; +import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; + +describe('DeepCopy', () => { + test('basic types', () => { + expect< + DeepCopy<{ + a: number; + b: number; + }> + >().type.toBe<{ + a: number; + b: number; + }>(); + }); + + test('iterables', () => { + expect>().type.toBe(); + + expect>>().type.toBe(); + }); + + test('immutable first-level types', () => { + expect>>().type.toBe<{ + [x: string]: string; + }>(); + + // should be `{ [x: string]: object }`, but there is an issue with circular references + expect>>().type.toBe<{ + [x: string]: unknown; + }>(); + + // should be `{ [x: string]: object; [x: number]: object }`, but there is an issue with circular references + expect>>().type.toBe<{ + [x: string]: unknown; + [x: number]: unknown; + }>(); + + expect>>().type.toBe(); + + expect>>().type.toBe(); + }); + + test('keyed', () => { + expect>>().type.toBe<{ + [x: string]: number; + }>(); + + expect>>().type.toBe<{ + [x: string]: number; + [x: number]: number; + }>(); + + expect>>().type.toBe<{ + [x: string]: number; + [x: number]: number; + }>(); + + expect>>().type.toBe<{ + [x: string]: number; + [x: number]: number; + }>(); + }); + + test('nested', () => { + // should be `{ map: { [x: string]: string }; list: string[]; set: string[] }`, but there is an issue with circular references + expect< + DeepCopy<{ + map: Map; + list: List; + set: Set; + }> + >().type.toBe<{ map: unknown; list: unknown; set: unknown }>(); + + // should be `{ map: { [x: string]: string } }`, but there is an issue with circular references + expect>>>().type.toBe<{ + map: unknown; + }>(); + }); + + test('circular references', () => { + type Article = Record<{ title: string; tag: Tag }>; + type Tag = Record<{ name: string; article: Article }>; + + // should handle circular references here somehow + expect>().type.toBe<{ title: string; tag: unknown }>(); + }); + + test('circular references #1957', () => { + class Foo1 extends Record<{ foo: undefined | Foo1 }>({ + foo: undefined, + }) {} + + class Foo2 extends Record<{ foo?: Foo2 }>({ + foo: undefined, + }) {} + + class Foo3 extends Record<{ foo: null | Foo3 }>({ + foo: null, + }) {} + + expect>().type.toBe<{ foo: unknown }>(); + expect>().type.toBe<{ foo?: unknown }>(); + expect>().type.toBe<{ foo: unknown }>(); + + class FooWithList extends Record<{ foo: undefined | List }>({ + foo: undefined, + }) {} + + expect>().type.toBe<{ foo: unknown }>(); + }); +}); diff --git a/type-definitions/ts-tests/empty.ts b/type-definitions/ts-tests/empty.ts new file mode 100644 index 0000000000..e9425c6eb5 --- /dev/null +++ b/type-definitions/ts-tests/empty.ts @@ -0,0 +1,40 @@ +import { expect, test } from 'tstyche'; +import { Seq, Collection } from 'immutable'; + +test('typed empty Seq', () => { + expect(Seq()).type.toBe>(); + + expect(Seq()).type.toBe>(); + + expect(Seq.Indexed()).type.toBe>(); + + expect(Seq.Indexed()).type.toBe>(); + + expect(Seq.Keyed()).type.toBe>(); + + expect(Seq.Keyed()).type.toBe>(); + + expect(Seq.Set()).type.toBe>(); + + expect(Seq.Set()).type.toBe>(); +}); + +test('typed empty Collection', () => { + expect(Collection()).type.toBe>(); + + expect(Collection()).type.toBe>(); + + expect(Collection.Indexed()).type.toBe>(); + + expect(Collection.Indexed()).type.toBe>(); + + expect(Collection.Keyed()).type.toBe>(); + + expect(Collection.Keyed()).type.toBe< + Collection.Keyed + >(); + + expect(Collection.Set()).type.toBe>(); + + expect(Collection.Set()).type.toBe>(); +}); diff --git a/type-definitions/ts-tests/es6-collections.ts b/type-definitions/ts-tests/es6-collections.ts new file mode 100644 index 0000000000..790bc3cf2b --- /dev/null +++ b/type-definitions/ts-tests/es6-collections.ts @@ -0,0 +1,21 @@ +import { expect, test } from 'tstyche'; +import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable'; + +test('immutable.js collections', () => { + const mapImmutable: ImmutableMap = ImmutableMap< + string, + number + >(); + const setImmutable: ImmutableSet = ImmutableSet(); + + expect(mapImmutable.delete('foo')).type.toBe>(); + expect(setImmutable.delete('bar')).type.toBe>(); +}); + +test('ES6 collections', () => { + const mapES6: Map = new Map(); + const setES6: Set = new Set(); + + expect(mapES6.delete('foo')).type.toBe(); + expect(setES6.delete('bar')).type.toBe(); +}); diff --git a/type-definitions/ts-tests/exports.ts b/type-definitions/ts-tests/exports.ts new file mode 100644 index 0000000000..39f9d2fe49 --- /dev/null +++ b/type-definitions/ts-tests/exports.ts @@ -0,0 +1,112 @@ +// Some tests look like they are repeated in order to avoid false positives. + +import { expect, test } from 'tstyche'; +import * as Immutable from 'immutable'; +import { + List, + Map, + OrderedMap, + OrderedSet, + Range, + Repeat, + Seq, + Set, + Stack, + Collection, +} from 'immutable'; + +test('named imports', () => { + expect(List).type.toBe(); + + expect(Map).type.toBe(); + + expect(OrderedMap).type.toBe(); + + expect(OrderedSet).type.toBe(); + + expect(Range).type.toBe< + ( + start: number, + end: number, + step?: number | undefined + ) => Seq.Indexed + >(); + + expect(Repeat).type.toBe< + (value: T, times?: number | undefined) => Seq.Indexed + >(); + + expect(Seq).type.toBe(); + + expect(Set).type.toBe(); + + expect(Stack).type.toBe(); + + expect(Collection).type.toBe(); + + expect(Collection.Set).type.toBe< + ( + collection?: Iterable | ArrayLike | undefined + ) => Collection.Set + >(); + + expect(Collection.Keyed).type.toBe<{ + (collection?: Iterable<[K, V]> | undefined): Collection.Keyed; + (obj: { [key: string]: V }): Collection.Keyed; + }>(); + + expect(Collection.Indexed).type.toBe< + ( + collection?: Iterable | ArrayLike | undefined + ) => Collection.Indexed + >(); +}); + +test('namespace import', () => { + expect(Immutable.List).type.toBe(); + + expect(Immutable.Map).type.toBe(); + + expect(Immutable.OrderedMap).type.toBe(); + + expect(Immutable.OrderedSet).type.toBe(); + + expect(Immutable.Range).type.toBe< + ( + start: number, + end: number, + step?: number | undefined + ) => Immutable.Seq.Indexed + >(); + + expect(Immutable.Repeat).type.toBe< + (value: T, times?: number | undefined) => Immutable.Seq.Indexed + >(); + + expect(Immutable.Seq).type.toBe(); + + expect(Immutable.Set).type.toBe(); + + expect(Immutable.Stack).type.toBe(); + + expect(Immutable.Collection).type.toBe(); + + expect(Immutable.Collection.Set).type.toBe< + ( + collection?: Iterable | ArrayLike | undefined + ) => Immutable.Collection.Set + >(); + + expect(Immutable.Collection.Keyed).type.toBe<{ + ( + collection?: Iterable<[K, V]> | undefined + ): Immutable.Collection.Keyed; + (obj: { [key: string]: V }): Immutable.Collection.Keyed; + }>(); + + expect(Immutable.Collection.Indexed).type.toBe< + ( + collection?: Iterable | ArrayLike | undefined + ) => Immutable.Collection.Indexed + >(); +}); diff --git a/type-definitions/ts-tests/from-js.ts b/type-definitions/ts-tests/from-js.ts new file mode 100644 index 0000000000..f04a1e78f8 --- /dev/null +++ b/type-definitions/ts-tests/from-js.ts @@ -0,0 +1,46 @@ +import { expect, test } from 'tstyche'; +import { fromJS, Collection, List, Map, MapOf } from 'immutable'; + +test('fromJS', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect(fromJS({}, (a: any, b: any) => b)).type.toBe< + Collection + >(); + + expect(fromJS('abc')).type.toBe(); + + expect(fromJS([0, 1, 2])).type.toBe>(); + + expect(fromJS(List([0, 1, 2]))).type.toBe>(); + + expect(fromJS({ a: 0, b: 1, c: 2 })).type.toBe< + Map<'b' | 'a' | 'c', number> + >(); + + expect(fromJS(Map({ a: 0, b: 1, c: 2 }))).type.toBe< + MapOf<{ a: number; b: number; c: number }> + >(); + + expect(fromJS([{ a: 0 }])).type.toBe>>(); + + expect(fromJS({ a: [0] })).type.toBe>>(); + + expect(fromJS([[[0]]])).type.toBe>>>(); + + expect(fromJS({ a: { b: { c: 0 } } })).type.toBe< + Map<'a', Map<'b', Map<'c', number>>> + >(); +}); + +test('fromJS in an array of function', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const create = [(data: any) => data, fromJS][1]; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect(create({ a: 'A' })).type.toBe(); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const createConst = ([(data: any) => data, fromJS] as const)[1]; + + expect(createConst({ a: 'A' })).type.toBe>(); +}); diff --git a/type-definitions/ts-tests/functional.ts b/type-definitions/ts-tests/functional.ts new file mode 100644 index 0000000000..01a8636c50 --- /dev/null +++ b/type-definitions/ts-tests/functional.ts @@ -0,0 +1,174 @@ +import { expect, test } from 'tstyche'; +import { + get, + getIn, + has, + hasIn, + set, + remove, + update, + Map, + List, + MapOf, +} from 'immutable'; + +test('get', () => { + expect(get([1, 2, 3], 0)).type.toBe(); + + expect(get([1, 2, 3], 0, 'a')).type.toBe(); + + expect(get({ x: 10, y: 20 }, 'x')).type.toBe(); + + expect(get({ x: 10, y: 20 }, 'z', 'missing')).type.toBe(); +}); + +test('getIn', () => { + expect(getIn('a', ['length' as const])).type.toBe(); + + expect(getIn([1, 2, 3], [0])).type.toBe(); + + // first parameter type is Array so we can not detect that the number will be invalid + expect(getIn([1, 2, 3], [99])).type.toBe(); + + // We do not handle List in getIn TS type yet (hard to convert to a tuple) + expect(getIn([1, 2, 3], List([0]))).type.toBe(); + + expect(getIn([1, 2, 3], [0], 'a' as const)).type.toBe(); + + expect(getIn(List([1, 2, 3]), [0])).type.toBe(); + + // first parameter type is Array so we can not detect that the number will be invalid + expect(getIn(List([1, 2, 3]), [99])).type.toBe(); + + expect(getIn(List([1, 2, 3]), ['a' as const])).type.toBe(); + + expect( + getIn(List([1, 2, 3]), ['a' as const], 'missing') + ).type.toBe<'missing'>(); + + expect(getIn({ x: 10, y: 20 }, ['x' as const])).type.toBe(); + + expect( + getIn({ x: 10, y: 20 }, ['z' as const], 'missing') + ).type.toBe<'missing'>(); + + expect(getIn({ x: { y: 20 } }, ['x' as const])).type.toBe<{ y: number }>(); + + expect(getIn({ x: { y: 20 } }, ['z' as const])).type.toBe(); + + expect( + getIn({ x: { y: 20 } }, ['x' as const, 'y' as const]) + ).type.toBe(); + + expect( + getIn({ x: Map({ y: 20 }) }, ['x' as const, 'y' as const]) + ).type.toBe(); + + expect( + getIn(Map({ x: Map({ y: 20 }) }), ['x' as const, 'y' as const]) + ).type.toBe(); + + const o = Map({ x: List([Map({ y: 20 })]) }); + + expect(getIn(o, ['x' as const, 'y' as const])).type.toBe(); + + expect(getIn(o, ['x' as const])).type.toBe>>(); + + expect(getIn(o, ['x' as const, 0])).type.toBe>(); + + expect(getIn(o, ['x' as const, 0, 'y' as const])).type.toBe(); +}); + +test('has', () => { + expect(has([1, 2, 3], 0)).type.toBe(); + + expect(has({ x: 10, y: 20 }, 'x')).type.toBe(); +}); + +test('hasIn', () => { + expect(hasIn('a', ['length' as const])).type.toBe(); + + expect(hasIn(123, [])).type.toBe(); + + expect(hasIn(true, [])).type.toBe(); + + expect(hasIn([1, 2, 3], [0])).type.toBe(); + + // first parameter type is Array so we can not detect that the number will be invalid + expect(hasIn([1, 2, 3], [99])).type.toBe(); + + // We do not handle List in hasIn TS type yet (hard to convert to a tuple) + expect(hasIn([1, 2, 3], List([0]))).type.toBe(); + + expect(hasIn(List([1, 2, 3]), [0])).type.toBe(); + + // first parameter type is Array so we can not detect that the number will be invalid + expect(hasIn(List([1, 2, 3]), [99])).type.toBe(); + + expect(hasIn(List([1, 2, 3]), ['a' as const])).type.toBe(); + + expect(hasIn({ x: 10, y: 20 }, ['x' as const])).type.toBe(); + + expect(hasIn({ x: { y: 20 } }, ['z' as const])).type.toBe(); + + expect( + hasIn({ x: { y: 20 } }, ['x' as const, 'y' as const]) + ).type.toBe(); + + expect( + hasIn({ x: Map({ y: 20 }) }, ['x' as const, 'y' as const]) + ).type.toBe(); + + expect( + hasIn(Map({ x: Map({ y: 20 }) }), ['x' as const, 'y' as const]) + ).type.toBe(); + + const o = Map({ x: List([Map({ y: 20 })]) }); + + expect(hasIn(o, ['x' as const, 'y' as const])).type.toBe(); + + expect(hasIn(o, ['x' as const, 0, 'y' as const])).type.toBe(); +}); + +test('set', () => { + expect(set([1, 2, 3], 0, 10)).type.toBe(); + + expect(set([1, 2, 3], 0, 'a')).type.toRaiseError(); + + expect(set([1, 2, 3], 'a', 0)).type.toRaiseError(); + + expect(set({ x: 10, y: 20 }, 'x', 100)).type.toBe<{ + x: number; + y: number; + }>(); + + expect(set({ x: 10, y: 20 }, 'x', 'a')).type.toRaiseError(); +}); + +test('remove', () => { + expect(remove([1, 2, 3], 0)).type.toBe(); + + expect(remove({ x: 10, y: 20 }, 'x')).type.toBe<{ + x: number; + y: number; + }>(); +}); + +test('update', () => { + expect(update([1, 2, 3], 0, (v: number) => v + 1)).type.toBe(); + + expect(update([1, 2, 3], 0, 1)).type.toRaiseError(); + + expect(update([1, 2, 3], 0, (v: string) => v + 'a')).type.toRaiseError(); + + expect(update([1, 2, 3], 'a', (v: number) => v + 1)).type.toRaiseError(); + + expect(update({ x: 10, y: 20 }, 'x', (v: number) => v + 1)).type.toBe<{ + x: number; + y: number; + }>(); + + expect( + update({ x: 10, y: 20 }, 'x', (v: string) => v + 'a') + ).type.toRaiseError(); +}); diff --git a/type-definitions/ts-tests/groupBy.ts b/type-definitions/ts-tests/groupBy.ts new file mode 100644 index 0000000000..141bfc2912 --- /dev/null +++ b/type-definitions/ts-tests/groupBy.ts @@ -0,0 +1,59 @@ +import { expect, test } from 'tstyche'; +import { + Collection, + List, + Map, + OrderedMap, + Set, + OrderedSet, + Seq, + Stack, + MapOf, +} from 'immutable'; + +test('groupBy', () => { + expect(Collection(['a', 'b', 'c', 'a']).groupBy((v) => v)).type.toBe< + Map> + >(); + + expect( + Collection({ a: 1, b: 2, c: 3, d: 1 }).groupBy((v) => `key-${v}`) + ).type.toBe>>(); + + expect(List(['a', 'b', 'c', 'a']).groupBy((v) => v)).type.toBe< + Map> + >(); + + expect(Seq(['a', 'b', 'c', 'a']).groupBy((v) => v)).type.toBe< + Map> + >(); + + expect(Seq({ a: 1, b: 2, c: 3, d: 1 }).groupBy((v) => `key-${v}`)).type.toBe< + Map> + >(); + + expect(Set(['a', 'b', 'c', 'a']).groupBy((v) => v)).type.toBe< + Map> + >(); + + expect(Stack(['a', 'b', 'c', 'a']).groupBy((v) => v)).type.toBe< + Map> + >(); + + expect(OrderedSet(['a', 'b', 'c', 'a']).groupBy((v) => v)).type.toBe< + Map> + >(); + + expect( + Map({ a: 1, b: 2, c: 3, d: 1 }).groupBy((v) => `key-${v}`) + ).type.toBe>>(); + + // type should be something like Map>> but groupBy returns a wrong type with `this` + expect(Map({ a: 1, b: 2, c: 3, d: 1 }).groupBy((v) => `key-${v}`)).type.toBe< + Map> + >(); + + expect( + OrderedMap({ a: 1, b: 2, c: 3, d: 1 }).groupBy((v) => `key-${v}`) + ).type.toBe>>(); +}); diff --git a/type-definitions/ts-tests/list.ts b/type-definitions/ts-tests/list.ts new file mode 100644 index 0000000000..2b86dca369 --- /dev/null +++ b/type-definitions/ts-tests/list.ts @@ -0,0 +1,403 @@ +import { expect, pick, test } from 'tstyche'; +import { + List, + get, + set, + remove, + update, + setIn, + removeIn, + updateIn, + merge, +} from 'immutable'; + +test('#constructor', () => { + expect(List()).type.toBe>(); + + expect>().type.toBeAssignableWith(List()); + + expect>().type.toBeAssignableWith(List([1, 'a'])); + expect>().type.not.toBeAssignableWith(List([1, 'a'])); +}); + +test('#size', () => { + expect(pick(List(), 'size')).type.toBe<{ readonly size: number }>(); +}); + +test('#setSize', () => { + expect(List().setSize(10)).type.toBe>(); + + expect(List().setSize('foo')).type.toRaiseError(); +}); + +test('.of', () => { + expect(List.of(1, 2, 3)).type.toBe>(); + + expect(List.of('a', 1)).type.toRaiseError(); + + expect(List.of('a', 1)).type.toBe>(); +}); + +test('#get', () => { + expect(List().get(4)).type.toBe(); + + expect(List().get(4, 'a')).type.toBe(); + + expect(List().get(4, 'a')).type.toRaiseError(); + + expect(get(List(), 4)).type.toBe(); + + expect(get(List(), 4, 'a')).type.toBe(); +}); + +test('#set', () => { + expect(List().set(0, 0)).type.toBe>(); + + expect(List().set(1, 'a')).type.toRaiseError(); + + expect(List().set('a', 1)).type.toRaiseError(); + + expect(List().set(0, 1)).type.toBe>(); + + expect(List().set(0, 'a')).type.toBe< + List + >(); + + expect(set(List(), 0, 0)).type.toBe>(); +}); + +test('#first', () => { + const a = List().first(); + // ^? + expect(List().first()).type.toBe(); + expect(List().first('first')).type.toBe(); +}); + +test('#last', () => { + expect(List().last()).type.toBe(); + expect(List().last('last')).type.toBe(); +}); + +test('#set', () => { + expect(set(List(), 1, 'a')).type.toRaiseError(); + + expect(set(List(), 'a', 1)).type.toRaiseError(); +}); + +test('#setIn', () => { + expect(List().setIn([], 0)).type.toBe>(); + + expect(setIn(List(), [], 0)).type.toBe>(); +}); + +test('#insert', () => { + expect(List().insert(0, 0)).type.toBe>(); + + expect(List().insert(1, 'a')).type.toRaiseError(); + + expect(List().insert('a', 1)).type.toRaiseError(); + + expect(List().insert(0, 1)).type.toBe< + List + >(); + + expect(List().insert(0, 'a')).type.toBe< + List + >(); +}); + +test('#push', () => { + expect(List().push(0, 0)).type.toBe>(); + + expect(List().push(1, 'a')).type.toRaiseError(); + + expect(List().push('a', 1)).type.toRaiseError(); + + expect(List().push(0, 1)).type.toBe>(); + + expect(List().push(0, 'a')).type.toBe< + List + >(); +}); + +test('#unshift', () => { + expect(List().unshift(0, 0)).type.toBe>(); + + expect(List().unshift(1, 'a')).type.toRaiseError(); + + expect(List().unshift('a', 1)).type.toRaiseError(); + + expect(List().unshift(0, 1)).type.toBe< + List + >(); + + expect(List().unshift(0, 'a')).type.toBe< + List + >(); +}); + +test('#delete', () => { + expect(List().delete(0)).type.toBe>(); + + expect(List().delete('a')).type.toRaiseError(); +}); + +test('#deleteIn', () => { + expect(List().deleteIn([])).type.toBe>(); +}); + +test('#remove', () => { + expect(List().remove(0)).type.toBe>(); + + expect(List().remove('a')).type.toRaiseError(); + + expect(remove(List(), 0)).type.toBe>(); +}); + +test('#removeIn', () => { + expect(List().removeIn([])).type.toBe>(); + + expect(removeIn(List(), [])).type.toBe>(); +}); + +test('#clear', () => { + expect(List().clear()).type.toBe>(); + + expect(List().clear(10)).type.toRaiseError(); +}); + +test('#pop', () => { + expect(List().pop()).type.toBe>(); + + expect(List().pop(10)).type.toRaiseError(); +}); + +test('#shift', () => { + expect(List().shift()).type.toBe>(); + + expect(List().shift(10)).type.toRaiseError(); +}); + +test('#update', () => { + expect(List().update((v) => 1)).type.toBe(); + + expect( + List().update((v: List | undefined) => v) + ).type.toRaiseError(); + + expect(List().update(0, (v: number | undefined) => 0)).type.toBe< + List + >(); + + expect( + List().update(0, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect(List().update(1, 10, (v: number | undefined) => 0)).type.toBe< + List + >(); + + expect( + List().update(1, 'a', (v: number | undefined) => 0) + ).type.toRaiseError(); + + expect( + List().update(1, 10, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect(List().update(1, (v) => v?.toUpperCase())).type.toBe< + List + >(); + + expect(update(List(), 0, (v: number | undefined) => 0)).type.toBe< + List + >(); + + expect( + update(List(), 1, 10, (v: number) => v + 'a') + ).type.toRaiseError(); +}); + +test('#updateIn', () => { + expect(List().updateIn([], (v) => v)).type.toBe>(); + + expect(List().updateIn([], 10)).type.toRaiseError(); + + expect(updateIn(List(), [], (v) => v)).type.toBe>(); +}); + +test('#map', () => { + expect( + List().map((value: number, key: number, iter: List) => 1) + ).type.toBe>(); + + expect( + List().map((value: number, key: number, iter: List) => 'a') + ).type.toBe>(); + + expect( + List().map( + (value: number, key: number, iter: List) => 1 + ) + ).type.toBe>(); + + expect( + List().map( + (value: number, key: number, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: string, key: number, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: number, key: string, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: number, key: number, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: number, key: number, iter: List) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + List().flatMap((value: number, key: number, iter: List) => [ + 1, + ]) + ).type.toBe>(); + + expect( + List().flatMap((value: number, key: number, iter: List) => [ + 'a', + ]) + ).type.toBe>(); + + expect(List>().flatMap((list) => list)).type.toBe< + List + >(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => [1] + ) + ).type.toBe>(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: string, key: number, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: number, key: string, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => ['a'] + ) + ).type.toRaiseError(); +}); + +test('#merge', () => { + expect(List().merge(List())).type.toBe>(); + + expect(List().merge(List())).type.toBe< + List + >(); + + expect(List().merge(List())).type.toBe< + List + >(); + + expect(List().merge(List())).type.toBe< + List + >(); + + expect(merge(List(), List())).type.toBe>(); +}); + +test('#mergeIn', () => { + expect(List().mergeIn([], [])).type.toBe>(); +}); + +test('#mergeDeepIn', () => { + expect(List().mergeDeepIn([], [])).type.toBe>(); +}); + +test('#flatten', () => { + expect(List().flatten()).type.toBe< + Immutable.Collection + >(); + + expect(List().flatten(10)).type.toBe< + Immutable.Collection + >(); + + expect(List().flatten(false)).type.toBe< + Immutable.Collection + >(); + + expect(List().flatten('a')).type.toRaiseError(); +}); + +test('#withMutations', () => { + expect(List().withMutations((mutable) => mutable)).type.toBe< + List + >(); + + expect( + List().withMutations((mutable: List) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(List().asMutable()).type.toBe>(); +}); + +test('#asImmutable', () => { + expect(List().asImmutable()).type.toBe>(); +}); + +test('#toJS', () => { + expect(List>().toJS()).type.toBe(); +}); + +test('#toJSON', () => { + expect(List>().toJSON()).type.toBe[]>(); +}); + +test('for of loops', () => { + const list = List([1, 2, 3, 4]); + + for (const val of list) { + expect(val).type.toBe(); + } +}); diff --git a/type-definitions/ts-tests/map.ts b/type-definitions/ts-tests/map.ts new file mode 100644 index 0000000000..59f39eb36c --- /dev/null +++ b/type-definitions/ts-tests/map.ts @@ -0,0 +1,668 @@ +import { expect, pick, test } from 'tstyche'; +import { Map, List, MapOf, OrderedMap } from 'immutable'; + +test('#constructor', () => { + expect(Map()).type.toBe>(); + + expect(Map()).type.toBe>(); + + expect(Map([[1, 'a']])).type.toBe>(); + + expect(Map([['a', 'a']])).type.toBe>(); + + expect(Map(List<[number, string]>([[1, 'a']]))).type.toBe< + Map + >(); + + expect(Map({ a: 1 })).type.toBe>(); + + expect(Map({ a: 1, b: 'b' })).type.toBe>(); + + expect(Map({ a: Map({ b: Map({ c: 3 }) }) })).type.toBe< + MapOf<{ a: MapOf<{ b: MapOf<{ c: number }> }> }> + >(); + + expect(Map<{ a: string }>({ a: 1 })).type.toRaiseError(); + + expect(Map<{ a: string }>({ a: 'a', b: 'b' })).type.toRaiseError(); + + // TODO this type is really weird, it should be `Map` or MapOf<{ a: string }> See https://github.com/immutable-js/immutable-js/pull/1991#discussion_r1510863932 + expect(Map(List([List(['a', 'b'])]))).type.toBe>>>(); + + expect(Map([[1, 'a']])).type.not.toBeAssignableTo>(); + + expect(Map<'status', string>({ status: 'paid' })).type.toBe< + Map<'status', string> + >(); + + expect(Map<'status' | 'amount', string>({ status: 'paid' })).type.toBe< + Map<'status' | 'amount', string> + >(); + + expect( + Map<'status', string>({ status: 'paid', amount: 10 }) + ).type.toRaiseError(); +}); + +test('#size', () => { + expect(pick(Map(), 'size')).type.toBe<{ readonly size: number }>(); +}); + +test('#get', () => { + expect(Map().get(4)).type.toBe(); + + expect(Map().get(4, 'a')).type.toBe(); + + expect(Map().get(4, 'a')).type.toRaiseError(); + + expect(Map({ a: 4, b: true }).get('a')).type.toBe(); + + expect(Map({ a: 4, b: true }).get('b')).type.toBe(); + + expect( + Map({ a: Map({ b: true }) }) + .get('a') + .get('b') + ).type.toBe(); + + expect(Map({ a: 4 }).get('b')).type.toRaiseError(); + + expect(Map({ a: 4 }).get('b', undefined)).type.toBe(); + + expect(Map({ 1: 4 }).get(1)).type.toBe(); + + expect(Map({ 1: 4 }).get(2)).type.toRaiseError(); + + expect(Map({ 1: 4 }).get(2, 3)).type.toBe<3>(); + + const s1 = Symbol('s1'); + + expect(Map({ [s1]: 4 }).get(s1)).type.toBe(); + + const s2 = Symbol('s2'); + + expect(Map({ [s2]: 4 }).get(s1)).type.toRaiseError(); +}); + +test('#getIn', () => { + const result = Map({ a: 4, b: true }).getIn(['a']); + + expect(result).type.toBe(); + + expect(Map({ a: 4, b: true }).getIn(['a' as const])).type.toBe(); + + expect( + Map({ a: Map({ b: Map({ c: Map({ d: 4 }) }) }) }).getIn([ + 'a' as const, + 'b' as const, + 'c' as const, + 'd' as const, + ]) + ).type.toBe(); + + expect(Map({ a: [1] }).getIn(['a' as const, 0])).type.toBe(); + + expect(Map({ a: List([1]) }).getIn(['a' as const, 0])).type.toBe(); +}); + +test('#set', () => { + expect(Map().set(0, 0)).type.toBe>(); + + expect(Map().set(1, 'a')).type.toRaiseError(); + + expect(Map().set('a', 1)).type.toRaiseError(); + + expect(Map().set(0, 1)).type.toBe< + Map + >(); + + expect(Map().set(0, 'a')).type.toBe< + Map + >(); + + expect(Map({ a: 1 }).set('b', 'b')).type.toRaiseError(); + + expect(Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b')).type.toBe< + MapOf<{ a: number; b?: string | undefined }> + >(); + + expect( + Map<{ a: number; b?: string }>({ a: 1 }).set('b', undefined) + ).type.toBe>(); + + expect( + Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b').get('a') + ).type.toBe(); + + expect( + Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b').get('b') + ).type.toBe(); + + const customer = Map<{ phone: string | number }>({ + phone: 'bar', + }); + + expect(customer).type.toBeAssignableWith(customer.set('phone', 8)); +}); + +test('#setIn', () => { + expect(Map().setIn([], 0)).type.toBe>(); +}); + +test('#delete', () => { + expect(Map().delete(0)).type.toBe>(); + + expect(Map().delete('a')).type.toRaiseError(); + + expect(Map({ a: 1, b: 'b' }).delete('b')).type.toBe(); + + expect( + Map<{ a: number; b?: string }>({ a: 1, b: 'b' }).delete('b') + ).type.toBe>(); + + expect( + Map<{ a?: number; b?: string }>({ a: 1, b: 'b' }).remove('b').delete('a') + ).type.toBe>(); + + expect( + Map<{ a: number; b?: string }>({ a: 1, b: 'b' }).remove('b').get('a') + ).type.toBe(); + + expect( + Map<{ a: number; b?: string }>({ a: 1, b: 'b' }).remove('b').get('b') + ).type.toBe(); +}); + +test('#deleteAll', () => { + expect(Map().deleteAll([0])).type.toBe>(); + + expect(Map().deleteAll([0, 'a'])).type.toRaiseError(); +}); + +test('#deleteIn', () => { + expect(Map().deleteIn([])).type.toBe>(); +}); + +test('#remove', () => { + expect(Map().remove(0)).type.toBe>(); + + expect(Map().remove('a')).type.toRaiseError(); +}); + +test('#removeAll', () => { + expect(Map().removeAll([0])).type.toBe>(); + + expect(Map().removeAll([0, 'a'])).type.toRaiseError(); +}); + +test('#removeIn', () => { + expect(Map().removeIn([])).type.toBe>(); +}); + +test('#clear', () => { + expect(Map().clear()).type.toBe>(); + + expect(Map().clear(10)).type.toRaiseError(); +}); + +test('#update', () => { + expect(Map().update((v) => 1)).type.toBe(); + + expect( + Map().update((v: Map | undefined) => v) + ).type.toRaiseError(); + + expect( + Map().update(0, (v: number | undefined) => 0) + ).type.toBe>(); + + expect( + Map().update(0, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect( + Map().update(1, 10, (v: number | undefined) => 0) + ).type.toBe>(); + + expect( + Map().update(1, 'a', (v: number | undefined) => 0) + ).type.toRaiseError(); + + expect( + Map().update(1, 10, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect(Map({ a: 1, b: 'b' }).update('c', (v) => v)).type.toRaiseError(); + + expect(Map({ a: 1, b: 'b' }).update('b', (v) => v.toUpperCase())).type.toBe< + MapOf<{ a: number; b: string }> + >(); + + expect( + Map({ a: 1, b: 'b' }).update('b', 'NSV', (v) => v.toUpperCase()) + ).type.toBe>(); + + expect(Map({ a: 1, b: 'b' }).update((v) => ({ a: 'a' }))).type.toRaiseError(); + + expect( + Map({ a: 1, b: 'b' }).update((v) => v.set('a', 2).set('b', 'B')) + ).type.toBe>(); + + expect( + Map({ a: 1, b: 'b' }).update((v) => v.set('c', 'c')) + ).type.toRaiseError(); + + expect( + Map().update('noKey', (ls) => ls?.toUpperCase()) + ).type.toBe>(); +}); + +test('#updateIn', () => { + expect(Map().updateIn([], (v) => v)).type.toBe< + Map + >(); + + expect(Map().updateIn([], 10)).type.toRaiseError(); +}); + +test('#map', () => { + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toBe>(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toBe>(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toBe>(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: string, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: number, key: string, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#mapKeys', () => { + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toBe>(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toBe>(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toBe>(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: string, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: number, key: string, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toBe>(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [['a', 'b']] + ) + ).type.toBe>(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toBe>(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: string, key: number, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: number, key: string, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 'a']] + ) + ).type.toRaiseError(); +}); + +test('#merge', () => { + expect(Map().merge({ a: 1 })).type.toBe< + Map + >(); + + expect(Map().merge({ a: { b: 1 } })).type.toBe< + Map + >(); + + expect(Map().merge(Map())).type.toBe< + Map + >(); + + expect(Map().merge(Map())).type.toBe< + Map + >(); + + expect(Map().merge(Map())).type.toBe< + Map + >(); + + expect(Map().merge(Map())).type.toBe< + Map + >(); + + expect(Map({ a: 1 }).merge(Map({ b: 2 }))).type.toBe< + Map<'b' | 'a', number> + >(); +}); + +test('#mergeIn', () => { + expect(Map().mergeIn([], [])).type.toBe< + Map + >(); +}); + +test('#mergeWith', () => { + expect( + Map().mergeWith( + (prev: number, next: number, key: number) => 1, + Map() + ) + ).type.toBe>(); + + expect( + Map().mergeWith( + (prev: string, next: number, key: number) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: string, key: number) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: string) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: number) => 'a', + Map() + ) + ).type.toBe>(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: number) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: string) => 1, + { a: 1 } + ) + ).type.toBe>(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: string) => 1, + { a: 'a' } + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number | string, key: string) => 1, + { a: 'a' } + ) + ).type.toBe>(); + + expect( + Map().mergeWith( + (prev: number | string, next: number | string, key: number) => 1, + Map() + ) + ).type.toBe>(); +}); + +test('#mergeDeep', () => { + expect(Map().mergeDeep({ a: 1 })).type.toBe< + Map + >(); + + expect(Map().mergeDeep({ a: { b: 1 } })).type.toBe< + Map + >(); + + expect(Map().mergeDeep(Map({ a: { b: 1 } }))).type.toBe< + Map + >(); + + expect(Map().mergeDeep(Map())).type.toBe< + Map + >(); + + expect(Map().mergeDeep(Map())).type.toBe< + Map + >(); + + expect( + Map().mergeDeep(Map()) + ).type.toBe>(); + + expect( + Map().mergeDeep(Map()) + ).type.toBe>(); +}); + +test('#mergeDeepIn', () => { + expect(Map().mergeDeepIn([], [])).type.toBe< + Map + >(); +}); + +test('#mergeDeepWith', () => { + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + Map() + ) + ).type.toBe>(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + { a: 1 } + ) + ).type.toBe>(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + { a: 'a' } + ) + ).type.toRaiseError(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + Map() + ) + ).type.toBe>(); +}); + +test('#flip', () => { + expect(Map().flip()).type.toBe>(); +}); + +test('#sort', () => { + expect(Map().sort()).type.toBe< + Map & OrderedMap + >(); + expect(Map().sort((a, b) => 1)).type.toBe< + Map & OrderedMap + >(); + + expect(Map({ a: 'a' }).sort()).type.toBe< + MapOf<{ a: string }> & OrderedMap<'a', string> + >(); +}); + +test('#sortBy', () => { + expect(Map().sortBy((v) => v)).type.toBe< + Map & OrderedMap + >(); + + expect( + Map().sortBy( + (v) => v, + (a, b) => 1 + ) + ).type.toBe & OrderedMap>(); + expect(Map({ a: 'a' }).sortBy((v) => v)).type.toBe< + MapOf<{ a: string }> & OrderedMap<'a', string> + >(); +}); + +test('#withMutations', () => { + expect(Map().withMutations((mutable) => mutable)).type.toBe< + Map + >(); + + expect( + Map().withMutations((mutable: Map) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(Map().asMutable()).type.toBe>(); +}); + +test('#asImmutable', () => { + expect(Map().asImmutable()).type.toBe>(); +}); + +test('#toJS', () => { + expect(Map().toJS()).type.toBe<{ + [x: string]: number; + [x: number]: number; + [x: symbol]: number; + }>(); + + expect(Map({ a: 'A' }).toJS()).type.toBe<{ a: string }>(); + + expect(Map({ a: Map({ b: 'b' }) }).toJS()).type.toBe<{ + a: { b: string }; + }>(); +}); + +test('#toJSON', () => { + expect(Map({ a: Map({ b: 'b' }) }).toJSON()).type.toBe<{ + a: MapOf<{ b: string }>; + }>(); +}); diff --git a/type-definitions/ts-tests/ordered-map.ts b/type-definitions/ts-tests/ordered-map.ts new file mode 100644 index 0000000000..56341ff76e --- /dev/null +++ b/type-definitions/ts-tests/ordered-map.ts @@ -0,0 +1,504 @@ +import { expect, pick, test } from 'tstyche'; +import { OrderedMap, List } from 'immutable'; + +test('#constructor', () => { + expect(OrderedMap()).type.toBe>(); + + expect(OrderedMap()).type.toBe>(); + + expect(OrderedMap([[1, 'a']])).type.toBe>(); + + expect(OrderedMap(List<[number, string]>([[1, 'a']]))).type.toBe< + OrderedMap + >(); + + expect(OrderedMap({ a: 1 })).type.toBe>(); + + // No longer works in typescript@>=3.9 + // // $ExpectError - TypeScript does not support Lists as tuples + // OrderedMap(List([List(['a', 'b'])])); +}); + +test('#size', () => { + expect(pick(OrderedMap(), 'size')).type.toBe<{ readonly size: number }>(); +}); + +test('#get', () => { + expect(OrderedMap().get(4)).type.toBe(); + + expect(OrderedMap().get(4, 'a')).type.toBe(); + + expect(OrderedMap().get(4, 'a')).type.toRaiseError(); +}); + +test('#set', () => { + expect(OrderedMap().set(0, 0)).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().set(1, 'a')).type.toRaiseError(); + + expect(OrderedMap().set('a', 1)).type.toRaiseError(); + + expect(OrderedMap().set(0, 1)).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().set(0, 'a')).type.toBe< + OrderedMap + >(); +}); + +test('#setIn', () => { + expect(OrderedMap().setIn([], 0)).type.toBe< + OrderedMap + >(); +}); + +test('#delete', () => { + expect(OrderedMap().delete(0)).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().delete('a')).type.toRaiseError(); +}); + +test('#deleteAll', () => { + expect(OrderedMap().deleteAll([0])).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().deleteAll([0, 'a'])).type.toRaiseError(); +}); + +test('#deleteIn', () => { + expect(OrderedMap().deleteIn([])).type.toBe< + OrderedMap + >(); +}); + +test('#remove', () => { + expect(OrderedMap().remove(0)).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().remove('a')).type.toRaiseError(); +}); + +test('#removeAll', () => { + expect(OrderedMap().removeAll([0])).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().removeAll([0, 'a'])).type.toRaiseError(); +}); + +test('#removeIn', () => { + expect(OrderedMap().removeIn([])).type.toBe< + OrderedMap + >(); +}); + +test('#clear', () => { + expect(OrderedMap().clear()).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().clear(10)).type.toRaiseError(); +}); + +test('#update', () => { + expect(OrderedMap().update((v) => 1)).type.toBe(); + + expect( + OrderedMap().update( + (v: OrderedMap | undefined) => v + ) + ).type.toRaiseError(); + + expect( + OrderedMap().update(0, (v: number | undefined) => 0) + ).type.toBe>(); + + expect( + OrderedMap().update(0, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect( + OrderedMap().update(1, 10, (v: number | undefined) => 0) + ).type.toBe>(); + + expect( + OrderedMap().update(1, 'a', (v: number | undefined) => 0) + ).type.toRaiseError(); + + expect( + OrderedMap().update( + 1, + 10, + (v: number | undefined) => v + 'a' + ) + ).type.toRaiseError(); +}); + +test('#updateIn', () => { + expect(OrderedMap().updateIn([], (v) => v)).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().updateIn([], 10)).type.toRaiseError(); +}); + +test('#map', () => { + expect( + OrderedMap().map( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toBe>(); + + expect( + OrderedMap().map( + (value: number, key: number, iter: OrderedMap) => 'a' + ) + ).type.toBe>(); + + expect( + OrderedMap().map( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toBe>(); + + expect( + OrderedMap().map( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().map( + (value: string, key: number, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().map( + (value: number, key: string, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().map( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().map( + (value: number, key: number, iter: OrderedMap) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#mapKeys', () => { + expect( + OrderedMap().mapKeys( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toBe>(); + + expect( + OrderedMap().mapKeys( + (value: number, key: number, iter: OrderedMap) => 'a' + ) + ).type.toBe>(); + + expect( + OrderedMap().mapKeys( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toBe>(); + + expect( + OrderedMap().mapKeys( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mapKeys( + (value: string, key: number, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mapKeys( + (value: number, key: string, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mapKeys( + (value: number, key: number, iter: OrderedMap) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mapKeys( + (value: number, key: number, iter: OrderedMap) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + OrderedMap().flatMap( + (value: number, key: number, iter: OrderedMap) => [[0, 1]] + ) + ).type.toBe>(); + + expect( + OrderedMap().flatMap( + (value: number, key: number, iter: OrderedMap) => [ + ['a', 'b'], + ] + ) + ).type.toBe>(); + + expect( + OrderedMap().flatMap( + (value: number, key: number, iter: OrderedMap) => [[0, 1]] + ) + ).type.toBe>(); + + expect( + OrderedMap().flatMap( + (value: number, key: number, iter: OrderedMap) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + OrderedMap().flatMap( + (value: string, key: number, iter: OrderedMap) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + OrderedMap().flatMap( + (value: number, key: string, iter: OrderedMap) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + OrderedMap().flatMap( + (value: number, key: number, iter: OrderedMap) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + OrderedMap().flatMap( + (value: number, key: number, iter: OrderedMap) => [ + [0, 'a'], + ] + ) + ).type.toRaiseError(); +}); + +test('#merge', () => { + expect(OrderedMap().merge({ a: 1 })).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().merge({ a: { b: 1 } })).type.toBe< + OrderedMap + >(); + + expect( + OrderedMap().merge(OrderedMap()) + ).type.toBe>(); + + expect( + OrderedMap().merge(OrderedMap()) + ).type.toBe>(); + + expect( + OrderedMap().merge(OrderedMap()) + ).type.toBe>(); + + expect( + OrderedMap().merge(OrderedMap()) + ).type.toBe>(); +}); + +test('#mergeIn', () => { + expect(OrderedMap().mergeIn([], [])).type.toBe< + OrderedMap + >(); +}); + +test('#mergeWith', () => { + expect( + OrderedMap().mergeWith( + (prev: number, next: number, key: number) => 1, + OrderedMap() + ) + ).type.toBe>(); + + expect( + OrderedMap().mergeWith( + (prev: string, next: number, key: number) => 1, + OrderedMap() + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeWith( + (prev: number, next: string, key: number) => 1, + OrderedMap() + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeWith( + (prev: number, next: number, key: string) => 1, + OrderedMap() + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeWith( + (prev: number, next: number, key: number) => 'a', + OrderedMap() + ) + ).type.toBe>(); + + expect( + OrderedMap().mergeWith( + (prev: number, next: number, key: number) => 1, + OrderedMap() + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeWith( + (prev: number, next: number, key: string) => 1, + { a: 1 } + ) + ).type.toBe>(); + + expect( + OrderedMap().mergeWith( + (prev: number, next: number, key: string) => 1, + { a: 'a' } + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeWith( + (prev: number | string, next: number | string, key: number) => 1, + OrderedMap() + ) + ).type.toBe>(); +}); + +test('#mergeDeep', () => { + expect(OrderedMap().mergeDeep({ a: 1 })).type.toBe< + OrderedMap + >(); + + expect(OrderedMap().mergeDeep({ a: { b: 1 } })).type.toBe< + OrderedMap + >(); + + expect( + OrderedMap().mergeDeep(OrderedMap()) + ).type.toBe>(); + + expect( + OrderedMap().mergeDeep(OrderedMap()) + ).type.toBe>(); + + expect( + OrderedMap().mergeDeep( + OrderedMap() + ) + ).type.toBe>(); + + expect( + OrderedMap().mergeDeep( + OrderedMap() + ) + ).type.toBe>(); +}); + +test('#mergeDeepIn', () => { + expect(OrderedMap().mergeDeepIn([], [])).type.toBe< + OrderedMap + >(); +}); + +test('#mergeDeepWith', () => { + expect( + OrderedMap().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + OrderedMap() + ) + ).type.toBe>(); + + expect( + OrderedMap().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + OrderedMap() + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + { a: 1 } + ) + ).type.toBe>(); + + expect( + OrderedMap().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + { a: 'a' } + ) + ).type.toRaiseError(); + + expect( + OrderedMap().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + OrderedMap() + ) + ).type.toBe>(); +}); + +test('#flip', () => { + expect(OrderedMap().flip()).type.toBe< + OrderedMap + >(); +}); + +test('#withMutations', () => { + expect( + OrderedMap().withMutations((mutable) => mutable) + ).type.toBe>(); + + expect( + OrderedMap().withMutations( + (mutable: OrderedMap) => mutable + ) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(OrderedMap().asMutable()).type.toBe< + OrderedMap + >(); +}); + +test('#asImmutable', () => { + expect(OrderedMap().asImmutable()).type.toBe< + OrderedMap + >(); +}); diff --git a/type-definitions/ts-tests/ordered-set.ts b/type-definitions/ts-tests/ordered-set.ts new file mode 100644 index 0000000000..b753c09a53 --- /dev/null +++ b/type-definitions/ts-tests/ordered-set.ts @@ -0,0 +1,278 @@ +import { expect, pick, test } from 'tstyche'; +import { Collection, OrderedSet, Map } from 'immutable'; + +test('#constructor', () => { + expect(OrderedSet()).type.toBe>(); + + expect(OrderedSet()).type.toBe>(); + + expect(OrderedSet([1, 'a'])).type.toBe>(); + + expect(OrderedSet([1, 'a'])).type.not.toBeAssignableTo(OrderedSet()); +}); + +test('#size', () => { + expect(pick(OrderedSet(), 'size')).type.toBe<{ readonly size: number }>(); +}); + +test('.of', () => { + expect(OrderedSet.of(1, 2, 3)).type.toBe>(); + + expect(OrderedSet.of('a', 1)).type.toRaiseError(); + + expect(OrderedSet.of('a', 1)).type.toBe< + OrderedSet + >(); +}); + +test('.fromKeys', () => { + expect(OrderedSet.fromKeys(Map())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet.fromKeys(Map())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet.fromKeys({ a: 1 })).type.toBe>(); + + expect( + OrderedSet.fromKeys(Map()) + ).type.toRaiseError(); + + expect( + OrderedSet.fromKeys(Map()) + ).type.toBe>(); +}); + +test('#get', () => { + expect(OrderedSet().get(4)).type.toBe(); + + expect(OrderedSet().get(4, 'a')).type.toBe(); + + expect(OrderedSet().get(4, 'a')).type.toRaiseError(); +}); + +test('#delete', () => { + expect(OrderedSet().delete(0)).type.toBe>(); + + expect(OrderedSet().delete('a')).type.toRaiseError(); +}); + +test('#remove', () => { + expect(OrderedSet().remove(0)).type.toBe>(); + + expect(OrderedSet().remove('a')).type.toRaiseError(); +}); + +test('#clear', () => { + expect(OrderedSet().clear()).type.toBe>(); + + expect(OrderedSet().clear(10)).type.toRaiseError(); +}); + +test('#map', () => { + expect( + OrderedSet().map( + (value: number, key: number, iter: OrderedSet) => 1 + ) + ).type.toBe>(); + + expect( + OrderedSet().map( + (value: number, key: number, iter: OrderedSet) => 'a' + ) + ).type.toBe>(); + + expect( + OrderedSet().map( + (value: number, key: number, iter: OrderedSet) => 1 + ) + ).type.toBe>(); + + expect( + OrderedSet().map( + (value: number, key: number, iter: OrderedSet) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedSet().map( + (value: string, key: number, iter: OrderedSet) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedSet().map( + (value: number, key: string, iter: OrderedSet) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedSet().map( + (value: number, key: number, iter: OrderedSet) => 1 + ) + ).type.toRaiseError(); + + expect( + OrderedSet().map( + (value: number, key: number, iter: OrderedSet) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + OrderedSet().flatMap( + (value: number, key: number, iter: OrderedSet) => [1] + ) + ).type.toBe>(); + + expect( + OrderedSet().flatMap( + (value: number, key: number, iter: OrderedSet) => ['a'] + ) + ).type.toBe>(); + + expect( + OrderedSet().flatMap( + (value: number, key: number, iter: OrderedSet) => [1] + ) + ).type.toBe>(); + + expect( + OrderedSet().flatMap( + (value: number, key: number, iter: OrderedSet) => [1] + ) + ).type.toRaiseError(); + + expect( + OrderedSet().flatMap( + (value: string, key: number, iter: OrderedSet) => [1] + ) + ).type.toRaiseError(); + + expect( + OrderedSet().flatMap( + (value: number, key: string, iter: OrderedSet) => [1] + ) + ).type.toRaiseError(); + + expect( + OrderedSet().flatMap( + (value: number, key: number, iter: OrderedSet) => [1] + ) + ).type.toRaiseError(); + + expect( + OrderedSet().flatMap( + (value: number, key: number, iter: OrderedSet) => ['a'] + ) + ).type.toRaiseError(); +}); + +test('#union', () => { + expect(OrderedSet().union(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet().union(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet().union(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet().union(OrderedSet())).type.toBe< + OrderedSet + >(); +}); + +test('#merge', () => { + expect(OrderedSet().merge(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet().merge(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet().merge(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect(OrderedSet().merge(OrderedSet())).type.toBe< + OrderedSet + >(); +}); + +test('#intersect', () => { + expect(OrderedSet().intersect(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect( + OrderedSet().intersect(OrderedSet()) + ).type.toRaiseError(); + + expect( + OrderedSet().intersect(OrderedSet()) + ).type.toBe>(); + + expect( + OrderedSet().intersect(OrderedSet()) + ).type.toBe>(); +}); + +test('#subtract', () => { + expect(OrderedSet().subtract(OrderedSet())).type.toBe< + OrderedSet + >(); + + expect( + OrderedSet().subtract(OrderedSet()) + ).type.toRaiseError(); + + expect( + OrderedSet().subtract(OrderedSet()) + ).type.toBe>(); + + expect( + OrderedSet().subtract(OrderedSet()) + ).type.toBe>(); +}); + +test('#flatten', () => { + expect(OrderedSet().flatten()).type.toBe< + Collection + >(); + + expect(OrderedSet().flatten(10)).type.toBe< + Collection + >(); + + expect(OrderedSet().flatten(false)).type.toBe< + Collection + >(); + + expect(OrderedSet().flatten('a')).type.toRaiseError(); +}); + +test('#withMutations', () => { + expect(OrderedSet().withMutations((mutable) => mutable)).type.toBe< + OrderedSet + >(); + + expect( + OrderedSet().withMutations((mutable: OrderedSet) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(OrderedSet().asMutable()).type.toBe>(); +}); + +test('#asImmutable', () => { + expect(OrderedSet().asImmutable()).type.toBe>(); +}); diff --git a/type-definitions/ts-tests/partition.ts b/type-definitions/ts-tests/partition.ts new file mode 100644 index 0000000000..a9d4871e94 --- /dev/null +++ b/type-definitions/ts-tests/partition.ts @@ -0,0 +1,184 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions */ +import { expect, test } from 'tstyche'; +import { + Collection, + List, + Map, + OrderedMap, + OrderedSet, + Seq, + Set, +} from 'immutable'; + +abstract class A {} +class B extends A {} + +test('Collection', () => { + type Indexed = Collection.Indexed; + type Keyed = Collection.Keyed; + type Set = Collection.Set; + + (c: Collection) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Collection, Collection] + >(); + }; + + (c: Collection) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Collection, Collection] + >(); + }; + + (c: Keyed) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Keyed, Keyed] + >(); + }; + + (c: Keyed) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Keyed, Keyed] + >(); + }; + + (c: Indexed) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Indexed, Indexed] + >(); + }; + + (c: Indexed) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Indexed, Indexed] + >(); + }; + + (c: Set) => { + expect(c.partition((x) => x % 2)).type.toBe<[Set, Set]>(); + }; + + (c: Set) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Set, Set] + >(); + }; +}); + +test('Seq', () => { + type Indexed = Seq.Indexed; + type Keyed = Seq.Keyed; + type Set = Seq.Set; + + (c: Seq) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Seq, Seq] + >(); + }; + + (c: Seq) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Seq, Seq] + >(); + }; + + (c: Keyed) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Keyed, Keyed] + >(); + }; + + (c: Keyed) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Keyed, Keyed] + >(); + }; + + (c: Indexed) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Indexed, Indexed] + >(); + }; + + (c: Indexed) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Indexed, Indexed] + >(); + }; + + (c: Set) => { + expect(c.partition((x) => x % 2)).type.toBe<[Set, Set]>(); + }; + + (c: Set) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Set, Set] + >(); + }; +}); + +test('Map', () => { + (c: Map) => { + expect(c.partition((x) => x % 2)).type.toBe< + [Map, Map] + >(); + }; + + (c: Map) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Map, Map] + >(); + }; +}); + +test('OrderedMap', () => { + (c: OrderedMap) => { + expect(c.partition((x) => x % 2)).type.toBe< + [OrderedMap, OrderedMap] + >(); + }; + + (c: OrderedMap) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [OrderedMap, OrderedMap] + >(); + }; +}); + +test('List', () => { + (c: List) => { + expect(c.partition((x) => x % 2)).type.toBe<[List, List]>(); + }; + + (c: List) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [List, List] + >(); + }; +}); + +test('Set', () => { + (c: Set) => { + expect(c.partition((x) => x % 2)).type.toBe<[Set, Set]>(); + }; + + (c: Set) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [Set, Set] + >(); + }; +}); + +test('OrderedSet', () => { + (c: OrderedSet) => { + expect(c.partition((x) => x % 2)).type.toBe< + [OrderedSet, OrderedSet] + >(); + }; + + (c: OrderedSet) => { + expect(c.partition((x): x is B => x instanceof B)).type.toBe< + [OrderedSet, OrderedSet] + >(); + }; +}); diff --git a/type-definitions/ts-tests/range.ts b/type-definitions/ts-tests/range.ts new file mode 100644 index 0000000000..79db184113 --- /dev/null +++ b/type-definitions/ts-tests/range.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'tstyche'; +import { Range, Seq } from 'immutable'; + +test('#constructor', () => { + expect(Range(0, 0, 1)).type.toBe>(); + + expect(Range('a', 0, 0)).type.toRaiseError(); + + expect(Range()).type.toRaiseError(); + + expect(Range(1)).type.toRaiseError(); +}); diff --git a/type-definitions/ts-tests/record.ts b/type-definitions/ts-tests/record.ts new file mode 100644 index 0000000000..bb2db4ee3a --- /dev/null +++ b/type-definitions/ts-tests/record.ts @@ -0,0 +1,110 @@ +import { expect, pick, test } from 'tstyche'; +import { List, Map, MapOf, Record, RecordOf, Set } from 'immutable'; + +test('Factory', () => { + const PointXY = Record({ x: 0, y: 0 }); + + expect(PointXY).type.toBe>(); + + expect(PointXY({ x: 'a' })).type.toRaiseError(); + + const pointXY = PointXY(); + + expect(pointXY).type.toBe< + Record<{ x: number; y: number }> & Readonly<{ x: number; y: number }> + >(); + + expect(pick(pointXY, 'x')).type.toBe<{ readonly x: number }>(); + + expect(pick(pointXY, 'y')).type.toBe<{ readonly y: number }>(); + + expect(pointXY.toJS()).type.toBe<{ x: number; y: number }>(); + + class PointClass extends PointXY { + setX(x: number) { + return this.set('x', x); + } + + setY(y: number) { + return this.set('y', y); + } + } + + const point = new PointClass(); + + expect(point).type.toBe(); + + expect(point.x).type.toBe(); + + expect(point.y).type.toBe(); + + expect(point.setX(10)).type.toBe(); + + expect(point.setY(10)).type.toBe(); + + expect(point.toJSON()).type.toBe<{ x: number; y: number }>(); + + expect(point.toJS()).type.toBe<{ x: number; y: number }>(); +}); + +test('.getDescriptiveName', () => { + const PointXY = Record({ x: 0, y: 0 }); + + expect(Record.getDescriptiveName(PointXY())).type.toBe(); + + expect(Record.getDescriptiveName({})).type.toRaiseError(); +}); + +test('Factory', () => { + const WithMap = Record({ + map: Map({ a: 'A' }), + list: List(['a']), + set: Set(['a']), + }); + + const withMap = WithMap(); + + expect(withMap.toJSON()).type.toBe<{ + map: MapOf<{ a: string }>; + list: List; + set: Set; + }>(); + + // should be `{ map: { a: string; }; list: string[]; set: string[]; }` but there is an issue with circular references + expect(withMap.toJS()).type.toBe<{ + map: unknown; + list: unknown; + set: unknown; + }>(); +}); + +test('optional properties', () => { + interface Size { + distance: string; + } + + const Line = Record<{ size?: Size; color?: string }>({ + size: undefined, + color: 'red', + }); + + const line = Line({}); + + // should be { size?: { distance: string; } | undefined; color?: string | undefined; } but there is an issue with circular references + expect(line.toJS()).type.toBe<{ + size?: unknown; + color?: string | undefined; + }>(); +}); + +test('similar properties, but one is optional', () => { + // see https://github.com/immutable-js/immutable-js/issues/1930 + + interface Id { + value: string; + } + + expect>().type.toBeAssignableWith< + RecordOf<{ id: Id }> + >(); +}); diff --git a/type-definitions/ts-tests/repeat.ts b/type-definitions/ts-tests/repeat.ts new file mode 100644 index 0000000000..9506b753f1 --- /dev/null +++ b/type-definitions/ts-tests/repeat.ts @@ -0,0 +1,10 @@ +import { expect, test } from 'tstyche'; +import { Repeat, Seq } from 'immutable'; + +test('#constructor', () => { + expect(Repeat(0, 0)).type.toBe>(); + + expect(Repeat('a', 0)).type.toBe>(); + + expect(Repeat('a', 'b')).type.toRaiseError(); +}); diff --git a/type-definitions/ts-tests/seq.ts b/type-definitions/ts-tests/seq.ts new file mode 100644 index 0000000000..d967acaade --- /dev/null +++ b/type-definitions/ts-tests/seq.ts @@ -0,0 +1,26 @@ +import { expect, pick, test } from 'tstyche'; +import { Seq } from 'immutable'; + +test('#constructor', () => { + expect(Seq([1, 2, 3])).type.toBe>(); +}); + +test('#size', () => { + expect(pick(Seq(), 'size')).type.toBe<{ + readonly size: number | undefined; + }>(); +}); + +test('Set.Indexed concat', () => { + const s: Seq.Indexed = Seq([1]); + expect(s).type.toBe>(); + expect(s.concat([4, 5, 6])).type.toBe>(); + expect(s.concat(Seq([4, 5, 6]))).type.toBe>(); +}); + +test('Set concat', () => { + const s: Seq = Seq([1]); + expect(s).type.toBe>(); + expect(s.concat([4, 5, 6])).type.toBe>(); + expect(s.concat(Seq([4, 5, 6]))).type.toBe>(); +}); diff --git a/type-definitions/ts-tests/set.ts b/type-definitions/ts-tests/set.ts new file mode 100644 index 0000000000..9149417986 --- /dev/null +++ b/type-definitions/ts-tests/set.ts @@ -0,0 +1,274 @@ +import { expect, pick, test } from 'tstyche'; +import { Set, Map, Collection, OrderedSet } from 'immutable'; + +test('#constructor', () => { + expect(Set()).type.toBe>(); + + expect(Set()).type.toBe>(); + + expect(Set([1, 'a'])).type.toBe>(); + + expect>().type.not.toBeAssignableWith(Set([1, 'a'])); +}); + +test('#size', () => { + expect(pick(Set(), 'size')).type.toBe<{ readonly size: number }>(); +}); + +test('.of', () => { + expect(Set.of(1, 2, 3)).type.toBe>(); + + expect(Set.of('a', 1)).type.toRaiseError(); + + expect(Set.of('a', 1)).type.toBe>(); +}); + +test('.fromKeys', () => { + expect(Set.fromKeys(Map())).type.toBe>(); + + expect(Set.fromKeys(Map())).type.toBe>(); + + expect(Set.fromKeys({ a: 1 })).type.toBe>(); + + expect(Set.fromKeys(Map())).type.toRaiseError(); + + expect( + Set.fromKeys(Map()) + ).type.toBe>(); +}); + +test('#get', () => { + expect(Set().get(4)).type.toBe(); + + expect(Set().get(4, 'a')).type.toBe(); + + expect(Set().get(4, 'a')).type.toRaiseError(); +}); + +test('#delete', () => { + expect(Set().delete(0)).type.toBe>(); + + expect(Set().delete('a')).type.toRaiseError(); +}); + +test('#remove', () => { + expect(Set().remove(0)).type.toBe>(); + + expect(Set().remove('a')).type.toRaiseError(); +}); + +test('#clear', () => { + expect(Set().clear()).type.toBe>(); + + expect(Set().clear(10)).type.toRaiseError(); +}); + +test('#map', () => { + expect( + Set().map((value: number, key: number, iter: Set) => 1) + ).type.toBe>(); + + expect( + Set().map((value: number, key: number, iter: Set) => 'a') + ).type.toBe>(); + + expect( + Set().map( + (value: number, key: number, iter: Set) => 1 + ) + ).type.toBe>(); + + expect( + Set().map( + (value: number, key: number, iter: Set) => 1 + ) + ).type.toRaiseError(); + + expect( + Set().map( + (value: string, key: number, iter: Set) => 1 + ) + ).type.toRaiseError(); + + expect( + Set().map( + (value: number, key: string, iter: Set) => 1 + ) + ).type.toRaiseError(); + + expect( + Set().map( + (value: number, key: number, iter: Set) => 1 + ) + ).type.toRaiseError(); + + expect( + Set().map( + (value: number, key: number, iter: Set) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + Set().flatMap((value: number, key: number, iter: Set) => [ + 1, + ]) + ).type.toBe>(); + + expect( + Set().flatMap((value: number, key: number, iter: Set) => [ + 'a', + ]) + ).type.toBe>(); + + expect( + Set().flatMap( + (value: number, key: number, iter: Set) => [1] + ) + ).type.toBe>(); + + expect( + Set().flatMap( + (value: number, key: number, iter: Set) => [1] + ) + ).type.toRaiseError(); + + expect( + Set().flatMap( + (value: string, key: number, iter: Set) => [1] + ) + ).type.toRaiseError(); + + expect( + Set().flatMap( + (value: number, key: string, iter: Set) => [1] + ) + ).type.toRaiseError(); + + expect( + Set().flatMap( + (value: number, key: number, iter: Set) => [1] + ) + ).type.toRaiseError(); + + expect( + Set().flatMap( + (value: number, key: number, iter: Set) => ['a'] + ) + ).type.toRaiseError(); +}); + +test('#union', () => { + expect(Set().union(Set())).type.toBe>(); + + expect(Set().union(Set())).type.toBe>(); + + expect(Set().union(Set())).type.toBe< + Set + >(); + + expect(Set().union(Set())).type.toBe< + Set + >(); +}); + +test('#merge', () => { + expect(Set().merge(Set())).type.toBe>(); + + expect(Set().merge(Set())).type.toBe>(); + + expect(Set().merge(Set())).type.toBe< + Set + >(); + + expect(Set().merge(Set())).type.toBe< + Set + >(); +}); + +test('#intersect', () => { + expect(Set().intersect(Set())).type.toBe>(); + + expect(Set().intersect(Set())).type.toRaiseError(); + + expect(Set().intersect(Set())).type.toBe< + Set + >(); + + expect(Set().intersect(Set())).type.toBe< + Set + >(); +}); + +test('#subtract', () => { + expect(Set().subtract(Set())).type.toBe>(); + + expect(Set().subtract(Set())).type.toRaiseError(); + + expect(Set().subtract(Set())).type.toBe< + Set + >(); + + expect(Set().subtract(Set())).type.toBe< + Set + >(); +}); + +test('#flatten', () => { + expect(Set().flatten()).type.toBe>(); + + expect(Set().flatten(10)).type.toBe>(); + + expect(Set().flatten(false)).type.toBe< + Collection + >(); + + expect(Set().flatten('a')).type.toRaiseError(); +}); + +test('#sort', () => { + expect(Set().sort()).type.toBe & OrderedSet>(); + expect(Set().sort((a, b) => 1)).type.toBe< + Set & OrderedSet + >(); +}); + +test('#sortBy', () => { + expect(Set().sortBy((v) => v)).type.toBe< + Set & OrderedSet + >(); + + expect( + Set().sortBy( + (v) => v, + (a, b) => 1 + ) + ).type.toBe & OrderedSet>(); +}); + +test('#withMutations', () => { + expect(Set().withMutations((mutable) => mutable)).type.toBe< + Set + >(); + + expect( + Set().withMutations((mutable: Set) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(Set().asMutable()).type.toBe>(); +}); + +test('#asImmutable', () => { + expect(Set().asImmutable()).type.toBe>(); +}); + +test('#toJS', () => { + expect(Set>().toJS()).type.toBe(); +}); + +test('#toJSON', () => { + expect(Set>().toJSON()).type.toBe[]>(); +}); diff --git a/type-definitions/ts-tests/stack.ts b/type-definitions/ts-tests/stack.ts new file mode 100644 index 0000000000..d261b1152a --- /dev/null +++ b/type-definitions/ts-tests/stack.ts @@ -0,0 +1,226 @@ +import { expect, pick, test } from 'tstyche'; +import { Collection, Stack } from 'immutable'; + +test('#constructor', () => { + expect(Stack()).type.toBe>(); + + expect(Stack()).type.toBe>(); + + expect(Stack([1, 'a'])).type.toBe>(); +}); + +test('#size', () => { + expect(pick(Stack(), 'size')).type.toBe<{ readonly size: number }>(); +}); + +test('.of', () => { + expect(Stack.of(1, 2, 3)).type.toBe>(); + + expect(Stack.of('a', 1)).type.toRaiseError(); + + expect(Stack.of('a', 1)).type.toBe>(); +}); + +test('#peek', () => { + expect(Stack().peek()).type.toBe(); +}); + +test('#push', () => { + expect(Stack().push(0)).type.toBe>(); + + expect(Stack().push('a')).type.toRaiseError(); + + expect(Stack().push(0)).type.toBe>(); + + expect(Stack().push('a')).type.toBe< + Stack + >(); +}); + +test('#pushAll', () => { + expect(Stack().pushAll([0])).type.toBe>(); + + expect(Stack().pushAll(['a'])).type.toRaiseError(); + + expect(Stack().pushAll([0])).type.toBe< + Stack + >(); + + expect(Stack().pushAll(['a'])).type.toBe< + Stack + >(); +}); + +test('#unshift', () => { + expect(Stack().unshift(0)).type.toBe>(); + + expect(Stack().unshift('a')).type.toRaiseError(); + + expect(Stack().unshift(0)).type.toBe< + Stack + >(); + + expect(Stack().unshift('a')).type.toBe< + Stack + >(); +}); + +test('#unshiftAll', () => { + expect(Stack().unshiftAll([0])).type.toBe>(); + + expect(Stack().unshiftAll(['a'])).type.toRaiseError(); + + expect(Stack().unshiftAll([1])).type.toBe< + Stack + >(); + + expect(Stack().unshiftAll(['a'])).type.toBe< + Stack + >(); +}); + +test('#clear', () => { + expect(Stack().clear()).type.toBe>(); + + expect(Stack().clear(10)).type.toRaiseError(); +}); + +test('#pop', () => { + expect(Stack().pop()).type.toBe>(); + + expect(Stack().pop(10)).type.toRaiseError(); +}); + +test('#shift', () => { + expect(Stack().shift()).type.toBe>(); + + expect(Stack().shift(10)).type.toRaiseError(); +}); + +test('#map', () => { + expect( + Stack().map((value: number, key: number, iter: Stack) => 1) + ).type.toBe>(); + + expect( + Stack().map( + (value: number, key: number, iter: Stack) => 'a' + ) + ).type.toBe>(); + + expect( + Stack().map( + (value: number, key: number, iter: Stack) => 1 + ) + ).type.toBe>(); + + expect( + Stack().map( + (value: number, key: number, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().map( + (value: string, key: number, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().map( + (value: number, key: string, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().map( + (value: number, key: number, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().map( + (value: number, key: number, iter: Stack) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + Stack().flatMap( + (value: number, key: number, iter: Stack) => [1] + ) + ).type.toBe>(); + + expect( + Stack().flatMap( + (value: number, key: number, iter: Stack) => 'a' + ) + ).type.toBe>(); + + expect( + Stack().flatMap( + (value: number, key: number, iter: Stack) => [1] + ) + ).type.toBe>(); + + expect( + Stack().flatMap( + (value: number, key: number, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().flatMap( + (value: string, key: number, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().flatMap( + (value: number, key: string, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().flatMap( + (value: number, key: number, iter: Stack) => 1 + ) + ).type.toRaiseError(); + + expect( + Stack().flatMap( + (value: number, key: number, iter: Stack) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatten', () => { + expect(Stack().flatten()).type.toBe>(); + + expect(Stack().flatten(10)).type.toBe>(); + + expect(Stack().flatten(false)).type.toBe< + Collection + >(); + + expect(Stack().flatten('a')).type.toRaiseError(); +}); + +test('#withMutations', () => { + expect(Stack().withMutations((mutable) => mutable)).type.toBe< + Stack + >(); + + expect( + Stack().withMutations((mutable: Stack) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(Stack().asMutable()).type.toBe>(); +}); + +test('#asImmutable', () => { + expect(Stack().asImmutable()).type.toBe>(); +}); diff --git a/type-definitions/ts-tests/tsconfig.json b/type-definitions/ts-tests/tsconfig.json new file mode 100644 index 0000000000..12fa9cfb76 --- /dev/null +++ b/type-definitions/ts-tests/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2015", + "module": "commonjs", + "sourceMap": true, + "strict": true, + "types": [], + "noEmit": true, + "lib": ["es2015"], + "baseUrl": "./", + "paths": { + "immutable": ["../immutable.d.ts"] + } + }, + "exclude": ["node_modules"] +} diff --git a/type-definitions/tsconfig.json b/type-definitions/tsconfig.json new file mode 100644 index 0000000000..18735e2da8 --- /dev/null +++ b/type-definitions/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2015", + "module": "commonjs", + "sourceMap": true, + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "lib": ["es2015"], + "types": [] + }, + "files": ["immutable.d.ts"] +} diff --git a/website/.eslintrc b/website/.eslintrc new file mode 100644 index 0000000000..97a2bb84ef --- /dev/null +++ b/website/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": ["next", "next/core-web-vitals"] +} diff --git a/website/next-env.d.ts b/website/next-env.d.ts new file mode 100644 index 0000000000..1b3be0840f --- /dev/null +++ b/website/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/website/next-sitemap.config.js b/website/next-sitemap.config.js new file mode 100644 index 0000000000..e4cc9ee5dd --- /dev/null +++ b/website/next-sitemap.config.js @@ -0,0 +1,16 @@ +// eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef +const { getVersions } = require('./src/static/getVersions'); + +/** @type {import('next-sitemap').IConfig} */ +// eslint-disable-next-line no-undef +module.exports = { + siteUrl: 'https://immutable-js.com', + generateRobotsTxt: true, + outDir: './out', + exclude: [ + '/docs', + ...getVersions() + .slice(1) + .map((version) => `/docs/${version}/*`), + ], +}; diff --git a/website/next.config.js b/website/next.config.js new file mode 100644 index 0000000000..61576f7219 --- /dev/null +++ b/website/next.config.js @@ -0,0 +1,6 @@ +// eslint-disable-next-line no-undef +module.exports = { + reactStrictMode: true, + trailingSlash: true, + output: 'export', +}; diff --git a/website/public/Immutable-Data-and-React-YouTube.png b/website/public/Immutable-Data-and-React-YouTube.png new file mode 100644 index 0000000000..fd5354bd80 Binary files /dev/null and b/website/public/Immutable-Data-and-React-YouTube.png differ diff --git a/website/public/favicon.png b/website/public/favicon.png new file mode 100644 index 0000000000..405ac768e2 Binary files /dev/null and b/website/public/favicon.png differ diff --git a/website/src/ArrowDown.tsx b/website/src/ArrowDown.tsx new file mode 100644 index 0000000000..662f63466c --- /dev/null +++ b/website/src/ArrowDown.tsx @@ -0,0 +1,31 @@ +import type { JSX } from 'react'; + +export function ArrowDown({ isActive }: { isActive: boolean }): JSX.Element { + return ( + + + + + + ); +} diff --git a/website/src/Defs.tsx b/website/src/Defs.tsx new file mode 100644 index 0000000000..a8a464643d --- /dev/null +++ b/website/src/Defs.tsx @@ -0,0 +1,428 @@ +import type { FocusEvent, JSX, MouseEvent, ReactNode } from 'react'; +import { Fragment, useCallback, useState } from 'react'; +import Link from 'next/link'; +import { + TypeKind, + Type, + InterfaceDefinition, + ObjectMember, + CallSignature, + CallParam, +} from './TypeDefs'; + +export function InterfaceDef({ + name, + def, +}: { + name: string; + def: InterfaceDefinition; +}) { + return ( + + type + {name} + {def.typeParams && ( + <> + {'<'} + {interpose( + ', ', + def.typeParams.map((t, i) => ( + + {t} + + )) + )} + {'>'} + + )} + {def.extends && ( + <> + extends + {interpose( + ', ', + def.extends.map((e, i) => ) + )} + + )} + {def.implements && ( + <> + implements + {interpose( + ', ', + def.implements.map((e, i) => ) + )} + + )} + + ); +} + +export function CallSigDef({ + name, + callSig, +}: { + name: string; + callSig?: CallSignature; +}) { + const shouldWrap = callSigLength(name, callSig) > 80; + + return ( + + {name} + {callSig?.typeParams && ( + <> + {'<'} + {interpose( + ', ', + callSig.typeParams.map((t, i) => ( + + {t} + + )) + )} + {'>'} + + )} + {'('} + {callSig && functionParams(callSig.params, shouldWrap)} + {')'} + {callSig?.type && ( + <> + {': '} + + + )} + + ); +} + +export function TypeDef({ type, prefix }: { type: Type; prefix?: number }) { + switch (type.k) { + case TypeKind.Never: + return wrap('primitive', 'never'); + case TypeKind.Any: + return wrap('primitive', 'any'); + case TypeKind.Unknown: + return wrap('primitive', 'unknown'); + case TypeKind.This: + return wrap('primitive', 'this'); + case TypeKind.Undefined: + return wrap('primitive', 'undefined'); + case TypeKind.Boolean: + return wrap('primitive', 'boolean'); + case TypeKind.Number: + return wrap('primitive', 'number'); + case TypeKind.String: + return wrap('primitive', 'string'); + case TypeKind.Union: + return wrap( + 'union', + interpose( + ' | ', + type.types.map((t, i) => ) + ) + ); + case TypeKind.Intersection: + return wrap( + 'intersection', + interpose( + ' & ', + type.types.map((t, i) => ) + ) + ); + case TypeKind.Tuple: + return wrap( + 'tuple', + <> + {'['} + {interpose( + ', ', + type.types.map((t, i) => ) + )} + {']'} + + ); + case TypeKind.Object: + if (!type.members) { + return wrap('primitive', 'object'); + } + return wrap( + 'object', + <> + {'{'} + {interpose( + ', ', + type.members.map((t, i) => ) + )} + {'}'} + + ); + case TypeKind.Indexed: + return wrap( + 'indexed', + <> + ,{'['} + + {']'} + + ); + case TypeKind.Operator: + return wrap( + 'operator', + <> + {wrap('primitive', type.operator)} + + ); + case TypeKind.Array: + return wrap( + 'array', + <> + + {'[]'} + + ); + case TypeKind.Function: { + const shouldWrap = (prefix || 0) + funcLength(type) > 78; + return wrap( + 'function', + <> + {type.typeParams && ( + <> + {'<'} + {interpose( + ', ', + type.typeParams.map((t, i) => ( + + {t} + + )) + )} + {'>'} + + )} + {'('} + {functionParams(type.params, shouldWrap)} + {') => '} + + + ); + } + case TypeKind.Param: + return wrap('typeParam', type.param); + case TypeKind.Type: { + return wrap( + 'type', + <> + {type.url ? ( + + {type.name} + + ) : ( + {type.name} + )} + {type.args && ( + <> + {'<'} + {interpose( + ', ', + type.args.map((a, i) => ) + )} + {'>'} + + )} + + ); + } + } + throw new Error('Type with unknown kind ' + JSON.stringify(type)); +} + +function wrap(className: string, child: ReactNode) { + return {child}; +} + +function Hover({ + className, + children, +}: { + className?: string; + children: ReactNode; +}) { + const [isOver, setIsOver] = useState(false); + const mouseOver = useCallback( + (event: MouseEvent | FocusEvent) => { + event.stopPropagation(); + setIsOver(true); + }, + [setIsOver] + ); + const mouseOut = useCallback(() => { + setIsOver(false); + }, [setIsOver]); + return ( + + {children} + + ); +} + +export function MemberDef({ member }: { member: ObjectMember }) { + return ( + + {member.index ? ( + <>[{functionParams(member.params, false)}] + ) : ( + {member.name} + )} + {member.type && ( + <> + : + + )} + + ); +} + +function functionParams( + params: Array | undefined, + shouldWrap: boolean +) { + const elements = interpose( + shouldWrap ? ( + <> + {','} +
+ + ) : ( + ', ' + ), + (params ?? []).map((t, i) => ( + + {t.varArgs ? '...' : null} + {t.name} + {t.optional ? '?: ' : ': '} + + + )) + ); + + return shouldWrap ? ( +
{elements}
+ ) : ( + elements + ); +} + +function callSigLength(name: string, sig?: CallSignature): number { + return name.length + (sig ? funcLength(sig) : 2); +} + +function funcLength(sig: CallSignature): number { + return ( + (sig.typeParams ? 2 + sig.typeParams.join(', ').length : 0) + + 2 + + (sig.params ? paramLength(sig.params) : 0) + + (sig.type ? 2 + typeLength(sig.type) : 0) + ); +} + +function paramLength(params: Array): number { + return params.reduce( + (s, p) => + s + + (p.varArgs ? 3 : 0) + + p.name.length + + (p.optional ? 3 : 2) + + typeLength(p.type), + (params.length - 1) * 2 + ); +} + +function memberLength(members: Array): number { + return members.reduce( + (s, m) => + s + + (m.index ? paramLength(m.params || []) + 2 : m.name!.length) + + (m.type ? typeLength(m.type) + 2 : 0), + (members.length - 1) * 2 + ); +} + +function typeLength(type: Type): number { + if (!type) { + throw new Error('Expected type'); + } + switch (type.k) { + case TypeKind.Never: + return 5; + case TypeKind.Any: + return 3; + case TypeKind.Unknown: + return 7; + case TypeKind.This: + return 4; + case TypeKind.Undefined: + return 9; + case TypeKind.Boolean: + return 7; + case TypeKind.Number: + return 6; + case TypeKind.String: + return 6; + case TypeKind.Union: + case TypeKind.Intersection: + return ( + type.types.reduce((s, t) => s + typeLength(t), 0) + + (type.types.length - 1) * 3 + ); + case TypeKind.Tuple: + return ( + 2 + + type.types.reduce((s, t) => s + typeLength(t), 0) + + (type.types.length - 1) * 2 + ); + case TypeKind.Object: + return type.members ? 2 + memberLength(type.members) : 6; + case TypeKind.Indexed: + return 2 + typeLength(type.type) + typeLength(type.index); + case TypeKind.Operator: + return 1 + type.operator.length + typeLength(type.type); + case TypeKind.Array: + return typeLength(type.type) + 2; + case TypeKind.Function: + return 2 + funcLength(type); + case TypeKind.Param: + return type.param.length; + case TypeKind.Type: + return ( + type.name.length + + (!type.args + ? 0 + : type.args.reduce((s, a) => s + typeLength(a), type.args.length * 2)) + ); + } + throw new Error('Type with unknown kind ' + JSON.stringify(type)); +} + +function interpose( + between: ReactNode, + array: Array +): Array { + const result: Array = []; + let i = 0; + for (const value of array) { + result.push(value, {between}); + } + result.pop(); + + return result; +} diff --git a/website/src/DocHeader.tsx b/website/src/DocHeader.tsx new file mode 100644 index 0000000000..b57499a864 --- /dev/null +++ b/website/src/DocHeader.tsx @@ -0,0 +1,20 @@ +import { HeaderLinks, HeaderLogoLink } from './Header'; + +export function DocHeader({ + versions, + currentVersion, +}: { + versions: Array; + currentVersion?: string; +}) { + return ( +
+
+
+ + +
+
+
+ ); +} diff --git a/website/src/DocOverview.tsx b/website/src/DocOverview.tsx new file mode 100644 index 0000000000..71a62ce155 --- /dev/null +++ b/website/src/DocOverview.tsx @@ -0,0 +1,57 @@ +import Link from 'next/link'; +import { MarkdownContent } from './MarkdownContent'; +import type { TypeDefs, TypeDoc } from './TypeDefs'; + +export type OverviewData = { + doc: TypeDoc | null; + api: Array; +}; + +type APIMember = { + label: string; + url: string; + synopsis?: string; +}; + +// Static use only +export function getOverviewData(defs: TypeDefs): OverviewData { + return { + doc: defs.doc || null, + api: Object.values(defs.types).map((def) => { + const member: APIMember = { label: def.label, url: def.url }; + const doc = def.doc || def.call?.doc; + if (doc?.synopsis) { + member.synopsis = doc?.synopsis; + } + return member; + }), + }; +} + +export function DocOverview({ data }: { data: OverviewData }) { + return ( +
+ {data.doc && ( +
+ + {data.doc.description && ( + + )} +
+ )} + +

API

+ + {data.api.map((member) => ( +
+

+ {member.label} +

+ {member.synopsis && ( + + )} +
+ ))} +
+ ); +} diff --git a/website/src/DocSearch.tsx b/website/src/DocSearch.tsx new file mode 100644 index 0000000000..82e07cf313 --- /dev/null +++ b/website/src/DocSearch.tsx @@ -0,0 +1,53 @@ +'use client'; + +import { useEffect, useState } from 'react'; + +export function DocSearch() { + const [enabled, setEnabled] = useState(null); + + useEffect(() => { + const script = document.createElement('script'); + const firstScript = document.getElementsByTagName('script')[0]; + script.src = + 'https://cdn.jsdelivr.net/npm/docsearch.js@2.5.2/dist/cdn/docsearch.min.js'; + script.addEventListener( + 'load', + () => { + // Initialize Algolia search. + // @ts-expect-error -- algolia is set on windows, need proper type + if (window.docsearch) { + // @ts-expect-error -- algolia is set on windows, need proper type + window.docsearch({ + apiKey: '83f61f865ef4cb682e0432410c2f7809', + indexName: 'immutable_js', + inputSelector: '#algolia-docsearch', + }); + setEnabled(true); + } else { + setEnabled(false); + } + }, + false + ); + firstScript?.parentNode?.insertBefore(script, firstScript); + + const link = document.createElement('link'); + const firstLink = document.getElementsByTagName('link')[0]; + link.rel = 'stylesheet'; + link.href = + 'https://cdn.jsdelivr.net/npm/docsearch.js@2.5.2/dist/cdn/docsearch.min.css'; + firstLink?.parentNode?.insertBefore(link, firstLink); + }, []); + + if (enabled === false) return null; + + return ( + + ); +} diff --git a/website/src/Header.tsx b/website/src/Header.tsx new file mode 100644 index 0000000000..b8e8b67d9e --- /dev/null +++ b/website/src/Header.tsx @@ -0,0 +1,198 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import Link from 'next/link'; + +import { SVGSet } from './SVGSet'; +import { Logo } from './Logo'; +import { StarBtn } from './StarBtn'; +import { isMobile } from './isMobile'; + +export function Header({ + versions, + currentVersion, +}: { + versions: Array; + currentVersion?: string; +}) { + const [scroll, setScroll] = useState(0); + + useEffect(() => { + let _pending = false; + function handleScroll() { + if (!_pending) { + const headerHeight = Math.min( + 800, + Math.max(260, document.documentElement.clientHeight * 0.7) + ); + if (window.scrollY < headerHeight) { + _pending = true; + window.requestAnimationFrame(() => { + _pending = false; + setScroll(window.scrollY); + }); + } + } + } + + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + const neg = scroll < 0; + const s = neg ? 0 : scroll; + const sp = isMobile() ? 35 : 70; + + return ( +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+ {[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].map((_, i) => ( + + + + + ))} + + + + +
+
+
+ +
+
+
+
+
+ ); +} + +export function HeaderLogoLink() { + return ( + + + + + + + ); +} + +export function HeaderLinks({ + versions, + currentVersion, +}: { + versions: Array; + currentVersion?: string; +}) { + return ( +
+ ); +} + +function DocsDropdown({ + versions, + currentVersion, +}: { + versions: Array; + currentVersion?: string; +}) { + return ( +
+ +
+ + Docs{currentVersion && ` (${currentVersion})`} + +
+
    + {versions.map((v) => ( +
  • + {v} +
  • + ))} +
+
+ ); +} + +function ty(s: number, p: number) { + return (p < s ? p : s) * -0.55; +} + +function o(s: number, p: number) { + return Math.max(0, s > p ? 1 - (s - p) / 350 : 1); +} + +function tz(s: number, p: number) { + return Math.max(0, s > p ? 1 - (s - p) / 20000 : 1); +} + +function t(y: number, z: number) { + return { transform: 'translate3d(0, ' + y + 'px, 0) scale(' + z + ')' }; +} diff --git a/website/src/ImmutableConsole.tsx b/website/src/ImmutableConsole.tsx new file mode 100644 index 0000000000..4875a22058 --- /dev/null +++ b/website/src/ImmutableConsole.tsx @@ -0,0 +1,69 @@ +'use client'; + +import { useEffect } from 'react'; + +type InstallSpace = { + Immutable?: unknown; + module?: unknown; + exports?: unknown; +}; + +let installingVersion: string | undefined; + +export function ImmutableConsole({ version }: { version: string }) { + useEffect(() => { + const installSpace = global as unknown as InstallSpace; + if (installingVersion === version) { + return; + } + installingVersion = version; + installUMD(installSpace, getSourceURL(version)).then((Immutable) => { + installSpace.Immutable = Immutable; + + console.log( + '\n' + + ' ▄▟████▙▄ _ __ __ __ __ _ _ _______ ____ _ _____ \n' + + ' ▟██████████▙ | | | \\ / | \\ / | | | |__ __|/\\ | _ \\| | | ___|\n' + + '██████████████ | | | \\/ | \\/ | | | | | | / \\ | |_) | | | |__ \n' + + '██████████████ | | | |\\ /| | |\\ /| | | | | | | / /\\ \\ | _ <| | | __| \n' + + ' ▜██████████▛ | | | | \\/ | | | \\/ | | |__| | | |/ ____ \\| |_) | |___| |___ \n' + + ' ▀▜████▛▀ |_| |_| |_|_| |_|\\____/ |_/_/ \\_\\____/|_____|_____|\n' + + '\n' + + `Version: ${version}\n` + + '> console.log(Immutable);' + ); + console.log(Immutable); + }); + }, [version]); + return null; +} + +function getSourceURL(version: string) { + if (version === 'latest@main') { + return `https://cdn.jsdelivr.net/gh/immutable-js/immutable-js@npm/dist/immutable.js`; + } + const semver = version[0] === 'v' ? version.slice(1) : version; + return `https://cdn.jsdelivr.net/npm/immutable@${semver}/dist/immutable.js`; +} + +function installUMD(installSpace: InstallSpace, src: string): Promise { + return new Promise((resolve) => { + const installedModule = (installSpace.module = { + exports: (installSpace.exports = {}), + }); + const script = document.createElement('script'); + const firstScript = document.getElementsByTagName('script')[0]; + script.src = src; + script.addEventListener( + 'load', + () => { + installSpace.module = undefined; + installSpace.exports = undefined; + script.remove(); + resolve(installedModule.exports); + }, + false + ); + firstScript?.parentNode?.insertBefore(script, firstScript); + }); +} diff --git a/website/src/Logo.tsx b/website/src/Logo.tsx new file mode 100644 index 0000000000..b9c0bb5e7c --- /dev/null +++ b/website/src/Logo.tsx @@ -0,0 +1,74 @@ +type Props = { + opacity?: number; + inline?: boolean; + color: string; +}; + +export function Logo({ opacity = 1, inline, color }: Props) { + return !inline ? ( + + + + + + + + + + + + ) : ( + + + + + + + + + + + + ); +} diff --git a/website/src/MarkdownContent.tsx b/website/src/MarkdownContent.tsx new file mode 100644 index 0000000000..7f90fca400 --- /dev/null +++ b/website/src/MarkdownContent.tsx @@ -0,0 +1,33 @@ +'use client'; + +import { memo, MouseEvent } from 'react'; +import { useRouter } from 'next/navigation'; + +type Props = { + contents: string; + className?: string; +}; + +// eslint-disable-next-line prefer-arrow-callback +export const MarkdownContent = memo(function MarkdownContent({ + contents, + className, +}) { + const router = useRouter(); + + const handleClick = (event: MouseEvent) => { + const link = event.target as HTMLAnchorElement; + if (link.tagName === 'A' && link.target !== '_blank') { + event.preventDefault(); + router.push(link.href); + } + }; + + return ( +
+ ); +}); diff --git a/website/src/MemberDoc.tsx b/website/src/MemberDoc.tsx new file mode 100644 index 0000000000..7d36ff2c52 --- /dev/null +++ b/website/src/MemberDoc.tsx @@ -0,0 +1,100 @@ +import Link from 'next/link'; +import { Fragment } from 'react'; +import { CallSigDef, MemberDef } from './Defs'; +import { MarkdownContent } from './MarkdownContent'; +import type { MemberDefinition } from './TypeDefs'; + +export function MemberDoc({ member }: { member: MemberDefinition }) { + return ( +
+

+ {member.label} +

+
+ {member.doc && ( + + )} + {!member.signatures ? ( + + + + ) : ( + + {member.signatures.map((callSig, i) => ( + + + {'\n'} + + ))} + + )} + {member.inherited && ( +
+

Inherited from

+ + + {member.inherited.interface}#{member.inherited.label} + + +
+ )} + {member.overrides && ( +
+

Overrides

+ + + {member.overrides.interface}#{member.overrides.label} + + +
+ )} + {member.doc?.notes.map((note, i) => ( +
+

{note.name}

+ {note.name === 'alias' ? ( + + + + ) : ( + + )} +
+ ))} + {member.doc?.description && ( +
+

+ {member.doc.description.slice(0, 5) === ' + +

+ )} +
+
+ ); +} + +// export type ParamTypeMap = { [param: string]: Type }; + +// function getParamTypeMap( +// interfaceDef: InterfaceDefinition | undefined, +// member: MemberDefinition +// ): ParamTypeMap | undefined { +// if (!member.inherited || !interfaceDef?.typeParamsMap) return; +// const defining = member.inherited.split('#')[0] + '>'; +// const paramTypeMap: ParamTypeMap = {}; +// // Filter typeParamsMap down to only those relevant to the defining interface. +// for (const [path, type] of Object.entries(interfaceDef.typeParamsMap)) { +// if (path.startsWith(defining)) { +// paramTypeMap[path.slice(defining.length)] = type; +// } +// } +// return paramTypeMap; +// } diff --git a/website/src/RunkitEmbed.tsx b/website/src/RunkitEmbed.tsx new file mode 100644 index 0000000000..8b394671c1 --- /dev/null +++ b/website/src/RunkitEmbed.tsx @@ -0,0 +1,153 @@ +import Script from 'next/script'; + +export function RunkitEmbed() { + return