diff --git a/.buildkite/hooks/pre-artifact b/.buildkite/hooks/pre-artifact index 362dbe840..6b9ab6bfb 100755 --- a/.buildkite/hooks/pre-artifact +++ b/.buildkite/hooks/pre-artifact @@ -3,7 +3,7 @@ set +u declare -A BUILDS=(["linux"]="amd64 arm arm64 amd64-musl arm-musl arm64-musl" ["freebsd"]="amd64") -DOCKER_IMAGE=authelia/authelia +DOCKER_IMAGE=authelia:dist if [[ "${BUILDKITE_LABEL}" == ":hammer_and_wrench: Unit Test" ]]; then if [[ ! "${BUILDKITE_BRANCH}" =~ ^renovate/ ]]; then @@ -35,4 +35,4 @@ if [[ "${BUILDKITE_LABEL}" =~ ":debian: Build Package" ]]; then for f in *.deb; do mv "$f" "$(echo "$f" | sed s/${VERSION}-1_//)"; done fi sha256sum "authelia_${PACKAGE}.deb" > "authelia_${PACKAGE}.deb.sha256" -fi \ No newline at end of file +fi diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index a7e2411a6..032cc3da2 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -17,7 +17,7 @@ if [[ "${BUILDKITE_LABEL}" == ":service_dog: Linting" ]]; then fi if [[ "${BUILDKITE_LABEL}" == ":docker: Build Image [coverage]" ]]; then - cp -R /buildkite/.pnpm-store . + cp -R /buildkite/.local . fi if [[ "${BUILDKITE_STEP_KEY}" =~ build-deb-package-(arm64|armhf) && "${BUILDKITE_AGENT_NAME}" =~ sauron* ]]; then @@ -30,10 +30,13 @@ fi if [[ "${BUILDKITE_LABEL}" =~ ":selenium:" ]]; then DEFAULT_ARCH=coverage - echo "--- :docker: Extract, load and tag build container" + echo "--- :docker: Extract and load build container" buildkite-agent artifact download "authelia-image-${DEFAULT_ARCH}*" . - zstdcat "authelia-image-${DEFAULT_ARCH}.tar.zst" | docker load - docker tag authelia/authelia authelia:dist + if [[ "${SUITE}" == "Kubernetes" ]]; then + zstd -d authelia-image-coverage.tar.zst --stdout > ./internal/suites/example/kube/authelia-image-${DEFAULT_ARCH}.tar + else + zstdcat "authelia-image-${DEFAULT_ARCH}.tar.zst" | docker load + fi if [[ "${BUILD_DUO}" == "true" ]] && [[ "${SUITE}" == "DuoPush" ]]; then CONTAINER="integration-duo" diff --git a/.editorconfig b/.editorconfig index 0466ef21c..cc3c38a0c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,11 @@ trim_trailing_whitespace = true end_of_line = lf insert_final_newline = true -[{.buildkite/hooks/**,*.sh,*.yml,*.yaml}] +[*.{sh,yml,yaml}] +indent_style = space +indent_size = 2 + +[.buildkite/hooks/**] indent_style = space indent_size = 2 diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 5465cdbc7..f0e55c1d6 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -26,6 +26,7 @@ body: description: What version(s) of Authelia can you reproduce this bug on? multiple: true options: + - v4.37.3 - v4.37.2 - v4.37.1 - v4.37.0 diff --git a/.gitignore b/.gitignore index aab30be7a..7bb4c5401 100644 --- a/.gitignore +++ b/.gitignore @@ -1,50 +1,27 @@ +# IDE user configuration +.idea/ +.vscode/ -# NodeJs modules +# Nodejs modules +.pnpm-store/ node_modules/ -# npm debug logs -npm-debug.log* - # Coverage reports coverage/ +.nyc_output/ coverage.txt -.vscode/ - -*.swp -*~ - -# Directory used by example -/notifications/ - -# VSCode user configuration -.vscode/ - # Generated by TypeScript compiler dist/ -.nyc_output/ - -*.tgz - # Specific files /configuration.yml /config.yml /config.test.yml -internal/suites/example/ldap/private.ldif - -Configuration.schema.json - .suite .kube -.idea +authelia-image-dev.tar -.authelia-interrupt - -qemu-*-static - -public_html.gen.go - -authelia +/authelia __debug_bin diff --git a/.renovaterc b/.renovaterc index 9ddef69e8..ef5a91e74 100644 --- a/.renovaterc +++ b/.renovaterc @@ -1,4 +1,5 @@ { + "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:base", ":semanticCommitTypeAll(build)", @@ -14,12 +15,15 @@ "workarounds:all" ], "enabledManagers": [ - "bundler", "docker-compose", "dockerfile", "gomod", + "kubernetes", "npm" ], + "kubernetes": { + "fileMatch": ["kube/.+\\.yml$"], + }, "labels": [ "dependencies" ], @@ -47,6 +51,14 @@ "go" ] }, + { + "datasources": [ + "kubernetes" + ], + "addLabels": [ + "kubernetes" + ] + }, { "datasources": [ "npm" diff --git a/.yamllint.yml b/.yamllint.yml index d7fc7209f..1d8112fd5 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -1,6 +1,13 @@ --- extends: default +locale: en_US.UTF-8 + +yaml-files: + - '*.yaml' + - '*.yml' + - '.yamllint' + ignore: | docs/pnpm-lock.yaml internal/configuration/test_resources/config_bad_quoting.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1b23c8aaf..b3c2bc9f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Anybody willing to contribute to the project either with code, documentation, security reviews or whatever, are very welcome to create or review pull requests and take part in discussions in any of our public -[chat rooms](./README.md#contact-options). +[chat rooms](README.md#contact-options). It's also possible to contribute financially in order to support the community. @@ -42,4 +42,4 @@ Read more about this in the [GitHub docs, Re-requesting a review](https://docs.g Sometimes the codebase can be a challenge to navigate, especially for a first-time contributor. We don't want you spending an hour trying to work out something that would take us only a minute to explain. -If you'd like some help getting started we have several [contact options](./README.md#contact-options) available. +If you'd like some help getting started we have several [contact options](README.md#contact-options) available. diff --git a/Dockerfile.coverage b/Dockerfile.coverage index ee1c9b0b6..de77fcef9 100644 --- a/Dockerfile.coverage +++ b/Dockerfile.coverage @@ -5,7 +5,7 @@ FROM node:19-alpine AS builder-frontend WORKDIR /node/src/app -COPY .pnpm-store /root/.pnpm-store +COPY .local /root/.local COPY web ./ # Install the dependencies and build @@ -15,7 +15,7 @@ RUN yarn global add pnpm && \ # ======================================= # ===== Build image for the backend ===== # ======================================= -FROM golang:1.19.3-alpine AS builder-backend +FROM golang:1.19.4-alpine AS builder-backend WORKDIR /go/src/app diff --git a/Dockerfile.coverage.dockerignore b/Dockerfile.coverage.dockerignore index 89aa98e77..81e93ded1 100644 --- a/Dockerfile.coverage.dockerignore +++ b/Dockerfile.coverage.dockerignore @@ -20,4 +20,4 @@ bootstrap.sh # Overrides !.healthcheck.env -!.pnpm-store \ No newline at end of file +!.local diff --git a/Dockerfile.dev b/Dockerfile.dev index 90988e0c5..5dab79868 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -13,7 +13,7 @@ RUN yarn install --frozen-lockfile && yarn build # ======================================= # ===== Build image for the backend ===== # ======================================= -FROM golang:1.19.3-alpine AS builder-backend +FROM golang:1.19.4-alpine AS builder-backend WORKDIR /go/src/app diff --git a/README.md b/README.md index e800faaee..abc3236bc 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ Internet (your reverse proxies are) however, it's still the control plane for yo ## Contribute -If you want to contribute to Authelia, please read our [contribution guidelines](./CONTRIBUTING.md). +If you want to contribute to Authelia, please read our [contribution guidelines](CONTRIBUTING.md). Authelia exists thanks to all the people who contribute so don't be shy, come chat with us on either [Matrix](#matrix) or [Discord](#discord) and start contributing too. @@ -379,7 +379,7 @@ Companies contributing to Authelia via Open Collective will have a special menti ## License **Authelia** is **licensed** under the **[Apache 2.0]** license. The terms of the license are detailed in -[LICENSE](./LICENSE). +[LICENSE](LICENSE). [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fauthelia%2Fauthelia.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fauthelia%2Fauthelia?ref=badge_large) diff --git a/SECURITY.md b/SECURITY.md index 6324e796c..90c512187 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -19,14 +19,14 @@ For more information about [security](https://www.authelia.com/information/secur ## Contact Options -Several [contact options](./README.md#contact-options) exist, it's important to make sure you contact the maintainers -privately which is described in each available contact method. The methods include our [security email](./README.md#security), -[Matrix](./README.md#matrix), and [Discord](./README.md#discord). +Several [contact options](README.md#contact-options) exist, it's important to make sure you contact the maintainers +privately which is described in each available contact method. The methods include our [security email](README.md#security), +[Matrix](README.md#matrix), and [Discord](README.md#discord). ## Credit Users who report bugs will optionally be credited for the discovery. Both in the [security advisory] and in our -[all contributors](./README.md#contribute) configuration/documentation. +[all contributors](README.md#contribute) configuration/documentation. ## Process diff --git a/api/openapi.yml b/api/openapi.yml index f2f0d6127..00840966d 100644 --- a/api/openapi.yml +++ b/api/openapi.yml @@ -1,5 +1,6 @@ +# yamllint disable rule:line-length --- -openapi: 3.0.0 +openapi: 3.0.3 info: title: Authelia API description: > @@ -7,12 +8,15 @@ info: sign-on (SSO) for your applications via a web portal. contact: name: Authelia Support - url: https://github.com/authelia/authelia#contact-options + url: https://www.authelia.com/contact/ email: team@authelia.com license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 version: 1.0.0 +servers: + - url: "{{ .BaseURL }}" + description: Authelia API tags: - name: State description: Configuration, health and state endpoints @@ -24,6 +28,12 @@ tags: description: User configuration endpoints - name: Second Factor description: TOTP, Webauthn and Duo endpoints + externalDocs: + url: https://www.authelia.com/configuration/second-factor/introduction/ + - name: OpenID Connect 1.0 + description: OpenID Connect 1.0 and OAuth 2.0 Endpoints + externalDocs: + url: https://www.authelia.com/integration/openid-connect/introduction/ paths: /api/configuration: get: @@ -635,7 +645,7 @@ paths: tags: - Second Factor summary: Second Factor Authentication - Duo Mobile Push - description: This endpoint retreives a users available devices and capabilities from Duo. + description: This endpoint retrieves a users available devices and capabilities from Duo. responses: "200": description: Successful Operation @@ -670,6 +680,520 @@ paths: description: Unauthorized security: - authelia_auth: [] + /.well-known/openid-configuration: + get: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect Discovery 1.0 Document + description: > + This endpoint retrieves the OpenID Connect Discovery 1.0 document used by clients to perform discovery for + an OpenID Connect 1.0 Provider. See https://openid.net/specs/openid-connect-discovery-1_0.html. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/openid.spec.Metadata.OpenIDConfiguration' + "400": + description: Bad Request + "500": + description: Internal Server Error + /.well-known/oauth-authorization-server: + get: + tags: + - OpenID Connect 1.0 + summary: OAuth 2.0 Authorization Server Metadata + description: > + This endpoint retrieves the OAuth 2.0 Authorization Server Metadata document (RFC8414) used by clients to + perform discovery for an OAuth 2.0 Authorization Server. See https://www.rfc-editor.org/rfc/rfc8414. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/openid.spec.Metadata.OAuth2AuthorizationServer' + "400": + description: Bad Request + "500": + description: Internal Server Error + /jwks.json: + get: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 JSON Web Key Set Document + description: > + This endpoint retrieves the OpenID Connect 1.0 JSON Web Key Set Document (JWKS) used by clients to validate + information from this OpenID Connect 1.0 Provider. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/jose.spec.JWKs' + /api/oidc/authorization: + get: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 Authorization Endpoint + description: > + This endpoint performs OpenID Connect 1.0 Authorization. + parameters: + - in: query + name: id + required: false + description: The OpenID Connect 1.0 consent workflow ID. + schema: + type: string + format: uuid + pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' + example: "713ef767-81bc-4a27-9b83-5fe2e101b2b4" + - in: query + name: scope + description: The requested scope. + required: true + schema: + type: string + example: "openid profile groups" + - in: query + name: response_type + description: The OAuth 2.0 response type. + required: true + schema: + $ref: '#/components/schemas/openid.spec.ResponseType' + - in: query + name: client_id + description: The OAuth 2.0 client identifier. + required: true + schema: + type: string + example: "app" + - in: query + name: redirect_uri + description: > + Redirection URI to which the response will be sent. This URI MUST exactly match one of the Redirection URI + values for the Client pre-registered at the OpenID Provider, with the matching performed as described in + Section 6.2.1 of [RFC3986] (Simple String Comparison). When using this flow, the Redirection URI SHOULD use + the https scheme; however, it MAY use the http scheme, provided that the Client Type is confidential, as + defined in Section 2.1 of OAuth 2.0, and provided the OP allows the use of http Redirection URIs in this + case. The Redirection URI MAY use an alternate scheme, such as one that is intended to identify a callback + into a native application. + required: true + schema: + type: string + example: "https://app.example.com" + - in: query + name: state + description: > + Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request + Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a + browser cookie. + required: false + schema: + type: string + example: "oV84Vsy7wyCgRk2h4aZBmXZq4q3g2f" + - in: query + name: response_mode + description: > + Informs the Authorization Server of the mechanism to be used for returning parameters from the Authorization + Endpoint. This use of this parameter is NOT RECOMMENDED when the Response Mode that would be requested is + the default mode specified for the Response Type. + required: false + schema: + $ref: '#/components/schemas/openid.spec.ResponseMode' + - in: query + name: nonce + description: > + String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value + is passed through unmodified from the Authentication Request to the ID Token. Sufficient entropy MUST be + present in the nonce values used to prevent attackers from guessing values. For implementation notes, see + Section 15.5.2. + required: false + schema: + type: string + example: "TRMLqchoKGQNcooXvBvUy9PtmLdJGf" + - in: query + name: display + description: > + Not Supported: ASCII string value that specifies how the Authorization Server displays the authentication + and consent user interface pages to the End-User. + required: false + schema: + $ref: '#/components/schemas/openid.spec.DisplayType' + - in: query + name: prompt + description: > + Not Supported: Space delimited, case sensitive list of ASCII string values that specifies whether the + Authorization Server prompts the End-User for reauthentication and consent. + required: false + schema: + type: string + - in: query + name: max_age + description: > + Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End-User + was actively authenticated by the OP. If the elapsed time is greater than this value, the OP MUST attempt to + actively re-authenticate the End-User. (The max_age request parameter corresponds to the OpenID 2.0 PAPE + [OpenID.PAPE] max_auth_age request parameter.) When max_age is used, the ID Token returned MUST include an + auth_time Claim Value. + required: false + schema: + type: integer + example: 3600 + - in: query + name: ui_locales + description: > + Not Supported: End-User's preferred languages and scripts for the user interface, represented as a + space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. For instance, the value + "fr-CA fr en" represents a preference for French as spoken in Canada, then French (without a region + designation), followed by English (without a region designation). An error SHOULD NOT result if some or all + of the requested locales are not supported by the OpenID Provider. + required: false + schema: + type: string + example: "en-US" + - in: query + name: claims_locales + description: > + Not Supported: End-User's preferred languages and scripts for Claims being returned, represented as a + space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. An error SHOULD NOT + result if some or all of the requested locales are not supported by the OpenID Provider. + required: false + schema: + type: string + example: "en-US" + - in: query + name: id_token_hint + required: false + description: > + Not Supported: ID Token previously issued by the Authorization Server being passed as a hint about the + End-User's current or past authenticated session with the Client. If the End-User identified by the ID Token + is logged in or is logged in by the request, then the Authorization Server returns a positive response; + otherwise, it SHOULD return an error, such as login_required. When possible, an id_token_hint SHOULD be + present when prompt=none is used and an invalid_request error MAY be returned if it is not; however, the + server SHOULD respond successfully when possible, even if it is not present. The Authorization Server need + not be listed as an audience of the ID Token when it is used as an id_token_hint value. If the ID Token + received by the RP from the OP is encrypted, to use it as an id_token_hint, the Client MUST decrypt the + signed ID Token contained within the encrypted ID Token. The Client MAY re-encrypt the signed ID token to + the Authentication Server using a key that enables the server to decrypt the ID Token, and use the + re-encrypted ID token as the id_token_hint value. + schema: + type: string + - in: query + name: login_hint + description: > + Not Supported: Hint to the Authorization Server about the login identifier the End-User might use to log in + (if necessary). This hint can be used by an RP if it first asks the End-User for their e-mail address + (or other identifier) and then wants to pass that value as a hint to the discovered authorization service. + It is RECOMMENDED that the hint value match the value used for discovery. This value MAY also be a phone + number in the format specified for the phone_number Claim. The use of this parameter is left to the OP's + discretion. + required: false + schema: + type: string + - in: query + name: acr_values + description: > + Not Supported: Requested Authentication Context Class Reference values. Space-separated string that + specifies the acr values that the Authorization Server is being requested to use for processing this + Authentication Request, with the values appearing in order of preference. The Authentication Context Class + satisfied by the authentication performed is returned as the acr Claim Value, as specified in Section 2. + The acr Claim is requested as a Voluntary Claim by this parameter. + required: false + schema: + type: string + - in: query + name: claims + description: > + Not Supported: The claims parameter value, as specified in Section 5.5. + required: false + schema: + type: string + - in: query + name: registration + description: > + Not Supported: This parameter is used by the Client to provide information about itself to a Self-Issued OP + that would normally be provided to an OP during Dynamic Client Registration, as specified in Section 7.2.1. + required: false + schema: + type: string + - in: query + name: request + description: > + Not Supported: Request Object value, as specified in Section 6.1. The Request Object MAY be encrypted to + the Self-Issued OP by the Client. In this case, the sub (subject) of a previously issued ID Token for this + Client MUST be sent as the kid (Key ID) of the JWE. Encrypting content to Self-Issued OPs is currently only + supported when the OP's JWK key type is RSA and the encryption algorithm used is RSA1_5. + required: false + schema: + type: string + - in: query + name: code_challenge + description: > + RFC7636 Code Challenge. + required: false + schema: + type: string + - in: query + name: code_challenge_method + required: false + description: > + RFC7636 Code Challenge Method. defaults to "plain" if not present in the request. + Code verifier transformation method is "S256" or "plain". + schema: + $ref: '#/components/schemas/openid.spec.CodeChallengeMethod' + responses: + "200": + description: OK + content: + text/html: + schema: + type: string + description: The Form Post Response Mode content. + "303": + description: See Other + headers: + Location: + schema: + type: string + description: > + Redirection location for the consent flow, or the authorization response callback location when using + the Query or Fragment Response Modes. + "400": + description: Bad Request + "500": + description: Internal Server Error + post: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 Authorization Endpoint + description: > + This endpoint performs OpenID Connect 1.0 Authorization. + requestBody: + description: Authorize Request Parameters. + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/openid.spec.AuthorizeRequest' + responses: + "200": + description: OK + content: + text/html: + schema: + type: string + description: The Form Post Response Mode content. + "303": + description: See Other + headers: + Location: + schema: + type: string + description: > + Redirection location for the consent flow, or the authorization response callback location when using + the Query or Fragment Response Modes. + "400": + description: Bad Request + "500": + description: Internal Server Error + security: + - authelia_auth: [] + /api/oidc/token: + post: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 Token Endpoint + description: > + This endpoint performs OpenID Connect 1.0 Token Access Requests. + requestBody: + description: Access Request Parameters. + required: true + content: + application/x-www-form-urlencoded: + schema: + oneOf: + - $ref: '#/components/schemas/openid.spec.AccessRequest.AuthorizationCodeFlow' + - $ref: '#/components/schemas/openid.spec.AccessRequest.RefreshTokenFlow' + - $ref: '#/components/schemas/openid.spec.AccessRequest.DeviceCodeFlow' + responses: + "200": + description: OK + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/openid.spec.AccessResponse' + "401": + description: Forbidden + "403": + description: Unauthorized + "500": + description: Internal Server Error + security: + - openid: [] + /api/oidc/revocation: + post: + tags: + - OpenID Connect 1.0 + summary: OAuth 2.0 Token Revocation Endpoint + description: > + This endpoint performs OAuth 2.0 Token Revocation Requests. + requestBody: + description: Required OAuth 2.0 revocation parameters. + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/openid.spec.IntrospectionRequest' + responses: + "200": + description: OK + "401": + description: Forbidden + "403": + description: Unauthorized + "500": + description: Internal Server Error + security: + - openid: [] + /api/oidc/introspection: + post: + tags: + - OpenID Connect 1.0 + summary: OAuth 2.0 Token Introspection Endpoint + description: > + This endpoint performs OAuth 2.0 Token Introspection Requests. + requestBody: + description: Required OAuth 2.0 introspection parameters. + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/openid.spec.IntrospectionRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/openid.implementation.Claims.Object' + "401": + description: Forbidden + "403": + description: Unauthorized + "500": + description: Internal Server Error + security: + - openid: [] + /api/oidc/userinfo: + get: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 UserInfo Endpoint + description: > + This endpoint performs OpenID Connect 1.0 UserInfo Access Requests. + parameters: + - in: query + name: access_token + description: The OAuth 2.0 Access Token issued by this OpenID Connect 1.0 Provider. + schema: + type: string + example: "authelia_at_cr4i4EtTn2F4k6mX4XzxbsBewkxCGn" + responses: + "200": + description: OK + content: + application/jwt: {} + application/json: + schema: + $ref: '#/components/schemas/openid.implementation.Claims.Object' + "401": + description: Forbidden + "403": + description: Unauthorized + "500": + description: Internal Server Error + security: + - openid: [] + post: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 UserInfo Endpoint + description: > + This endpoint performs OpenID Connect 1.0 UserInfo Access Requests. + parameters: + - in: query + name: access_token + description: The OAuth 2.0 Access Token issued by this OpenID Connect 1.0 Provider. + schema: + type: string + example: "authelia_at_cr4i4EtTn2F4k6mX4XzxbsBewkxCGn" + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + access_token: + description: The OAuth 2.0 Access Token issued by this OpenID Connect 1.0 Provider. + type: string + example: "authelia_at_cr4i4EtTn2F4k6mX4XzxbsBewkxCGn" + responses: + "200": + description: OK + content: + application/jwt: {} + application/json: + schema: + $ref: '#/components/schemas/openid.implementation.Claims.Object' + "401": + description: Forbidden + "403": + description: Unauthorized + "500": + description: Internal Server Error + security: + - openid: [] + /api/oidc/consent: + get: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 Consent Information + description: > + This endpoint retrieves the consent information about a specific consent ID during the consent workflow. + parameters: + - $ref: '#/components/parameters/idRequiredParam' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/openid.request.consent' + "403": + description: Forbidden + security: + - authelia_auth: [] + post: + tags: + - OpenID Connect 1.0 + summary: OpenID Connect 1.0 Consent Response + description: > + This endpoint retrieves the consent response for a specific consent ID during the consent workflow. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/openid.response.consent' + "403": + description: Forbidden + security: + - authelia_auth: [] components: parameters: deviceID: @@ -722,6 +1246,13 @@ components: schema: type: string enum: ["basic"] + idRequiredParam: + name: id + in: query + description: The ID of what is being requested + required: true + schema: + type: string schemas: handlers.checkURIWithinDomainRequestBody: type: object @@ -851,7 +1382,9 @@ components: example: openid_connect workflowID: type: string - example: 3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c + format: uuid + pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' + example: "3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c" requestMethod: type: string example: GET @@ -917,7 +1450,9 @@ components: example: openid_connect workflowID: type: string - example: 3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c + format: uuid + pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' + example: "3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c" handlers.bodySignTOTPRequest: type: object properties: @@ -932,7 +1467,9 @@ components: example: openid_connect workflowID: type: string - example: 3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c + format: uuid + pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' + example: "3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c" handlers.StateResponse: type: object properties: @@ -965,7 +1502,7 @@ components: example: 5ZH7Y5CTFWOXN7EOLGBMMXADRNQFHVUDZSYKCN5HMFAIRSLAWY3Q otpauth_url: type: string - example: otpauth://totp/auth.example.com:john?algorithm=SHA1&digits=6&issuer=auth.example.com&period=30&secret=5ZH7Y5CTFWOXN7EOLGBMMXADRNQFHVUDZSYKCN5HMFAIRSLAWY3Q # yamllint disable-line rule:line-length + example: otpauth://totp/auth.example.com:john?algorithm=SHA1&digits=6&issuer=auth.example.com&period=30&secret=5ZH7Y5CTFWOXN7EOLGBMMXADRNQFHVUDZSYKCN5HMFAIRSLAWY3Q handlers.UserInfo: type: object properties: @@ -1041,7 +1578,7 @@ components: properties: token: type: string - example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDc5MjU1OTYsImlzcyI6IkF1dGhlbGlhIiwiYWN0aW9uIjoiUmVzZXRQYXNzd29yZCIsInVzZXJuYW1lIjoiQW1pciJ9.636yqRrUCGCe4jsMCsonleX5CYWHncYqZum-YYb6VaY # yamllint disable-line rule:line-length + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDc5MjU1OTYsImlzcyI6IkF1dGhlbGlhIiwiYWN0aW9uIjoiUmVzZXRQYXNzd29yZCIsInVzZXJuYW1lIjoiQW1pciJ9.636yqRrUCGCe4jsMCsonleX5CYWHncYqZum-YYb6VaY middlewares.OkResponse: type: object properties: @@ -1123,7 +1660,9 @@ components: example: openid_connect workflowID: type: string - example: 3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c + format: uuid + pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' + example: "3ebcfbc5-b0fd-4ee0-9d3c-080ae1e7298c" webauthn.DeviceUpdateRequest: type: object properties: @@ -1356,9 +1895,1608 @@ components: written: type: boolean example: false + openid.request.consent: + type: object + properties: + status: + type: string + example: OK + data: + type: object + properties: + client_id: + type: string + description: The identifier of the client for the user to provide consent for. + example: "app" + client_description: + description: The descriptive name of the client for the user to provide consent for. + type: string + example: "App Platform" + scopes: + description: The list of the requested scopes for the user to provide consent for. + type: array + items: + type: string + enum: + - "openid" + - "offline_access" + - "groups" + - "email" + - "profile" + audience: + description: The list of the requested audiences for the user to provide consent for. + type: array + items: + type: string + pre_configuration: + description: Indicates if this client supports pre-configuration. + type: boolean + example: true + openid.response.consent: + type: object + properties: + status: + type: string + example: OK + data: + type: object + properties: + id: + description: The identifier of the consent session. + type: string + format: uuid + pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' + example: "713ef767-81bc-4a27-9b83-5fe2e101b2b4" + client_id: + description: The identifier of the client for the user to provide consent for. + type: string + example: "app" + consent: + description: Indicates if the user consented to the consent request. + type: boolean + example: true + pre_configure: + description: Indicates if the user consented to pre-configuration. + type: boolean + example: true + openid.spec.Metadata.OAuth2AuthorizationServer: + type: object + required: + - issuer + - authorization_endpoint + - subject_types_supported + - response_types_supported + - require_pushed_authorization_requests + properties: + authorization_endpoint: + description: > + URL of the OP''s OAuth 2.0 Authorization Endpoint [OpenID.Core]. + See Also: OpenID.Core: https://openid.net/specs/openid-connect-core-1_0.html + type: string + example: "{{ .BaseURL }}api/oidc/authorization" + claims_supported: + description: > + JSON array containing a list of the Claim Names of the Claims that the OpenID Provider MAY be able to supply + values for. Note that for privacy or other reasons, this might not be an exhaustive list. + type: array + example: + - "amr" + - "aud" + - "azp" + - "client_id" + - "exp" + - "iat" + - "iss" + - "jti" + - "rat" + - "sub" + - "auth_time" + - "nonce" + - "email" + - "email_verified" + - "alt_emails" + - "groups" + - "preferred_username" + - "name" + items: + $ref: '#/components/schemas/openid.implementation.Claims.Array' + code_challenge_methods_supported: + description: > + JSON array containing a list of PKCE [RFC7636] code challenge methods supported by this authorization + server. Code challenge method values are used in the "code_challenge_method" parameter defined in Section + 4.3 of [RFC7636]. The valid code challenge method values are those registered in the IANA "PKCE Code + Challenge Methods" registry [IANA.OAuth.Parameters]. If omitted, the authorization server does not support + PKCE. See Also: PKCE: https://datatracker.ietf.org/doc/html/rfc7636 IANA.OAuth.Parameters: https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml + type: array + example: ["S256", "none"] + items: + $ref: '#/components/schemas/openid.spec.CodeChallengeMethod' + grant_types_supported: + type: array + description: > + JSON array containing a list of the OAuth 2.0 Grant Type values that this OP supports. Dynamic OpenID + Providers MUST support the authorization_code and implicit Grant Type values and MAY support other Grant + Types. If omitted, the default value is ["authorization_code", "implicit"]. + example: ["authorization_code", "implicit"] + items: + $ref: '#/components/schemas/openid.spec.GrantType' + introspection_endpoint: + description: > + URL of the authorization server''s OAuth 2.0 introspection endpoint [RFC7662]. See Also: OAuth 2.0 Token + Introspection: https://datatracker.ietf.org/doc/html/rfc7662 + type: string + example: "{{ .BaseURL }}api/oidc/introspection" + introspection_endpoint_auth_methods_supported: + description: > + JSON array containing a list of client authentication methods supported by this introspection endpoint. The + valid client authentication method values are those registered in the IANA "OAuth Token Endpoint + Authentication Methods" registry [IANA.OAuth.Parameters] or those registered in the IANA "OAuth Access Token + Types" registry [IANA.OAuth.Parameters]. (These values are and will remain distinct, due to Section 7.2.) If + omitted, the set of supported authentication methods MUST be determined by other means. See Also: + IANA.OAuth.Parameters: https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml + OAuth 2.0 Authorization Server Metadata - Updated Registration Instructions: + https://datatracker.ietf.org/doc/html/draft-ietf-oauth-discovery-10#section-7.2 + type: array + example: ["client_secret_post"] + items: + $ref: '#/components/schemas/openid.spec.ClientAuthMethod' + introspection_endpoint_auth_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms ("alg" values) supported by the introspection + endpoint for the signature on the JWT [JWT] used to authenticate the client at the introspection endpoint + for the "private_key_jwt" and "client_secret_jwt" authentication methods. This metadata entry MUST be + present if either of these authentication methods are specified in the + "introspection_endpoint_auth_methods_supported" entry. No default algorithms are implied if this entry is + omitted. The value "none" MUST NOT be used. See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.jws' + issuer: + description: + URL using the https scheme with no query or fragment component that the OP asserts as its Issuer Identifier. + If Issuer discovery is supported (see Section 2), this value MUST be identical to the issuer value returned + by WebFinger. This also MUST be identical to the iss Claim value in ID Tokens issued from this Issuer. + type: string + example: "{{ .BaseURL }}" + jwks_uri: + description: > + URL of the OP's JSON Web Key Set [JWK] document. This contains the signing key(s) the RP uses to validate + signatures from the OP. The JWK Set MAY also contain the Server's encryption key(s), which are used by RPs + to encrypt requests to the Server. When both signing and encryption keys are made available, a use (Key Use) + parameter value is REQUIRED for all keys in the referenced JWK Set to indicate each key's intended usage. + Although some algorithms allow the same key to be used for both signatures and encryption, doing so is NOT + RECOMMENDED, as it is less secure. The JWK x5c parameter MAY be used to provide X.509 representations of + keys provided. When used, the bare key values MUST still be present and MUST match those in the certificate. + type: string + example: "{{ .BaseURL }}jwks.json" + op_policy_uri: + description: + URL that the OpenID Provider provides to the person registering the Client to read about the OP's + requirements on how the Relying Party can use the data provided by the OP. The registration process SHOULD + display this URL to the person registering the Client if it is given. + type: string + op_tos_uri: + description: > + URL that the OpenID Provider provides to the person registering the Client to read about OpenID Provider's + terms of service. The registration process SHOULD display this URL to the person registering the Client if + it is given. + type: string + pushed_authorization_request_endpoint: + description: > + The URL of the pushed authorization request endpoint at which a client can post an authorization request to + exchange for a "request_uri" value usable at the authorization server. + type: string + example: "{{ .BaseURL }}api/oidc/par" + registration_endpoint: + description: > + URL of the authorization server''s OAuth 2.0 Dynamic Client Registration endpoint [RFC7591]. See Also: + OAuth 2.0 Dynamic Client Registration Protocol: https://datatracker.ietf.org/doc/html/rfc7591 + type: string + example: "{{ .BaseURL }}api/oidc/registration" + require_pushed_authorization_requests: + description: > + Boolean parameter indicating whether the authorization server accepts authorization request data only via + PAR. If omitted, the default value is "false". + type: boolean + example: false + response_modes_supported: + description: > + JSON array containing a list of the OAuth 2.0 response_mode values that this OP supports, as specified in + OAuth 2.0 Multiple Response Type Encoding Practices [OAuth.Responses]. If omitted, the default for Dynamic + OpenID Providers is ["query", "fragment"]. + type: array + example: ["query", "fragment"] + items: + $ref: '#/components/schemas/openid.spec.ResponseMode' + response_types_supported: + description: > + JSON array containing a list of the OAuth 2.0 response_type values that this OP supports. + Dynamic OpenID Providers MUST support the code, id_token, and the token id_token Response Type values. + type: array + example: ["code", "id_token", "token id_token"] + items: + $ref: '#/components/schemas/openid.spec.ResponseType' + revocation_endpoint: + description: > + URL of the authorization server''s OAuth 2.0 revocation endpoint [RFC7009]. + See Also: OAuth 2.0 Token Revocation: https://datatracker.ietf.org/doc/html/rfc7009 + type: string + example: "{{ .BaseURL }}api/oidc/revocation" + revocation_endpoint_auth_methods_supported: + description: > + JSON array containing a list of client authentication methods supported by this revocation endpoint. The + valid client authentication method values are those registered in the IANA "OAuth Token Endpoint + Authentication Methods" registry [IANA.OAuth.Parameters]. If omitted, the default is "client_secret_basic" + -- the HTTP Basic Authentication Scheme specified in Section 2.3.1 of OAuth 2.0 [RFC6749]. See Also: + IANA.OAuth.Parameters: https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml + OAuth 2.0 - Client Password: https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 + type: array + example: ["client_secret_post"] + items: + $ref: '#/components/schemas/openid.spec.ClientAuthMethod' + revocation_endpoint_auth_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms ("alg" values) supported by the revocation + endpoint for the signature on the JWT [JWT] used to authenticate the client at the revocation endpoint for + the "private_key_jwt" and "client_secret_jwt" authentication methods. This metadata entry MUST be present if + either of these authentication methods are specified in the "revocation_endpoint_auth_methods_supported" + entry. No default algorithms are implied if this entry is omitted. The value "none" MUST NOT be used. + See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.jws' + scopes_supported: + description: > + JSON array containing a list of the OAuth 2.0 [RFC6749] scope values that this server supports. The server + MUST support the openid scope value. Servers MAY choose not to advertise some supported scope values even + when this parameter is used, although those defined in [OpenID.Core] SHOULD be listed, if supported. + See Also: OAuth 2.0: https://datatracker.ietf.org/doc/html/rfc6749 OpenID.Core: https://openid.net/specs/openid-connect-core-1_0.html + type: array + example: + - "openid" + - "offline_access" + - "profile" + - "email" + - "groups" + items: + $ref: '#/components/schemas/openid.implementation.Scopes.Object' + service_documentation: + description: > + URL of a page containing human-readable information that developers might want or need to know when using + the OpenID Provider. In particular, if the OpenID Provider does not support Dynamic Client Registration, + then information on how to register Clients needs to be provided in this documentation. + type: string + example: "https://authelia.com" + subject_types_supported: + description: > + JSON array containing a list of the Subject Identifier types that this OP supports. + Valid types include pairwise and public. + type: array + example: ["public", "pairwise"] + items: + $ref: '#/components/schemas/openid.spec.SubjectIdentifier' + token_endpoint: + description: > + URL of the OP''s OAuth 2.0 Token Endpoint [OpenID.Core]. This is REQUIRED unless only the Implicit Flow is + used. See Also: OpenID.Core: https://openid.net/specs/openid-connect-core-1_0.html + type: string + example: "{{ .BaseURL }}api/oidc/token" + token_endpoint_auth_methods_supported: + description: > + JSON array containing a list of Client Authentication methods supported by this Token Endpoint. The options + are client_secret_post, client_secret_basic, client_secret_jwt, and private_key_jwt, as described in Section + 9 of OpenID Connect Core 1.0 [OpenID.Core]. Other authentication methods MAY be defined by extensions. If + omitted, the default is client_secret_basic -- the HTTP Basic Authentication Scheme specified in Section + 2.3.1 of OAuth 2.0 [RFC6749]. See Also: OAuth 2.0: https://datatracker.ietf.org/doc/html/rfc6749 + OpenID.Core Section 9: https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication + type: array + example: ["client_secret_post"] + items: + $ref: '#/components/schemas/openid.spec.ClientAuthMethod' + token_endpoint_auth_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms (alg values) supported by the Token Endpoint for + the signature on the JWT [JWT] used to authenticate the Client at the Token Endpoint for the private_key_jwt + and client_secret_jwt authentication methods. Servers SHOULD support RS256. The value none MUST NOT be used. + See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519' + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.jws' + ui_locales_supported: + type: array + description: > + Languages and scripts supported for the user interface, represented as a JSON array of BCP47 [RFC5646] + language tag values. See Also: BCP47: https://datatracker.ietf.org/doc/html/rfc5646 + example: ["en-US"] + items: + type: string + openid.spec.Metadata.OpenIDConfiguration: + type: object + required: + - "issuer" + - "authorization_endpoint" + - "subject_types_supported" + - "response_types_supported" + - "require_pushed_authorization_requests" + - "request_uri_parameter_supported" + - "require_request_uri_registration" + - "claims_parameter_supported" + - "frontchannel_logout_supported" + - "frontchannel_logout_session_supported" + - "backchannel_logout_supported" + - "backchannel_logout_session_supported" + properties: + acr_values_supported: + description: + JSON array containing a list of the Authentication Context Class References that this OP supports. + type: array + items: + type: string + authorization_endpoint: + description: > + URL of the OP''s OAuth 2.0 Authorization Endpoint [OpenID.Core]. + See Also: OpenID.Core: https://openid.net/specs/openid-connect-core-1_0.html + type: string + example: "{{ .BaseURL }}api/oidc/authorization" + backchannel_logout_session_supported: + description: > + Boolean value specifying whether the OP can pass a sid (session ID) Claim in the Logout Token to identify + the RP session with the OP. If supported, the sid Claim is also included in ID Tokens issued by the OP. + If omitted, the default value is false. + type: boolean + example: false + backchannel_logout_supported: + description: > + Boolean value specifying whether the OP supports back-channel logout, with true indicating support. If + omitted, the default value is false. + type: boolean + example: false + claim_types_supported: + description: > + JSON array containing a list of the Claim Types that the OpenID Provider supports. These Claim Types are + described in Section 5.6 of OpenID Connect Core 1.0 [OpenID.Core]. Values defined by this specification are + normal, aggregated, and distributed. If omitted, the implementation supports only normal Claims. See Also: + OpenID.Core Section 5.6: https://openid.net/specs/openid-connect-core-1_0.html#ClaimTypes + type: array + example: ["normal"] + items: + $ref: '#/components/schemas/openid.spec.ClaimType' + claims_locales_supported: + description: > + Languages and scripts supported for values in Claims being returned, represented as a JSON array of BCP47 + [RFC5646] language tag values. Not all languages and scripts are necessarily supported for all Claim values. + See Also: BCP47: https://datatracker.ietf.org/doc/html/rfc5646 + type: array + example: ["en-US"] + items: + type: string + claims_parameter_supported: + description: > + Boolean value specifying whether the OP supports use of the claims parameter, with true indicating support. + If omitted, the default value is false. + type: boolean + example: false + claims_supported: + description: > + JSON array containing a list of the Claim Names of the Claims that the OpenID Provider MAY be able to supply + values for. Note that for privacy or other reasons, this might not be an exhaustive list. + type: array + example: + - "amr" + - "aud" + - "azp" + - "client_id" + - "exp" + - "iat" + - "iss" + - "jti" + - "rat" + - "sub" + - "auth_time" + - "nonce" + - "email" + - "email_verified" + - "alt_emails" + - "groups" + - "preferred_username" + - "name" + items: + $ref: '#/components/schemas/openid.implementation.Claims.Array' + code_challenge_methods_supported: + description: > + JSON array containing a list of PKCE [RFC7636] code challenge methods supported by this authorization + server. Code challenge method values are used in the "code_challenge_method" parameter defined in Section + 4.3 of [RFC7636]. The valid code challenge method values are those registered in the IANA "PKCE Code + Challenge Methods" registry [IANA.OAuth.Parameters]. If omitted, the authorization server does not support + PKCE. See Also: PKCE: https://datatracker.ietf.org/doc/html/rfc7636 IANA.OAuth.Parameters: + https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml + type: array + example: ["S256", "plain"] + items: + $ref: '#/components/schemas/openid.spec.CodeChallengeMethod' + display_values_supported: + description: > + JSON array containing a list of the display parameter values that the OpenID Provider supports. These values + are described in Section 3.1.2.1 of OpenID Connect Core 1.0 [OpenID.Core]. See Also: OpenID.Core Section + 3.1.2.1: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest + type: array + example: ["page"] + items: + $ref: '#/components/schemas/openid.spec.DisplayType' + frontchannel_logout_session_supported: + description: > + Boolean value specifying whether the OP can pass iss (issuer) and sid (session ID) query parameters to + identify the RP session with the OP when the frontchannel_logout_uri is used. If supported, the sid Claim is + also included in ID Tokens issued by the OP. If omitted, the default value is false. + type: boolean + example: false + frontchannel_logout_supported: + description: > + Boolean value specifying whether the OP supports HTTP-based logout, with true indicating support. If + omitted, the default value is false. + type: boolean + example: false + grant_types_supported: + description: > + JSON array containing a list of the OAuth 2.0 Grant Type values that this OP supports. Dynamic OpenID + Providers MUST support the authorization_code and implicit Grant Type values and MAY support other Grant + Types. If omitted, the default value is ["authorization_code", "implicit"]. + type: array + example: ["authorization_code", "implicit"] + items: + $ref: '#/components/schemas/openid.spec.GrantType' + id_token_encryption_alg_values_supported: + description: > + JSON array containing a list of the JWE encryption algorithms (alg values) supported by the OP for the ID + Token to encode the Claims in a JWT [JWT]. See Also: JWE: https://datatracker.ietf.org/doc/html/rfc7516 JWT: + https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["A256GCMKW"] + items: + $ref: '#/components/schemas/jose.spec.JWE.alg' + id_token_encryption_enc_values_supported: + description: > + JSON array containing a list of the JWE encryption algorithms (enc values) supported by the OP for the ID + Token to encode the Claims in a JWT [JWT]. See Also: JWE: https://datatracker.ietf.org/doc/html/rfc7516 + JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["A256GCM"] + items: + $ref: '#/components/schemas/jose.spec.JWE.enc' + id_token_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms (alg values) supported by the OP for the ID Token + to encode the Claims in a JWT [JWT]. The algorithm RS256 MUST be included. The value none MAY be supported, + but MUST NOT be used unless the Response Type used returns no ID Token from the Authorization Endpoint + (such as when using the Authorization Code Flow). + See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.JWS.None' + introspection_endpoint: + description: > + URL of the authorization server''s OAuth 2.0 introspection endpoint [RFC7662]. See Also: OAuth 2.0 + Token Introspection: https://datatracker.ietf.org/doc/html/rfc7662' + type: string + example: "{{ .BaseURL }}api/oidc/introspection" + introspection_endpoint_auth_methods_supported: + description: > + JSON array containing a list of client authentication methods supported by this introspection endpoint. The + valid client authentication method values are those registered in the IANA "OAuth Token Endpoint + Authentication Methods" registry [IANA.OAuth.Parameters] or those registered in the IANA "OAuth Access + Token Types" registry [IANA.OAuth.Parameters]. (These values are and will remain distinct, due to Section + 7.2.) If omitted, the set of supported authentication methods MUST be determined by other means. See Also: + IANA.OAuth.Parameters: https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml + OAuth 2.0 Authorization Server Metadata - Updated Registration Instructions: + https://datatracker.ietf.org/doc/html/draft-ietf-oauth-discovery-10#section-7.2 + type: array + example: ["client_secret_post"] + items: + $ref: '#/components/schemas/openid.spec.ClientAuthMethod' + introspection_endpoint_auth_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms ("alg" values) supported by the introspection + endpoint for the signature on the JWT [JWT] used to authenticate the client at the introspection endpoint + for the "private_key_jwt" and "client_secret_jwt" authentication methods. This metadata entry MUST be + present if either of these authentication methods are specified in the + "introspection_endpoint_auth_methods_supported" entry. No default algorithms are implied if this entry is + omitted. The value "none" MUST NOT be used. See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.jws' + issuer: + description: > + URL using the https scheme with no query or fragment component that the OP asserts as its Issuer Identifier. + If Issuer discovery is supported (see Section 2), this value MUST be identical to the issuer value returned + by WebFinger. This also MUST be identical to the iss Claim value in ID Tokens issued from this Issuer. + type: string + example: "{{ .BaseURL }}" + jwks_uri: + description: > + URL of the OP's JSON Web Key Set [JWK] document. This contains the signing key(s) the RP uses to validate + signatures from the OP. The JWK Set MAY also contain the Server's encryption key(s), which are used by RPs + to encrypt requests to the Server. When both signing and encryption keys are made available, a use (Key Use) + parameter value is REQUIRED for all keys in the referenced JWK Set to indicate each key's intended usage. + Although some algorithms allow the same key to be used for both signatures and encryption, doing so is NOT + RECOMMENDED, as it is less secure. The JWK x5c parameter MAY be used to provide X.509 representations of + keys provided. When used, the bare key values MUST still be present and MUST match those in the certificate. + type: string + example: "{{ .BaseURL }}jwks.json" + op_policy_uri: + description: > + URL that the OpenID Provider provides to the person registering the Client to read about the OP's + requirements on how the Relying Party can use the data provided by the OP. The registration process SHOULD + display this URL to the person registering the Client if it is given. + type: string + op_tos_uri: + description: > + URL that the OpenID Provider provides to the person registering the Client to read about OpenID Provider's + terms of service. The registration process SHOULD display this URL to the person registering the Client + if it is given. + type: string + pushed_authorization_request_endpoint: + description: > + The URL of the pushed authorization request endpoint at which a client can post an authorization request to + exchange for a "request_uri" value usable at the authorization server. + type: string + example: "{{ .BaseURL }}api/oidc/par" + registration_endpoint: + description: > + URL of the authorization server''s OAuth 2.0 Dynamic Client Registration endpoint [RFC7591]. See Also: + OAuth 2.0 Dynamic Client Registration Protocol: https://datatracker.ietf.org/doc/html/rfc7591 + type: string + example: "{{ .BaseURL }}api/oidc/registration" + request_object_encryption_alg_values_supported: + description: > + JSON array containing a list of the JWE encryption algorithms (alg values) supported by the OP for Request + Objects. These algorithms are used both when the Request Object is passed by value and when it is passed by + reference. See Also: JWE: https://datatracker.ietf.org/doc/html/rfc7516 + type: array + example: ["A256GCMKW"] + items: + $ref: '#/components/schemas/jose.spec.JWE.alg' + request_object_encryption_enc_values_supported: + description: > + JSON array containing a list of the JWE encryption algorithms (enc values) supported by the OP for Request + Objects. These algorithms are used both when the Request Object is passed by value and when it is passed by + reference. See Also: JWE: https://datatracker.ietf.org/doc/html/rfc7516 + JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["A256GCM"] + items: + $ref: '#/components/schemas/jose.spec.JWE.enc' + request_object_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms (alg values) supported by the OP for Request + Objects, which are described in Section 6.1 of OpenID Connect Core 1.0 [OpenID.Core]. These algorithms are + used both when the Request Object is passed by value (using the request parameter) and when it is passed by + reference (using the request_uri parameter). Servers SHOULD support none and RS256. + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.JWS.None' + request_uri_parameter_supported: + description: > + Boolean value specifying whether the OP supports use of the request_uri parameter, with true indicating + support. If omitted, the default value is true. + type: boolean + example: true + require_pushed_authorization_requests: + description: > + Boolean parameter indicating whether the authorization server accepts authorization request data only via + PAR. If omitted, the default value is "false". + type: boolean + example: false + require_request_uri_registration: + description: > + Boolean value specifying whether the OP requires any request_uri values used to be pre-registered using the + request_uris registration parameter. Pre-registration is REQUIRED when the value is true. If omitted, the + default value is false. + type: boolean + example: false + response_modes_supported: + description: > + JSON array containing a list of the OAuth 2.0 response_mode values that this OP supports, as specified in + OAuth 2.0 Multiple Response Type Encoding Practices [OAuth.Responses]. If omitted, the default for Dynamic + OpenID Providers is ["query", "fragment"]. + type: array + example: ["query", "fragment"] + items: + $ref: '#/components/schemas/openid.spec.ResponseMode' + response_types_supported: + description: > + JSON array containing a list of the OAuth 2.0 response_type values that this OP supports. Dynamic OpenID + Providers MUST support the code, id_token, and the token id_token Response Type values. + type: array + example: ["code", "id_token", "token id_token"] + items: + $ref: '#/components/schemas/openid.spec.ResponseType' + revocation_endpoint: + description: > + URL of the authorization server''s OAuth 2.0 revocation endpoint [RFC7009]. See Also: + OAuth 2.0 Token Revocation: https://datatracker.ietf.org/doc/html/rfc7009 + type: string + example: "{{ .BaseURL }}api/oidc/revocation" + revocation_endpoint_auth_methods_supported: + description: > + JSON array containing a list of client authentication methods supported by this revocation endpoint. The + valid client authentication method values are those registered in the IANA "OAuth Token Endpoint + Authentication Methods" registry [IANA.OAuth.Parameters]. If omitted, the default is "client_secret_basic" + -- the HTTP Basic Authentication Scheme specified in Section 2.3.1 of OAuth 2.0 [RFC6749]. + See Also: IANA.OAuth.Parameters: https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml + OAuth 2.0 - Client Password: https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 + type: array + example: ["client_secret_basic"] + items: + $ref: '#/components/schemas/openid.spec.ClientAuthMethod' + revocation_endpoint_auth_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms ("alg" values) supported by the revocation + endpoint for the signature on the JWT [JWT] used to authenticate the client at the revocation endpoint for + the "private_key_jwt" and "client_secret_jwt" authentication methods. This metadata entry MUST be present if + either of these authentication methods are specified in the "revocation_endpoint_auth_methods_supported" + entry. No default algorithms are implied if this entry is omitted. The value "none" MUST NOT be used. + See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.jws' + scopes_supported: + description: > + JSON array containing a list of the OAuth 2.0 [RFC6749] scope values that this server supports. + The server MUST support the openid scope value. Servers MAY choose not to advertise some supported scope + values even when this parameter is used, although those defined in [OpenID.Core] SHOULD be listed, if + supported. See Also: OAuth 2.0: https://datatracker.ietf.org/doc/html/rfc6749 OpenID.Core: + https://openid.net/specs/openid-connect-core-1_0.html + type: array + example: + - "openid" + - "offline_access" + - "profile" + - "email" + - "groups" + items: + $ref: '#/components/schemas/openid.implementation.Scopes.Object' + service_documentation: + description: > + URL of a page containing human-readable information that developers might want or need to know when using + the OpenID Provider. In particular, if the OpenID Provider does not support Dynamic Client Registration, + then information on how to register Clients needs to be provided in this documentation. + type: string + example: "https://www.authelia.com" + subject_types_supported: + description: > + JSON array containing a list of the Subject Identifier types that this OP supports. Valid types include + pairwise and public. + type: array + example: ["public", "pairwise"] + items: + $ref: '#/components/schemas/openid.spec.SubjectIdentifier' + token_endpoint: + description: > + URL of the OP''s OAuth 2.0 Token Endpoint [OpenID.Core]. This is REQUIRED unless only the Implicit Flow is + used. See Also: OpenID.Core: https://openid.net/specs/openid-connect-core-1_0.html + type: string + example: "{{ .BaseURL }}api/oidc/token" + token_endpoint_auth_methods_supported: + description: > + JSON array containing a list of Client Authentication methods supported by this Token Endpoint. The options + are client_secret_post, client_secret_basic, client_secret_jwt, and private_key_jwt, as described in Section + 9 of OpenID Connect Core 1.0 [OpenID.Core]. Other authentication methods MAY be defined by extensions. If + omitted, the default is client_secret_basic -- the HTTP Basic Authentication Scheme specified in Section + 2.3.1 of OAuth 2.0 [RFC6749]. See Also: OAuth 2.0: https://datatracker.ietf.org/doc/html/rfc6749 + OpenID.Core Section 9: https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication + type: array + example: ["client_secret_post"] + items: + $ref: '#/components/schemas/openid.spec.ClientAuthMethod' + token_endpoint_auth_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS signing algorithms (alg values) supported by the Token Endpoint + for the signature on the JWT [JWT] used to authenticate the Client at the Token Endpoint for the + private_key_jwt and client_secret_jwt authentication methods. Servers SHOULD support RS256. + The value none MUST NOT be used. See Also: JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["RS256"] + items: + $ref: '#/components/schemas/jose.spec.jws' + ui_locales_supported: + description: > + Languages and scripts supported for the user interface, represented as a JSON array of BCP47 + [RFC5646] language tag values. See Also: BCP47: https://datatracker.ietf.org/doc/html/rfc5646 + type: array + example: ["en-US"] + items: + type: string + userinfo_encryption_alg_values_supported: + description: > + JSON array containing a list of the JWE [JWE] encryption algorithms (alg values) [JWA] supported by the + UserInfo Endpoint to encode the Claims in a JWT [JWT]. See Also: JWE: + https://datatracker.ietf.org/doc/html/rfc7516 JWA: https://datatracker.ietf.org/doc/html/rfc7518 + JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["A256GCMKW"] + items: + $ref: '#/components/schemas/jose.spec.JWE.alg' + userinfo_encryption_enc_values_supported: + description: > + JSON array containing a list of the JWE encryption algorithms (enc values) [JWA] supported by the UserInfo + Endpoint to encode the Claims in a JWT [JWT]. See Also: JWE: https://datatracker.ietf.org/doc/html/rfc7516 + JWA: https://datatracker.ietf.org/doc/html/rfc7518 JWT: https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["A256GCM"] + items: + $ref: '#/components/schemas/jose.spec.JWE.enc' + userinfo_endpoint: + description: > + URL of the OP''s UserInfo Endpoint [OpenID.Core]. This URL MUST use the https scheme and MAY contain port, + path, and query parameter components. + See Also: OpenID.Core: https://openid.net/specs/openid-connect-core-1_0.html + type: string + example: "{{ .BaseURL }}api/oidc/userinfo" + userinfo_signing_alg_values_supported: + description: > + JSON array containing a list of the JWS [JWS] signing algorithms (alg values) [JWA] supported by the + UserInfo Endpoint to encode the Claims in a JWT [JWT]. The value none MAY be included. See Also: + JWS: https://datatracker.ietf.org/doc/html/rfc7515 JWA: https://datatracker.ietf.org/doc/html/rfc7518 JWT: + https://datatracker.ietf.org/doc/html/rfc7519 + type: array + example: ["none", "RS256"] + items: + $ref: '#/components/schemas/jose.spec.JWS.None' + openid.implementation.Claims.Array: + type: array + items: + type: string + enum: + - "amr" + - "aud" + - "azp" + - "client_id" + - "exp" + - "iat" + - "iss" + - "jti" + - "rat" + - "sub" + - "auth_time" + - "nonce" + - "email" + - "email_verified" + - "alt_emails" + - "groups" + - "preferred_username" + - "name" + openid.implementation.Claims.Object: + description: OpenID Connect 1.0 User Claims. + type: object + properties: + amr: + type: array + items: + type: string + enum: + - "mfa" + - "mca" + - "user" + - "pin" + - "pwd" + - "otp" + - "hwk" + - "sms" + aud: + type: array + items: + type: string + azp: + type: string + client_id: + type: string + scope: + type: string + scp: + type: array + items: + type: string + exp: + type: integer + iat: + type: integer + iss: + type: string + jti: + type: string + rat: + type: integer + sub: + type: string + auth_time: + type: integer + nonce: + type: string + email: + type: string + email_verified: + type: boolean + alt_emails: + type: array + items: + type: string + groups: + type: array + items: + type: string + preferred_username: + type: string + name: + type: string + openid.implementation.Scopes.Object: + description: The scope. + type: string + oneOf: + - $ref: '#/components/schemas/openid.spec.Scopes' + - type: string + enum: + - "groups" + openid.spec.Scopes: + type: string + enum: + - "openid" + - "offline_access" + - "profile" + - "email" + - "address" + - "phone" + openid.spec.IntrospectionRequest: + type: object + required: + - "token" + properties: + token: + description: > + The string value of the token. For access tokens, this + is the "access_token" value returned from the token endpoint + defined in OAuth 2.0 [RFC6749], Section 5.1. For refresh tokens, + this is the "refresh_token" value returned from the token endpoint + as defined in OAuth 2.0 [RFC6749], Section 5.1. Other token types + are outside the scope of this specification. + type: string + example: "authelia_at_cr4i4EtTn2F4k6mX4XzxbsBewkxCGn" + token_type_hint: + description: > + A hint about the type of the token submitted for + introspection. The protected resource MAY pass this parameter to + help the authorization server optimize the token lookup. If the + server is unable to locate the token using the given hint, it MUST + extend its search across all of its supported token types. An + authorization server MAY ignore this parameter, particularly if it + is able to detect the token type automatically. Values for this + field are defined in the "OAuth Token Type Hints" registry defined + in OAuth Token Revocation [RFC7009]. + type: string + example: "access_token" + enum: + - "access_token" + - "refresh_token" + openid.spec.AccessRequest.ClientAuth: + type: object + properties: + client_id: + description: > + REQUIRED if the client is not authenticating with the + authorization server as described in Section 3.2.1. of [RFC6749]. + The client identifier as described in Section 2.2 of [RFC6749]. + type: string + example: "authelia_dc_mn123kjn12kj3123njk" + client_secret: + description: > + REQUIRED. The client secret. The client MAY omit the + parameter if the client secret is an empty string. + type: string + format: password + openid.spec.AccessRequest.AuthorizationCodeFlow: + allOf: + - $ref: '#/components/schemas/openid.spec.AccessRequest.ClientAuth' + - type: object + required: + - "code" + - "grant_type" + properties: + grant_type: + description: Value MUST be set to "urn:ietf:params:oauth:grant-type:device_code". + type: string + enum: + - "authorization_code" + code: + description: The Authorization Code. + type: string + example: "authelia_ac_1j2kn3knj12n3kj12n" + code_verifier: + description: The Authorization Code Verifier (PKCE). + type: string + example: "88a25754f7c0b3b3b88cf6cd4e29e8356b160524fdc1cb329a94471825628fd3" + redirect_uri: + description: The original Redirect URI used in the Authorization Request. + type: string + example: "https://app.example.com/oidc/callback" + openid.spec.AccessRequest.DeviceCodeFlow: + allOf: + - $ref: '#/components/schemas/openid.spec.AccessRequest.ClientAuth' + - type: object + required: + - "grant_type" + - "device_code" + properties: + grant_type: + description: Value MUST be set to "urn:ietf:params:oauth:grant-type:device_code". + type: string + enum: + - "urn:ietf:params:oauth:grant-type:device_code" + device_code: + description: The Device Authorization Code. + type: string + example: "authelia_dc_mn123kjn12kj3123njk" + openid.spec.AccessRequest.RefreshTokenFlow: + allOf: + - $ref: '#/components/schemas/openid.spec.AccessRequest.ClientAuth' + - type: object + required: + - "grant_type" + - "device_code" + properties: + grant_type: + description: Value MUST be set to "refresh_token". + type: string + enum: + - "refresh_token" + refresh_token: + description: The Refresh Token. + example: "authelia_rt_1n2j3kihn12kj3n12k" + scope: + description: > + The scope of the access request as described by + Section 3.3. The requested scope MUST NOT include any scope + not originally granted by the resource owner, and if omitted is + treated as equal to the scope originally granted by the + resource owner. + openid.spec.AccessResponse: + type: object + properties: + access_token: + description: The access token issued by the authorization server. + type: string + example: "authelia_at_cr4i4EtTn2F4k6mX4XzxbsBewkxCGn" + refresh_token: + type: string + description: > + The refresh token, which can be used to obtain new access tokens using the + same authorization grant as described in Section 6. + token_type: + type: string + description: > + The access token type provides the client with the information + required to successfully utilize the access token to make a protected + resource request (along with type-specific attributes). The client + MUST NOT use an access token if it does not understand the token + type. + enum: + - "bearer" + expires_in: + type: integer + description: > + The lifetime in seconds of the access token. For + example, the value "3600" denotes that the access token will + expire in one hour from the time the response was generated. + If omitted, the authorization server SHOULD provide the + expiration time via other means or document the default value. + state: + type: string + description: Exactly the state value passed in the authorization request if present. + scope: + type: string + description: > + The scope of the access token as described by Section 3.3 if it differs from the requested scope. + openid.spec.AuthorizeRequest: + type: object + required: + - "scope" + - "response_type" + - "client_id" + - "redirect_uri" + properties: + scope: + description: The requested scope. + type: string + example: "openid profile groups" + response_type: + $ref: '#/components/schemas/openid.spec.ResponseType' + client_id: + description: The OAuth 2.0 client identifier. + type: string + example: "app" + redirect_uri: + description: > + Redirection URI to which the response will be sent. This URI MUST exactly match one of the + Redirection URI values for the Client pre-registered at the OpenID Provider, with the matching + performed as described in Section 6.2.1 of [RFC3986] (Simple String Comparison). When using this + flow, the Redirection URI SHOULD use the https scheme; however, it MAY use the http scheme, provided + that the Client Type is confidential, as defined in Section 2.1 of OAuth 2.0, and provided the OP + allows the use of http Redirection URIs in this case. The Redirection URI MAY use an alternate + scheme, such as one that is intended to identify a callback into a native application. + type: string + example: "https://app.example.com" + state: + description: > + Opaque value used to maintain state between the request and the callback. Typically, Cross-Site + Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this + parameter with a browser cookie. + type: string + example: "oV84Vsy7wyCgRk2h4aZBmXZq4q3g2f" + response_mode: + $ref: '#/components/schemas/openid.spec.ResponseMode' + nonce: + description: > + String value used to associate a Client session with an ID Token, and to mitigate replay attacks. + The value is passed through unmodified from the Authentication Request to the ID Token. Sufficient + entropy MUST be present in the nonce values used to prevent attackers from guessing values. For + implementation notes, see Section 15.5.2. + type: string + example: "TRMLqchoKGQNcooXvBvUy9PtmLdJGf" + display: + $ref: '#/components/schemas/openid.spec.DisplayType' + prompt: + description: > + Not Supported: Space delimited, case sensitive list of ASCII string values that specifies whether + the Authorization Server prompts the End-User for reauthentication and consent. + type: string + max_age: + description: > + Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the + End-User was actively authenticated by the OP. If the elapsed time is greater than this value, the + OP MUST attempt to actively re-authenticate the End-User. (The max_age request parameter corresponds + to the OpenID 2.0 PAPE [OpenID.PAPE] max_auth_age request parameter.) When max_age is used, the ID + Token returned MUST include an auth_time Claim Value. + type: integer + ui_locales: + description: > + Not Supported: End-User's preferred languages and scripts for the user interface, represented as a + space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. For instance, + the value "fr-CA fr en" represents a preference for French as spoken in Canada, then French (without + a region designation), followed by English (without a region designation). An error SHOULD NOT + result if some or all of the requested locales are not supported by the OpenID Provider. + type: string + claims_locales: + description: > + Not Supported: End-User's preferred languages and scripts for Claims being returned, represented as + a space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. An error + SHOULD NOT result if some or all of the requested locales are not supported by the OpenID Provider. + type: string + id_token_hint: + description: > + Not Supported: ID Token previously issued by the Authorization Server being passed as a hint about + the End-User's current or past authenticated session with the Client. If the End-User identified by + the ID Token is logged in or is logged in by the request, then the Authorization Server returns a + positive response; otherwise, it SHOULD return an error, such as login_required. When possible, an + id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be + returned if it is not; however, the server SHOULD respond successfully when possible, even if it is + not present. The Authorization Server need not be listed as an audience of the ID Token when it is + used as an id_token_hint value. If the ID Token received by the RP from the OP is encrypted, to use + it as an id_token_hint, the Client MUST decrypt the signed ID Token contained within the encrypted + ID Token. The Client MAY re-encrypt the signed ID token to the Authentication Server using a key + that enables the server to decrypt the ID Token, and use the re-encrypted ID token as the + id_token_hint value. + type: string + login_hint: + description: > + Not Supported: Hint to the Authorization Server about the login identifier the End-User might use to + log in (if necessary). This hint can be used by an RP if it first asks the End-User for their e-mail + address (or other identifier) and then wants to pass that value as a hint to the discovered + authorization service. It is RECOMMENDED that the hint value match the value used for discovery. + This value MAY also be a phone number in the format specified for the phone_number Claim. The use + of this parameter is left to the OP's discretion. + type: string + acr_values: + description: > + Not Supported: Requested Authentication Context Class Reference values. Space-separated string that + specifies the acr values that the Authorization Server is being requested to use for processing this + Authentication Request, with the values appearing in order of preference. The Authentication Context + Class satisfied by the authentication performed is returned as the acr Claim Value, as specified in + Section 2. The acr Claim is requested as a Voluntary Claim by this parameter. + type: string + claims: + description: > + Not Supported: The claims parameter value, as specified in Section 5.5. + type: string + registration: + description: > + Not Supported: This parameter is used by the Client to provide information about itself to a + Self-Issued OP that would normally be provided to an OP during Dynamic Client Registration, as + specified in Section 7.2.1. + type: string + request: + description: > + Not Supported: Request Object value, as specified in Section 6.1. The Request Object MAY be + encrypted to the Self-Issued OP by the Client. In this case, the sub (subject) of a previously + issued ID Token for this Client MUST be sent as the kid (Key ID) of the JWE. Encrypting content to + Self-Issued OPs is currently only supported when the OP's JWK key type is RSA and the encryption + algorithm used is RSA1_5. + type: string + openid.spec.SubjectIdentifier: + description: > + A Subject Identifier is a locally unique and never reassigned identifier within the Issuer for the + End-User, which is intended to be consumed by the Client. + type: string + enum: + - "public" + - "pairwise" + openid.spec.ClientAuthMethod: + description: The OAuth 2.0 / OpenID Connect 1.0 Client Authentication Method. + type: string + enum: + - "client_secret_basic" + - "client_secret_post" + - "client_secret_jwt" + - "private_key_jwt" + - "none" + openid.spec.DisplayType: + description: > + ASCII string value that specifies how the Authorization Server displays the authentication and consent user + interface pages to the End-User. + type: string + example: "page" + enum: + - "page" + - "popup" + - "touch" + - "wap" + openid.spec.ResponseType: + description: The OAuth 2.0 / OpenID Connect 1.0 Response Type. + type: string + example: "code" + enum: + - "code" + - "id_token" + - "token" + - "code token" + - "code id_token" + - "token id_token" + - "code id_token token" + - "none" + openid.spec.ResponseMode: + description: > + Informs the Authorization Server of the mechanism to be used for returning parameters from the Authorization + Endpoint. This use of this parameter is NOT RECOMMENDED when the Response Mode that would be requested is + the default mode specified for the Response Type. + type: string + example: "query" + enum: + - "query" + - "fragment" + - "form_post" + openid.spec.GrantType: + description: The OAuth 2.0 / OpenID Connect 1.0 Grant Type. + type: string + example: "authorization_code" + enum: + - "authorization_code" + - "refresh_token" + - "implicit" + - "password" + - "client_credentials" + - "urn:ietf:params:oauth:grant-type:device_code" + openid.spec.CodeChallengeMethod: + description: The RFC7636 Code Challenge Verifier Method. + type: string + example: "S256" + enum: + - "plain" + - "S256" + openid.spec.ClaimType: + description: The representation of claims. + type: string + example: "normal" + enum: + - "normal" + - "aggregated" + - "distributed" + jose.spec.None: + description: The JSON Web Signature Algorithm + type: string + enum: + - "none" + jose.spec.JWS.None: + description: The JSON Web Signature Algorithm + type: string + oneOf: + - $ref: '#/components/schemas/jose.spec.None' + - $ref: '#/components/schemas/jose.spec.jws' + jose.spec.jws: + description: The JSON Web Signature Algorithm + type: string + enum: + - "HS256" + - "HS384" + - "HS512" + - "RS256" + - "RS384" + - "RS512" + - "ES256" + - "ES384" + - "ES512" + - "PS256" + - "PS384" + - "PS512" + jose.spec.JWE.alg: + description: The JSON Web Encryption Algorithm (CEK) + type: string + enum: + - "RSA1_5" + - "RSA-OAEP" + - "RSA-OAEP-256" + - "A128KW" + - "A192KW" + - "A256KW" + - "dir" + - "ECDH-ES" + - "ECDH-ES+A128KW" + - "ECDH-ES+A192KW" + - "ECDH-ES+A256KW" + - "A128GCMKW" + - "A192GCMKW" + - "A256GCMKW" + - "PBES2-HS256+A128KW" + - "PBES2-HS384+A192KW" + - "PBES2-HS512+A256KW" + jose.spec.JWE.enc: + description: The JSON Web Encryption Algorithm (Claims) + type: string + enum: + - "A128CBC-HS256" + - "A192CBC-HS384" + - "A256CBC-HS512" + - "A128CBC" + - "A256CBC" + - "A128GCM" + - "A256GCM" + jose.spec.JWK.base: + type: object + properties: + use: + description: > + The "use" (public key use) parameter identifies the intended use of + the public key. The "use" parameter is employed to indicate whether + a public key is used for encrypting data or verifying the signature + on data. + type: string + example: "sig" + enum: + - "sig" + - "enc" + key_ops: + description: > + The "key_ops" (key operations) parameter identifies the operation(s) + for which the key is intended to be used. The "key_ops" parameter is + intended for use cases in which public, private, or symmetric keys + may be present. + type: array + example: ["sign"] + items: + type: string + enum: + - "sign" + - "verify" + - "encrypt" + - "decrypt" + - "wrapKey" + - "unwrapKey" + - "deriveKey" + - "deriveBits" + kid: + description: > + The "kid" (key ID) parameter is used to match a specific key. This + is used, for instance, to choose among a set of keys within a JWK Set + during key rollover. The structure of the "kid" value is + unspecified. When "kid" values are used within a JWK Set, different + keys within the JWK Set SHOULD use distinct "kid" values. (One + example in which different keys might use the same "kid" value is if + they have different "kty" (key type) values but are considered to be + equivalent alternatives by the application using them.) The "kid" + value is a case-sensitive string. Use of this member is OPTIONAL. + When used with JWS or JWE, the "kid" value is used to match a JWS or + JWE "kid" Header Parameter value. + type: string + x5u: + description: > + The "x5u" (X.509 URL) parameter is a URI [RFC3986] that refers to a + resource for an X.509 public key certificate or certificate chain + [RFC5280]. The identified resource MUST provide a representation of + the certificate or certificate chain that conforms to RFC 5280 + [RFC5280] in PEM-encoded form, with each certificate delimited as + specified in Section 6.1 of RFC 4945 [RFC4945]. The key in the first + certificate MUST match the public key represented by other members of + the JWK. The protocol used to acquire the resource MUST provide + integrity protection; an HTTP GET request to retrieve the certificate + MUST use TLS [RFC2818] [RFC5246]; the identity of the server MUST be + validated, as per Section 6 of RFC 6125 [RFC6125]. Use of this + member is OPTIONAL. + type: string + x5c: + description: > + The "x5c" (X.509 certificate chain) parameter contains a chain of one + or more PKIX certificates [RFC5280]. The certificate chain is + represented as a JSON array of certificate value strings. Each + string in the array is a base64-encoded (Section 4 of [RFC4648] -- + not base64url-encoded) DER [ITU.X690.1994] PKIX certificate value. + The PKIX certificate containing the key value MUST be the first + certificate. This MAY be followed by additional certificates, with + each subsequent certificate being the one used to certify the + previous one. The key in the first certificate MUST match the public + key represented by other members of the JWK. Use of this member is + OPTIONAL. + type: array + items: + type: string + format: byte + x5t: + description: > + The "x5t" (X.509 certificate SHA-1 thumbprint) parameter is a + base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER + encoding of an X.509 certificate [RFC5280]. Note that certificate + thumbprints are also sometimes known as certificate fingerprints. + The key in the certificate MUST match the public key represented by + other members of the JWK. Use of this member is OPTIONAL. + type: string + format: byte + x5t#S256: + description: > + The "x5t#S256" (X.509 certificate SHA-256 thumbprint) parameter is a + base64url-encoded SHA-256 thumbprint (a.k.a. digest) of the DER + encoding of an X.509 certificate [RFC5280]. Note that certificate + thumbprints are also sometimes known as certificate fingerprints. + The key in the certificate MUST match the public key represented by + other members of the JWK. Use of this member is OPTIONAL. + type: string + format: byte + jose.spec.JWK.RSA: + description: RSA Public Key in JSON Web Key format as defined by RFC7517 and RFC7518. + allOf: + - $ref: '#/components/schemas/jose.spec.JWK.base' + - type: object + required: + - "kty" + - "n" + - "e" + properties: + kty: + description: > + The "kty" (key type) parameter identifies the cryptographic algorithm + family used with the key. + type: string + example: "RSA" + enum: + - "RSA" + alg: + description: The JSON Web Signature Algorithm + type: string + example: "RS256" + enum: + - "RS256" + - "RS384" + - "RS512" + - "PS256" + - "PS384" + - "PS512" + n: + description: > + RSA Public Key: The "n" (modulus) parameter contains the modulus value for the RSA public key. It is + represented as a Base64urlUInt-encoded value. + type: string + format: byte + e: + description: > + RSA Public Key: The "e" (exponent) parameter contains the exponent value for the RSA public key. + It is represented as a Base64urlUInt-encoded value. + type: string + format: byte + jose.spec.JWK.RSA.Private: + description: RSA Private Key in JSON Web Key format as defined by RFC7517 and RFC7518. + allOf: + - $ref: '#/components/schemas/jose.spec.JWK.base' + - $ref: '#/components/schemas/jose.spec.JWK.RSA' + - type: object + required: + - "d" + properties: + d: + description: > + RSA Private Key: The "d" (private exponent) parameter contains the private exponent value for the RSA + private key. It is represented as a Base64urlUInt-encoded value. + type: string + format: byte + p: + description: > + RSA Private Key: The "p" (first prime factor) parameter contains the first prime factor. + It is represented as a Base64urlUInt-encoded value. + type: string + format: byte + q: + description: > + RSA Private Key: The "q" (second prime factor) parameter contains the second prime factor. It is + represented as a Base64urlUInt-encoded value. + type: string + format: byte + dp: + description: > + RSA Private Key: The "dp" (first factor CRT exponent) parameter contains the Chinese Remainder Theorem + (CRT) exponent of the first factor. It is represented as a Base64urlUInt-encoded value. + type: string + dq: + description: > + RSA Private Key: The "dq" (second factor CRT exponent) parameter contains the CRT exponent of the + second factor. It is represented as a Base64urlUInt-encoded value. + type: string + qi: + description: > + RSA Private Key: The "qi" (first CRT coefficient) parameter contains the CRT coefficient of the second + factor. It is represented as a Base64urlUInt-encoded value. + type: string + format: byte + oth: + description: > + The "oth" (other primes info) parameter contains an array of + information about any third and subsequent primes, should they exist. + type: array + items: + type: object + required: + - "r" + - "d" + - "t" + properties: + r: + description: > + The "r" (prime factor) parameter within an "oth" array member + represents the value of a subsequent prime factor. It is represented + as a Base64urlUInt-encoded value. + type: string + format: byte + d: + description: > + The "d" (factor CRT exponent) parameter within an "oth" array member + represents the CRT exponent of the corresponding prime factor. It is + represented as a Base64urlUInt-encoded value. + type: string + format: byte + t: + description: > + The "t" (factor CRT coefficient) parameter within an "oth" array + member represents the CRT coefficient of the corresponding prime + factor. It is represented as a Base64urlUInt-encoded value. + type: string + format: byte + jose.spec.JWK.EC: + description: Elliptic Curve Public Key in JSON Web Key format as defined by RFC7517 and RFC7518. + allOf: + - $ref: '#/components/schemas/jose.spec.JWK.base' + - type: object + required: + - "kty" + - "crv" + - "x" + properties: + kty: + description: > + The "kty" (key type) parameter identifies the cryptographic algorithm + family used with the key. + type: string + example: "EC" + enum: + - "EC" + alg: + description: The JSON Web Signature Algorithm + type: string + example: "ES256" + enum: + - "ES256" + - "ES384" + - "ES512" + x: + description: > + EC Public Key: The x coordinate parameter contains the x coordinate for the Elliptic Curve point. + It is represented as the base64url encoding of the octet string representation of the coordinate, as + defined in Section 2.3.5 of SEC1 [SEC1]. + type: string + format: byte + y: + description: > + EC Public Key: The y coordinate parameter contains the y coordinate for the Elliptic Curve point. + It is represented as the base64url encoding of the octet string representation of the coordinate, as + defined in Section 2.3.5 of SEC1 [SEC1]. + type: string + format: byte + crv: + description: > + The curve parameter identifies the cryptographic curve used with the key. Curve + values from [DSS] used by this specification. + type: string + example: "P-521" + enum: + - "P-256" + - "P-384" + - "P-521" + - "Ed25519" + - "Ed448" + - "X25519" + - "X448" + - "secp256k1" + jose.spec.JWK.EC.Private: + description: Elliptic Curve Private Key in JSON Web Key format as defined by RFC7517 and RFC7518. + allOf: + - $ref: '#/components/schemas/jose.spec.JWK.base' + - $ref: '#/components/schemas/jose.spec.JWK.EC' + - type: object + required: + - "d" + properties: + d: + description: > + ECC Private Key: The "d" (ECC private key) parameter contains the Elliptic Curve private key value. It + is represented as the base64url encoding of the octet string representation of the private key value, + as defined in Section 2.3.7 of SEC1 [SEC1]. The length of this octet string MUST be + ceiling(log-base-2(n)/8) octets (where n is the order of the curve). + type: string + format: byte + jose.spec.JWK.Symmetric: + description: Symmetric Key in JSON Web Key format as defined by RFC7517 and RFC7518. + allOf: + - $ref: '#/components/schemas/jose.spec.JWK.base' + - type: object + required: + - "k" + properties: + kty: + description: > + The "kty" (key type) parameter identifies the cryptographic algorithm + family used with the key. + type: string + example: "oct" + enum: + - "oct" + k: + description: > + The "k" (key value) parameter contains the value of the symmetric (or + other single-valued) key. It is represented as the base64url + encoding of the octet sequence containing the key value. + type: string + format: byte + jose.spec.JWK: + type: string + anyOf: + - $ref: '#/components/schemas/jose.spec.JWK.RSA' + - $ref: '#/components/schemas/jose.spec.JWK.RSA.Private' + - $ref: '#/components/schemas/jose.spec.JWK.EC' + - $ref: '#/components/schemas/jose.spec.JWK.EC.Private' + - $ref: '#/components/schemas/jose.spec.JWK.Symmetric' + jose.spec.JWKs: + type: object + description: The JSON Web Key Sets Document as defined by RFC7517. + properties: + keys: + description: List of JSON Wek Key's in the JSON Web Key format as defined by RFC7517. + type: array + items: + $ref: '#/components/schemas/jose.spec.JWK' securitySchemes: authelia_auth: type: apiKey - name: "{{.Session}}" + name: "{{ .Session }}" in: cookie + openid: + type: openIdConnect + openIdConnectUrl: "{{ .BaseURL }}.well-known/openid-configuration" ... diff --git a/cmd/authelia-scripts/cmd/bootstrap.go b/cmd/authelia-scripts/cmd/bootstrap.go index ce2583e6c..0e43531d6 100644 --- a/cmd/authelia-scripts/cmd/bootstrap.go +++ b/cmd/authelia-scripts/cmd/bootstrap.go @@ -87,12 +87,19 @@ var hostEntries = []HostEntry{ {Domain: "mail.example.com", IP: "192.168.240.100"}, {Domain: "duo.example.com", IP: "192.168.240.100"}, - // For Traefik suite. - {Domain: "traefik.example.com", IP: "192.168.240.100"}, - // For HAProxy suite. {Domain: "haproxy.example.com", IP: "192.168.240.100"}, + // Kubernetes dashboard. + {Domain: "kubernetes.example.com", IP: "192.168.240.100"}, + + // OIDC tester app. + {Domain: "oidc.example.com", IP: "192.168.240.100"}, + {Domain: "oidc-public.example.com", IP: "192.168.240.100"}, + + // For Traefik suite. + {Domain: "traefik.example.com", IP: "192.168.240.100"}, + // For testing network ACLs. {Domain: "proxy-client1.example.com", IP: "192.168.240.201"}, {Domain: "proxy-client2.example.com", IP: "192.168.240.202"}, @@ -107,12 +114,6 @@ var hostEntries = []HostEntry{ {Domain: "redis-sentinel-0.example.com", IP: "192.168.240.120"}, {Domain: "redis-sentinel-1.example.com", IP: "192.168.240.121"}, {Domain: "redis-sentinel-2.example.com", IP: "192.168.240.122"}, - - // Kubernetes dashboard. - {Domain: "kubernetes.example.com", IP: "192.168.240.110"}, - // OIDC tester app. - {Domain: "oidc.example.com", IP: "192.168.240.100"}, - {Domain: "oidc-public.example.com", IP: "192.168.240.100"}, } func runCommand(cmd string, args ...string) { @@ -151,8 +152,8 @@ func createTemporaryDirectory() { func createPNPMDirectory() { home := os.Getenv("HOME") if home != "" { - bootstrapPrintln("Creating ", home+"/.pnpm-store") - err := os.MkdirAll(home+"/.pnpm-store", 0755) + bootstrapPrintln("Creating ", home+"/.local/share/pnpm/store") + err := os.MkdirAll(home+"/.local/share/pnpm/store", 0755) if err != nil { panic(err) @@ -161,7 +162,7 @@ func createPNPMDirectory() { } func pnpmInstall() { - bootstrapPrintln("Installing web dependences ") + bootstrapPrintln("Installing web dependencies ") cwd, err := os.Getwd() if err != nil { diff --git a/docs/content/en/configuration/first-factor/ldap.md b/docs/content/en/configuration/first-factor/ldap.md index 9fb9127f3..95b91524d 100644 --- a/docs/content/en/configuration/first-factor/ldap.md +++ b/docs/content/en/configuration/first-factor/ldap.md @@ -167,14 +167,14 @@ section [here](../prologue/common.md#tls-configuration). Sets the base distinguished name container for all LDAP queries. If your LDAP domain is example.com this is usually `DC=example,DC=com`, however you can fine tune this to be more specific for example to only include objects inside the -authelia OU: `OU=authelia,DC=example,DC=com`. This is prefixed with the [additional_users_dn](#additional_users_dn) for -user searches and [additional_groups_dn](#additional_groups_dn) for groups searches. +authelia OU: `OU=authelia,DC=example,DC=com`. This is prefixed with the [additional_users_dn](#additionalusersdn) for +user searches and [additional_groups_dn](#additionalgroupsdn) for groups searches. ### additional_users_dn {{< confkey type="string" required="no" >}} -Additional LDAP path to append to the [base_dn](#base_dn) when searching for users. Useful if you want to restrict +Additional LDAP path to append to the [base_dn](#basedn) when searching for users. Useful if you want to restrict exactly which OU to get users from for either security or performance reasons. For example setting it to `OU=users,OU=people` with a base_dn set to `DC=example,DC=com` will mean user searches will occur in `OU=users,OU=people,DC=example,DC=com`. @@ -184,28 +184,31 @@ exactly which OU to get users from for either security or performance reasons. F {{< confkey type="string" required="situational" >}} *__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a -default negating this requirement. Refer to the [filter defaults](#filter-defaults) for more information.* +default negating this requirement. Refer to the [filter defaults](../../reference/guides/ldap.md#filter-defaults) for +more information.* The LDAP filter to narrow down which users are valid. This is important to set correctly as to exclude disabled users. The default value is dependent on the [implementation](#implementation), refer to the -[attribute defaults](#attribute-defaults) for more information. +[attribute defaults](../../reference/guides/ldap.md#attribute-defaults) for more information. ### username_attribute {{< confkey type="string" required="situational" >}} *__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a -default negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information.* +default negating this requirement. Refer to the [attribute defaults](../../reference/guides/ldap.md#attribute-defaults) +for more information.* The LDAP attribute that maps to the username in *Authelia*. This must contain the `{username_attribute}` -[placeholder](#users-filter-replacements). +[placeholder](../../reference/guides/ldap.md#users-filter-replacements). ### mail_attribute {{< confkey type="string" required="situational" >}} *__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a -default negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information.* +default negating this requirement. Refer to the [attribute defaults](../../reference/guides/ldap.md#attribute-defaults) +for more information.* The attribute to retrieve which contains the users email addresses. This is important for the device registration and password reset processes. The user must have an email address in order for Authelia to perform identity verification @@ -294,7 +297,7 @@ characters and the user password is changed to this value. ## Refresh Interval -It's recommended you either use the default [refresh interval](./introduction.md#refresh_interval) or configure this to +It's recommended you either use the default [refresh interval](introduction.md#refreshinterval) or configure this to a value low enough to refresh the user groups and status (deleted, disabled, etc) to adequately secure your environment. ## Important notes @@ -311,6 +314,6 @@ for your users. - [LDAP Reference Guide](../../reference/guides/ldap.md) -[username attribute]: #username_attribute +[username attribute]: #usernameattribute [TechNet wiki]: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx [RFC2307]: https://www.rfc-editor.org/rfc/rfc2307.html diff --git a/docs/content/en/configuration/identity-providers/open-id-connect.md b/docs/content/en/configuration/identity-providers/open-id-connect.md index 9baad93f0..2e0f78e55 100644 --- a/docs/content/en/configuration/identity-providers/open-id-connect.md +++ b/docs/content/en/configuration/identity-providers/open-id-connect.md @@ -157,8 +157,8 @@ The HMAC secret used to sign the [JWT]'s. The provided string is hashed to a SHA purpose of meeting the required format. It's __strongly recommended__ this is a -[Random Alphanumeric String](../../reference/guides/generating-secure-values.md#generating-a-random-alphanumeric-string) with 64 or more -characters. +[Random Alphanumeric String](../../reference/guides/generating-secure-values.md#generating-a-random-alphanumeric-string) +with 64 or more characters. ### issuer_certificate_chain @@ -173,7 +173,7 @@ as per [RFC7517]. [x5c]: https://www.rfc-editor.org/rfc/rfc7517#section-4.7 [x5t]: https://www.rfc-editor.org/rfc/rfc7517#section-4.8 -The first certificate in the chain must have the public key for the [issuer_private_key](#issuer_private_key), each +The first certificate in the chain must have the public key for the [issuer_private_key](#issuerprivatekey), each certificate in the chain must be valid for the current date, and each certificate in the chain should be signed by the certificate immediately following it if present. @@ -185,14 +185,15 @@ certificate immediately following it if present. especially for containerized deployments.* The private key used to sign/encrypt the [OpenID Connect] issued [JWT]'s. The key must be generated by the administrator -and can be done by following the [Generating an RSA Keypair](../../reference/guides/generating-secure-values.md#generating-an-rsa-keypair) guide. +and can be done by following the +[Generating an RSA Keypair](../../reference/guides/generating-secure-values.md#generating-an-rsa-keypair) guide. The private key *__MUST__*: * Be a PEM block encoded in the DER base64 format ([RFC4648]). * Be an RSA Key. * Have a key size of at least 2048 bits. -If the [issuer_certificate_chain](#issuer_certificate_chain) is provided the private key must include matching public +If the [issuer_certificate_chain](#issuercertificatechain) is provided the private key must include matching public key data for the first certificate in the chain. ### access_token_lifespan @@ -302,7 +303,7 @@ you must configure this option manually if you want http endpoints to be permitt Origins must only have the scheme, hostname and port, they may not have a trailing slash or path. In addition to an Origin URI, you may specify the wildcard origin in the allowed_origins. It MUST be specified by itself -and the [allowed_origins_from_client_redirect_uris](#allowed_origins_from_client_redirect_uris) MUST NOT be enabled. The +and the [allowed_origins_from_client_redirect_uris](#allowedoriginsfromclientredirecturis) MUST NOT be enabled. The wildcard origin is denoted as `*`. Examples: ```yaml @@ -422,7 +423,7 @@ Configures the consent mode. The following table describes the different modes: | implicit | Automatically assumes consent for every authorization, never asking the user if they wish to give consent. *__Note:__* this option is not technically part of the specification. | | pre-configured | Allows the end-user to remember their consent for the [pre_configured_consent_duration]. | -[pre_configured_consent_duration]: #pre_configured_consent_duration +[pre_configured_consent_duration]: #preconfiguredconsentduration #### pre_configured_consent_duration @@ -439,7 +440,7 @@ The period of time dictates how long a users choice to remember the pre-configur Pre-configured consents are only valid if the subject, client id are exactly the same and the requested scopes/audience match exactly with the granted scopes/audience. -[consent_mode]: #consent_mode +[consent_mode]: #consentmode #### audience diff --git a/docs/content/en/configuration/methods/environment.md b/docs/content/en/configuration/methods/environment.md index e5e4686bb..5a59b7060 100644 --- a/docs/content/en/configuration/methods/environment.md +++ b/docs/content/en/configuration/methods/environment.md @@ -27,7 +27,7 @@ likely result in an error or even worse misconfiguration. ### Kubernetes Please see the -[Kubernetes Integration: Enable Service Links](../../integration/kubernetes/introduction/index.md#enable-service-links) +[Kubernetes Integration: Enable Service Links](../../integration/kubernetes/introduction.md#enable-service-links) documentation for specific requirements for using *Authelia* with Kubernetes. ## Mapping diff --git a/docs/content/en/configuration/methods/secrets.md b/docs/content/en/configuration/methods/secrets.md index 25802b9bb..182c74edd 100644 --- a/docs/content/en/configuration/methods/secrets.md +++ b/docs/content/en/configuration/methods/secrets.md @@ -55,15 +55,15 @@ other configuration using the environment but instead of loading a file the valu {{% table-config-keys secrets="true" %}} [server.tls.key]: ../miscellaneous/server.md#key -[jwt_secret]: ../miscellaneous/introduction.md#jwt_secret -[duo_api.integration_key]: ../second-factor/duo.md#integration_key -[duo_api.secret_key]: ../second-factor/duo.md#secret_key +[jwt_secret]: ../miscellaneous/introduction.md#jwtsecret +[duo_api.integration_key]: ../second-factor/duo.md#integrationkey +[duo_api.secret_key]: ../second-factor/duo.md#secretkey [session.secret]: ../session/introduction.md#secret [session.redis.password]: ../session/redis.md#password [session.redis.tls.certificate_chain]: ../session/redis.md#tls [session.redis.tls.private_key]: ../session/redis.md#tls -[session.redis.high_availability.sentinel_password]: ../session/redis.md#sentinel_password -[storage.encryption_key]: ../storage/introduction.md#encryption_key +[session.redis.high_availability.sentinel_password]: ../session/redis.md#sentinelpassword +[storage.encryption_key]: ../storage/introduction.md#encryptionkey [storage.mysql.password]: ../storage/mysql.md#password [storage.mysql.tls.certificate_chain]: ../storage/mysql.md#tls [storage.mysql.tls.private_key]: ../storage/mysql.md#tls @@ -77,9 +77,9 @@ other configuration using the environment but instead of loading a file the valu [authentication_backend.ldap.password]: ../first-factor/ldap.md#password [authentication_backend.ldap.tls.certificate_chain]: ../first-factor/ldap.md#tls [authentication_backend.ldap.tls.private_key]: ../first-factor/ldap.md#tls -[identity_providers.oidc.issuer_certificate_chain]: ../identity-providers/open-id-connect.md#issuer_certificate_chain -[identity_providers.oidc.issuer_private_key]: ../identity-providers/open-id-connect.md#issuer_private_key -[identity_providers.oidc.hmac_secret]: ../identity-providers/open-id-connect.md#hmac_secret +[identity_providers.oidc.issuer_certificate_chain]: ../identity-providers/open-id-connect.md#issuercertificatechain +[identity_providers.oidc.issuer_private_key]: ../identity-providers/open-id-connect.md#issuerprivatekey +[identity_providers.oidc.hmac_secret]: ../identity-providers/open-id-connect.md#hmacsecret ## Secrets in configuration file diff --git a/docs/content/en/configuration/miscellaneous/introduction.md b/docs/content/en/configuration/miscellaneous/introduction.md index d8de18f72..b7036e231 100644 --- a/docs/content/en/configuration/miscellaneous/introduction.md +++ b/docs/content/en/configuration/miscellaneous/introduction.md @@ -73,7 +73,7 @@ default_2fa_method: totp especially for containerized deployments.* Defines the secret used to craft JWT tokens leveraged by the identity verification process. This can a random string. -It's strongly recommended this is a [Random Alphanumeric String](../../reference/guides/generating-secure-values.md/#generating-a-random-alphanumeric-string) with +It's strongly recommended this is a [Random Alphanumeric String](../../reference/guides/generating-secure-values.md#generating-a-random-alphanumeric-string) with 64 or more characters. ### theme diff --git a/docs/content/en/configuration/miscellaneous/ntp.md b/docs/content/en/configuration/miscellaneous/ntp.md index 6de640f5c..b16751d8e 100644 --- a/docs/content/en/configuration/miscellaneous/ntp.md +++ b/docs/content/en/configuration/miscellaneous/ntp.md @@ -68,4 +68,4 @@ Setting this to true will disable the startup check entirely. Setting this to true will allow Authelia to start and just log an error instead of exiting. The default is that if Authelia can contact the NTP server successfully, and the time reported by the server is greater than what is configured -in [max_desync](#max_desync) that Authelia fails to start and logs a fatal error. +in [max_desync](#maxdesync) that Authelia fails to start and logs a fatal error. diff --git a/docs/content/en/configuration/prologue/common.md b/docs/content/en/configuration/prologue/common.md index 6222e5448..1f4be33a1 100644 --- a/docs/content/en/configuration/prologue/common.md +++ b/docs/content/en/configuration/prologue/common.md @@ -123,7 +123,7 @@ require an IP address for the host of the backend service but want to verify a s The key `skip_verify` completely negates validating the certificate of the backend service. This is not recommended, instead you should tweak the `server_name` option, and the global option -[certificates directory](../miscellaneous/introduction.md#certificates_directory). +[certificates directory](../miscellaneous/introduction.md#certificatesdirectory). ### minimum_version @@ -147,7 +147,7 @@ this value. At the time of this writing `SSL3.0` will always produce errors. {{< confkey type="string" required="no" >}} -The certificate chain/bundle to be used with the [private_key](#private_key) to perform mutual TLS authentication with +The certificate chain/bundle to be used with the [private_key](#privatekey) to perform mutual TLS authentication with the server. The value must be one or more certificates encoded in the DER base64 ([RFC4648]) encoded PEM format. @@ -159,7 +159,7 @@ The value must be one or more certificates encoded in the DER base64 ([RFC4648]) *__Important Note:__ This can also be defined using a [secret](../methods/secrets.md) which is __strongly recommended__ especially for containerized deployments.* -The private key to be used with the [certificate_chain](#certificate_chain) for mutual TLS authentication. +The private key to be used with the [certificate_chain](#certificatechain) for mutual TLS authentication. The value must be one private key encoded in the DER base64 ([RFC4648]) encoded PEM format. diff --git a/docs/content/en/configuration/prologue/migration.md b/docs/content/en/configuration/prologue/migration.md index e03460c95..82f9c3f59 100644 --- a/docs/content/en/configuration/prologue/migration.md +++ b/docs/content/en/configuration/prologue/migration.md @@ -73,7 +73,7 @@ environment variable or other environment variables set. This also applies to ot *__Please Note:__ if you're using Authelia with Kubernetes and are not using the provided [helm chart](https://charts.authelia.com) you will be required to -[configure the enableServiceLinks](../../integration/kubernetes/introduction/index.md#enable-service-links) option.* +[configure the enableServiceLinks](../../integration/kubernetes/introduction.md#enable-service-links) option.* ### 4.25.0 @@ -99,7 +99,7 @@ The following changes occurred in 4.7.0: | logs_level | log_level | | logs_file | log_file | -*__Please Note:__ The new keys also changed in [4.30.0](#4.30.0) so you will need to update them to the new values if you -are using [4.30.0](#4.30.0) or newer instead of the new keys listed here.* +*__Please Note:__ The new keys also changed in [4.30.0](#4300) so you will need to update them to the new values if you +are using [4.30.0](#4300) or newer instead of the new keys listed here.* [YAML]: https://yaml.org/ diff --git a/docs/content/en/configuration/second-factor/time-based-one-time-password.md b/docs/content/en/configuration/second-factor/time-based-one-time-password.md index a3767882a..a7b64a3c6 100644 --- a/docs/content/en/configuration/second-factor/time-based-one-time-password.md +++ b/docs/content/en/configuration/second-factor/time-based-one-time-password.md @@ -61,10 +61,12 @@ by Authelia from others. *__Important Note:__ Many TOTP applications do not support this option. It is strongly advised you find out which applications your users use and test them before changing this option. It is insufficient to test that the application -can add the key, it must also authenticate with Authelia as some applications silently ignore these options. Bitwarden +can add the key, it must also authenticate with Authelia as some applications silently ignore these options. [Bitwarden] is the only one that has been tested at this time. If you'd like to contribute to documenting support for this option please see [Issue 2650](https://github.com/authelia/authelia/issues/2650).* +[Bitwarden]: https://bitwarden.com/ + The algorithm used for the TOTP key. Possible Values (case-insensitive): @@ -82,7 +84,7 @@ information. *__Important Note:__ Some TOTP applications do not support this option. It is strongly advised you find out which applications your users use and test them before changing this option. It is insufficient to test that the application -can add the key, it must also authenticate with Authelia as some applications silently ignore these options. Bitwarden +can add the key, it must also authenticate with Authelia as some applications silently ignore these options. [Bitwarden] is the only one that has been tested at this time. If you'd like to contribute to documenting support for this option please see [Issue 2650](https://github.com/authelia/authelia/issues/2650).* @@ -137,7 +139,7 @@ validations. This means if the configuration options are changed, users will not need to regenerate their keys. This functionality takes effect from 4.33.0 onwards, previously the effect was the keys would just fail to validate. If you'd like to force users to register a new device, you can delete the old device for a particular user by using the -`authelia storage totp delete ` command regardless of if you change the settings or not. +`authelia storage user totp delete ` command regardless of if you change the settings or not. ## Input Validation @@ -160,7 +162,7 @@ check the clients. ## Encryption -The TOTP secret is [encrypted](../storage/introduction.md#encryption_key) in the database in version 4.33.0 and above. +The TOTP secret is [encrypted](../storage/introduction.md#encryptionkey) in the database in version 4.33.0 and above. This is so a user having access to only the database cannot easily compromise your two-factor authentication method. This may be inconvenient for some users who wish to export TOTP keys from Authelia to other services. As such there is @@ -170,19 +172,19 @@ at least a minimal configuration that has the storage backend connection details Export in [Key URI Format](https://github.com/google/google-authenticator/wiki/Key-Uri-Format): ```bash -authelia storage totp export --format uri +authelia storage user totp export --format uri ``` Export as CSV: ```bash -authelia storage totp export --format csv +authelia storage user totp export --format csv ``` Help: ```bash -authelia storage totp export --help +authelia storage user totp export --help ``` [RFC4226]: https://www.rfc-editor.org/rfc/rfc4226.html diff --git a/docs/content/en/configuration/security/access-control.md b/docs/content/en/configuration/security/access-control.md index 011cec776..8993b2027 100644 --- a/docs/content/en/configuration/security/access-control.md +++ b/docs/content/en/configuration/security/access-control.md @@ -198,7 +198,7 @@ When used in conjunction with [domain] the rule will match when either the [doma In addition to standard regex patterns this criteria can match some [Named Regex Groups]. -[domain_regex]: #domain_regex +[domain_regex]: #domainregex ##### Examples @@ -339,7 +339,7 @@ access_control: {{< confkey type="list(string)" required="no" >}} This criteria is a list of values which can be an IP Address, network address range in CIDR notation, or an alias from -the [global](#networks-global) section. It matches against the first address in the `X-Forwarded-For` header, or if there +the [global](#networks--global-) section. It matches against the first address in the `X-Forwarded-For` header, or if there are none it will fall back to the IP address of the packet TCP source IP address. For this reason it's important for you to configure the proxy server correctly in order to accurately match requests with this criteria. *__Note:__ you may combine CIDR networks with the alias rules as you please.* @@ -360,7 +360,7 @@ for administrators to tune the security to their specific needs if desired. ##### Examples -*Require [two_factor](#two_factor) for all clients other than internal clients and `112.134.145.167`. The first two +*Require [two_factor](#twofactor) for all clients other than internal clients and `112.134.145.167`. The first two rules in this list are effectively the same rule just expressed in different ways.* ```yaml @@ -485,7 +485,7 @@ access_control: ## Policies The policy of the first matching rule in the configured list decides the policy applied to the request, if no rule -matches the request the [default_policy](#default_policy) is applied. +matches the request the [default_policy](#defaultpolicy) is applied. [policies]: #policies @@ -510,14 +510,14 @@ about the subject is [one_factor]. See [Rule Matching Concept 2] for more inform This policy requires the user at minimum complete 1FA successfully (username and password). This means if they have performed 2FA then they will be allowed to access the resource. -[one_factor]: #one_factor +[one_factor]: #onefactor ### two_factor This policy requires the user to complete 2FA successfully. This is currently the highest level of authentication policy available. -[two_factor]: #two_factor +[two_factor]: #twofactor ## Rule Matching @@ -554,7 +554,7 @@ a match for that request. policy: two_factor ``` -[Rule Matching Concept 1]: #rule-matching-concept-1-sequential-order +[Rule Matching Concept 1]: #rule-matching-concept-1--sequential-order ### Rule Matching Concept 2: Subject Criteria Requires Authentication @@ -569,7 +569,7 @@ for authentication if no prior rules match the request per [Rule Matching Concep identical rules, and one of them has a subject based reliant criteria, and the other one is a [bypass] rule then the [bypass] rule should generally come first. -[Rule Matching Concept 2]: #rule-matching-concept-2-subject-criteria-requires-authentication +[Rule Matching Concept 2]: #rule-matching-concept-2--subject-criteria-requires-authentication ## Named Regex Groups diff --git a/docs/content/en/configuration/session/introduction.md b/docs/content/en/configuration/session/introduction.md index 6bc2a3baa..24e54f1aa 100644 --- a/docs/content/en/configuration/session/introduction.md +++ b/docs/content/en/configuration/session/introduction.md @@ -40,7 +40,7 @@ There are currently two providers for session storage (three if you count Redis * Memory (default, stateful, no additional configuration) * [Redis](redis.md) (stateless). -* [Redis Sentinel](redis.md#high_availability) (stateless, highly available). +* [Redis Sentinel](redis.md#highavailability) (stateless, highly available). ### Kubernetes or High Availability @@ -99,7 +99,7 @@ characters. the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* The period of time before the cookie expires and the session is destroyed. This is overriden by -[remember_me_duration](#remember_me_duration) when the remember me box is checked. +[remember_me_duration](#remembermeduration) when the remember me box is checked. ### inactivity diff --git a/docs/content/en/configuration/storage/postgres.md b/docs/content/en/configuration/storage/postgres.md index 55f4c88e3..8ea2fae07 100644 --- a/docs/content/en/configuration/storage/postgres.md +++ b/docs/content/en/configuration/storage/postgres.md @@ -32,7 +32,7 @@ storage: username: authelia password: mypassword tls: - server_name: psotgres.example.com + server_name: postgres.example.com skip_verify: false minimum_version: TLS1.2 maximum_version: TLS1.3 diff --git a/docs/content/en/configuration/storage/sqlite.md b/docs/content/en/configuration/storage/sqlite.md index d0a27b758..cdb39a319 100644 --- a/docs/content/en/configuration/storage/sqlite.md +++ b/docs/content/en/configuration/storage/sqlite.md @@ -35,7 +35,7 @@ storage: ### encryption_key -See the [encryption_key docs](introduction.md#encryption_key). +See the [encryption_key docs](introduction.md#encryptionkey). ### path diff --git a/docs/content/en/configuration/telemetry/introduction.md b/docs/content/en/configuration/telemetry/introduction.md index f073ae94b..c7d1e84ff 100644 --- a/docs/content/en/configuration/telemetry/introduction.md +++ b/docs/content/en/configuration/telemetry/introduction.md @@ -13,7 +13,7 @@ toc: true --- *Authelia* allows collecting telemetry for the purpose of monitoring it. At the present time we only allow collecting -[metrics](./metrics.md). These [metrics](./metrics.md) are stored in memory and must be scraped manually by the +[metrics](metrics.md). These [metrics](metrics.md) are stored in memory and must be scraped manually by the administrator. No metrics or telemetry are reported from an *Authelia* binary to any location the administrator doesn't explicitly diff --git a/docs/content/en/contributing/prologue/financial.md b/docs/content/en/contributing/prologue/financial.md index 9b7de9e96..1b68bf242 100644 --- a/docs/content/en/contributing/prologue/financial.md +++ b/docs/content/en/contributing/prologue/financial.md @@ -24,7 +24,7 @@ was not prompted by any bug bounty program as we do not have one, but we hope to Potential usage for the money, ranked in order of priority: -1. Put Authelia through a comprehensive [Security Audit](../../../information/security.md#help-wanted). +1. Put Authelia through a comprehensive [Security Audit](../../policies/security.md#help-wanted). 1. Audit of Code Security via Analysis. 2. Audit via Penetration Testing. 2. Bug Bounty Program. @@ -38,11 +38,11 @@ Please visit [Open Collective] in order to financially contribute to Authelia. Authelia is sponsored by several companies via indirect means. These companies deserve a special mention since their contributions are very important to us but not easily visible. -If you feel you have a product or service that Authelia could benefit from please feel free to [contact](../../../information/contact.md) us. +If you feel you have a product or service that Authelia could benefit from please feel free to [contact](../../information/contact.md) us. We are currently directly looking for someone to sponsor: -* [Security Audit](../../../information/security.md#help-wanted) +* [Security Audit](../../policies/security.md#help-wanted) ### Balto diff --git a/docs/content/en/contributing/prologue/translations.md b/docs/content/en/contributing/prologue/translations.md index f7290b9af..510fa4e54 100644 --- a/docs/content/en/contributing/prologue/translations.md +++ b/docs/content/en/contributing/prologue/translations.md @@ -29,7 +29,7 @@ If the language you wish to translate is not on [Crowdin] then you have a few op ## Overrides Users can override translations easily locally using the -[assets](../../configuration/miscellaneous/server.md#asset_path) directory. This is useful if you wish to perform a +[assets](../../configuration/miscellaneous/server.md#assetpath) directory. This is useful if you wish to perform a translation and see if it looks correct in the browser. [Crowdin]: https://translate.authelia.com diff --git a/docs/content/en/information/contact.md b/docs/content/en/information/contact.md index dc3b4f38f..25ca62ff8 100644 --- a/docs/content/en/information/contact.md +++ b/docs/content/en/information/contact.md @@ -11,8 +11,8 @@ aliases: ## Security -If you believe you have identified a security related bug with Authelia please visit the [security policy](security.md) -documentation. +If you believe you have identified a security related bug with Authelia please visit the +[security policy](../policies/security.md) documentation. ## GitHub diff --git a/docs/content/en/integration/deployment/docker.md b/docs/content/en/integration/deployment/docker.md index 58177b2be..3aee92211 100644 --- a/docs/content/en/integration/deployment/docker.md +++ b/docs/content/en/integration/deployment/docker.md @@ -42,10 +42,10 @@ It expects the following: * The file `data/authelia/config/configuration.yml` is present and the configuration file. * The directory `data/authelia/secrets/` exists and contain the relevant [secret](../../configuration/methods/secrets.md) files: - * A file named `JWT_SECRET` for the [jwt_secret](../../configuration/miscellaneous/introduction.md#jwt_secret) + * A file named `JWT_SECRET` for the [jwt_secret](../../configuration/miscellaneous/introduction.md#jwtsecret) * A file named `SESSION_SECRET` for the [session secret](../../configuration/session/introduction.md#secret) * A file named `STORAGE_PASSWORD` for the [PostgreSQL password secret](../../configuration/storage/postgres.md#password) - * A file named `STORAGE_ENCRYPTION_KEY` for the [storage encryption_key secret](../../configuration/storage/introduction.md#encryption_key) + * A file named `STORAGE_ENCRYPTION_KEY` for the [storage encryption_key secret](../../configuration/storage/introduction.md#encryptionkey) * You're using PostgreSQL. * You have an external network named `net` which is in bridge mode. diff --git a/docs/content/en/integration/deployment/introduction.md b/docs/content/en/integration/deployment/introduction.md index 76d245bea..bd590c057 100644 --- a/docs/content/en/integration/deployment/introduction.md +++ b/docs/content/en/integration/deployment/introduction.md @@ -15,7 +15,7 @@ toc: true There are three main methods to deploy *Authelia*. 1. [Docker](docker.md) -2. [Kubernetes](../kubernetes/introduction/index.md) +2. [Kubernetes](../kubernetes/introduction.md) 3. [Bare-Metal](bare-metal.md) ## Get Started diff --git a/docs/content/en/integration/deployment/kubernetes.md b/docs/content/en/integration/deployment/kubernetes.md index 99edc587d..0e317abf8 100644 --- a/docs/content/en/integration/deployment/kubernetes.md +++ b/docs/content/en/integration/deployment/kubernetes.md @@ -15,4 +15,4 @@ search: index: false --- -Please see the dedicated [Kubernetes Documentation](../kubernetes/introduction/index.md). +Please see the dedicated [Kubernetes Documentation](../kubernetes/introduction.md). diff --git a/docs/content/en/integration/kubernetes/introduction.md b/docs/content/en/integration/kubernetes/introduction.md index 4439f8aa0..71027e218 100644 --- a/docs/content/en/integration/kubernetes/introduction.md +++ b/docs/content/en/integration/kubernetes/introduction.md @@ -30,7 +30,7 @@ Users are welcome to reach out directly by using any of our various [contact opt ## Get Started It's __*strongly recommended*__ that users setting up *Authelia* for the first time take a look at our -[Get Started](../../prologue/get-started) guide. This takes you through various steps which are essential to +[Get Started](../prologue/get-started.md) guide. This takes you through various steps which are essential to bootstrapping *Authelia*. ## Important Notes @@ -70,7 +70,7 @@ spec: If using file-based authentication, the argon2id provider will by default use 1GB of RAM for password generation. This means you should allow for at least this amount in your deployment/daemonset spec and have this much available on your node, alternatively you can -[tweak the providers settings](../../../configuration/first-factor/file.md#memory). Otherwise, +[tweak the providers settings](../../configuration/first-factor/file.md#memory). Otherwise, your Authelia may OOM during login. See [here](https://github.com/authelia/authelia/issues/1234#issuecomment-663910799) for more info. diff --git a/docs/content/en/integration/kubernetes/traefik-ingress.md b/docs/content/en/integration/kubernetes/traefik-ingress.md index 67fbda97c..3ada01b8e 100644 --- a/docs/content/en/integration/kubernetes/traefik-ingress.md +++ b/docs/content/en/integration/kubernetes/traefik-ingress.md @@ -86,7 +86,7 @@ metadata: name: app namespace: default annotations: - traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.entryPoints: websecure traefik.ingress.kubernetes.io/router.middlewares: default-forwardauth-authelia@kubernetescrd traefik.ingress.kubernetes.io/router.tls: "true" spec: diff --git a/docs/content/en/integration/openid-connect/introduction.md b/docs/content/en/integration/openid-connect/introduction.md index bc7939fca..6a36150af 100644 --- a/docs/content/en/integration/openid-connect/introduction.md +++ b/docs/content/en/integration/openid-connect/introduction.md @@ -111,7 +111,7 @@ Below is a list of the potential values we place in the [Claim] and their meanin ## User Information Signing Algorithm The following table describes the response from the [UserInfo] endpoint depending on the -[userinfo_signing_algorithm](../../configuration/identity-providers/open-id-connect.md#userinfo_signing_algorithm). +[userinfo_signing_algorithm](../../configuration/identity-providers/open-id-connect.md#userinfosigningalgorithm). | Signing Algorithm | Encoding | Content Type | |:-----------------:|:------------:|:-----------------------------------:| diff --git a/docs/content/en/integration/prologue/get-started.md b/docs/content/en/integration/prologue/get-started.md index 5d41d4c7c..e9202ef8d 100644 --- a/docs/content/en/integration/prologue/get-started.md +++ b/docs/content/en/integration/prologue/get-started.md @@ -38,9 +38,9 @@ used as a basis for configuration. The important sections to consider in initial configuration are as follows: -1. [jwt_secret](../../configuration/miscellaneous/introduction.md#jwt_secret) which is used to sign identity +1. [jwt_secret](../../configuration/miscellaneous/introduction.md#jwtsecret) which is used to sign identity verification emails -2. [default_redirection_url](../../configuration/miscellaneous/introduction.md#default_redirection_url) which is the +2. [default_redirection_url](../../configuration/miscellaneous/introduction.md#defaultredirectionurl) which is the default URL users will be redirected to when visiting *Authelia* directly 3. [authentication_backend](../../configuration/first-factor/introduction.md) which you must pick between [LDAP](../../configuration/first-factor/ldap.md) and a [YAML File](../../configuration/first-factor/file.md) and is @@ -76,8 +76,8 @@ There are several methods of deploying *Authelia* and we recommend reading the The default method of utilizing *Authelia* is via the [Proxy Integrations](../proxies/introduction.md). It's recommended that you read the relevant [Proxy Integration Documentation](../proxies/introduction.md). -*__Important Note:__ When your [Deployment](#deployment) is on [Kubernetes](../kubernetes/introduction/index.md) we -recommend viewing the dedicated [Kubernetes Documentation](../kubernetes/introduction/index.md) prior to viewing the +*__Important Note:__ When your [Deployment](#deployment) is on [Kubernetes](../kubernetes/introduction.md) we +recommend viewing the dedicated [Kubernetes Documentation](../kubernetes/introduction.md) prior to viewing the [Proxy Integration Documentation](../proxies/introduction.md).* ## Moving to Production diff --git a/docs/content/en/integration/proxies/nginx-proxy-manager/index.md b/docs/content/en/integration/proxies/nginx-proxy-manager/index.md index e0bdf2ceb..8532112ab 100644 --- a/docs/content/en/integration/proxies/nginx-proxy-manager/index.md +++ b/docs/content/en/integration/proxies/nginx-proxy-manager/index.md @@ -24,12 +24,12 @@ throughout this documentation and in the [See Also](#see-also) section.* ## Get Started It's __*strongly recommended*__ that users setting up *Authelia* for the first time take a look at our -[Get Started](../prologue/get-started.md) guide. This takes you through various steps which are essential to +[Get Started](../../prologue/get-started.md) guide. This takes you through various steps which are essential to bootstrapping *Authelia*. ## Requirements -[NGINX Proxy Manager] supports the required [NGINX](nginx.md#requirements) requirements for __Authelia__ out-of-the-box. +[NGINX Proxy Manager] supports the required [NGINX](../nginx.md#requirements) requirements for __Authelia__ out-of-the-box. ## Trusted Proxies @@ -37,7 +37,7 @@ bootstrapping *Authelia*. Especially if you have never read it before.* To configure trusted proxies for [NGINX Proxy Manager] see the [NGINX] section on -[Trusted Proxies](nginx.md#trusted-proxies). Adapting this to [NGINX Proxy Manager] is beyond the scope of +[Trusted Proxies](../nginx.md#trusted-proxies). Adapting this to [NGINX Proxy Manager] is beyond the scope of this documentation. ## Docker Compose @@ -137,9 +137,9 @@ either most likely require an adjustment, or may require an adjustment if you're ### Snippets The examples assume you've mounted a volume containing the relevant -[NGINX Snippets](nginx.md#supporting-configuration-snippets) from the [NGINX Integration Guide](nginx.md). The suggested -snippets are the `proxy.conf`, `authelia-location.conf`, and `authelia-authrequest.conf`. It may be fine to substitute -the standard variant of the `proxy.conf` for the headers only variant but this is untested. +[NGINX Snippets](../nginx.md#supporting-configuration-snippets) from the [NGINX Integration Guide](../nginx.md). The +suggested snippets are the `proxy.conf`, `authelia-location.conf`, and `authelia-authrequest.conf`. It may be fine to +substitute the standard variant of the `proxy.conf` for the headers only variant but this is untested. These snippets make the addition of a protected proxy host substantially easier. diff --git a/docs/content/en/integration/proxies/nginx.md b/docs/content/en/integration/proxies/nginx.md index 5b48e39be..683c2cf2a 100644 --- a/docs/content/en/integration/proxies/nginx.md +++ b/docs/content/en/integration/proxies/nginx.md @@ -62,7 +62,7 @@ required modules including the `http_set_misc` module. It also includes the [nginx-proxy-confs](https://github.com/linuxserver/docker-mods/tree/nginx-proxy-confs) mod where they have several configuration examples in the `/config/nginx/proxy-confs` directory. This can be omitted if desired. -If you're looking for a more complete solution [linuxserver.io] also have an nginx container called [SWAG](./swag.md) +If you're looking for a more complete solution [linuxserver.io] also have an nginx container called [SWAG](swag.md) which includes ACME and various other useful utilities. {{< details "docker-compose.yaml" >}} diff --git a/docs/content/en/integration/proxies/support.md b/docs/content/en/integration/proxies/support.md index cc0803e64..d74252e4e 100644 --- a/docs/content/en/integration/proxies/support.md +++ b/docs/content/en/integration/proxies/support.md @@ -76,7 +76,7 @@ For example the nginx ngx_http_auth_request_module does not seem to support this Authelia detects the upstream request method using the X-Forwarded-Method header. Some proxies set this out of the box, some require you to configure this manually. At the present time all proxies that have -[Standard Support](#standard-support) do support this. +[Standard Support](#standard) do support this. ## Specific proxy notes diff --git a/docs/content/en/integration/proxies/swag.md b/docs/content/en/integration/proxies/swag.md index d659672a2..2e49ce249 100644 --- a/docs/content/en/integration/proxies/swag.md +++ b/docs/content/en/integration/proxies/swag.md @@ -77,7 +77,7 @@ required modules including the `http_set_misc` module. It also includes the [nginx-proxy-confs](https://github.com/linuxserver/docker-mods/tree/nginx-proxy-confs) mod where they have several configuration examples in the `/config/nginx/proxy-confs` directory. This can be omitted if desired. -If you're looking for a more complete solution [linuxserver.io] also have an nginx container called [SWAG](./swag.md) +If you're looking for a more complete solution [linuxserver.io] also have an nginx container called [SWAG](swag.md) which includes ACME and various other useful utilities. {{< details "docker-compose.yaml" >}} diff --git a/docs/content/en/overview/authentication/introduction.md b/docs/content/en/overview/authentication/introduction.md index 9d3c0f632..4376e82e1 100644 --- a/docs/content/en/overview/authentication/introduction.md +++ b/docs/content/en/overview/authentication/introduction.md @@ -25,8 +25,8 @@ unreliable and simple usernames and passwords are not sufficient for security. __Authelia__ enables primarily two-factor authentication. These methods offered come in two forms: -* 1FA or first-factor authentication which is handled by a username and password. This falls into the *something you know* - categorization. +* 1FA or first-factor authentication which is handled by a username and password. This falls into the + *something you know* categorization. * 2FA or second-factor authentication which is handled by several methods including one-time passwords, authentication keys, etc. This falls into the *something you have* categorization. diff --git a/docs/content/en/overview/authentication/push-notification/index.md b/docs/content/en/overview/authentication/push-notification/index.md index e509f22d1..c7e5ba725 100644 --- a/docs/content/en/overview/authentication/push-notification/index.md +++ b/docs/content/en/overview/authentication/push-notification/index.md @@ -28,14 +28,7 @@ the user must match the name of the user in Authelia, or must have an alias that Then, in Duo interface, click on *Applications* and *Protect an Application*. Select the option *Partner Auth API*. This will generate an integration key, a secret key and a hostname. You can set the name of the application to __Authelia__ -and then you must add the generated information to Authelia [configuration](../../deployment/index.md) as shown below: - -```yaml -duo_api: - hostname: api-123456789.example.com - integration_key: ABCDEF - secret_key: 1234567890abcdefghifjkl -``` +and then you must add the generated information to Authelia [configuration](../../../configuration/second-factor/duo.md). See the [configuration documentation](../../../configuration/second-factor/duo.md) for more details. diff --git a/docs/content/en/overview/authorization/openid-connect-1.0.md b/docs/content/en/overview/authorization/openid-connect-1.0.md index 53f7637c0..a8326699a 100644 --- a/docs/content/en/overview/authorization/openid-connect-1.0.md +++ b/docs/content/en/overview/authorization/openid-connect-1.0.md @@ -1,7 +1,7 @@ --- title: "OpenID Connect 1.0" description: "OpenID Connect 1.0 is a authorization identity framework supported by Authelia." -date: 2022-06-15T17:51:47+10:00 +date: 2022-11-27T16:07:08+11:00 draft: false images: [] menu: diff --git a/docs/content/en/overview/authorization/trusted-headers.md b/docs/content/en/overview/authorization/trusted-headers.md index c99122f9b..ed6673436 100644 --- a/docs/content/en/overview/authorization/trusted-headers.md +++ b/docs/content/en/overview/authorization/trusted-headers.md @@ -2,7 +2,7 @@ title: "Trusted Headers SSO" description: "Trusted Headers SSO is a simple header authorization framework supported by Authelia." lead: "Trusted Headers is a simple header authorization framework supported by Authelia." -date: 2022-06-15T17:51:47+10:00 +date: 2022-11-27T16:07:08+11:00 draft: false images: [] menu: diff --git a/docs/content/en/overview/prologue/architecture/index.md b/docs/content/en/overview/prologue/architecture/index.md index d4e36f494..dd1866a7f 100644 --- a/docs/content/en/overview/prologue/architecture/index.md +++ b/docs/content/en/overview/prologue/architecture/index.md @@ -53,6 +53,6 @@ Authelia only works for websites served over HTTPS because the session cookie ca connections. Please note that it has been decided that we won't support websites served over HTTP in order to avoid any risk due to misconfiguration (see [#590](https://github.com/authelia/authelia/issues/590)). -If a self-signed certificate is required, the -[Generating an RSA Self-Signed Certificate](../../../reference/guides/generating-secure-values.md#generating-an-rsa-self-signed-certificate) -guide should be followed. +If a self-signed certificate is required, the [Generating an RSA Self-Signed Certificate] guide should be followed. + +[Generating an RSA Self-Signed Certificate]: ../../../reference/guides/generating-secure-values.md#generating-an-rsa-self-signed-certificate diff --git a/docs/content/en/overview/security/measures.md b/docs/content/en/overview/security/measures.md index 17d9dc17b..5c7067b8a 100644 --- a/docs/content/en/overview/security/measures.md +++ b/docs/content/en/overview/security/measures.md @@ -73,7 +73,7 @@ attacker obtains the file, each password has to be brute forced individually. Lastly Authelia's implementation of Argon2id is highly tunable. You can tune the key length, salt used, iterations (time), parallelism, and memory usage. To read more about this please read how to -[configure](../configuration/authentication/file.md) file authentication. +[configure](../../configuration/first-factor/file.md) file authentication. ## User profile and group membership always kept up-to-date (LDAP authentication provider) @@ -147,7 +147,7 @@ If you wish to change your encryption key for any reason you can do so using the ## Notifier security measures (SMTP) -The SMTP Notifier implementation does not allow connections that are not secure without changing default configuration +The SMTP Notifier implementation does not allow connections that are not secure without changing default configuration values. As such all SMTP connections require the following: @@ -158,59 +158,60 @@ As such all SMTP connections require the following: There is an option to disable both of these security measures however they are __not recommended__. -The following configuration options exist to configure the security level in order of most preferable to least +The following configuration options exist to configure the security level in order of most preferable to least preferable: ### Configuration Option: certificates_directory -You can [configure a directory](../../configuration/miscellaneous/introduction.md#certificates_directory) of -certificates for Authelia -to trust. These certificates can either be CA's or individual public certificates that should be trusted. These -are added in addition to the environments PKI trusted certificates if available. This is useful for trusting a -certificate that is self-signed without drastically reducing security. This is the most recommended workaround to not -having a valid PKI trusted certificate as it gives you complete control over which ones are trusted without disabling -critically needed validation of the identity of the target service. +You can configure a [certificates_directory] option which contains certificates for Authelia to trust. These certificates +can either be CA's or individual public certificates that should be trusted. These are added in addition to the +environments PKI trusted certificates if available. This is useful for trusting a certificate that is self-signed without +drastically reducing security. This is the most recommended workaround to not having a valid PKI trusted certificate as +it gives you complete control over which ones are trusted without disabling critically needed validation of the identity +of the target service. -Read more in the [documentation](../../configuration/miscellaneous/introduction.md#certificates_directory) for this -option. +Read more in the [certificates_directory] documentation for this option. + +[certificates_directory]: ../../configuration/miscellaneous/introduction.md#certificatesdirectory +[certificates directory]: #configuration-option--certificatesdirectory ### Configuration Option: tls.skip_verify The [tls.skip_verify](../../configuration/notifications/smtp.md#tls) option allows you to skip verifying the certificate -entirely which is why [certificates_directory](#configuration-option-certificates_directory) is preferred over this. -This will effectively mean you cannot be sure the certificate is valid which means an attacker via DNS poisoning or MITM -attacks could intercept emails from Authelia compromising a user's security without their knowledge. +entirely which is why [certificates directory] is preferred over this. This will effectively mean you cannot be sure the +certificate is valid which means an attacker via DNS poisoning or MITM attacks could intercept emails from Authelia +compromising a user's security without their knowledge. ### Configuration Option: disable_require_tls Authelia by default ensures that the SMTP server connection is secured via TLS prior to sending sensitive information. -The [disable_require_tls](../../configuration/notifications/smtp.md#disable_require_tls) option disables this -requirement which means the emails may be sent in cleartext. This is the least secure option as it effectively removes +The [disable_require_tls](../../configuration/notifications/smtp.md#disablerequiretls) option disables this +requirement which means the emails may be sent in cleartext. This is the least secure option as it effectively removes the validation of SMTP certificates and makes using an encrypted connection with TLS optional. -This means not only can the vulnerabilities of the [skip_verify](#configuration-option-tlsskip_verify) option be -exploited, but any router or switch along the route of the email which receives the packets could be used to silently +This means not only can the vulnerabilities of the [skip_verify](#configuration-option--tlsskipverify) option be +exploited, but any router or switch along the route of the email which receives the packets could be used to silently exploit the cleartext nature of the connection to manipulate the email in transit. -This is only usable currently with authentication disabled (_comment out the password_), and as such is only an option +This is only usable currently with authentication disabled (_comment out the password_), and as such is only an option for SMTP servers that allow unauthenticated relaying (bad practice). ### SMTP Ports All SMTP connections begin as [cleartext], and then negotiate to upgrade to a secure TLS connection via STARTTLS. -The [`submissions` service][service-submissions] (_typically port 465_) is an exception to this rule, where the -connection begins immediately secured with TLS (_similar to HTTPS_). When the configured [port for -SMTP][docs-config-smtp-port] is set to `465`, Authelia will initiate TLS connections without requiring STARTTLS +The [`submissions` service][service-submissions] (_typically port 465_) is an exception to this rule, where the +connection begins immediately secured with TLS (_similar to HTTPS_). When the configured [port for +SMTP][docs-config-smtp-port] is set to `465`, Authelia will initiate TLS connections without requiring STARTTLS negotiation. -When the `submissions` service port is available, it [should be preferred][port-465] over any STARTTLS port for +When the `submissions` service port is available, it [should be preferred][port-465] over any STARTTLS port for submitting mail. -**NOTE:** Prior to 2018, port 465 was previously assigned for a similar purpose known as [`smtps`][port-465] (_A TLS +**NOTE:** Prior to 2018, port 465 was previously assigned for a similar purpose known as [`smtps`][port-465] (_A TLS only equivalent of the `smtp` port 25_), which it had been deprecated for. Port 465 has since been re-assigned for only -supporting mail submission (_which unlike SMTP transfers via port 25, [requires authentication][smtp-auth]_), similar +supporting mail submission (_which unlike SMTP transfers via port 25, [requires authentication][smtp-auth]_), similar to port 587 (_the `submission` port, a common alternative that uses STARTTLS instead_). [docs-config-smtp-port]: ../../configuration/notifications/smtp.md#port @@ -237,7 +238,7 @@ would not even be able to create a TCP connection. This measure is recommended i configured some kind of ACLs specifically allowing the communication between proxies and Authelia instances like in a service mesh or some kind of network overlay. -To configure mutual TLS, please refer to [this document](../../configuration/miscellaneous/server.md#client_certificates) +To configure mutual TLS, please refer to [this document](../../configuration/miscellaneous/server.md#clientcertificates) ## Additional security @@ -255,7 +256,7 @@ database. The value of this option should be long and as random as possible. See [documentation](../../configuration/session/introduction.md#secret) for this option. The validity period of session is highly configurable. For example in a highly security conscious domain you could -set the session [remember_me_duration](../../configuration/session/introduction.md#remember_me_duration) to 0 to disable this +set the session [remember_me_duration](../../configuration/session/introduction.md#remembermeduration) to 0 to disable this feature, and set the [expiration](../../configuration/session/introduction.md#expiration) to 2 hours and the [inactivity](../../configuration/session/introduction.md#inactivity) of 10 minutes. Configuring the session security in this manner would mean if the cookie age was more than 2 hours or if the user was inactive for more than 10 minutes the diff --git a/docs/content/en/policies/security.md b/docs/content/en/policies/security.md index bbd332090..13618ba1c 100644 --- a/docs/content/en/policies/security.md +++ b/docs/content/en/policies/security.md @@ -37,11 +37,11 @@ This is the preferred method of reporting. ### Chat -If you wish to chat directly instead of sending an email please use one of the [chat options](../information/contact.md#chat) but it -is vital that when you do that you only do so privately with one of the maintainers. In order to start a private -discussion you should ask to have a private discussion with a team member without mentioning the reason why you wish to -have a private discussion so that provided the bug is confirmed we can coordinate the release of fixes and information -responsibly. +If you wish to chat directly instead of sending an email please use one of the +[chat options](../information/contact.md#chat) but it is vital that when you do that you only do so privately with one +of the maintainers. In order to start a private discussion you should ask to have a private discussion with a team +member without mentioning the reason why you wish to have a private discussion so that provided the bug is confirmed we +can coordinate the release of fixes and information responsibly. ## Credit diff --git a/docs/content/en/reference/guides/branding.md b/docs/content/en/reference/guides/branding.md index a4b26d392..42066893f 100644 --- a/docs/content/en/reference/guides/branding.md +++ b/docs/content/en/reference/guides/branding.md @@ -20,12 +20,12 @@ modifications that are in harmony with the following rules which are not intende only intended to preserve the Authelia branding identity: 1. They do not unreasonably alter the quality of the branding: - - Image size changes should be done only when the size is appropriate for the intended display scenario. - - Compression should not be applied overly aggressively for the intended display scenario. + - Image size changes should be done only when the size is appropriate for the intended display scenario. + - Compression should not be applied overly aggressively for the intended display scenario. 2. The changes do not unreasonably alter the design of the branding and should fit one or more of the following categories: - - Layout - - Format + - Layout + - Format Examples of changes which fit these categories include: @@ -48,7 +48,7 @@ The logo is just the Authelia circle logo without any text. #### Logo Files -[PSD](https://www.authelia.com/images/branding/logo.psd) | [SVG](https://www.authelia.com/images/branding/logo.svg) | [PNG](https://www.authelia.com/images/branding/logo.png) +[PSD](https://www.authelia.com/images/branding/logo.psd) | [AI](https://www.authelia.com/images/branding/logo.ai) | [SVG](https://www.authelia.com/images/branding/logo.svg) | [PNG](https://www.authelia.com/images/branding/logo.png) #### Logo Example @@ -60,7 +60,7 @@ The logo is the same as the standard logo without padding. #### Logo (Cropped) Files -[PSD](https://www.authelia.com/images/branding/logo-cropped.psd) | [SVG](https://www.authelia.com/images/branding/logo-cropped.svg) | [PNG](https://www.authelia.com/images/branding/logo-cropped.png) +[PSD](https://www.authelia.com/images/branding/logo-cropped.psd) | [AI](https://www.authelia.com/images/branding/logo-cropped.ai) | [SVG](https://www.authelia.com/images/branding/logo-cropped.svg) | [PNG](https://www.authelia.com/images/branding/logo-cropped.png) #### Logo (Cropped) Example @@ -72,7 +72,7 @@ The title is the Authelia circle logo with the `authelia` branded text. #### Title Files -[PSD](https://www.authelia.com/images/branding/title.psd) | [SVG](https://www.authelia.com/images/branding/title.svg) | [PNG](https://www.authelia.com/images/branding/title.png) +[PSD](https://www.authelia.com/images/branding/title.psd) | [AI](https://www.authelia.com/images/branding/title.ai) | [SVG](https://www.authelia.com/images/branding/title.svg) | [PNG](https://www.authelia.com/images/branding/title.png) #### Title Example diff --git a/docs/content/en/reference/guides/ldap.md b/docs/content/en/reference/guides/ldap.md index 80a5eccb2..97d9281f6 100644 --- a/docs/content/en/reference/guides/ldap.md +++ b/docs/content/en/reference/guides/ldap.md @@ -22,7 +22,7 @@ The most insecure method is unauthenticated binds. They are generally considered at all ensures anyone with any level of network access can easily obtain objects and their attributes. Authelia does support unauthenticated binds but it is not by default, you must configure the -[permit_unauthenticated_bind](../../configuration/first-factor/ldap.md#permit_unauthenticated_bind) configuration +[permit_unauthenticated_bind](../../configuration/first-factor/ldap.md#permitunauthenticatedbind) configuration option. ### End-User Binding @@ -94,17 +94,18 @@ accounts. The active directory example has two attribute filters that accomplish be appreciated). The userAccountControl filter checks that the account is not disabled and the pwdLastSet makes sure that value is not 0 which means the password requires changing at the next login. -| Implementation | Users Filter | Groups Filter | -|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------:| -| custom | N/A | N/A | -| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(sAMAccountType=268435456)) | +| Implementation | Users Filter | Groups Filter | +|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------:| +| custom | N/A | N/A | +| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) | ##### Microsoft Active Directory sAMAccountType -| Account Type Value | Description | Equivalent Filter | -|:------------------:|:--------------------------:|:----------------------------------------------:| -| 268435456 | Normal Group Objects | N/A | -| 805306368 | Normal User Accounts | `(&(objectCategory=person)(objectClass=user))` | +| Account Type Value | Description | Equivalent Filter | +|:------------------:|:---------------------------------------:|:----------------------------------------------:| +| 268435456 | Global/Universal Security Group Objects | N/A | +| 536870912 | Domain Local Security Group Objects | N/A | +| 805306368 | Normal User Accounts | `(&(objectCategory=person)(objectClass=user))` | *__References:__* - Account Type Values: [Microsoft Learn](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e742be45-665d-4576-b872-0bc99d1e1fbe). diff --git a/docs/content/en/reference/guides/notification-templates.md b/docs/content/en/reference/guides/notification-templates.md index 42ab8f871..2962a39fe 100644 --- a/docs/content/en/reference/guides/notification-templates.md +++ b/docs/content/en/reference/guides/notification-templates.md @@ -16,7 +16,7 @@ Authelia uses templates to generate the HTML and plaintext emails sent via the n two extensions; `.html` for HTML templates, and `.txt` for plaintext templates. This guide effectively documents the usage of the -[template_path](../../configuration/notifications/introduction.md#template_path) notification configuration option. +[template_path](../../configuration/notifications/introduction.md#templatepath) notification configuration option. ## Important Notes @@ -37,7 +37,7 @@ This guide effectively documents the usage of the | PasswordReset | Used to render notifications sent when password has successfully been reset | For example, to modify the `IdentityVerification` HTML template, if your -[template_path](../../configuration/notifications/introduction.md#template_path) was configured as +[template_path](../../configuration/notifications/introduction.md#templatepath) was configured as `/config/email_templates`, you would create the `/config/email_templates/IdentityVerification.html` file to override the HTML `IdentityVerification` template. diff --git a/docs/content/en/reference/guides/passwords.md b/docs/content/en/reference/guides/passwords.md index 42c204f25..1163fa792 100644 --- a/docs/content/en/reference/guides/passwords.md +++ b/docs/content/en/reference/guides/passwords.md @@ -156,7 +156,7 @@ See the [Crypt (C) Wiki page](https://en.wikipedia.org/wiki/Crypt_(C)) for more #### Tuning The configuration variables are unique to the file authentication provider, thus they all exist in a key under the file -authentication configuration key called [password](../../configuration/first-factor/file.md#password). The defaults are +authentication configuration key called [password](../../configuration/first-factor/file.md#password-options). The defaults are considered as sane for a reasonable system however we still recommend taking time to figure out the best values to adequately determine the [cost](#cost). diff --git a/docs/content/en/reference/guides/server-asset-overrides.md b/docs/content/en/reference/guides/server-asset-overrides.md index d24790fa1..966401668 100644 --- a/docs/content/en/reference/guides/server-asset-overrides.md +++ b/docs/content/en/reference/guides/server-asset-overrides.md @@ -26,10 +26,10 @@ This guide effectively documents the usage of the ## Assets -| Asset | File Name | Directory | Notes | -|:-------------------:|:-----------:|:---------:|:-------------:| -| Favicon | favicon.ico | No | N/A | -| Logo | logo.png | No | N/A | +| Asset | File Name | Directory | Notes | +|:-------------------:|:-----------:|:---------:|:-----------------------:| +| Favicon | favicon.ico | No | N/A | +| Logo | logo.png | No | N/A | | Translation Locales | locales | Yes | see [locales](#locales) | ## locales diff --git a/docs/content/en/reference/guides/troubleshooting-sanitizaiton.md b/docs/content/en/reference/guides/troubleshooting-sanitizaiton.md index a73df0959..46448ada6 100644 --- a/docs/content/en/reference/guides/troubleshooting-sanitizaiton.md +++ b/docs/content/en/reference/guides/troubleshooting-sanitizaiton.md @@ -12,7 +12,6 @@ weight: 220 toc: true aliases: - /r/sanitize - - /reference/guides/domain-sanitizaiton --- Some users may wish to hide their domain in files provided during troubleshooting. While this is discouraged, if a user diff --git a/docs/content/en/reference/integrations/cache-integrations.md b/docs/content/en/reference/integrations/cache-integrations.md new file mode 100644 index 000000000..c301c7b4b --- /dev/null +++ b/docs/content/en/reference/integrations/cache-integrations.md @@ -0,0 +1,40 @@ +--- +title: "Cache Integrations" +description: "A cache integration reference guide" +lead: "This section contains a cache integration reference guide for Authelia." +date: 2022-11-19T16:47:09+11:00 +draft: false +images: [] +menu: + reference: + parent: "integrations" +weight: 320 +toc: true +--- + +We currently only support [Redis Standalone] and [Redis Sentinel] for cached information like sessions +(other than in-memory). + +## Redis + +The following is guidance on versions of [Redis] supported. + +### Standalone + +When it comes to [Redis Standalone] we support the versions supported by [Redis] themselves which can be found in the +[Redis release cycle](https://redis.io/docs/about/releases/) documentation. This is typically the latest available +version. + + +### Sentinel + +When it comes to [Redis Sentinel] we support the versions supported by [Redis] themselves which can be found in the +[Redis release cycle](https://redis.io/docs/about/releases/) documentation. This is typically the latest available +version. + +_**Note:** Currently we only support [Redis Sentinel] version 6.x due to a breaking change to [Redis Sentinel] in +version 7.x. This will be resolved in the near future._ + +[Redis]: https://redis.io/ +[Redis Standalone]: https://redis.io/docs/getting-started/ +[Redis Sentinel]: https://redis.io/docs/management/sentinel/ diff --git a/docs/content/en/reference/integrations/database-integrations.md b/docs/content/en/reference/integrations/database-integrations.md index d3f11103e..efe33915f 100644 --- a/docs/content/en/reference/integrations/database-integrations.md +++ b/docs/content/en/reference/integrations/database-integrations.md @@ -15,16 +15,29 @@ toc: true We generally recommend using [PostgreSQL] for a database. If high availability is not a consideration we also support [SQLite3]. +It is also a general recommendation that if you're using [PostgreSQL], [MySQL], or [MariaDB]; that you do not +automatically upgrade the major/minor version of these databases, and pin the image tag so at most the patch version +is updated. For example for database version `x.y.z` only the `z` should change, `x` and `y` should remain the same. + +It is also generally recommended that you do not rely on automatic update tools to perform this action +unless you are sure they shut down the container properly (i.e. with a graceful stop). + +While this guide exists and it contains some guidance on managing the database being used, it is by no means exhaustive +or intended as such and users should refer to the database vendors documentation. ## PostgreSQL The only current support criteria for [PostgreSQL] at present is that the version you're using is supported by the -[PostgreSQL] developers. See their [Versioning Policy](https://www.postgresql.org/support/versioning/) for more -information. +[PostgreSQL] developers. See [Vendor Supported Versions](#vendor-supported-versions) more information. We generally perform integration testing against the latest supported version of [PostgreSQL] and that is generally the recommended version for new installations. +### Vendor Supported Versions + +See the [PostgreSQL Versioning Policy](https://www.postgresql.org/support/versioning/) for information on the versions +and platforms that are currently supported by this vendor. + ## MySQL [MySQL] and [MariaDB] are both supported as part of the [MySQL] implementation. This is generally discouraged as @@ -40,8 +53,8 @@ party. 4. Must support maximum index size of no less than 2048 bytes. The default maximum index size for the InnoDB engine is 3072 bytes on: 1. [MySQL] [8.0](https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html) or later. - 2. [MySQL] [5.7](https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html) provided - [innodb_large_prefix](#innodb-large-prefixes) or later. + 2. [MySQL] [5.7](https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html) or later provided: + 1. The [innodb_large_prefix](#innodb-large-prefixes) option is **_ON_**. 3. [MariaDB] [10.3](https://mariadb.com/kb/en/innodb-system-variables/#innodb_large_prefix) or later. 5. Must support ANSI standard time behaviours. See [ANSI standard time behaviours](#ansi-standard-time-behaviours). @@ -52,8 +65,8 @@ supported version of [MariaDB] is generally the recommended version for new inst #### InnoDB Large Prefixes -This can be configured in the [MySQL] configuration file by setting the `innodb_large_prefix` value to on. -According to the Oracle documentation this is the default behaviour in +This can be configured in the [MySQL] configuration file by setting the `innodb_large_prefix` option to on. +According to the [Oracle] documentation this is the default behaviour in [MySQL] [5.7](https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix) and it can't be turned off in [MySQL] [8.0](https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html) or in [MariaDB] 10.3 and later. @@ -65,7 +78,7 @@ innodb_large_prefix = ON #### ANSI standard time behaviours This can be configured in the [MySQL] configuration file by setting the `explicit_defaults_for_timestamp` value to on. -According to the Oracle documentation this is the default behaviour in +According to the [Oracle] documentation this is the default behaviour in [MySQL] [5.7](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp) and [MySQL] [8.0](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp). This is however not the default behaviour in @@ -76,19 +89,43 @@ This is however not the default behaviour in explicit_defaults_for_timestamp = ON ``` +#### Upgrades + +[MySQL] and [MariaDB] have several standard but important system databases named `mysql`, `sys`, and +`performance_schema`. These databases are outside the scope and not intended for individual applications to manage as +they are system databases used by [MySQL] and [MariaDB] internally. + +These servers/engines may successfully start when these databases are incompatible with your particular [MySQL] or +[MariaDB] version, but may raise errors when you attempt to use particular features of the database. This may lead a +user to believe the server/engine is functioning correctly when it is in fact running with a potentially badly corrupted +schema. + +The risk here is that the database may run for an extended period of time unnoticed and may be getting more and more +corrupt with no visible signs until it's no longer recoverable. This makes it critically important users do not neglect +this operation or ensure it's happening. + +While some [MySQL] or [MariaDB] containers will do this automatically or give users an option to perform this +automatically, it is strongly recommended that this process is manually done and only done **_after_** doing a backup of +all databases on the server as is the recommendation from both [MySQL] and [MariaDB]. + +It is your responsibility to ensure these tables are upgraded as per the +[mysql_upgrade](https://dev.mysql.com/doc/refman/8.0/en/mysql-upgrade.html) and +[mariadb_upgrade](https://mariadb.com/kb/en/mysql_upgrade/) documentation. + ### Vendor Supported Versions #### MariaDB Vendor Supported Versions -See the [MariaDB Server Releases](https://mariadb.com/kb/en/mariadb-server-release-dates/) for more information. +See the [MariaDB Server Releases](https://mariadb.com/kb/en/mariadb-server-release-dates/) for information on the +versions and platforms that are currently supported by this vendor. #### MySQL Vendor Supported Versions See the [MySQL Supported Platforms](https://www.mysql.com/support/supportedplatforms/database.html) for information on -which versions and platforms they support. +the versions and platforms that are currently supported by this vendor. [PostgreSQL]: https://www.postgresql.org/ [MySQL]: https://www.mysql.com/ [MariaDB]: https://mariadb.org/ [SQLite3]: https://www.sqlite.org/index.html - +[Oracle]: https://www.oracle.com/ diff --git a/docs/netlify.toml b/docs/netlify.toml index f6ee25609..a31a1275e 100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@ -3,20 +3,21 @@ functions = "functions" [build.environment] - NODE_VERSION = "16.16.0" - NPM_VERSION = "8.11.0" + NODE_VERSION = "16.18.1" + NPM_VERSION = "8.19.2" + GO_VERSION = "1.19.4" [context.production] - command = "npm run build" + command = "pnpm run build" [context.deploy-preview] - command = "npm run build -- -b $DEPLOY_PRIME_URL" + command = "pnpm run build --baseURL $DEPLOY_URL" [context.branch-deploy] - command = "npm run build -- -b $DEPLOY_PRIME_URL" + command = "pnpm run build --baseURL $DEPLOY_URL" [context.next] - command = "npm run build" + command = "pnpm run build" [context.next.environment] HUGO_ENV = "next" diff --git a/docs/package.json b/docs/package.json index 5b0c3df18..fd1d63a90 100644 --- a/docs/package.json +++ b/docs/package.json @@ -3,7 +3,7 @@ "description": "Doks theme", "version": "0.5.0", "engines": { - "node": ">=16.16.0" + "node": ">=16.18.1" }, "browserslist": [ "defaults" @@ -39,7 +39,7 @@ }, "devDependencies": { "@babel/cli": "7.19.3", - "@babel/core": "7.20.2", + "@babel/core": "7.20.5", "@babel/preset-env": "7.20.2", "@fullhuman/postcss-purgecss": "5.0.0", "@hyas/images": "0.3.2", @@ -49,25 +49,25 @@ "bootstrap": "5.2.3", "bootstrap-icons": "1.10.2", "clipboard": "2.0.11", - "eslint": "8.28.0", + "eslint": "8.29.0", "exec-bin": "1.0.0", "flexsearch": "0.7.31", "highlight.js": "11.7.0", "hugo-installer": "4.0.1", "instant.page": "5.1.1", - "katex": "0.16.3", + "katex": "0.16.4", "lazysizes": "5.3.2", "markdownlint-cli2": "0.5.1", "netlify-plugin-submit-sitemap": "0.4.0", "node-fetch": "3.3.0", "postcss": "8.4.19", - "postcss-cli": "10.0.0", + "postcss-cli": "10.1.0", "purgecss-whitelister": "2.4.0", "shx": "0.3.4", - "stylelint": "14.15.0", + "stylelint": "14.16.0", "stylelint-config-standard-scss": "6.1.0" }, "otherDependencies": { - "hugo": "0.107.0" + "hugo": "0.108.0" } } diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 29f43ea9c..6d6ad757c 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -2,7 +2,7 @@ lockfileVersion: 5.4 specifiers: '@babel/cli': 7.19.3 - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/preset-env': 7.20.2 '@fullhuman/postcss-purgecss': 5.0.0 '@hyas/images': 0.3.2 @@ -12,28 +12,28 @@ specifiers: bootstrap: 5.2.3 bootstrap-icons: 1.10.2 clipboard: 2.0.11 - eslint: 8.28.0 + eslint: 8.29.0 exec-bin: 1.0.0 flexsearch: 0.7.31 highlight.js: 11.7.0 hugo-installer: 4.0.1 instant.page: 5.1.1 - katex: 0.16.3 + katex: 0.16.4 lazysizes: 5.3.2 markdownlint-cli2: 0.5.1 netlify-plugin-submit-sitemap: 0.4.0 node-fetch: 3.3.0 postcss: 8.4.19 - postcss-cli: 10.0.0 + postcss-cli: 10.1.0 purgecss-whitelister: 2.4.0 shx: 0.3.4 - stylelint: 14.15.0 + stylelint: 14.16.0 stylelint-config-standard-scss: 6.1.0 devDependencies: - '@babel/cli': 7.19.3_@babel+core@7.20.2 - '@babel/core': 7.20.2 - '@babel/preset-env': 7.20.2_@babel+core@7.20.2 + '@babel/cli': 7.19.3_@babel+core@7.20.5 + '@babel/core': 7.20.5 + '@babel/preset-env': 7.20.2_@babel+core@7.20.5 '@fullhuman/postcss-purgecss': 5.0.0_postcss@8.4.19 '@hyas/images': 0.3.2 '@popperjs/core': 2.11.6 @@ -42,23 +42,23 @@ devDependencies: bootstrap: 5.2.3_@popperjs+core@2.11.6 bootstrap-icons: 1.10.2 clipboard: 2.0.11 - eslint: 8.28.0 + eslint: 8.29.0 exec-bin: 1.0.0 flexsearch: 0.7.31 highlight.js: 11.7.0 hugo-installer: 4.0.1 instant.page: 5.1.1 - katex: 0.16.3 + katex: 0.16.4 lazysizes: 5.3.2 markdownlint-cli2: 0.5.1 netlify-plugin-submit-sitemap: 0.4.0 node-fetch: 3.3.0 postcss: 8.4.19 - postcss-cli: 10.0.0_postcss@8.4.19 + postcss-cli: 10.1.0_postcss@8.4.19 purgecss-whitelister: 2.4.0 shx: 0.3.4 - stylelint: 14.15.0 - stylelint-config-standard-scss: 6.1.0_a37symlv4urgexnspmy4gyeh7i + stylelint: 14.16.0 + stylelint-config-standard-scss: 6.1.0_u4cmdib575x7lmfjhgvokchuwe packages: @@ -70,14 +70,14 @@ packages: '@jridgewell/trace-mapping': 0.3.13 dev: true - /@babel/cli/7.19.3_@babel+core@7.20.2: + /@babel/cli/7.19.3_@babel+core@7.20.5: resolution: {integrity: sha512-643/TybmaCAe101m2tSVHi9UKpETXP9c/Ff4mD2tAwkdP6esKIfaauZFc67vGEM6r9fekbEGid+sZhbEnSe3dg==} engines: {node: '>=6.9.0'} hasBin: true peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@jridgewell/trace-mapping': 0.3.13 commander: 4.1.1 convert-source-map: 1.8.0 @@ -102,20 +102,20 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/core/7.20.2: - resolution: {integrity: sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==} + /@babel/core/7.20.5: + resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.4 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/generator': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.1 - '@babel/parser': 7.20.3 + '@babel/helpers': 7.20.6 + '@babel/parser': 7.20.5 '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -125,11 +125,11 @@ packages: - supports-color dev: true - /@babel/generator/7.20.4: - resolution: {integrity: sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==} + /@babel/generator/7.20.5: + resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 dev: true @@ -138,7 +138,7 @@ packages: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-builder-binary-assignment-operator-visitor/7.18.6: @@ -146,29 +146,29 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true - /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.2: + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 semver: 6.3.0 dev: true - /@babel/helper-create-class-features-plugin/7.18.6_@babel+core@7.20.2: + /@babel/helper-create-class-features-plugin/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 @@ -180,24 +180,24 @@ packages: - supports-color dev: true - /@babel/helper-create-regexp-features-plugin/7.19.0_@babel+core@7.20.2: + /@babel/helper-create-regexp-features-plugin/7.19.0_@babel+core@7.20.5: resolution: {integrity: sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 regexpu-core: 5.1.0 dev: true - /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.2: + /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.5: resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} peerDependencies: '@babel/core': ^7.4.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 debug: 4.3.4 lodash.debounce: 4.0.8 @@ -216,7 +216,7 @@ packages: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-function-name/7.19.0: @@ -224,28 +224,28 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-member-expression-to-functions/7.18.9: resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-module-transforms/7.20.2: @@ -258,8 +258,8 @@ packages: '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -268,7 +268,7 @@ packages: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-plugin-utils/7.20.2: @@ -276,17 +276,17 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.2: + /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-wrap-function': 7.18.11 - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -298,8 +298,8 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-member-expression-to-functions': 7.18.9 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -311,8 +311,8 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-member-expression-to-functions': 7.18.9 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -321,21 +321,21 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-skip-transparent-expression-wrappers/7.18.9: resolution: {integrity: sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-string-parser/7.19.4: @@ -359,19 +359,19 @@ packages: dependencies: '@babel/helper-function-name': 7.19.0 '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/helpers/7.20.1: - resolution: {integrity: sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==} + /@babel/helpers/7.20.6: + resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -385,412 +385,412 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser/7.20.3: - resolution: {integrity: sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==} + /@babel/parser/7.20.5: + resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.2: + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.9_@babel+core@7.20.2: + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.2 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-async-generator-functions/7.20.1_@babel+core@7.20.2: + /@babel/plugin-proposal-async-generator-functions/7.20.1_@babel+core@7.20.5: resolution: {integrity: sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.2 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.2 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.2: + /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.2 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.2 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-logical-assignment-operators/7.18.9_@babel+core@7.20.2: + /@babel/plugin-proposal-logical-assignment-operators/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.2 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.2 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.2 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-object-rest-spread/7.20.2_@babel+core@7.20.2: + /@babel/plugin-proposal-object-rest-spread/7.20.2_@babel+core@7.20.5: resolution: {integrity: sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-transform-parameters': 7.20.3_@babel+core@7.20.2 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.20.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.2 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-optional-chaining/7.18.9_@babel+core@7.20.2: + /@babel/plugin-proposal-optional-chaining/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.2 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.2 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.2 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.2: + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} engines: {node: '>=4'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.2: + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.5: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.2: + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.5: resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.2: + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.20.2: + /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.20.5: resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.2: + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.5: resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.2: + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.5: resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.2: + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.2: + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.2: + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-block-scoping/7.20.2_@babel+core@7.20.2: + /@babel/plugin-transform-block-scoping/7.20.2_@babel+core@7.20.5: resolution: {integrity: sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-classes/7.20.2_@babel+core@7.20.2: + /@babel/plugin-transform-classes/7.20.2_@babel+core@7.20.5: resolution: {integrity: sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 '@babel/helper-optimise-call-expression': 7.18.6 @@ -802,120 +802,120 @@ packages: - supports-color dev: true - /@babel/plugin-transform-computed-properties/7.18.9_@babel+core@7.20.2: + /@babel/plugin-transform-computed-properties/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-destructuring/7.20.2_@babel+core@7.20.2: + /@babel/plugin-transform-destructuring/7.20.2_@babel+core@7.20.5: resolution: {integrity: sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.2: + /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.2: + /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.5: resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.2: + /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-function-name': 7.19.0 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.2: + /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-modules-amd/7.19.6_@babel+core@7.20.2: + /@babel/plugin-transform-modules-amd/7.19.6_@babel+core@7.20.5: resolution: {integrity: sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-commonjs/7.19.6_@babel+core@7.20.2: + /@babel/plugin-transform-modules-commonjs/7.19.6_@babel+core@7.20.5: resolution: {integrity: sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-simple-access': 7.20.2 @@ -923,13 +923,13 @@ packages: - supports-color dev: true - /@babel/plugin-transform-modules-systemjs/7.19.6_@babel+core@7.20.2: + /@babel/plugin-transform-modules-systemjs/7.19.6_@babel+core@7.20.5: resolution: {integrity: sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.20.2 @@ -938,262 +938,262 @@ packages: - supports-color dev: true - /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-named-capturing-groups-regex/7.19.1_@babel+core@7.20.2: + /@babel/plugin-transform-named-capturing-groups-regex/7.19.1_@babel+core@7.20.5: resolution: {integrity: sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-replace-supers': 7.18.9 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-parameters/7.20.3_@babel+core@7.20.2: + /@babel/plugin-transform-parameters/7.20.3_@babel+core@7.20.5: resolution: {integrity: sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 regenerator-transform: 0.15.0 dev: true - /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-spread/7.19.0_@babel+core@7.20.2: + /@babel/plugin-transform-spread/7.19.0_@babel+core@7.20.5: resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 dev: true - /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.2: + /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.2: + /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.5: resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.2: + /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.5: resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/preset-env/7.20.2_@babel+core@7.20.2: + /@babel/preset-env/7.20.2_@babel+core@7.20.5: resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-async-generator-functions': 7.20.1_@babel+core@7.20.2 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-object-rest-spread': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.2 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.2 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.2 - '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-block-scoping': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-transform-classes': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-transform-computed-properties': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-destructuring': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.2 - '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-amd': 7.19.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-commonjs': 7.19.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-systemjs': 7.19.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-named-capturing-groups-regex': 7.19.1_@babel+core@7.20.2 - '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-parameters': 7.20.3_@babel+core@7.20.2 - '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-spread': 7.19.0_@babel+core@7.20.2 - '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.2 - '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.2 - '@babel/preset-modules': 0.1.5_@babel+core@7.20.2 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-async-generator-functions': 7.20.1_@babel+core@7.20.5 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-object-rest-spread': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.5 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.20.5 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoping': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-transform-classes': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-transform-computed-properties': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-destructuring': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.5 + '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-amd': 7.19.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-commonjs': 7.19.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-systemjs': 7.19.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-named-capturing-groups-regex': 7.19.1_@babel+core@7.20.5 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.20.3_@babel+core@7.20.5 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-spread': 7.19.0_@babel+core@7.20.5 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.5 + '@babel/preset-modules': 0.1.5_@babel+core@7.20.5 '@babel/types': 7.20.2 - babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.2 - babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.2 - babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.2 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.5 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.5 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.5 core-js-compat: 3.25.2 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules/0.1.5_@babel+core@7.20.2: + /@babel/preset-modules/0.1.5_@babel+core@7.20.5: resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.2 - '@babel/types': 7.20.2 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 esutils: 2.0.3 dev: true @@ -1209,22 +1209,22 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 dev: true - /@babel/traverse/7.20.1: - resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==} + /@babel/traverse/7.20.5: + resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.4 + '@babel/generator': 7.20.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -1240,7 +1240,16 @@ packages: to-fast-properties: 2.0.0 dev: true - /@csstools/selector-specificity/2.0.2_45y636a2vqremknoajyxd5nkzy: + /@babel/types/7.20.5: + resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: true + + /@csstools/selector-specificity/2.0.2_tbwh2mpcdwdeb2slx6bobindua: resolution: {integrity: sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: @@ -1248,7 +1257,7 @@ packages: postcss-selector-parser: ^6.0.10 dependencies: postcss: 8.4.19 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.11 dev: true /@eslint/eslintrc/1.3.3: @@ -1259,7 +1268,7 @@ packages: debug: 4.3.4 espree: 9.4.0 globals: 13.15.0 - ignore: 5.2.0 + ignore: 5.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -1543,38 +1552,38 @@ packages: postcss-value-parser: 4.2.0 dev: true - /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.2: + /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.5: resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.2: + /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.5: resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 core-js-compat: 3.25.2 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.2: + /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.5: resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -2079,13 +2088,13 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.28.0: + /eslint-utils/3.0.0_eslint@8.29.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.28.0 + eslint: 8.29.0 eslint-visitor-keys: 2.1.0 dev: true @@ -2099,8 +2108,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.28.0: - resolution: {integrity: sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==} + /eslint/8.29.0: + resolution: {integrity: sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: @@ -2115,7 +2124,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.28.0 + eslint-utils: 3.0.0_eslint@8.29.0 eslint-visitor-keys: 3.3.0 espree: 9.4.0 esquery: 1.4.0 @@ -2314,9 +2323,9 @@ packages: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: true - /fs-extra/10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} + /fs-extra/11.1.0: + resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} + engines: {node: '>=14.14'} dependencies: graceful-fs: 4.2.10 jsonfile: 6.1.0 @@ -2457,7 +2466,7 @@ packages: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.2.12 - ignore: 5.2.0 + ignore: 5.2.1 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -2468,7 +2477,7 @@ packages: dependencies: dir-glob: 3.0.1 fast-glob: 3.2.12 - ignore: 5.2.0 + ignore: 5.2.1 merge2: 1.4.1 slash: 4.0.0 dev: true @@ -2612,6 +2621,11 @@ packages: engines: {node: '>= 4'} dev: true + /ignore/5.2.1: + resolution: {integrity: sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==} + engines: {node: '>= 4'} + dev: true + /import-fresh/3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -2811,8 +2825,8 @@ packages: graceful-fs: 4.2.10 dev: true - /katex/0.16.3: - resolution: {integrity: sha512-3EykQddareoRmbtNiNEDgl3IGjryyrp2eg/25fHDEnlHymIDi33bptkMv6K4EOC2LZCybLW/ZkEo6Le+EM9pmA==} + /katex/0.16.4: + resolution: {integrity: sha512-WudRKUj8yyBeVDI4aYMNxhx5Vhh2PjpzQw1GRu/LVGqL4m1AxwD1GcUp0IMbdJaf5zsjtj8ghP0DOQRYhroNkw==} hasBin: true dependencies: commander: 8.3.0 @@ -3307,8 +3321,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /postcss-cli/10.0.0_postcss@8.4.19: - resolution: {integrity: sha512-Wjy/00wBBEgQqnSToznxLWDnATznokFGXsHtF/3G8glRZpz5KYlfHcBW/VMJmWAeF2x49zjgy4izjM3/Wx1dKA==} + /postcss-cli/10.1.0_postcss@8.4.19: + resolution: {integrity: sha512-Zu7PLORkE9YwNdvOeOVKPmWghprOtjFQU3srMUGbdz3pHJiFh7yZ4geiZFMkjMfB0mtTFR3h8RemR62rPkbOPA==} engines: {node: '>=14'} hasBin: true peerDependencies: @@ -3316,7 +3330,7 @@ packages: dependencies: chokidar: 3.5.3 dependency-graph: 0.11.0 - fs-extra: 10.1.0 + fs-extra: 11.1.0 get-stdin: 9.0.0 globby: 13.1.2 picocolors: 1.0.0 @@ -3325,7 +3339,7 @@ packages: postcss-reporter: 7.0.5_postcss@8.4.19 pretty-hrtime: 1.0.3 read-cache: 1.0.0 - slash: 4.0.0 + slash: 5.0.0 yargs: 17.5.1 transitivePeerDependencies: - ts-node @@ -3393,6 +3407,14 @@ packages: util-deprecate: 1.0.2 dev: true + /postcss-selector-parser/6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + /postcss-value-parser/4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true @@ -3739,6 +3761,11 @@ packages: engines: {node: '>=12'} dev: true + /slash/5.0.0: + resolution: {integrity: sha512-n6KkmvKS0623igEVj3FF0OZs1gYYJ0o0Hj939yc1fyxl2xt+xYpLnzJB6xBSqOfV9ZFLEWodBBN/heZJahuIJQ==} + engines: {node: '>=14.16'} + dev: true + /slice-ansi/4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} @@ -3829,7 +3856,7 @@ packages: resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} dev: true - /stylelint-config-recommended-scss/8.0.0_a37symlv4urgexnspmy4gyeh7i: + /stylelint-config-recommended-scss/8.0.0_u4cmdib575x7lmfjhgvokchuwe: resolution: {integrity: sha512-BxjxEzRaZoQb7Iinc3p92GS6zRdRAkIuEu2ZFLTxJK2e1AIcCb5B5MXY9KOXdGTnYFZ+KKx6R4Fv9zU6CtMYPQ==} peerDependencies: postcss: ^8.3.3 @@ -3840,20 +3867,20 @@ packages: dependencies: postcss: 8.4.19 postcss-scss: 4.0.4_postcss@8.4.19 - stylelint: 14.15.0 - stylelint-config-recommended: 9.0.0_stylelint@14.15.0 - stylelint-scss: 4.2.0_stylelint@14.15.0 + stylelint: 14.16.0 + stylelint-config-recommended: 9.0.0_stylelint@14.16.0 + stylelint-scss: 4.2.0_stylelint@14.16.0 dev: true - /stylelint-config-recommended/9.0.0_stylelint@14.15.0: + /stylelint-config-recommended/9.0.0_stylelint@14.16.0: resolution: {integrity: sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==} peerDependencies: stylelint: ^14.10.0 dependencies: - stylelint: 14.15.0 + stylelint: 14.16.0 dev: true - /stylelint-config-standard-scss/6.1.0_a37symlv4urgexnspmy4gyeh7i: + /stylelint-config-standard-scss/6.1.0_u4cmdib575x7lmfjhgvokchuwe: resolution: {integrity: sha512-iZ2B5kQT2G3rUzx+437cEpdcnFOQkwnwqXuY8Z0QUwIHQVE8mnYChGAquyKFUKZRZ0pRnrciARlPaR1RBtPb0Q==} peerDependencies: postcss: ^8.3.3 @@ -3863,21 +3890,21 @@ packages: optional: true dependencies: postcss: 8.4.19 - stylelint: 14.15.0 - stylelint-config-recommended-scss: 8.0.0_a37symlv4urgexnspmy4gyeh7i - stylelint-config-standard: 29.0.0_stylelint@14.15.0 + stylelint: 14.16.0 + stylelint-config-recommended-scss: 8.0.0_u4cmdib575x7lmfjhgvokchuwe + stylelint-config-standard: 29.0.0_stylelint@14.16.0 dev: true - /stylelint-config-standard/29.0.0_stylelint@14.15.0: + /stylelint-config-standard/29.0.0_stylelint@14.16.0: resolution: {integrity: sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==} peerDependencies: stylelint: ^14.14.0 dependencies: - stylelint: 14.15.0 - stylelint-config-recommended: 9.0.0_stylelint@14.15.0 + stylelint: 14.16.0 + stylelint-config-recommended: 9.0.0_stylelint@14.16.0 dev: true - /stylelint-scss/4.2.0_stylelint@14.15.0: + /stylelint-scss/4.2.0_stylelint@14.16.0: resolution: {integrity: sha512-HHHMVKJJ5RM9pPIbgJ/XA67h9H0407G68Rm69H4fzFbFkyDMcTV1Byep3qdze5+fJ3c0U7mJrbj6S0Fg072uZA==} peerDependencies: stylelint: ^14.5.1 @@ -3885,17 +3912,17 @@ packages: lodash: 4.17.21 postcss-media-query-parser: 0.2.3 postcss-resolve-nested-selector: 0.1.1 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 - stylelint: 14.15.0 + stylelint: 14.16.0 dev: true - /stylelint/14.15.0: - resolution: {integrity: sha512-JOgDAo5QRsqiOZPZO+B9rKJvBm64S0xasbuRPAbPs6/vQDgDCnZLIiw6XcAS6GQKk9k1sBWR6rmH3Mfj8OknKg==} + /stylelint/14.16.0: + resolution: {integrity: sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true dependencies: - '@csstools/selector-specificity': 2.0.2_45y636a2vqremknoajyxd5nkzy + '@csstools/selector-specificity': 2.0.2_tbwh2mpcdwdeb2slx6bobindua balanced-match: 2.0.0 colord: 2.9.3 cosmiconfig: 7.1.0 @@ -3908,7 +3935,7 @@ packages: globby: 11.1.0 globjoin: 0.1.4 html-tags: 3.2.0 - ignore: 5.2.0 + ignore: 5.2.1 import-lazy: 4.0.0 imurmurhash: 0.1.4 is-plain-object: 5.0.0 @@ -3922,7 +3949,7 @@ packages: postcss-media-query-parser: 0.2.3 postcss-resolve-nested-selector: 0.1.1 postcss-safe-parser: 6.0.0_postcss@8.4.19 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 resolve-from: 5.0.0 string-width: 4.2.3 diff --git a/docs/static/images/branding/logo-cropped.ai b/docs/static/images/branding/logo-cropped.ai new file mode 100644 index 000000000..8d8307779 --- /dev/null +++ b/docs/static/images/branding/logo-cropped.ai @@ -0,0 +1,399 @@ +%PDF-1.6 %âãÏÓ +1 0 obj <>/OCGs[20 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator 27.0 (Windows) + 2022-12-15T21:33:04+11:00 + 2022-12-15T21:33:04+11:00 + 2022-12-15T21:33:04+11:00 + + + + 256 + 252 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA/AEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYqsuLiC3hee4kSGGMVklkYKqjxLGgGEAnYK878yfn55A0cvFbXD6vcrtws1rHXtWZiqU915Zm4 uzssufp97TLPEPMde/5yW823ZZNIsrbTIj0d63Mw/wBk3GP/AITM/H2XAfUSWmWoPRgOr/mR581Y k32u3jqesUcphjP/ADzi4J+GZcNNjjyiGo5JHqxyWSSRy8jF3PVmJJPbqcuYKZwKy78rvOOreW/N +myW1w62VxcRwX1ryPpyRSsEYlOnJQaqfHMbVYROBvmzxzIL7Mzm3YuxV2KuxV2KuxV2KuxV2Kux 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 + + + + 3 + + + xmp.did:33ff98ee-93c4-e448-90bf-017ad67f2b0f + xmp.did:feeeff93-18d2-154f-91b1-dcb9a891b83b + + + application/pdf + + + logo-cropped + + + uuid:621d8401-71b1-4ee7-aa64-a8a07b15ca79 + xmp.did:79104415-1304-c049-8620-1e1cf7450da8 + xmp.did:aa8a0a42-3b65-1849-b56e-5a9e0f01b5c7 + proof:pdf + + + + created + xmp.iid:aa8a0a42-3b65-1849-b56e-5a9e0f01b5c7 + 2022-12-15T12:43:15+11:00 + Adobe Photoshop 24.1 (Windows) + + + saved + xmp.iid:79104415-1304-c049-8620-1e1cf7450da8 + 2022-12-15T21:33:01+11:00 + Adobe Illustrator 27.0 (Windows) + / + + + + + xmp.iid:aa8a0a42-3b65-1849-b56e-5a9e0f01b5c7 + xmp.did:aa8a0a42-3b65-1849-b56e-5a9e0f01b5c7 + xmp.did:aa8a0a42-3b65-1849-b56e-5a9e0f01b5c7 + + 1 + 900000/10000 + 900000/10000 + 2 + 1 + 335 + 335 + 1 + False + False + + 268.000000 + 268.000000 + Points + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + AIRobin + Adobe PDF library 16.07 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 5 0 obj <>/ExtGState<>/Properties<>/Shading<>>>/Thumb 26 0 R/TrimBox[0.0 0.0 268.0 268.0]/Type/Page/PieceInfo<>>> endobj 22 0 obj <>stream +H‰¬—»®$7DýþŠúåðýp5+¬%,’?Æʨ èÿö½·«°c¬îÌn&ÉÌÈÈà§ÿ~>>ýô9?üûóñøóÑgèi©”PÛñUviýX=¬‘5Cëè²j!¶b³¯ãËãæ8i¤Pùÿ±¤#ÇúLÇj¡×i³-o•Û`ùÍqÚQW?ÒÈ!Âg iÔ#­JÙèµØîk>Oðê9í©iÙ3bòš¤˜¶3võÕÞlŸzˆãÞÿƒ¤ÌE(n×b=®9#@Žaéž5¤9IbJ#Œ>œE–¥ºâµ’-ýJ¶R¬¡Ç®õWÇ逵ræÔÂ,íH¹„Èõ3y]úlì§Äͧ¯pó({“ÔT¿pXì®ÏÊ&y8dëªÒ•ãê9}®Ä5R+!Åå‹ÄÅz¢`‡N™”af¾%âÕs:èêªh YÅHûTc†6t^ÊFFÓàtÏb\=„àýò{<þúýøñ·ãçÇÏl2á(*‘3d“3Ý7éÒzdÛb9@ ks¢WÇa\˜h†äkÞçƒzjUš•r£äÕy*¬Ò91·åÖZ}1½¶¶æM ¢Éþœƒ:à…ùÈ«=IçÅ!Þ†èÓ!äôž¶Y °þl®'À^*/¹O^_ Óö4J²¹«˜4_M‘6HØ#L$t]øÙ]dŽÖÄìQ;ß°všÜô4½Ÿs&)àŠÜäŽI'­z,ê8Ô7Ëéˆ&ûq!ý>Ì…­RE1Š0öKòú«Gû³BKvÂsJ ~ºs2©Wm—0 +ý7çÝ£ÁC6I#ÍÒóž7¸Ž‰×ƒPÐrC”Z•À«C)ìÞ«s¶• —Eñ'‰Ùè -¯¿:4pH +üH‹wšð5Z´Ó‚Ñ …öÈgimCöÃ< ^GGbÑŸb…šIM°&xxlØ\m¯.böiБIÍYZ¨rþ©˜Íˆè"ç«}>¦æCsº*PZ"f%œ30¦¼MCfÝÍȹ9tmy˜ï­ºêj7uë]£ü,„èÌÝ<çC{S*µ¿FµF®´sG!¤hPm“3\¬çЩ},Ø3Z(ÜáF.ßOl=¥UÕ’ðižq¯ß"¶LÕÊ´%1Û@V0Ý™(„\‡!€§šòThñ^²,¹Ú¢pÐ é¼ Èó*9¢ƒ¦Ù§ªÃ]~±éPÖLû`ý€L ™(S§ñÛVôPíâ—«­2ÓñÇXLJB %ÚbÌ È ¥QŠ:ójè…*ÀLŒW¦Yq#¶‚&«±y1 l±©x%X’ +Å+   Ë‹Éž:'­H®‘²ŒíÞP<º¡Lÿ^‡Èèj“%ÀŒ]C„Doý‡0£¦4)´yèê`9¼,1;ÔÓÎNöpÚü¯KjLc±øà7Çù Å RÈšÝÔõËeÆÒª{FWAm3ÞåÚ«g˵VäáHÒ\\hI¶2?IšLÆ­]ožÓä¦h™D)æL-4I¢-÷ý;nÓzíæ9ía} #ÂB7ÊBk6¢ƒ¥6d§ç)®Ý„š”§G‚$UÝLL7Ti½ÛRáWô/õ¬k’…üŽ)ν6è? {Òº ƒ#rïÅý9(ßKýË PúŠ‡mw¯lþ¯Þ 4šT¾ËC2 ü\ùa+WÉÀÚµW]š™„+ÓÝ’zËT%úÕÞ’‰Ä‘^½é–:MÛ{°IÂuU[Y˜fÊ‹ƒ*¨‹E~f×Tó‘޹镆>CÑNüæ8ÝšzLyHiü÷Eô Ú6²·• EÉ„¸yC÷Þ#´K‚@V/ilÊÉmîß'àˆ¾ÆÍCŒ¦sd¿7¤¼D’Í£ƒ¶îæÐ)¦Ù¦æâ8íhÆùû©b›Âå&¾Ÿ¢Fk½ï†ì­ñxZßÔ/]ª[×´ ¨D†ºíÝnпp±IÌ1¢™ç@¥ô‰gI"$2«%ãÍCˆ© €NrjY¾š¦^&Ë¡U Ñ<nqL´~—l.B d• AäQ7­5½6€¯žÍSUƒ‰Æ- ¿kÜ­tW!ÿ^ŒT½|®=–ß`~î-±#²Ml£a\¶¹û²úûܶ°#œÏÕê\ΪqŒýÿfùµ¼z‚)“ó¾¹x6U“LJ.3wÙÀpG¸8N?‹˜Ž–è³léï“$"$¿5œR\­ïÕ“ÂÔl©›UPÞ)ÅoO`¼„†‡SL}‘»Gt¤Æó볕î‘¥­Ÿ¯UÁ¬ DO[!®žÓXed¼/0 + +R/ ¿"oíðý­XãCJà¶Y¢þzñÇŸ>4äß  ¦Cf +endstream endobj 26 0 obj <>stream +8;V_W99R1H#Xk$=0X)FB(u;j.1]6?.lp2AQ'1&OA!1ZljK==Yh04^\6 +H.i5sHg:L7^(YuWOfRnS_nG>&rH(;6)E\>\*0a'Y@'Gf7B8jPI35bh>%BI7($`d&. +*)8Z?]g]VUaSMiqN5]Rf_NnU:f*IYc.Xd!rc0g-:$V%F0 +>;tt"Ld#(?W8A?F>Bi+QBit[AIA'rr,WOuK*h&09LXUst2i!c3E3O6,*('ZYLF.j$ +eWVBkSQ4,QBB^D]1kGi^kjE_>-`+]T8["mBf"+r[ZX$DpjP`q!jE;(r)LR51dm;U+ +f'V/IUu7:+[^QpLK"M"`*"L +endstream endobj 8 0 obj <> endobj 9 0 obj <> endobj 10 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 24.0 +%%AI8_CreatorVersion: 27.0.1 +%%For: (James Elliott) () +%%Title: (logo-cropped.psd) +%%CreationDate: 12/15/2022 9:33 PM +%%Canvassize: 16383 +%%BoundingBox: 828 408 1094 670 +%%HiResBoundingBox: 828.181602872553 408.941926138741 1093.03630192866 669.271293498627 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 14.0 +%AI12_BuildNumber: 620 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 826 406 1094 674 +%AI3_TemplateBox: 959.5 540.5 959.5 540.5 +%AI3_TileBox: 654 144 1266 936 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 2 +%AI24_LargeCanvasScale: 1 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI17_Begin_Content_if_version_gt:24 4 +%AI10_OpenToVie: 611.443037974684 688.962025316456 4.38888888888889 0 8187.03797468354 8267.12658227848 3030 1947 26 0 0 128 238 0 0 0 1 1 1 1 1 0 1 +%AI17_Alternate_Content +%AI9_OpenToView: 611.443037974684 688.962025316456 4.38888888888889 3030 1947 26 0 0 128 238 0 0 0 1 1 1 1 1 0 1 +%AI17_End_Versioned_Content +%AI5_OpenViewLayers: 7 +%AI17_Begin_Content_if_version_gt:24 4 +%AI17_Alternate_Content +%AI17_End_Versioned_Content +%%PageOrigin:0 0 +%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 11 0 obj <>stream +%AI24_ZStandard_Data(µ/ýX”ß¾èÄw7Edvüÿÿÿpúÿÿ8ÂNi”±µUWÝÔÝõ÷÷÷ÿÿÿßU×õQ:\UWõâÿ;„Z>-*£qðäáic$l3ÆЧ-­Mƒ Â0`Øf©ãƒâÆw@8ÆÓÂH¸$ +C Ñ5ãVc„Œ‚׬ÁÐåËcÔ\°ÛGb­>~6¼>ÜŒÆð¥Ö„계Ýô=>¡OV Û|&˜½|"C4ðãÊ?[)ºŸB#~ QŠñ}ANÀûÂÍz[äTÖl!û„`‹¥\P…ņ,ÔHi±ÀÐB2f΢qIÌ»}Än¥ðµ“· »mÀE i,`•QbªB†)ÙßÑðÁ Šš)f*Ò’T*·¿ h<*…„ Á@¡ H +‚ÙH¡±&Žbä‘ +„†’E` (Ô²æ`fl…Wå«àp“DqÐ: +YE3‹Ô”PðScM|DÇ“n‰…›¢–À©Ngw` ®µ+Ï´J$h£BB ´ª„j=%l´RB‡^£Äˆ£JÐ: „þ0h¦’ “À©RKb lˆ E áhˆ|ÂCi؉…nN”!›`}ª$a+0qJÉ †âÂH„.7E"Wv¼GVwàÂy›p„z8¥æq,cæ­%*ó@â æ-n©—g*¡Z^d°<Zƒ×O)ï; d+/AS^¢!‡òN){òt¨còαUàu8ƒä=ÀŠÈ[}%Ès’§¸:žÂíãxIã-RFÆ[)0 ¡\<ðÚ,^ŒUñFQôúƒÀûˆÕåð¼ÅãhÍ÷rÈâ½tu»Ç ˆpÏ3ÀØ?å²·XÙ3»z½RÍzglâ=$­ÐkÈ(H<*â]  +| jÊ<¼ZÅám,¥á}Ä0âáR¢‡—X€êh4¹Zq3Æë; F ¸œ*œ%ò¢Ì.,®pÙ@R(#C0I ß1`€VL2FåUKªËæ†"…ì+¦‚K/už·yž'@Iœ3Ïó> ÏK= Ïð+Ðó¼QBáy9] Ì °ÓÃó 0`Àw@€bM6¹H¼ FPI xìôpnI7Æ€¥‹bYJ‚ġÜ!±ÌSŒàw@d†œû§#(‹VfÁ1¢X0ä’Ñ|*Î`$I&— ©€r8æÈM´2²Gà`MmsËþiK†/û{žW:p"+#9áR£É\‰çyª¤’;¨'&ãyž'Šxž—E³oSJxžwƒxžÃÆæ; žçÁH~Hxž—pxžwË~tQ\–QEÀç‹€§ãbe Ïó¸”e{žçÉžç}ÄÆ´\6>áy^Áçy-¶ÐGÏó¼táyÞí¤ìyž7`”mÿ Ãó ˆç‘¬‡ç%n  C#Ë©F~€BHsþÕ2¢XJÍðìAêy" R„`¦ Aú•ÏMÈ,Š*ouñ~.ãyÞŠŠ&ÝË|¥¨Ë,M:ºšºÎÑ tdçtêÖttt“‰2@ƒ3ù Ê™Šð<Ïó P\ÑÁÀ÷B]&¹}§ƒ1“夙¥-éìZ®&õDu«f¡–;_f(Á¡®¦ªŽ&­U®)z 3Y]'iª0Øf‚®ÿ~¯¶3½¥¦ôÖýÖ´²Õ ¤Ú÷ÛûËlÕ2jzjÊ“Vvçj+ùš»­¹Q÷;cV»×™Æº\63-oª­L×îwÆX·æЙ µÍLZ«3×’†ªg×ÝÛêdªê~g¼±{¬ñN»Ûaüýïþ݆ž13í0i·êên'Í•C14š‰™ ½/¶~›h4“a&H_̱æú²¡.Ó”¢(M³óÞÜL7wœÍU€ fbú;óÝÞ¬=dž8S”ƒghºªi;ikíRÖÙÛÑs-KêjC5«©¶r&{]¶rUO2f;`ž(¯W–ÓtÆ™Ãü˜´†¦$™ë”Äl£é*5[ßPƒßËÕä*o#»c¶S¦ž¶Õí}qˆ;÷ªj¦·Š¹¬²ØY:×òVC1’¤¦æjÖÊ´$uÆÙ +3AXkßáow×Óv*­0”÷æ«×™nPê*»ßÑs-i¹Ú©v©y+oÝOÍU-KºæÆ®3:Vô¦¾Ê[ÏÛ«ÏÔ²vÒÊ”†ºôË\]&Í4‘Ó)›Þä·\Ý%i}\J`;k lç/yýÏ_® s`Ýùmý,-C”´›z’jçÚÐs=U”äèVßQB hfiµ(IwÞqìEæ u¶Ó¤{Üî•–hkMÇÒHK3ohŠp®'íl•«¦Ag +HMÕLI·Ü %uf¬ÌÅl%¨ëîíŒö†HH›ÎÖé0_¶NתådÝ¥[mæë|•éæ¥(×òU®f 0Õt¥9Ô$[_'¸½|Ûÿ¹Þ>Ô0€,vš2îýß¹óüq-ÇPš¥É +3A5t]Ѧ¡èeÒ]×ISSWÓ´š¦r-I“v«•*E¥†®jεRmŒkÒZåù2g.”fCmŽˆh5Mi)ß³U+mªÍL_´SæÂ5-¬TÃqË4Us͵Ît]KÛëjëLº¿úˆH÷0s´R€ùBmó…Úh5]Ìv¦«iÒ­¾*…R¤¥ =W×Ié&«ï€(×’|Ù2+5^Õt!.Òq@ HµH溚´’$‘¼l™Õè`&9éÉñJu·»D)ÕYÄ«³ ]¨³·@w»†ÎvžÎ¤:{@Œ©Îv—ç»í¿}ëkh»Ï÷÷kﶇ¶Ó^k¾oÇúßß¹þºs}qÿº‡ö€(uö€(Sö€uÖ¤Ýj§ir@D:³VŠ&Ýca¥åJ˜I&8JgjûLÕ¤ °šÖtü/[†¼ê¥÷{uh;Þom‡¯þxgìý¶]ãÐêŽýý[ã{³å=´Ö6{~-ÞßûìC{@¨—Õw@˜.«¯³övvw¼»îü·[wÌ=ßÿÚ®sÚ.wüýÇÛÝ}ΡíöÅz[¼qÇÚZÚnóo9÷}[¯³mwÓËêëôÞ|÷í÷ßã¾lÌ&wfk¶å—cžù¡ùæœwîùç#¿p 'y†k¸í·ãž»î»óÞ»ï¿ýÒ1ì™®éÖ_}öÛsß½÷ßþâ1þ€ }Æk¼ý÷㟿þûóß¿ÿÿÿò1Ÿü™¯ùv¼#ó¨Ç=ò±~üã8^FÌHŽ™Q3Ú˽àK¾èËa/Îú€Ð›w¯¿þãCf4Ún»í¾ûî{ïÅß|óÕWß}÷å—ß~ûõ÷€ð÷ßÇ;Þ˽\ÌÅdnÆb‹/¾cŒ3ÎXc7Þ˜cŽ;îüñˆG|Á|@`0“˜Ô` ¶Ùæ›oÆçœsÖYçwæ™çž{öÙçŸó˜/ù’1“ÉLæLÎdMÖä­7Þvg4‰ÉąĘŽ·Å™K~%-¦Û~@l«m¶Ùâk/ç›kž9æ—[®Ù™Mn̾ìqûí÷Á÷Þzç÷ÝÑÑ=j¯»æzk­±¾ÚêL&3&ÙçžuÆùf Îà ñÇs¬qÆk˜;^ùÕ7ß{56c1v´ßzËí¶Új‹íµ›û@Œ’Ìd†$3$†Ä$†< FòB^ÈOŽäHzò“¿“œÜä&5™/©Á 3zŽÑÉŒÁñ€8 4¤†Ô`4ÍEƒ¹Œš¯ù¯é®ášbk´&kòÕX&£Éd2d†Ì`2—̘ùŸé™žá™Ñ™œÁ™›± ™!IC^È‘ü¤'=ÉINDÂñºt¸³ÝñÐ]¬{™µÒf;9:Êj3ÏW™nl—îÉ®™«:€É¤¹Î5-I5õ¤¡­Ú&SÀ R_6“æ2­é¸¦£l-I¶‘©{˜·Rfê^¶z«¡æzæL]j¾l'L¶–$ŠÐPÔ “©¹ôÒ¹NÙ­Lc'VbR«i+i¤Õv– ´´•4µu‚d®µ€)E×ó•él©¹®e'à\]æMMM’£{Äl§«L :G÷X]fCkÔ½ÌgŠ®.uCi¦[¦–¢0“|ÜÎ2ttÎLKšÆq@ 0[ç–CÓíŒåh¤•1Û¹ÚΔdCEû–[MS ¥¡)ÉvÆLuµ™µŠyÙ2ßw@˜B¡µ!Ì +ÛÌu-išÕÇúú}yÿ‹ÿ½Ö‡¾Ãýu¦›Ub;cg:2c%éë0OÔ~™«—-€o®¥-5WÚh}ÆÇw]ÿÛÙlsçµïûÍñ ;ǾÓ;‡Ý_ßÙîûêŽoÍoÞØbþCïy§=×ý÷l³Öá½¼£˜' +5°™·ÑÊÞNcÊ[ XÁÎÕj3WŠYÙΘyYõ«¦æ%¨–ùŽbCÏ5GCU³´š±´4Xí[Ò44ó…†þí(&­t™ÌXZ‚V㎢®§í”š´\ÉZ­Mk:®¶iCEæ)ÀäùwœãÛi};½9íÜ¡Õ»Ûáßß\KÚ­fhnuDZï(ê,-k74},ØÐ󌙥‡í(—M©£¨1Û¹®¦ÉŒ•µÎªw3Vª§UƼ£¤f«–½hgî²Â·3Þn-k)ª1i§fµ;ãw@Ì\%íÒ¥ÑLUW®63V†:[9¦£¨)JC1ªjºÐ”´ÚÌZÎ…’ßw@tÌý×ùãÛqø9ï8÷ø_›y¶aþövWwŸ/Çÿêz«»¼7î[~ý U³tr:ïô··óVwûŽ"z‰ÙΗ-‡^¾ï€È>óÛQ̧ª–leˆÔåLùÆOöàÛQ̵$mèùx©·ðeÞnhê’ 1”æè(&m= ¾ï€x8ºÇº¢'–éT³Vz%E5ßw@ÜІwzª©‰ZùÎø}„ 5î%GŠ®eºª9­Óu”]K3Å|ßÑÙ0KÌú%&’÷ NŒB Ì‚ŽKD̘/#~.¹¬)‘A7r«ÎŸ‰ æ; p¸%‚·«¶6“ÓjZKºb„$sB2>›|;˜©¦Í00j¤2B’iÐçVÀ J!³FTŒk#Q‰·ˆJÑðfU‰ ³7Õ& +d”AºuHn* Tò*óHß‘cD°  ’‰tl¥¤)›|¤)›\0#ä^J%Ç!Q‰h(òeDܨ ™K&l¾H¦ÊÁâXÒióÅï€Ð4H"Hªèå EpN¾o{ì¥TZL ”A*(™ôÄÚ@ç–¹§Èµ¼71%`¼ì¥TÒrÌAXÕ%ˆCzè4)è4ýŠ7¡(ÎÉw@(B`ÁJ Û¿Ielª@äÍ—Ì1 Pý\Ó$Ô•VÈqœBÁK50¼¬\º0iG‚¶ÉRšSód¤¨©‚Áx}Ɇ¥Òeè} +^p1ÐØÉK“H©4ê |Ù\ „DÐÀ‰”D)ðj&1Bî£EpN¡(‡ Þ@šæRÛ°ùÐ$v;)8^„¬³IOìÍ´EüL.Œ+¼`¾"È * ©ê ¦±N,ß-‰ÒËc4ÀÂNÅÄ Sbš„¦{É"ÄcäL†dp§aAↃüØLJ…~Ä^i&ööÀx›öa/‹H0¥ˆ¾P¶ò,½Ñxõ; RFo¨ŽÄÊÖ DŽ×\n +BÁ ­pIÔ ¹´â @Jƒã?®³êi€ÃøŽ¯Dk:1yO<©iÄøG^pîWS0“¦ž‡ñ²ŽŠ ñ3’&M=o a‚M: 3¤ßqšÎKËiÅ-¤¬51¢mÎ%&9…«^Я: +B ©‚*@Ût½ñfáqi YåØxÕ" iJxÑV¼ñ oãcªBª/ûµ 0ø„ÓxG'‚ ¨뀀a3> ªûxx&º¨Ë“(ø\“†q¹ŠV³þu”û ïw@¤+4})äÏJ–(ƒÜàÈ›3 Š«‰ôÈÀ`+ +YàÄ`¿‚§A£Ì87ÒÚJ´ì—Zp@\^ƒÙI'áÔŒ!‚‚=¿b¡+,I!à(‰ ³Þ¤õ0P’û8…iqPyTãƒ$˜ñ²b&¡<18(¡Š ”í$lÖDIàP–“ ›ˆLƒï€8W‹ê iÍ}$¨N!Á>Ÿ‡©c`u‚#d1°a‚þè Wl ¨çiKHSŠ†á¡ñÁÁd1ÀÚI¨ßaÑF–¡Ôql¡Å y?SMV ‚½ «¡¨‹õÙ[g¼¬®\tÿÜŒbÆËfÞ°ñ›ŒÉ¿²"‚g È hf +™[2Ípå 6©°ÕiX$›ï€@±"T3<'Z +£rÓ$TŒ¹*q4và‘Ú +~)øhìw@ˆ¥¾à¯‡È~U!  +¤!ce¼¤Z/«á +/ij¨9e2¶@• d,IõŽ3ÔÁÔanQo e‘Y"}‹ÈF„ +ä; d!]Y@dI)4Ðv/«PZ´‹•û“žXG<=8±·(d²sDã«Ò´´ ªv T!f;&ËÂ)¤bU‡”ŠltÁ5¬ó±'ã¥Æbµ5o#]m ÈøµµÁœåGZx2^"©è¥ÏR{’:MU8±ÕõÀ—†Øæª#Gä~,_h)ÄJ“†Cv3¼».ÎTÉFÐ@fÌ%ïC~g]Jåmàq™Ö¹ Îi›-‚7RÅxë£ähò»N,&”´„Ö½œ6eäâœ1” ±.9¯’¦sű"kTÑ4È …„f G ×V#„ĘQ +š”B¯Ò˜^NÐ ‘¯Òè© ø; TÐœ F£§°aR•½Ö/S +ôCbqlͳEPâ+d¤bùt±. 2°B~”Í9[ƒ@â2-ÚþˆÆº¿ì¢1õD÷v@ +ÑD!¯šŒ Bã¥á¹4ñXÓ¸7Ú ‹¬êï€(x`¼më#ä– +!CÒ: £ö¸„þVdü!Òe ¦N,%ór!Ø°>g«“pFn¬xXKÐE÷yÁÚðˆ B“‚É‚ã™d¿¦‚‘,©‰ r£™Íy «„«kE•…‘%AIÁ™m>Œ¼¬•,P)‡À‰Í«¬NBàÄNZ¨ +ØY[ˆUÓàÞÎ3UÙZÞV1Û) ™´Svp+m¦kÂR“D38IŸ ²SEmgס¶î_º‰í•0Ýí¤a^¶r”©å­¬­gëv£™/´öº¡ÓÛí¶Ð»ÚÌwWIk¥&mUÍXY;Ãô†ÞRš¥­j sSÍÝ–+TO3VÞ, +Ko´W¸Ú`¶•¢4t@ŠÊn' ¾R×z®-´á¾Ò4œÕbÖ´4˜ù’ÝJZj +XM5To´5„ÁÐ4„ÁÐj.ÙŠ^Z«´™ix …7VWxÀ\On95¼ Pž«­ o .×¥…ê-¼ {ÝÐð&€ÍVÞš+ÄÎÿå˜L§»lJªC€Ë–ƒ…júJ[©+œÕbV5mkIƒ…j˜Þnaz»]ÞÓÛ-5œ)Ù Ðê^¦í„™¤ÃæZÍÕv†5Í`ÒBõ–š¯R¦†êí&@˜Þnaz»¹Ðna m(c¦-To&­t©á+u¥4—,Œ¥høJ]¦zC-m€U gµíÕÊ©ájƒµNš+¼ pmèjC]¡z{¡µ°æ*m&̪!IŽNà‡iù²•« ×ÎÔàÚÛ™ºT“ m@m3[®SOÚ™j®£•6[ìTMÒÖéÔ²“¹rjç:i·[Ù­9t€’Ö•íìÖ³3]%íÖ¡k÷2M[—CHÑ.rv¶³Œ™ íl%íÖåÐLU=u¡†$ÙÊN-;“vÂ:[ÙÅl§€Ríl¦ Ú½:S¶vfZv¦jÊ w––¡˜Y²øP¦›t´—ÓÎÒf®ejÚÌͽ¥í\U“€y¢ZæÁª–÷Ýh§©žð,-C©iMÚiÀ7 +³uÌXI²·[™`“vq¡äJC’ty±á˜í\ËšºÆÊtƒÀLjCCú„«Í|u^6ƒ¶FŒË\Á-ÍRk:ÖÐTÓÍZ)ê P¦×ISs4—­ƒùÎçÇ”4kh*s¡64tM uu ŽóVbb¶s=_™•†$ÝÛ¯I»+-2”&“‰”qd‡ÂlêéVÛ)`¾RÔTSS€™^‡­¤µnçLµ1[™š±’F+i4ԶІÉD-OÚØ«m䣮3Œ:)cWµé›W¯“V¢V©yÂÎÔD­6³–s¡¤†$9VßéåZ’I;ahJêV›Y˹P²Ã·3::Õw@ˆø°ï¡n:d•¢BKj†ÙKeç·E–Ç}„ÇÑke"Ý#‹obK†dŽ]ÃA ìÄeS¸Œ­ñ ›Gƒj5Ó€¥&ÖR‰šys*š/È ÐÊ[ƒ:ë#‰š½hŒ?#èÄn 5PÁÔÐq‘xÃw@4@"Û™@9œ}¦éŒ&CÕ&$™€­ ËPµWj]¯†X„¿ÊÎu%\ÕäúÔ*ò®R ’¶H¨ªE"•Z¤N®4‘,åÊR)ZEéZX³kðrý`²”kÕ¯£³ÊœNáêé' Á1(x©:Í]™ +N -ŠH`á; á‚· ÞZ + +ç‡Qð\±ÅðJ`ˆåOD…ÝÐ#SC@)„ +HFA€¥‡àq‚ªuZ U}ÁU®Ð,–p€£Tǧ2",=H|áà‹ß¡M—ÇAC†C…DYu 6j&`ž +,&„å“p9)P.È©[c#…d0P1ð BÂ3¸=F ¦Vi²1æÄä9‰j¥ÊÄ£J½!WJ–4q”„|Äçø£‚ªñ9Ø‚W°2¬+RN¡Ò!)J&5fÜ(’K$Œ°e GšP8"j"‘bˆ2|Éby—†>O!ÌåC(ï>B (26L ï€¸àH•zh=²Ï/ÍÒÅ€@ðQFŽh¢dž™É*LÑ#¹‡'Ýü†Æ•pê4<cGüD:1¤Æ3²g–’Hæó-'}€¸MÈõ-l¾=:/Ù‚Åۨ먥9ÍL‘æË&µá ¡QÕ gfôN™Ä_2§È˜dL!Öe dŽ<¤*uò•K-HÔ¦ÃxÖÕ„AxÄdˆ(Ä|èJoÅæÂpIíís©å +þ¥a6иÈÊFÃ;ˆŒ1Õ+3ž eg Þx›Õ^ïs˜,ÜGËd3šX~yK+dDSVH Û¨²ŠÄÊ #‘T·ó&~D!¬Ää#Z$˜~61oÏà³@­\²RDðxADŒª"!`!Àp_t\2ÒÀÙ€± l…ÃØrhx^ Ò@@m¤€fƒÑ(í³ø’Àà¤Üd¦Š²©$</¡¡P +T'„ð·¿°0Y@–)ø7ãòIl)~ƒåsz‘€ˆàõóñ7gÀŒB?¶^j‡ é«Ï°ˆê©æ„æõøkHg¨>ŽÓ´_™JÜ4¹h8‡u=¯\ Þ!ܶ1‰k?F“Óþ0˜ÍNôƒ¿WÈ Üê"«Z]¨L½. )UÍèĬývtÐ>jÈ–Å_ÈžK'åkc2ë¡y¶™ÈGn(@8ÜMæ oBH +«0LË "'îÃ(ÇvQÌm]ÜÑÓ Ù²seÁ<_hL|‹hÒ|®›ð Ð,¶Ì$Œ²»pðw@Ü8Ü°à\U~­"Æzx#‰—x‰p¡AñLʹjKÄOÖº8Çm[8ë^›L”' M,± +‰ ‘`¾F*1‘ûß!R¿"&qÝÔú27Áï€øˆ ¤ÒÀ¨T‡—ˆË pžÌ«´øq+¾Æò—‚¤(ƒž@›2G¬’\í¶¹`¦To §Ð$Œ¼ž#0£žhf¿âF“xìç2d×öè$áFîw@”< Ê&¯RÂX±=7"¹@DÎw@XJ3€å.¬+ÍÁ@’ø€‹ ƒˆ^m…ñJƒË¤Á8#ØlHrñøñ; P•žQvS'›°9£B +EÛˆ6‚…!ÍD\>ó-œ¹˜HÏ&õ6güTÖ‰dºdL7·78ç3_¤±.ßqàœÑÂ9gü!Ò¥Ç*›¡ƒ=‹ïA¹‹&ŽdI4VMÞ\D,¬IÀ´næ0òì×WNl)¢¿bÚFôh^b“4V¬æ¾üªReaMp6Ë,Ã*3–’!rßQj™¶sUxq‹A¼ôe0ÊN0£*¸Š1j B¢TÒT6⬌g°®4ßÑ!ø ,&ªÑgà =ãe=FN©ßQàpÌ.§™¡XJ Êw@X,ˆgJ…"^*qÞg&‚¨1‘x .â (‘G¼Kè½ zx|Å  ˜K¤¥áH´èx™Y2ù,M¾„¶.'Õñ8:Àlk¡3‹ +ò!9 ‡Úâw@0D +˜ø P*/Ìw@ˆ f6õUZSÕ'+ duAœÓˆwRž Cn_j#G‡'y¹4R£žµ9NFœåž$NFc0®HL¦(à2ËbÁ=ë¡`q¬€6M(ëø +¸­N•‹UfZ$&S7Œ,ˆ|é¥cV¥Ô‚K5P–”¡91Ô¢‘ ( +džŒGtDRŽC“û"$(ª®Œ\$V ¤dcÁSչФÁˆF'²Ò´l0LÊ*…äw@¬d +ÈÊ…PëF´I!sSÛ'›àBMeÀ’päL£‡'tHGƒ€ÁÈÚ›Ô,XH£‹T-¨`q¬-´EP|`öSL,˜ !1$õ@Wb6±*‚‰Å, Ÿ,ñBÈ„²Ì€J\Ÿ¥ßP=$lÙƒ¹)¸Ïþ’+¤æúrc2Bî‚4e“‹•™z6tžBM≴óá1H¼Ä‹\ £ÁOºÀ‡ô<¯UÄÓhè}„Åz¢ÆDâá1]ˆÆ\ÚHìqcîÐ6xl#‹v…h‚Rð¸iX˜£9Uòw@¤£DyÎÔ“t4 U*dnÔ%“Ómb|MÐ1±¤í{YPm!ðƒ(á! [Øüˆ<·YRÜâ$3éK3 “mö‘ŠÓ‚ÂT‰II3z%Ü¥ñø™‹`$ЀF ¹ª¢‚¤–w¤Y‘,Ój[D \h‚]9M&éÓ‹­ƒˆÇ&>‘‹IŒPÒÁ—¹°Ÿfô\„¶PÎcåRÈ™jh_w>MáM~"ñÍd ÏÆDú.4¿ ¥>Ä‹!, ¾Âû"Έó:%§éZò«\Š²Ý\*€*¨é$“¦i#IJTfÙ5—V–b`°£DkÁ>Në@IlŽ€ei«EY˜L=YÔÙ1°ßñsÈde&mdc°È®D•ü‚¨Æ’¥H2vÒÉXtv€ª’Àøq¢86„žŒÃÐðFÈmx PáóÒ’dšü=ëÄr–D…õ6a…m£XirZÑ4¹r[<°€åF®'~¡ñr\òìCqs„†¬Ð@ÌÉr²Ó!¥š„˜$ÄÀP Œ Xºz¤RéÊ:(’ˆSÀ)¤ŠV¢¼˜o•(/&qaö yÜb0{SÝT›|S¡R8S3Õ´³Á´˜ñ²ßŠa¼l#Nl~¬J3×HÑ”2¥BÇbj¤Iñù>ß©’?7Ê©’ (Ÿ›·ïTÉŸÛçQ@©|ýTÉ”Ê'n“œçzjžŒû‹œçzjMYxjž…ƒ²ðÔrž»(hÐ^¥.˜ËX'«Ôs8.u¹)Ò9¹)R¢²VVqU%.Ì¡)5%„TÈ\K*dî-¢3 Ì0HT† DTÈÜK&@$d„L 1™@âH’ Ž4§©9F…r/²=Jep +n«åj/Ìã›’‹×i¡7 ë³bE6ZÕ,¨4®•˜€•KU„Ú'r¼)S¨ßaºˆü˵ò\†‚c“¦¹ •þˆ‚CV.e$¾âSpBs|ú]5e,>(‡ß)‘Ϻ@ÏÒ ‹x ²ˆ§úžÌ÷H<†A/þ o^OeEC›×Fõ3¼yM©É¥eÆÛˆ &ßn•˜aØ|‘qSmD0C*dî-¢’¨2 ™ˆê†QÈ\[D%’ L€äVdB¢A&@Rœe„Ü[AK#G„ñ²ßl•K=‚QÂTŒ^9‘äž"7‘®MBÍ$"ÞÀ‰+<WxbjJ±›²…šÌ>ç,hlLuƒX ²­NBщ&–,~Áøˆ¬J7›ímTZÁGü¢±MBá1+-ZŽºh¨vBòo`†ˆ{õ‘x˜™z¤×*âå Ïൊx&TÄ;(‘ï +| Þw@¬$^âf"è™d¯/Joõ ¦©¹Š5Öºd ¹5+šY‘( m¨…;Ž44 ØFÅbEî¤Á¸dÈMm©@FBu 1°³9ÄÀ¬'K]°*%Q¥.¸‘JIP ÌÓÕæ:(0ûÈ­5 ˜8(’Ä…ÙkC‰r†å„åM\˜Å)lp +œÂF<À%¸I”×€Ep› +…B¥: +™‹Á5`‚kÀ,gªi¿‚De“I(!"0Bnž©(j#¢¨ Š:¡”r{„\ÌxYŒAÊ ezÂo^ŽÁ9ñþ s‹òn^›/n¾BM4pêgbwüßØúïsxõýXc1îžûÛ¿µ^εåaæ¿ËÝkû1ßXžù·œ‡œ{9¿Øÿ1ß‹ûíüî{uöÿc­±îž{¯ïŘ_ï½Ùãíå×ë»CÛ·÷¾s›­Ï×盽¿ýÛÚþ;û½¼÷­³ÖÝ··ó˳·=‡þÿÎû¾7Î[Ýyí·ïøþ^¼ñݼcouØ»î²Îwo1ç¡Ïöv™olý µ×ÆÙöûÏ6ÔÚÞ._þ»Å}ãëó¾^o»ó ½¶—sÿñö˜÷þ¯»ßmÇùîü}‡÷µ|gÜùåÛZw÷ùïPo{»»õ½»ãžõþ7|µµ=¼Û^‹m¾vo›qˆïîzÞ×æ¬w¾!×övÜkæól{¯¶·Ãßöß1ÎöwÛu÷>ìÙÞŒ¹÷û[¾;ÞŸÿêlo×÷¶Þû¬3æ¡÷7sì?¶·ûØæ‹/ï·÷ð{Ýa¿3×8g‹Ãí½çýCìuÇ;öó«ûýµ·ëÿ_}/ÆøßsÝeÌoÖ·ûŽClíízßÿÚk}·>ì[wÿr½µÏ—ÿðúìý¾ù_ýyè·î0ï9[¾»Î9ôûwý{÷ÍÞ{þ­;µ÷ùã}±oþÝö9÷Ë¿çö†·ëî~m¿ë¼C{qöšó­wñ×]ç¿óûß>Ôìs¿»ëÿvÎ}ÇüZ»ýÎߌ³½™g¬uè»? \ø~œÿÇ»¯5¿û{Zï;ÿ3î<ÿ|-?ß]þÖòÛsÿ6‡ØûÎ[m¹»ß]Æûoî3繇÷wÞû׺[ÌÃ{/Þ×îËCo§½Î—gì{Öœ_»æ]óæû;ïæ;Û-þøïúû3þv_û­×ÖcíÏç0ãßíþ׸[½s¸/ï6×=ëë;Î<ôø{Ÿy×Öý-×—onmh³¶ÛßÿíÕ¶‡óîïœq¾˜Û}ÃŽwýîc¯ÖáÇøoëï÷9Ôøwýê¯sïÚbÚÌ»õå_í·ÿõ}¾?ǘ‡ónãk³çÖî®C}ç-÷ÿÝaƼóÿl7ÿ?ï°Ûßeëûç:ü—w»s}ûÇÖæZûoïšcmÆ7Ô—wã®;Æ›û¼ûçÜ{ö¡ý»Ã×z³·Øîýw¾÷ó­s/ßööïÎ;·6ôÛoŸ±î^ÛlÃŽw‡-ÆzcŸ?¾!æ¾ë7ã­ïï?‡ºëÎóÏõÖ¡ç¾ë8{Ëöß÷ÐgÝ錯ÕÖú¼w˜oÇýã½óþ8´ZwXçnùÿÙëZnû= NâréìûÛ~î7ç;‡ÝòŽïÿ;ÿ7{âoïÅuétïú÷kÞy{ý¾ß~¼ÃÍo—ø»}ÿ{ïm÷ u–t˜ÿ￵6ãðþ߈ZªÃøó¿·¼Ëzû›ýýÖöpcßiîïçöbýmØó•tßbÍñþw¿ýïgn·Õøç^I—¯½!çø€ˆ]ôç9ßß³ïÚÚw¹c­­ço¯5­¤³æ[ã›?Ç^[¼C+éîѺ˜nwßwÆüjï1þ[·å¹Û®wîßnî½»ìí½þÿÿ÷w×ùZ¾;Æ:Ä{wýn½¯oÿ]ÖÞóÿ»ÞkûõÝÛó»³Õžwë÷ç>ôzwþo¯;?çwoí±æ{ãëÝñïý¶_üÃÏç¹ÕŸ¿÷æ¡Î»Ó|÷ŽwÏ=û÷ßéþ{ßöZœm˜ñîvׇ»ó»ñýº÷žÃ{w—¯µ˜k­î|÷øb½qî8Üvw>ÿÛ±Æwëþþ»žy¾[ûÛ±æykžuæX‡¾ûkÇßï}è¿îz·ÛæëõżóŒ÷ó×]îzÿì³Íú÷Ïñî÷ûýu¨¿î6Çc®ÿÿ<ÌkÏ}×YwCkwÇ»ÕV{Í­ÿzßìõµþÛ¿oîøßÎyç{î;Æ[‡Üîîrn5ÏýÞÎCÌ3ÿ;çÌ-íÝ]æxÛï=·Ÿëîµÿön}xñî6·wßû3×úêlñ¿ØöoÃœw÷µî~[¬?·á×ûâ­3ç{j=ïß]Üù×úæîØõîxÞûëË?ß?Äûwú{¾±·ŸcÚ½;¾íÆÙêß=1ö=w®=¾W‡yï.sŸñÏóííÇ6oͽ½áß»ûkË÷åü†Yÿn뽶ÝÃÎw÷µßçÞñ·!Öûf~¯Å~ûê¾»œqïcÜï ¹þ×<‹Ãëw‡¹×{çí7ÿá׿ËÛbÏmÿ¾ïPûÝqüsï{{¾Ø÷? \ÝÿÙvŸõµ<Ä~wÞZÏ»ÞX[nþ»Œ³Å÷¾ý­ßöYßìóý?‡¹ÿNkŒ{æÜ[ûÃÜwçï·ÿf¿÷Ρï˜së½¾ßjn¾»î-÷ßÞq}ÿÙÝ{Øéú½¾sn»Í6Ì]w—÷›±ýÛ~öÿ;ìqîwÿî5¯Ýîûãn»õü€puWó«;Þ›oŒ{¶kûwÏ}žñ͇¾ïnûŒóßvlowýþÖç¿yÎ{Û{¿>÷òÿL×æ~g‹ýçᶼûøfÏ7ÇXóðòß]®³Í;knCny×ñÝ×s­}ç!Ç¿Û¿û}9ö_÷°÷Ýñm=þ>ÔߘŽÿÍsç˜Û­ÃŸw×í¿vg¿ûåž[Ïw·÷b»;o½þvë½s¨¿ïþîÞçl{çÖò¿ÿ×ÞëPã@Ô:ß³çgüùq׶;[þñ¶áåÿ€ˆuöªc§ˆ$w@˜Huö€X}„ÀšŽ+Û=V;[ͳÏûû1¿¶ëkûÕ¿w»oçÙÞkûÊŽ¬:²sZÓ13vö€°º‡p@´@íìîl÷{÷{·7îîMÍJÐË–Y}bT‰AJØB[üˆï; &š³·ÅJ"Äy‹)ˆ hNžà;aq¬„IdNHÌg“PG¾"ÂâXUÊ\êpXr„ű‘H$ÂzD®}’·‰= \h’ðRñx;m.è’ðÀÊ„Áa?$edÖÀÀ"‡ +ÇrJk×Ö‰õ¨PF£yxĨP,M^Ø"¨c!F¾ [*´ [íèÁÈá ”°0<~$ó™h˜#ì†ÙbFf„“³°E˜ ¸V[yM ƒõª¢0lDîÁÁÇBKíÁä`‹àS@âW¯XdÕ5Ø"hI/„̹șƘGXؘ Òº/ ‚ ç/FE/&¯ó!A0iüH,¤]J–Êl”hɧ+N>¸î-Ø"è;×l¼W("RúÂ)Ø"‚±VÁÁ\ªpîmÌ DzàÜPôÒ±Íýˆˆ¨å8m ¢-‚Üesc˜ÛÄì ‘Û‘¸@X®ÿñ‘5"×N4{’&¤.¸A°'öÖI”·Ñ·ãîF¸'v]m ë$Uí´²…&Ýòx¶dH3Å×¼Ô‰%ñˆøw@¤J›L&÷R)Sƒ@æ0ÓìÞ¼jòB•¡X4 $ #Lø2.w M)mâ‡Ä‚m!ÿtÚbãiÍØF˜Æîò‰&¤òãÍ#D±pr±“…srlîÃ/¸¥áùd\ä>´‰Ç’(šh2cy4ù; @bBo 7^fˆ À5ÍTƒ¾l'"ÒM:œ»ïpÆý€0Òf‘Œ­"Ð ç‹ë-‡[m­”‚:k1¤²Îl!ÜZ-“ ÕðT¬P $r^ʳ©Ö™J•©RS×R¥V*Ä*•èR…8¶¦J¤$šúˆIFBq˜Êb"¤-ÊtS@`@U$ŠäÑVSµ ¶6 +8…j!¥b$¨Úór ªKš™ ^Š&ü¥%dÑ@ù1ÌÀðBÀ<.¥•ÓÈw@$ÌÑÄÞNÓÙ¨g%ágÅ÷þZÚèDy1‹:lêX'gŠˆ '¡¨¹ '"‚Q!s±("‚EƒÃàäpšª F`x +õ¤bYD¡cM•4M H‘þ&;aZNÄ M%Cëbç\ѧµí´±-uK4›kTÑ e&@›ûÉ: ÉÕØ´ möC8±ð‚Xä~¶J@Pä&¼2×A¡8/ªRìÐâÄ2ÍþlÄÔhóų'V‰lg‹`d¦šÖÁY•¦-3•l÷¹™º€!&‚†˜£‰µ…6c2ºá"ž™z +ŸR“7ÙâºýØ–Z²¹šRMH ×mP: Í…Ü…>:¼ˆCÙ’À˜óç:8øŒœ*ò…-‚ÜxlWWŒü¿KJHP]@|@4¨uë†ubq%‚Ưubo¹N,ws-Ãê +SëÄz…§]F.ÃÀ ¦¯Í>\ˆ…? •f•=Üʯ™ª4p‹a–0›¤f+Q°8¥™~å²5±(î|3´Z6˜÷¨4tµÑPV‚N)DFfddf›$Ó ‘J&÷¶€M8(P@T*4 Jƒ8( ˆ„±Åa EQ +2åÔ• ÀolÒ(Ȥ®$Éþ˜Š#U‡†3§®rMkadFöÉ"¬hzˆcé =êØ™¦†øÜýG· ’6ž p5B».ÀDÖº;ÖmÁ`üI›8X˺üš‰W©¬òÂ\>°Y#N÷!§üIWÈžz´…™ òHbâ~>Ç#.$"\Dfb°àHŒŽ +Z–/8X™óèÑ7B¸ØFf?›\èoMü$n#Ò ÖFœ«§–ZšoßP©¤F~zEaR– /óæ·BíwùÛžÑñFÊè%Ðh*<7·Ü3õõY9€ž ‘¨tšZâú;kž °a‰|X’áÎ;Ž )¢A屶ŽcGbý–ÄlÁ°Roñb¡æ½–pßt8uç®:CåÖoø„°®b ƆuŸRÃ:Øoô1dܵÄ“ As•h$!MQ¬ìD¨ o²c‚A8j({*AˆÃù°³ÎdwD?*Zg2‡Ñ´ßçi‚–Žh‚U:S³#šö¢As&s#šºAΔNÕ Þ¦UÌJ‰©œå¡»‰”ªœ^((N¤¼ÐÕ\¢r²FÓCiBQªœÐ?( «îâ¡rš Þe­–˜{x9¶GU‚Ãtµâ«Ê¶~ÝŒúÐî CwSŠ/¢ŒÆ Èx•PÛ$Y+d³= êÏ=ŒAl*¨ÂM„Ì´(rqUb’‡."æ푵$oó§øÑå98Vê˜ß;´6ó悈¾È“t›6Âl +è,4ÿÓ ++‚æ 1¶ZÝH¶ˆ£€Ù *'ÁÆÊcxh&"½ô›»µÄD”©*èåf÷—ç™b:€ö’#÷AÀÜàñLªl¢¹g&Í°uQ!¢ÿµ~Ó¾’¿Iô¾uzàÓ P!kNó´J? +oûRŒ N‰ö#«^bŽø/† ȲŒ>…n:xñ„’"‹J 9>ªp¢òf*•±ü_ÙŽ`ýÇ;žÍEàÍIFÏd6[–{ +Õ–±Ðªg·^üW‘®ð0(1ÁyÏß(\È@ >o:KñùS17¥`QOÎ(~ 8 Ù)8w ÑjLfšs)^B•{€QpçÚ÷¼q'-~ûÉÕÊe‡”ðç-ÀoDDf¸„PªÙÁ»`@°¦Ù7·EÆV÷Ñ7$£Sj?•»«ß‹£0‚öaQî+M+O¬Ç9³d¬l§}ƒ<†ÃœCq½Q~m5"è>ü¢2± wC+Cšºm')UˆðGMÊ%åÂÅ‹À.…«¯ÓUßm½ä0?å^5Mø$SžµË‘tvüÏ% ÔÅ9 ‚ÖtÑ«ÒXû™m©D4I !ýxTк¡bsy¯…ÑnË&ŸÿåKÀqý¤, åàL’ᶙ1D•ëøyƒò]‚™+ :ú"W¿ï’(t.jôY ‡®­jºÞ1P;¥ÿ¡Á˜BýHõ;Ý1y"i2¢J µ…#ArFá¤@…RÔÅDYÕôªj2?VST>ÌOcj6‘ššŽ„!—M¡â€0~èÒ|Ìk&€õè¶` +Àdò•ùËv^¾ÅxJÂJÙæ½òv!ð#·ó³ 8`jh(*+ºëî'D$‹6X8Nñ›ßGðpº¼XÆmqÍœ‘ò­¨¬-Äq‰¥Ez¯H·LÀÆEùL‹¬çà’¤v1ï Ž-ä’ÄzšN +“¾2@tQÜ?]‚%„¸ýAïË}-—‰˜ÇÃÖÃyÔ¨¶áû “|G™.Tõ:ßFiHÄë$§¦4þ¾ÓÔ§ «X´áyuQ—ܭϬ–‹šGDÁ€ô[œšAÀS^j2¯cIÎFüÐ3ÒžkªHÌìÛT鳌×ïAò7X;³ +MJRöUS~¼Î>§÷õà„cÇ{¸«ƒ>qjáUÄ×ÔF&¿Å"/8ÐM‰[œxA†^‚§ú˜OÿCè6¸j|¶Ðo‹cz­¬;q7$ÕŽ-ñHPd¾2µNq3MÜ™tÒJ‰=„¥“ÊèVS0Ž…i‚/G"µ h^Ò¯·±÷!IPoî¥_ŒÛÝ}²øŽø‹ƒÚÛoÎ'. ‹ÛÞ)6&>öKæ¾ËEê+êÄ´¸½‰·I·)ë}Mªd¢äÿ=¯"äð¯SèZÒ‡o¨ÿfÌoØqn„8X‚ Ðí7ˆ®D0èþ‘IØVü{uÉ\á0Y¯PN8w/\aÓõÒ<*J~ÖŸ¼• Ñ,$—KÞs@æÌÝÛƒD–[ˆðô +€µ-‚˜PdLz]î ”p-´ýºÌººå)Ç|Âo2jl¿´óçÁâ%° Â-Kó&¤n!ø¿|{ 6¸vTûäïÖ0ÝÀ^!õÍÖŒ°÷i”vƒÈ•71…Ûê2èf´Ì,Q._£¡W‡—§¤ó6 !I2LšsW_‹'´p¿ÞÆħºðG:õ>Ã(yüX×Ƽù‹Ì¥.—æýÝ >€¡Èü;† ,ëAƒíÆTC@'x]£ã¡üGàFW¢i&]ç èsy§UçלŠ¼Æ:~.N™ïŽó +&‚÷kUVì­|ij·»"O±{ ú1Ë2Y%~»›ÜÞžÉÖËoŸ©¹ 0.$škß磞Þ(EFšFŒ—6QiƒB¶A|dÐú,¶RàjžõµT#¡þz \¶×­à[Àù1À:Ï p)Þïÿ‚²ü“ô¦6-SÉñJõ‘¾;è–Ê",Íב¤n`« ÛDrœà]·ÑìvyÓ|-¾p~ð±=\¾+þÌ9¢”ê6óÄåÎA(2¼±î|>EmÊš&E%ÌDrïYQ ¢)Õƒ·tcN²\(âŠó>CZ¡œaãñ:ñ;ªpj“6H–œú(Ò/ ʆ›TßÉ' {›Aö ù ¤ +à™͹Šï6Í›l ÊfÏÈÓ¸®e#4.Ðp¡·>´JC+ñD>vòéGõ!ž:fœ!D‚*ä„kïs ›{.ÌÙŠÛ=B%ñ<×W]Rî{ÜøG½Û=“s»pÛåSååpq†.ÌîÉù7°‚º?\€[Ñd©êÓ–#j×á0=¥>ƒ ý³$$%eRuí„üÐ2בɷb¸ñt@놲Ç=åÕCRt þ¹®Ø†út¼ì½ +p¯uxçEb;9¼·&I)>Âz™µµZˆs‹e÷]ÖI?¾”GL³ìñv]ñ»^›c€ŠŒÝzèjÀ¡wÏRžv5‚á£%à«wA1•0#8@#ü0*ò3âi“&Åûã:#)›z9£J›„^N44²\‹ÉÃqºÈ=à¬I*r¾ø6 öæt\«ä !šO‰4 ÌÓéÕã2ö°Ïþìot ”Zd?“¦[=P®ˆQh{¯¬Î9î«JÇþ‘ e¼­&r%äÖžjÿŠ)‹„)¼¦gDÅÌ{1~ÈÌã>šn?ý¿VEÄUž¢ ·jƒÂı¤XI™Ÿ«Š]3sæb ³ ;Œì Òx p›ÏS#¾¼Ô"bÝã…ÌaP¾Žó]}Wé9ÿÅ1ÊkuÂÔAîôu­P¥ž½µddY‹ÖØ K‚oï.|c[™Óྫf.²].ÒlÆ/þ»Qê«'@€nKûvÔyŸÎÍßz­œÚknozUÚ¹ käeá^wPÛÉ­*7XD·M +#þ þ§:à +†êÊJ Th!^ÈBâÆnؘ V;FÑv²W")0>²ÃÌQ¼è…m-(θ·1÷ûqÇæ\w†ÑÀæèo!‡nÕKÔ;æš.ßåÍÖBì³…ANZŽÊ±í›ÊäÍ #[¬‹€…2ïtí‹Üš€Îo£ohÈþ`ùþ…`ÊV¯ÂLÔ–dYûü#´e¤Góõ ÀaI1̆m5*:DPµˆ%%?œ}>Ïdù‘{I¹èRJ;ÑÀK³ª]Ò×nŒå,©txKâÖâdÊ’rh}‚xL*¾¤b'J§’€9%K¬´Lû—·Û¤#UL1L#—ìC æYp'ß`g¡âZFs˜Ÿ¸E"E—ø4ÀüªLMm„Ÿù> ©ûg†(,æ¿œ>/yF +ÃŽeîçdb¥±¶ä¿ðsÏ~„æ}Nª,õ9f9y)¡O©I«¾ÄÉ™lpŲänLz¡íè1Ø@Ÿ²¬>…},²”šuJ¸3X‡¸`ÙÁÓýl8²ÄöƒYØž$Ët>/e³L€Ábô,REJ¯9´X@.-|ª”Ú³5„}ã5ÒÀÁVÊíÈ Y£ZûƒÓ[Â.AfÊV)ÁžÞ/|lé—–-#½vÇ:â扒µ +&À–"å˜óZ÷²ŠºíîžÚŽäE-ê©tsWøÂBJ„”æJðAZ¼AÛðâZW~âº"›%é1_&ÿÿëäd†n߆#ë6I8>MŠêº1)—ÍN¹TNLÊ·3r»YušTX½&÷Û[*MJâËy“Ús߆åtM»®.¬GBÖû9¤D]ÁÛÎ߶‹FÅ«32T¾ß•¥}•LÝ•‘ò%ŽE­P'*<áðö™÷±n+jª-¾^ÐÜ­o±Ø ‰'r09Ük(|V€¼5…÷ŸYÆ7Òï™Ï×3kÔK‰3ÙæP +l§š¹kñíÕˆ|Ðñ/æ©.mi¶´ªaÑÍd÷/£ÛiþIÜÂ[³Biàjô§¦êÓG_±çLÔù#ƒk-õ ¯~ÄmÁ:¹/|Åd]Q+} Zëþ—ŽòÁPRûßZÈƤ¼짉qHJݤrXní4q@´U1I·O⨪~»à«ÍÜÌèyDõ¢Ùš¡‘¶öÜ1zÂÔ#ýrt:4Bêó~*¿O’€%6ý¾`8¯·äI"Œ”ÛÇÙð²b›ÍÇñ1˜ÿ·Ÿú›…;½tb‹ÌýºN• 1‹½ˆK±öYÚ‹ã²ï*¢›AžÒ"Z`Mt=œŒ€í:mt—ÛŠ1ºžÔ ä·vI•ÈÄ +ÊI±žÀüt£LÉtI Žªiïôh×9Ó…‡ ¾!‡¸4Èw`¬%H  UÍ¡ªy åŸ …}FÍnˆò(šn/óºÀ¥Ï'ï5˜ø/j¹T]iPà +ôCÄ:Ø8÷XéÇÞ‡NX%l›bÍ$ϱ2ßíF’²w›5ý:xbýÆÊ<׋nºÓwC*|DÆVg`+É£ç·)x4í^‡Ú`ÚuúáCƒTÐö§€Îèû8)u™÷+ùäµv­!!›‘§·\µ<©ø6£Â#J­&6!G¯¡šQ¨oþ~!ÂLJDoaæ`Ê“˜2 _¹ß¥Eu§E˜h2î|Âu„-oÃÔ#ŸÔ àøìÏ9Ø8Û¬9æDIJ“1幄dñPýýâ“]ÚB Ýáᔇ¸ºŠB¨P‘Q•F¹©ÊÛ8/k$ë=ž^ùC>ˆEóRB,TÓÞq72Ò÷…e6%_ ’öKö.3‘ý˜ðá²]ÂâXØ [f²zé-e ¯ü'@´×<*UKµSbP!Ï„˜†j¥Á žK­áÊ¥'Ä +;H@ÿ[”C¼âHôNÔ¾‚ H±Äþ¯kþ¿o8š“‹ßNfÓ!!ΓP÷úö¿äo¢Ê~F«ZŸ±O=V´ ÃAÛÊl‡ø˜RÝâ9ûuˆá@4ÔÌ¿B\]µbZlO›¾þûÙ•X/g‡x~Ž™l±‰I³mÀûP!«çPmÄ?ûrÙC\ã'­(܆Ö.Ú–Øøf"Nwæxé… ¼…ƒ3âNÆJ(×j[ßô¿†é&*JŒCÜõPL´‰ƒ l-T:dGZ¦RŒÆTA:f3q&Bö‹w(…ÚQ&Òæ6>!.e¸Ì²OWÇ\®N"}!ôh;c³ Ê +&bTrÑú#ŒQ¡,òñé9é”óeB{ª©Úç7anÃâ÷HK–ûüËæ=Ì<ת‚ZÚðq4 6׫Íi_ùúšæˆ|Û÷yÌ 57aË4‹Û-÷ +PH>1‹ubÄ·><’¢ðSbiÕo‘Ùã6ë4½PËåÏf+tŸ}ß_œ°¨%-b«pFÔ@Áð/-ókà-v!4Kù!‡®”óæÈù=¿Ë:ÿBa[¾SfîBØÊ|b¾*#!¨‡ÜÐ0­!ù[0„Ã<;`x°¼ ÛòdGüêeÁ«¡¡6þ/ÍšT›ò»ã(”l‹ "ÓCÓÛA˜ÔÆ'K§~ BŠVù"ׂdÌcL€¯1€ +yH òGØίJÀ‘Ò{ijÙ3X^Üž¡Üa*ˆŒt}¹cd áÀ½h…,AŸŠÕ`äø³?<ƒW?ÍƈÖ¼€{ñqT58BhºËÐ]a)tÂoSÃ0t™oÂCš ÊïmŸ™ ³KQÈ2„'ó0HUçêÜq']g?ãÍÊE<$ÖŸuÔrŒzQë}vGd@ÚÖuG›¦Þ ^Gv§C'9L”Qb¹™W*¹Ö58*êM?_oôº÷b +#uá8‚|Ð3·@ŸZ'5øòð5–SB·³ïçR¼Ýë'¤E»)êïõ±Ïú»_-8ze¯Êd)F\Y*ôK[8Äoûd­?ð(ÅàÉ| ÓΈê$/OUó®Ãí ÑXv¨;™¤+‹Éëp¢¨w ¯ùÜX”É2ÝœÉ[ÇùÉJsï×–tá-ð93œ]žTiòfµÆ DËOƒÑjp~g +×û±ctÄ.ÿ)¸rj¤>¯w2Tá>`HÂÚŠ Ëíµþ Tu. dö.pm^OÛ:šù•Þõ£`Õæõ¬¥c˜'ÈiŽª½ªF į¿ÁÈ J+S´§ÙàðfBÚ6Áoq8_Íãþëù®xƒ¨Ïð×uH4E’K¾ÁsT3DÔaƒÇX"`fÝ”op“è +ªzEqÃ5eÏZ`ªØ%6XYýÿ—iþ Öå<Ú.A_ÏŠö.nÊôªBl°Íbã >¶9>”E™+³+6¸¿EYœhuˆFçŽá‰ .$ZÁ,–¼‘oð´P]kóÀ ÊdÝ-¬G D/ÊÞ'yl`ã›—°ÜÌ ÂtQƒõAšÙf®þ7¶1k¯N8–³Å&¬SÌz³×ê[FÌ̓Z¼æpy´OÄw¦J0­©cÎ|E†Un|<°U ”4g§ @J¦‡(¢Ž&é¼¾QA n› ºùÓõ$abþÁel€–bøjW³rAŽˆwiN7t$­`vc{1]D7,þ¨f†Rb)æ €ÀçW8=ûnkêKc—¸´2Õ|žÖÓP+óÊ>ÅRÇl×WØ“ƒjÖj°ªü_þhöÜ’ôA²Z§jqØ]——ïI'ßZ-óZÑgrYÈÁmÀ“ÎÏyŠÒ£J&Αd}R4}tš"!ЛÅz•¶UàÓ™¼ƒôA¼û˜ªße°É’’³P&ç(3ìi;Þã®=ÕkÙÕj #ÀbÈÓï¹&ëJtÊWä¯ +K&+W(€™)ëvÇ ÀÙӶ݆8YÓ¼Gâ_©½eÝhþ‘/J¤ö—AÛxsõàíJr’V¸8 Ÿ3`€fe¡aÊ(³µ‡u`FV÷0ûÁý±G€õpô»-¥k M4š«„„>Q_9"­Ç¾ÓF¨då2e\Ækø ÀNA¨#A]R Û}K«ônú?@30°ì,ØK| ÎW/Q›*²oçÿIñ`õ_¥™'F½WeÀªiµÓ}·Ò :ÇMåg †öÍ9õÐ œšN~yfx¯%NðÅŽ³k®Ü+&ΆV=)(˜×‘M¾Ø|áÒk³s0yÓ@yUA·`˜*d0‚˹³«±N¼)[<œpŠ¥PjÅõ˜8Ê,šL=h5Ynþ2y|Ž9øÊîl"ó¾a¾Ê's­–}4^ü&JÅqc.cjTÈF°ŽÚã\²rÎø0¹4 ˆ] ½a­OÀdYõj1V–k7Ö’+Æ•Ã\,¹2â/N¿6¶‘)ÝV7ÿõ†Ü–É–t!ÔÒÚŒÿçîj5y"Q(\r’ÙÒ3ž³òRä_y»¤œÓaëç +GiUVn "aoÆ3,U ÁEs pþ&æÄÆÇ î&y›asñ* à~©ãš&Ðv(.ГæŽó-v5$`C÷¢ãfV´Ñþ­U¥jðj.RvÈ°1Ö}íüñ&¯†z?¢œÎ¶•” +×/°cï‘»Ø>ù~ÍB=Ý/RþÆ÷fYFÒCHk¨Ø‹Å5¿=_ëw;Ä–m}fýª fˆ5Ç J,Lh‹º±OªãŠÏ”âL´>ýN-(~úý?ڦà-d» /šL]« 7û³Fó­Ö¯ýŠsj8I—:™Ð‚KUs0èZ$—6­ó.fé8,D…œ$¶ýLtãdàGB%ˆÿÒ£xJW¸£4þ X=JÒ§õl9dú CÀàc|ò ïõ d¬±’¾ L†uCÄYé.äsö=šh‹ñ¶¾‚$œ´³QËb*\¾¥È®•Å–x‡<ß ÆlÇÉšLúÖ®ÀH^¹ õÙ¯ô­ôyâ@x`ã!x¾-È—ÒñN죎äb—¾Ko-É Z„¬<Žéì/I¥¸d%ùP›n"àâ97œk%ô2Eú‹·' cï1y±¶ÊŸoÂÁ=ê %óÆäºÑ '[Ñu Š$¹³,™ªkú$£ˆÃCʶ©å˜i!·R&Oîd%ã4`½¾Éi,ÿÁ€Â *+ +•6ïˆDÝž,òŠ} +îüémÕ—iƒ¼V&“2‘u$3VÃÍVf\ÜÊ3<Ñí½€ñ2¸†_ƒ¸ä'wlÏð¿Q iv:#ûi·âʇ݈AümSiF?j“¾êÿ§ðÔ½?u\ãcëÏÜw)„h¹XÁÌöˆP‚øi¦&êlÅ#”Fû#nøÞŸŸc¶3BÿD×U^®þp<==×K &§½5Æò’Ã20(ËòÔ£™ÙÆcÀÌÐî4®’ã¤l"ã×%옞š›7|ðxÄò mûfIgÀ3é +Aß÷¹‡K+Δ½Eﻵ½!ŠTg¡19Õ  A3 +|M®‘JX*ïû à†ì‚p–úb/Å,×w¦õé—ÔèO}S]ÂõµH©FE„¯¯[†5ÁV’ºÖ®ïçÓgtˆÂy¼kÛ~yÄi}M½EI—ÏE&®/[¹|]ô‡€ÜdöÔõ¬‚LƒÊªú¾›S uaSÔŠLs“Ãüúl) …6–<\ÔšÇ1ÝI«ÑÇ›w »Þ·µ˜ (ã†,üÈŠöÌÓàØòUÔð(…‡ÏçŸ?»ƒu¬ºƒ%’H/)á¹!‹u÷ ¹i Ž?Aå™+< zÎ)Ì®|ÖÜâvò^0âÉ2Åæ7Ì ß‹Xì,‡pòÅ©…‚"ꇼB½1ívñÂeúM©oÇG×¼ACþ»LŽµ^k¬fgô?¶Î´¸ôªÄ(ÁÁ©'k¾Œ÷]š¶T’<¨ñ©*ò´Ó1ÁpMæw!äÌs×î‰iˆž¶Þa™ÖÐàÑ'ÌYDhý½; Y¡IñN&²5RþºƒM@[Ò ›+;Îb´®ùÌEy4G‹–Zž‹ØEa&ü;Ïîãü¢™©æ"ËÑ‘zßšî˜ÿñzò“eGçæ_4ZÍqB·ù^¯ŠoÈmûIAl“‡HÝÙ;8ÇÓ£ \?gIŪþŽu¹.K¾i;·èAä‚å&ø„ƒkñÓ»úÿVÎå8ùãÁÈjÚ):á†E`œ†Ì‰¬ó…+m¯Ò{µtÒž’~F¦{+Çíl7ú=$^ñšù¥½¢jÙ¥i4˜Káåj€™7¢åVåNmš4°KíN ‹€)3`«µÀä·É}õéùöU2îï$Š; ›¹M‡´+‘d¿g€½ZÌZz@ˆ +R`Ÿ1¶R°¦®³G`¾¨3‚´§7¼Î›FÍQàK# <ÑC*Éð,ZEÛæÅ„ò{݈‡Sýi¼(X#ÜáSb¢©µŠg°Ä{«%š b¦¶þeºíñîíÕ+ D 9Õ4©“|F–ª¥Q›>t)Ü»'-rË¢t%µRô€>!Ò +ÜMÔŸÀ]Ì?hN-o 1Ïòy4_duVËó(Y«Ú †ÏµÿÙ‹HÌß=¾ñ½?•˜Ó)$d¨¤þ¨ÀsÔ q^»¼aÈÇ3/4´ÿ¦×ÀÏL.»ÃåäSD2ëw‰(W3 ·¼¡ù±@Ñ—-ÔV—‰Xaº<+äs¦ðsXÕá;cD3}“XFŸo)uç) Ýæ ÃQüò7ZçH39§c—Þâ ‚Û®f\ QÄq_9f +XY,þ¸œ¼ŽPš;3âÚÃy®“rP|ÍóÈ!§bŒ7®LÝÕ=ÙúQª48hmh+mMQ‰„‹º¯Th!kʆ,*ß3uÖ¯dlAøØ{9åؒ᪕>W&KQrýz‹á㯎‡$¹ûŠUüŽu—¦B娹xŠœ„ásË˳È4„l \*^íÕ/ ÷¥Þ¥X¿XøoWea‰Vë‘udïè Fï€n&ÕìXH¯y…¿5ºgh­ `§:¤¹z§@_.4s<<3–:–+{îª}•|ÆR ‹¶ˆ­gHªO€n ÕìΚ›/ô^ó¹1Ÿ'”¯ËoÔZvX•|÷ˆZ¢Çinu&¯J×êRÛ=Ù€Cv«8º*œKsÿN;yfþ¤Á)4”BêPƒ¢óÞ>ýŽ½Ñg†¥Dm\šMùâ¡3ñ}¡¯3Eªê¯¿-Œ…ÇR’AmÑ“5yù¬?+ñ‡kŒueXs2Î +%7¼CÏ6 M‘ ĬiÜ"êÎ4 ä°²÷‘yœ,È‹ù8^-ƒDq-8›¼¶™8^âZ§ ŒRLaj¬æ5L”—á®%5¿n=Î"µ2#èmò‹IãŠ<òÊg€‘)wcõ=| ø¯ýA©º¯’ÔJGyë(ÈIˆÈ›L§ºtBÆá{rÖ´ hŸßM@A%†¼ŸâlUÞŒ²*äÛ8E¾‰²ÏüÃ=’³ó#g¤›RÞ[;—ÓÕLÝɯãšU´a)* R]è¯h;¨¶.Õ‹”Ú4t +NöÑôövOS"ÅåBΞ²®‚]2~±3/[ÈñpqøL.j¾kt¡0XbiY†ÈäŽ.VŒ–µÇqB_{>á"Cª°ìƒéK€vÇÂœËp~œõ)0j"\Q×/y]“ðÄìIÛ§îî´ ˆyëÝ wa_êO ´u‘¥1 \jw5¨P¶€‰g»8L  ª TðÀ<ÕžVþ ÿ›€€0øY|q^úñBkÌÛ7¤=Œ¤£ÅO ÍF…i6ir®ü€Sׇ/E0(r„*Mb'ñ‰å¹ß*Sv¢añ}lvÝlE߶Ôñ΋ZæˆÎq~*Ñѱ.õˆ÷ÏÛS«Àÿ¹ä]øÀ»ël½oɹf/Ü~ŸM3ÒY{‹­Pôa pþ5çá*îèmŽÌ9>e¢ +†¦ G p´Ó+¼ñú`€r(œ™Ù ;îD+•²Ñ+HÕq¼ðÀ¬å=äu'! ˆ–`ð|b{OÊÂ첧SbE­ðZè¸b[cyçõ{°È,Áÿ¬F pïœd¬ +é"IJˆ³¯Þpú‰õ¦@'‡&Á4äLcþ\L» BßÀAô—(ãt‘iÊè.“;þ‘pš°îF6ÿ&üb]Šñ1LtüK¨OÇ'죨pn#Lè¨U¦Ãðx€Ýù:)ð'ª+/Sn Ž‰Ø=!g4þ鬋{¶D!cißrmƒiNql&¾x9«‘— XаßÀ‚¨+qYôÇrfß9ÀOÃ9'Ò’r€y**úQŽ›qR +;Ú£ó+§p#AÆ“%#û ^½M<`Jf\M†DQÁ\Pé‹×è›@¿E?3fI_úhõ÷Œò"M [8dH5Ÿiê–‹Q†1ÁÄjM½A*ÊB}ØB±ÇG?åVÁa%RêŸè½rýÓ ›»¢C[ EjÞE­,‹@€j 2iŒkÒš‘Óº”‚4ŽfËYgoIjˆ° PÃùÚð¤ÐB3²1àJs Q²²b®š¨ˆô¿ôQþJ÷ŸL<rj:v„Eýˆ˜IK`pÿ'êž7ýÉDDvqþÖ¢ìcµÍa^š\~ +àãÚ¥ßÉ‘PLáð=ûÑhÀÜ6X0'sŽzÊJ™ Ioæ¼cî¼BýŘÃDëÅ­”Gò)sê‹eõ¥sóE–äÈMpÅf†õT®7-âÓjt•“ä8;ɲÿZ›UÆš{>Ïî û1øqª:ñ#®®[…íZÏqÕË0ºÅ[œ»Ö¯£ûãÕ·D›Ùî'›hM'—aw¥RÀ~¼Õ!HñY&ÿpþ•ÃwFCKU¶¶ dga^Á!+qšžÔŠSx´Âcç½»#_À§<šF4»póš—;êš4ù™Ì¤7]ÐÅG¹D*Ggè`‡sñs?<ñ-L¯µ9)ž@è0 Á¸&à01lÀ×u 8‹`ÜåI Whpj¯Ð"ètØŒktr€·W‹Ù¨Ѫ‹~wÃK«*c0¥l u€w"@¦².Ê œ5e1”Ö,d8×V‰”V;1VŠ’ +5»ë º@ô t÷^sôŒîá»÷É5.ÀSa„Ðv¸;øÆÑéÖ¤w& fIXÛS5G=Â>CY|õcYZFþà<ØaBñå]m ¯¡ +ò¡Æe$è*ÇjÛO4­|CB¿7ÐîYáz‘™ÅggÌ;{‘´I}Ê xU¨³„¡ÔŒ¼Ê +ÒãšÌ–,;öY5ìÓhd¬?Î+÷içú¨U"dÜêD6òéQöfö—»B·Sb(ÚäÍ¡¿`Qá€_ÀC#Š¢¢ØP„dXØ>$‹1ÎËbàPÞ¾ù^Zü%û£·ö® ²ä*ºÔ7NZo¥}1Q0vr¨c53½œ®€»„ð’¿`?b§fXà—0âïWþB1˜YÅÊ#^(\9.Jd´êa6W­ ¡g¬öŽ–¶@ë%ïxâÅØúv\ +êÜ+ÜW°ãAKjà†Û@…èsM#§ÍdîŽé› ,E54t‹Â$Yml¾D^ +>në÷Q Âgîís° +ÐŇG÷|¾‰´F¨Êju„¦Æ2ÜÒ ½éß(“Ó¯ÓX”¢è1è)°²J‚ ”–rÑø-= Ù3Ú㞢 `E²u†ƒžk$žó¡-c^(Šg¨]›fÐ9øwžC»Ñ¨ +âˆk•úuc×¢EÊ¢-ñ}ÓJã3,Eu1÷ÃÜY;™ß,L@uK˜+b›àÁ +âÞâaMƒÅ[Zä—̆Š*à—ÄDÇ"Ÿ6.´²‘÷/à“’ DJ& ¦«!±C†Ö¯ÇÙ }ñIûj>’ +v=Úw©Å1ã^{èFŠ4#š@úM:W\ß-H@›ž—5臑)Ó‡Á–À ÁÚnf¨^ SehiB‘Z/WÅÍèz)ÊÉåqdœ;„õ²Ä5Ž¼Óç)ƒol©N涷߶ç#£{¯æ,E߯…S&“?æ!ÎûÜA°û(á«K?V>ó8œöï5¨£„œ€Óçõg"xý5¨_×Lõ‚ žË_ZSmHÓÍÝÐXÑû%V£¡€"ʇݲ`Òqÿ®ƒ³'Ú/G(h¡+þ„F/ƒr ÂmرÇL &¢¾@ _-ÎØÛßQsƒŽŸ†À5Ÿ¢bð. Îm ®hT¼^¬ò> :W¨rŠ>V¾ÂM"lø, Ž»+Žé/e]°¦÷¥E¶™ÐÐ{l,[Ó­çÀ™6A šY"wÒ^_äæ)ÍA¥˜W 0¤›!!§vD ˆaÞ—|s¼`q³ãLu¼1O&iUÌ㎄ˆ©kå% p“Àè[uS~[#Æ|l•Úá]/L)ˆ8]Ü!éé IË!êMöørùß÷šÉ4)"Ç59œt¨n­l7 ²‘Ô—§JZ¹ý~ø: ¼<´¹™y§‚Æ£Ú3˜*7b¯'Vô˜BÂàdº8ÔʨÙç*@%­ËGœ€0´yâmgì>Á£Š~¹¤‰þÞ9«é$S”1!®Ë €VãÔa È^c¥N¼)]¤Pïª3ø¢ä7ñðAX¸˜‰|˜«ì…\Û„Ç5Ç®ý/SkÃiÁ ×Åžuž-;®œJ%’Rf(Aµ-·JS ˆêƒñÎnº»[U„ýy:Úâ|BˆW殢c{èhÉÑd`qêÊ`î…R Ô_y .%ÙêCƒ3â® úâpÀ@Œ€¦"”gå``R¯9ó”D×LÓ M?Ï°ÄéiŽ0Ä€ +ö $x©×MØä%–w”°ì*;£ö“zîU`¤—IG€2þ®òU¦¡ =ÝULÇ÷J¡{• 4~OŒvR€HåZ»5X•€“¶DbÙFáðtÃ)`=Ê€ñéàxÙ?uë6·øßïÀ¨‚àƒï`éBÛß‹:ã1ünˆu`”’Žš¸††y$5< •d¼Oª¨ÔWhÈA£‰e¸õ"ØRo¾¬iàV°ýÙü 5<Ÿûd;"4¾©½~0†zÓR2)e¶Ó=@mS=«ðÏéÍ|ÕÜÐmBìHB >sÊÆ‘îà(º:?vœy«ÂÂwº!ÜÁ'®ðŠÂ%ƒ43ÜGjéÀ¶ ˜óÆêÌÞ“•ÚŒw–誽l? 4Úüî+-xtE^¼üêô‚Çb>cìT0©Pc¼Â(»Xydãr…©Åfó™’¹\·þ,ƒ9¶Ñ¨T— {¾6éHÝŒÊ ÆfÂNOxìx1+´ÞäÎ܉Ž^²û84ä~I«Ms‹ig}|•*}!X`yƒ©$5aP·€žjUÚùÙû«Ð`-Xö¼øk&¡+‚¨[¾¯ÍÀ¬éXÀq±ó…)<Œ ÙKsÙ6|Åzw$±„+s!6uÕ?—Ü`L,€ÐŒøj+έ “Óo^U °k„+ ­JÀ%ÁŠ4-ŽM¦|4‰‚ºa€]‡ÖL¬¦(å‚Wp¥¾ [$ˆf„¦‰‘Ïɱ•nœÊQü†gÐxÈ¡D¬Ž²çJÙåLT:ëBÔ2sf"î?ˆ­og?ìs"Þeê Nt–QôWL=Š⾸)Ô¹¶SÆpô9ÍXE‹Øh€q²9‘R(=IÚ5BŸªML=:ˆJ:¦ðˆ ðò/õ­ò+gc6–fôi•Ñ00`ãD‹¿há!=›ûMààêÈXË%hüú¡:?+å£Ùc—#—?ê}çó„7Ôfsúb˜¿ªÈ/–þEû>Ï¿Ö ]_nEè†0(É9(|ì”È[Øotd¶–Ë£S¶à +ó6±§FAžò5q·%äQ~ã!„ Ä6{@w2søo°oók&Ï˹£[N¶=ÄÚ ô¶Íï{àÃue©½¹yƒ½¦˜»No ÍM’·¿Xy«u“š[‹·Qžuñ3c“,ðy­æ T¹¿¿ª1 ß_òAº:¼“@KI þéÿ˜¼k‘Õm}W1u:ê¹Í× e5kDg ŽÂ€>ýwÏÓª`—V‹k¼éí¦¥(ÝÙ„Öd! +§ìØ¥äR–¥¹ù«R·è‡R ÓQ«£ ]•J¯ë´ÉVTp¤ûÿ¹2mËxb?cŒˆ©úMw$gWb2«Èl\™={²ÊÖ7ËÖ>.ÞÏê«SÑàÈC;,î¥Ì‚°d{éU(ó"xF©#Æ-®è“‘XO  ÖäåRTC§)Ã&I®~º2œ“eIDe4BPoÃœ3œùOS¸èM=½²@Á}˜ß™”C‚xHëCZ–’ƒ?õX§D|J F Q›:P%÷¼_Öõ!2Ø’ÜÕˆéÇá$;ؘá¬y.ò!ÈäzzÝo-Ñb綼‹ø½ƒFù*\°RÛ] ŒóŒ,äêœ\„‘è]8'•‹ ¸ ¼“òÓ„¡Ç¯)¨ÿÆ‹sì9­Zè ûBæE—$ExØ©âfkŸüñ +ÛÆN:fœÈÙ2¬bæƒê~2'À,Ô{Jìñ÷ÐK³¦}uZ*%Vºé°@¥Ø€}YñÕòÃákƒ!2º™d¦Èn1ž]«êmo^¯µ­wvH‘ùÎJÉ%¤Ctáó`C$2ÏvQµÁj^3sž‡º¢[É%®6ü*5ÿB]Ý’™_ÈÙ0–©ž©ãxݪJð6Ì«N ¢‡òÕQ‰ÂÌ.Ê°¤™1Î^÷ŒÕ÷ñÙe¡±¤ÉÈäèj +¶sÖ-UV"a{8–™®´Cüñ>$ƒr;´‡­ñyQì¾v°žeÝùÚ#9껣Î\½5±Ím¬¿ë‚Hz­N‘0v8O]‘(æU®Øúwæ H®¹g‡÷èf”ÓBz×cÍįv¨3²Œ }q +IÍNŽ¶C*÷ó˜å>$ÂËH™ëä_rD2&¢ÑÙ-~?\X¾"Gc¡G\>[œÙÐÅÇU 1Ûø£x†áv ›•Ô‰aõÁ®Û j‡úëÓªñEɇ‘*¥UEgü˦eû®ì› ÍýX©…é¡Èªc«"ŠÓÜÉï.\öŒ°r1Çaêäˆ.ó ý,XÎø ªýk»8¾¸§ãÚÁu+#$t>UD%çJõGF–Äe;[Ɉ(ª:ØtÑ™Ó-1Jôó`¨TIªwå+[W76:™Á#5tC#2n‘ø°“éÅnTqÅál…^3-÷l¹K/<fX">ºJ½Äa45¬xe^Sej³= )ÝÅ¢Žt¼o‚Lfp­dHG½°²ÁT"EµUpdürK4+L6¼¬=ßØväCçO½%š¹VÙpCs4å² ºÐ7Sg”làŒj£êÉžžÉ¾îNÇ„Âú¦f¹¹²²,ÿe4ŠéQÇ»Çõl~çì,hl ’ŠÆDFAý`«!‰+äkêÆ(ô¢¡š[Od'%M<åŸLü$ýô˜»Èð5+E]Õ¦JÛ½µ×Ob®Ãˆ‘œ)Ú•èîdæÆStXBóÔ‰ÝÔmG1D|V +º$Bu÷Õ&cDHуáå•NU›óéšòÕRŒCiºs!”ÎGþÄs†üÄ‚Ejù$a¾œç49«Žü³×C&œ0e¦4Ûaç`&÷šŸèt6Y$wœ:XÉÈÜ唘‡TGÕƒÁ÷[¥èw›ç¢ç0e·±ªG³°çÁP§y»+*Šßr}5™ÇjšÄ\­E¬¡ ¥ó¹ˆˆÉ;ô°Hâb.+ +‹åJMÃîƒ9w$=ûÄåÇÿEßYÅEìHvÕø™ÅÆHææâr%W*š  ßØ]ª¾ÖHÞÿì37CÈã·›<„d†4îï,¨l8 MUÄöIˆÐ4ìW¶~lQÊ 4+ZþG^r2Fw‘zì(Û@“lÈÐG~9se¯ÏìªN)ÅEº1ý‚—‘ÿ¨r°“k+F ¹Í}))‹¾ùõ‰Ûf,‘dûÑ-ênJ25ÞßýC— û‡×É· éàžflyIô§È\‘Ù¼®ÿݬÆÚª1z‡ÎÈk‰öœýàQ¿÷ëÐdñS ‚¾Ekó…‚ J»ïÏÊ4À°`~ˆEË*ÆõbÀp°X¶ ¥gÍqßÏYÙz¨ÑÚ*è?¯ûû8W©s?ÎGüaHÄf‚¢~§e›~-¼ñ‹Áàó¶BÚŒp“5¼@ 9,ò@*Ù03ô8Gç;gã"¦9ˆxæð‡èœ:  Y¥™ MV «Á콿FgضÊrqðF(× ÜpÞQû\HD>€ +ñ­VscËѱÖ69XÉlR¦:èÙ«ÿµÅu,.“å@ºÀdBêàw7†»•^tCÜ(NE¹£L%Aó×LQºcpjÀh¾Ô0¡À5)ú%té¬+‰ÈÉíIý±e˪裥ˆñ®®àF ™Ë"ñ‹L¶ ùàѦq‘Ü!*‹ç×€ã)Ë(˜ãÎ 2­ªý¾ãjû¢!­Ü• ‘ñ_/eÖzÞ—]Ð.׊Â2p‰q÷w'•^w»‘žVX‡†éü[Jà÷Wa-9lCfªæ ç’ÐN Xö2<öŒ’äü[Z€¥ØxñC2u+C !ÖNSIN‚šñ¬{QTߨ9hçZ‹B ØŽòÄ°b¶w°’Ù¤Lu,€È¶AaíÖÖ È)wZ™þd§0GI#ŠSxµ&°n¨Ž·”‘~e’ÜÛQAE6$ À5-Md šòë|–‚%ƒ.Õ +Œ‰~®Ó——Š®ËÛá=³Bt-€×¡”ÕùÓ•ßy½wй^£iüçˆá•"ÁÚx‘q¸;ržËżƒÙ¸êq?.ƒ¿ Lœúù¾^ã@!Jèñ wö=ôÉ$ø#ÚžãËU ·óOQÇ6ņM1yžê­–ÔÝì«ñò~±]Þ¨'5hÀ8$Þ/6¤R”§3”F¯Ü^¦ÁŸ„i9•FQš8H°3Š)ÈXú¸”¿U +endstream endobj 27 0 obj [/Indexed/DeviceRGB 255 28 0 R] endobj 28 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 25 0 obj <> endobj 23 0 obj [/ICCBased 30 0 R] endobj 29 0 obj <> endobj 31 0 obj <> endobj 30 0 obj <>stream +H‰œ–yTSwÇoÉž•°Ãc [€°5, ‹ì ˆBHBK!aPªVÊX·Ñ=uº¸Žµ:X÷©KÔè£ãÐZ\;v^àõ´™N¿üÞçÜß½÷ý~÷Þw΀.MÑh«aUZƒ>31[”_€‘& (€DȵºÔ¬„l€K/Ájq'ðVO¯›V®¥éþ?±:½O“Žs€RU«À¹çÊzƒÎdŸÁ™WRab5±? Ζ&Vϳ÷œÏSº7åÁâT¥rc¥3ÕMQ]YmÔcµ:¹B… :Ä¿9ð—Ïá©*UéUZ<"Ÿ2V·[«Ô4ÕZL£ýOMüa?Ñü\ã⎽¼"ÀºÈÈ?.”KHá6|zÓ·J.HÇŸy÷æç~NÐϳÂ}¦¥V£ž‹“dfc +£¾n~ÏôY &à+`œ;ÂA4ˆI dƒ|°(@¨zPZ@;è=`=؆Áv0vƒýà ƒàÏà<ø\·À$˜Á x +^AD‚²‚ WÈ ò‡ÄP$¥@™P>T ©!-d„Z PÔ C; ÝС£Ð èt ú +š‚@ßA/a¦Ã<Øvƒ}a1'ÃÙðX ×ÀMp'¼‚Gá}ðaø|¾OÂáY 4„8"BDŒH4¤)EôH+Ò "£È~är¹‚L"(å¢*DÃQ)šƒ*дíE‡Ñ]èaô4zBgÐ×Á–àE#È‹jB=¡‹0HØIøˆp†p0MxJ$ùD1„(%æˉÍÄ^âVââqâ%â]â,‰D²"y‘"Hi$9É@ê"m!í#}FºLš&='ÓÈdr¹€¬%wÉ{ÈŸ’/“ï‘_QXWJ%¢¤4Rú(c”c”‹”iÊ+*›* FP³©åÔvêu?õ õ6õ Fs¢…Ò2hÚrÚí´ÏiS´tÝ“.¡ÒôuôéÇé_ÑŸ0 7F4£€a`¬cìfœb|ÍxnÆ5ó1“™)ÍÚÌFÌ›]6{̤0]™1Ì¥Ì&æ óó"ó‹ÂrcIXrV+k„u”uƒ5Ëæ²Eì4v»—½‡}Ž}ŸCâ¸qâ9JN'çÎ)Î].ÂuæJ¸ +î +î÷ wšGä x2^9¯‡÷{ÞoÆœchžkÞ`>bþ‰ù$á»ñeüJ~ÿ ÿ:ÿ¥…EŒ…ÊbÅ~‹ËÏ,m,£-U–Ý–,¯Y¾´Â¬â­*¬6X[ݱF­=­3¬ë­·YŸ±~dó ·QØtÛ´¹i ÛzÚfÚ6Û~`{ÁvÖÎÞ.ÑNg·Åî”Ý#{¾}´}¹ý€ý§ö¸‘‡‡ÏþŽ™c1X%6„Æfm¥ŽFÇŽŽ¯œN9NNœî8SÅÎ¥ÎÎ'g\\R]Z\öºÜt¥¸Š]Ë\7»žu}æ&pËs[å6îv_`) š{·ÝîQî5î£îW=ˆb +­_zžAžež#ž½`¯`/×V¯KÞïPo­÷¨÷ !]#¬îNùð}R|:|Æ}ûºøønð=ëûÚ/ȯÒoÌï–ˆ#JuˆŽ‰¾ó÷ôWøø_ `$´ ø6Ð+P¸-ð¯AÜ Ô UA'ƒþ¬Þü Ä%¤8ä½bž8]Ü+þ<”Úúqè‹°à0CØÁ°† Ã+Â÷„ß_ X Z0¶àn„S„PE¨úU÷J#JûKï«#ÔÕÊ¢ÊËi$šaÍ·åÒòíåÏ*Ò*>¬ø±2¯ò@¹ª¸ê¨–£­Ðž®¶¯n¨¾¤óÒué&kÂj6ÕÌè“õ;k¡Ú%µG <ügê‚ÑݸÒ8UY7R÷¼>·þP»AÛp¡Ñ³qM㽦„¦ß5£ÍŠæ“-Ž-í-SËb–íh…ZKZO¶9·u¶M/O\¾«Ú^Ñþ—¿ŽþŽïWä­8Öi×¹¼óîÊÄ•{»Ìºô]7V…¯Ú¾]­Y=±&`Í–5¯»•Ý_ôøõ öüЫèýb­híÐÚו®›è îÛ¶ž¸^»þú†¨ »úÙýMýw7¦n<<€ t|¿©hÓ¹ÁÀÁ훩››'‡þ ¥ZþL˜¸™$™™üš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 20 0 obj <> endobj 32 0 obj [/View/Design] endobj 33 0 obj <>>> endobj 24 0 obj <> endobj 21 0 obj [20 0 R] endobj 34 0 obj <> endobj xref +0 35 +0000000004 65535 f +0000000016 00000 n +0000000147 00000 n +0000031585 00000 n +0000000000 00000 f +0000031636 00000 n +0000000000 00000 f +0000000000 00000 f +0000034870 00000 n +0000034942 00000 n +0000035082 00000 n +0000036647 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000074824 00000 n +0000075135 00000 n +0000032050 00000 n +0000071923 00000 n +0000075022 00000 n +0000071780 00000 n +0000034353 00000 n +0000071218 00000 n +0000071266 00000 n +0000071958 00000 n +0000072174 00000 n +0000072053 00000 n +0000074906 00000 n +0000074937 00000 n +0000075160 00000 n +trailer +<]>> +startxref +75350 +%%EOF diff --git a/docs/static/images/branding/logo-cropped.png b/docs/static/images/branding/logo-cropped.png index 9f2c464fe..b9592452d 100644 Binary files a/docs/static/images/branding/logo-cropped.png and b/docs/static/images/branding/logo-cropped.png differ diff --git a/docs/static/images/branding/logo-cropped.psd b/docs/static/images/branding/logo-cropped.psd index 5c4448b9a..4e5f9582d 100644 Binary files a/docs/static/images/branding/logo-cropped.psd and b/docs/static/images/branding/logo-cropped.psd differ diff --git a/docs/static/images/branding/logo-cropped.svg b/docs/static/images/branding/logo-cropped.svg index a6e6847c2..944f3257b 100644 --- a/docs/static/images/branding/logo-cropped.svg +++ b/docs/static/images/branding/logo-cropped.svg @@ -1,3 +1,71 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/images/branding/logo.ai b/docs/static/images/branding/logo.ai new file mode 100644 index 000000000..73c624c61 --- /dev/null +++ b/docs/static/images/branding/logo.ai @@ -0,0 +1,401 @@ +%PDF-1.6 %âãÏÓ +1 0 obj <>/OCGs[20 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator 27.0 (Windows) + 2022-12-15T21:28:47+11:00 + 2022-12-15T21:28:48+11:00 + 2022-12-15T21:28:48+11:00 + + + + 256 + 252 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA/AEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYqtllihiaWZ1jiQFnkchVUDqSTsMIFq8+8yfnt+X2il4orttVul29KxAkWv/GYlYqf6rHMzF2f ll0r3tUs0Q8x17/nJnzPclk0bT7fToj9mSYm4l+f7CD/AIE5n4+y4D6jbRLUHo8/1j8zvP8Aqxb6 7rt2Ub7UUMnoRmvYpD6a/hmXDS448ohqOSR6sbnuLic8ppXlI6F2LHfr1y4ABgonArOvyk8967oH nDS7eK6lfTL25itbuyZyYmSVhGGCnYMnKoI8KdMxNXgjOB23DZimQX2DnPOwdirsVdirsVdirsVd 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 uxV2KuxV2KuxV2Kv/9k= + + + + 3 + + + xmp.did:33ff98ee-93c4-e448-90bf-017ad67f2b0f + xmp.did:feeeff93-18d2-154f-91b1-dcb9a891b83b + + + application/pdf + + + logo + + + uuid:0285d363-7ccd-47c8-b852-d59268d715d5 + xmp.did:c5f30ab6-73f2-664a-865a-0768f3b66bd4 + xmp.did:b6eabf47-c2cd-8b40-aefb-e1f7870eae39 + proof:pdf + + + + created + xmp.iid:b6eabf47-c2cd-8b40-aefb-e1f7870eae39 + 2022-12-15T12:42:37+11:00 + Adobe Photoshop 24.1 (Windows) + + + saved + xmp.iid:c5f30ab6-73f2-664a-865a-0768f3b66bd4 + 2022-12-15T21:28:43+11:00 + Adobe Illustrator 27.0 (Windows) + / + + + + + xmp.iid:b6eabf47-c2cd-8b40-aefb-e1f7870eae39 + xmp.did:b6eabf47-c2cd-8b40-aefb-e1f7870eae39 + xmp.did:b6eabf47-c2cd-8b40-aefb-e1f7870eae39 + + 1 + 900000/10000 + 900000/10000 + 2 + 1 + 640 + 640 + 1 + False + False + + 512.000000 + 512.000000 + Points + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + AIRobin + Adobe PDF library 16.07 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 5 0 obj <>/ExtGState<>/Properties<>/Shading<>>>/Thumb 26 0 R/TrimBox[0.0 0.0 512.0 512.0]/Type/Page/PieceInfo<>>> endobj 22 0 obj <>stream +H‰¬—Í®5„÷ç)æ˜ØnÛmo+„P°Ï$ÄûK|Õž›œ± «l®®ëÌô´û§ºúÝÏŽw?}HÇûï?¿y¦³–|”ÖN³züHIv”<ÎYÛQ +Oärä1Α+OöÓ}½×ãÓcGž2íìÃ’í°bçì›~zqöY×Wð  g?ʬgs~˜åL¦7ËÙkáA?s™œóÙ[/îÈ3üªÜ)±îèÕÖyZœS»Ž%LÜ�,ð_‰¯ +9š^唩cªE¦3ŸšN8‹MÂ6"œU7´Á…8s‘l„„ß;W.g=¼Øܨ…ðŽù9:¿Tüœëäk|¿ü&(ÿpW~ÜÙ˜gRZ{=‹{¼ÓâLòz ›­a³O¾•ÃÆy†gÙxÇÛ™õ}î’ +%2¸u›‡üL„¾(.ÕÃÆy†Õ™øÞôÓ¿4;Ç$è)Qò8Řҩádž`lò½‰ï•˜z=kÊñ•þÕÓ¶ov“ yÒ½Ç]dÊW}ϧçî§þ’´1É׳\hgOáë +ç¢#¼³[œ£{z9-GJ6D6è(ʨ4’4Z|»Ï%‘Š_×P!ªh“Ñ5Ú9ô,š|]={ŽNëÓÃãžUuuÚ¬›”¦7ð«y$ õj>­çÕiÁë|uÚ ¢N£˜ÓøòNu +ÔÃæí­->=~=þ‚}Þýø1¿ÿ×kkŠäw2Iðú뿯d(‰ 7S/‚Ï6æ >ýùxÿÛñîãéøçã‡ßŽ_¿ð•’ßrX­joz2ÙÙ 4#ЪýL%£Š'yг¸kF=U¥Gž¬>"Ô0W„êTÇÆUÝéÚƪƒuuë*€‘ Þ¡;Ä#Sœ”έ®äA`p`Ö縘öPàgØzCT\­¿=Ñ¢ ½Ë"7Lå*ÃWD€Qhû ѹ½=!†â<%)ÓOáCÓI6æÙ +‘¥üÌD)²Ñ!Îbbë €ðk‚ø:ÚUÏ…Ì +Ïš_jeÕ¬“û&¢£šƒ§wdÙP}”Ñ‚ëó *4Né¿®L%öÕ"iÁM6„«$fNíF×;D F1ÜIÇCÊ"…ÁN¢hÐNÑÞ·“!µ¬™º‰x¢5R?¨ c\lÈ¥†ÊRJ¦Å8w9Zƒ–Vʯë,?î6p]Åþå’@çlºË§¾IæéEm ¿Ó†}ªŠþ$a6gRªh›BPð0’ÈE3r +ÃŒªÞ‡i¦ZB9íÁow„ü‹_} ªÊ/ÙV8•C`eu¦ úú’ ÁÉKi† +™¨\w‹ +»Žä¶Ž(˹ۙp$O‹éä¹Ü¡N™|"-&^7ÜÑÕR´Ã†ˆªyVW€à4*²+º¢y‚$òt‹É¦7¤žÕwdµC&±úL®¢Å|Ù¢ž£]ƒˆiµd½#²Á¤ÖF;„-lh� ¦w‘ÇÐ{Ñê%¦ÎÀ‚h1¦·W^ÑðЖqõ·Fy„"=Ø]D5T¨Ì™ê’õUß’¶(Ñ,Í°#êkdÉ@r,ÙA¹ºÄú›’æ]òÕ¼Ô†,-)e*¤å|iZ=1m75-_U²®UåŽ<ƒ;£®%¾VY5¨Ò ³ªq¤ŽRQté§;° hë1®Ø£0©2. FòÜB MÍ’ÑbsÑEîȺȠ7ÑW SW£èl²l­ùóY6îÈs!—UמçËi/Ëú}¬EcC$ðñ¬^ži±aþ±y-Èž$¾E1ý é&SûWtœRT´)@H‚2­.(U"kYñ3hãZ]À1_qß�F5­©]æ Å£óÔD/¸¯%ÔÇeá*MTΨ®¥G•Ð]¨À:¢Î¦ö°&, wà@K+ÔÝsÔ׎ÇL kšÝ5tQ‚Û©í–´2ÞA¦§ ‘Oȶ«÷¡" –5à6D‹D‰ÕFÝnZ$bOhqNeÄb3‚JÌc©À;"%‰vƒ×¨«”{lEÒØ$;,Î.î2¸júµI¼"ꦱÞÑô^Ë`Ö©…èð”PÇ›—}Ež±©¹˜ÄE +%Ï뉬M Èíë¬`Ü‘ç)ýþŽúñõ¼zzCV@‘BŸø@9„_"\‰³¾~îËÄ xF’¤…ÌÔcµˆD44¥ Q;q¶%Ÿ6diɘde¬¥¬²Æ(9uÖ¶s¨éè’ ‘°.xŸu‡;ò þ ZøüñèyS;îüô ¸1a áÂÈfÊE½1|BÒÒ‹­ˆA0 ¡¸!k,ñD Ñ+”ÂkfCéš¡φ¨x%L؆šÞ™Òà3¤5±+,o¹/¡ngâ…toCò«0â¡w’&ÖüËavˆ 1[¢vDÔVbÜj…È×F¦ƒÒkQ¾dSž)Y±›îÈbGÉjƒ)"ŠQZŒ6µ0Ž×ÞÂ[66D-CÙˆn:MlM«Ö"‚œ¯s ¢µîð  DÓÒ€¡œS ˆžˆ1¡[M’|™¸#Ïð«‹¢jDë‘Kéë4ÈKIRsi–ÌhÄ Á³¡*øÒæŠFR»Pfº™f_Uð-*"ÒzGT$£ä@fò(„¡‹2$5hîոβqG°14«ú—wЧæk]š1Qïý Ú©N.¬õ×[b2üW?ýðÓ‡ƒ¦úW€�¾H‚ +endstream endobj 26 0 obj <>stream +8;Z\t5nX8C#QuY*H&Q'=*j\)'mfXUa]/`:2@nQHZ<'_$'#jg3Kiu^XGPi^t(mE;Q` +RTuZN21Bg2]e7/@I4:M)jeIS(>]5mJnZ!c3O=W?QpknKlY@G4BT[QQm"pg/P>sRWZ +l#a^)D4s]?nBi\TrX6?9Jt.RZ1qHDsktQ^EC'C]$@CccCs2F2@"d2f=Umunsf7SIt +!OGT;BHrW%bSZ=hepn:g`"2Z9n(UXPFe:Z\rK2h^9(rY!rgdngj>"J80)T\(@\WlY +hk#l^rht>(54n_"h76JUO6nb'd;FKH2s^M.!knWr^lsQG4!3m?73h>[o^>)7QZs%=N%$b./3s##&!0;a@@Y[b_6IuO+%,"7Yh~> +endstream endobj 8 0 obj <> endobj 9 0 obj <> endobj 10 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 24.0 +%%AI8_CreatorVersion: 27.0.1 +%%For: (James Elliott) () +%%Title: (logo.psd) +%%CreationDate: 12/15/2022 9:28 PM +%%Canvassize: 16383 +%%BoundingBox: 828 408 1094 670 +%%HiResBoundingBox: 828.079744285221 408.776733131879 1093.43083843645 669.872033691407 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 14.0 +%AI12_BuildNumber: 620 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 704 284 1216 796 +%AI3_TemplateBox: 959.5 540.5 959.5 540.5 +%AI3_TileBox: 654 144 1266 936 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 2 +%AI24_LargeCanvasScale: 1 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI17_Begin_Content_if_version_gt:24 4 +%AI10_OpenToVie: 276.050632911392 810.177215189874 2.19444444444444 0 8195.24050632911 8370 3030 1947 26 0 0 128 238 0 0 0 1 1 1 1 1 0 1 +%AI17_Alternate_Content +%AI9_OpenToView: 276.050632911392 810.177215189874 2.19444444444444 3030 1947 26 0 0 128 238 0 0 0 1 1 1 1 1 0 1 +%AI17_End_Versioned_Content +%AI5_OpenViewLayers: 7 +%AI17_Begin_Content_if_version_gt:24 4 +%AI17_Alternate_Content +%AI17_End_Versioned_Content +%%PageOrigin:0 0 +%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 11 0 obj <>stream +%AI24_ZStandard_Data(µ/ý�XÔÖ.³„î5�EDÔüÿÿÿpúÿÿ8Â.NqDòõë¿ê¯ÿÿÿÿÏåVý¬-í”’J–Vkàï"©ePòA†ŠÜƒG(løÁ¡6Š±‡x­üUã€:<$¤ƒJ’Ù�ç`Ñ#Ìá£ñ¤‚å�‹°òZ+_OøC‰êû€GÃ@«ed1q@Ä#Ãa,)fƒG(dJlPÁ‡šÁ†*µž‰À ^kVÝhe0ÐΔ!²j”dšK7DÄÎëcø`R-£ÊÄÅ0ÉPƒ S «Â4¤\HÄ°PxJƒrà ¡Pëìnˆ¬m`yòà'èg(d CâPI:ø`¸­™Î€áŽ¹³ ¸lÝü¼ ©u˜uóúÊ:Žù‚uøôêF"S«sx«KÑBY:¥:PIVêxOáàfêJ']êÄNfÔµg+Ôeƨc|O·òVNwÞ›î�2] +ö0Ųtˆ8¡v«CÚ¥ H¥û¶KébÓ¤ûhL³#’Î#f—+Òt%H‡-¿ëJÙÅ«MvÇØi¾K·Þ!æCïXRÞ]TÓ¤…ãÑ»5õèL&GW1„¾ŒlÝ;R]m²è.¢è¤ÑÙNFgP5³fÒuh¬v8vÝæeèj®ðÐ=6ãÐ `v:•´§°Ô�>ʳ¥@)ß#ÞçÆÕÊ'ën£óå8F§&dèºTöíŒ+>;LI²åyZ¥Ó(´ŠG((2¯LZúÊw`#°jsÞº¥~0r&Ò)í‚)~°M8;ð@( Œ@%'2›‚fªFz„ÂüŠµ¨KqŒNˆÆ%ãÙüºfàº!úè±pÔtMl”Íé¨#iQ“k3ŽŸŒEÀr‹½µÓ6K¼ +oTT‹'ÛH'èVzcÂéàyK,Mj©2x$HT0ÔRó#‰âÜ’ñŠÿ]×­ ›ÉR%[Ì¢u?º®“"0õqH’[Tíº®ó8º®ëž™wº®ƒ]×9NPqñ’„Ñuì�Tž†®ë ‹®ëà*OÄE@¢|&‘²W"šŒ‹¥*]×1l*Åw]×É]×y„Â…¥T.¥¡ëº×u-¦"OR×u]ŒèºngB1…w]× ø¨_z„‚A³è:ƒ¢Ñu)‹Ñu˜sIXd7Ô§êXÚ?S>Š#&:=w'Ò9‡lT‘ÄÞj‰|Ì'L»i¢ºUEú7µëºùõ„Ü‹}ů‹…\~çÇ-¸—fJ%nŽÏqažƒšªh¤ZÍ6¢š€®ëºnÀ€ƒ +)y¯×Ŧ¾ÌdÐÑrm…ÐÎ+ù§çuÉ­‰›-ªÚ­}±‚…<³²|²´Ö:Ç/,€ή6eeìc9»ü¥ŸÝ6†cVÀ “¥ik‹ðˆÅ’Ü$ùb[5UŽ[ËÚÒV®Ýuœoð|ûp?sv™{µqŒÀå²ñ +ËîÏÜÏœ1n¾½3×ëÎXZ‹cç•öÊ-ÇíÝâd2Ûá~æÜ1Ž—\ä>æ6Çù/?¸ý'Ý·±1'�Kƒk¯‹ƒ[šëö¢4‹ÂXŽ÷›ëÒh4í0–#n>rØùå¾.v¿/Íâ»÷#_È‘äPi4%w/¹’Ô»‹%Æ}´ñ‹á³7žeŽu[Ú|{¹˜…qzgηW‘<»¯efåÖm¤·Ë]g¹Mcn �¶5•â<¢Ñn–Ì9[°–ÖÂÞ$sµ²˜{²®ÕâEø%}rG®Ö>æ¶2¹uWçýæ 'ÇR–Ù®½he–ÅZQ;¯píE-)HŽÙ™­­ñ +Êœ³Ær¸(–ÿ»ÜÜž[·$ša,§{?’V¯6¾¼´×µr?s¾í¼ÒnµVæb^aîÇì,¯"îo'—9ó ˯^p` ¿È™¼ÖZÚÓ^—øbgKcGi¦T"½fÿî[t‰­ÇÉÖÃå»øà­×hÏKò“ä‚‹%çÆþÉY¼vXi°Ü¦rf»o;·ò Zp+P½$+šÝö}’5éa_¯«uK!ÇØÜ+^ßÖŸ¢t®l|ÂoŒhç–Ö¶ÖY�–ıbVfc|ƒ_ÇÆÖ[Ì]9·wæÔðKz€.œ›á`_n†kÕn2Wáf—}µ¯5¾¼ë¼¾Ö™­�&³®øöŽdó«ÀÈùö[üzûú‘0€,Ö²2’ûï½ÖÝ î‘ ÀÊŠÂÆrjï<¿-N{ßJÈmWK“�“gv4³£u^S–×V"�R{gùæZÉnb³´Öھؙ륹¯»pxfv¯øn[µÕ•]6~ÑZ™‹3"r¼ +XÉnb±×8>ev¾µÚxž×<À<»™û+Ppp öF[°¯×}°¯×¥ÕXp1·çQÈ­¼×ëátNÄ«û¶³«…páÊ#ÖyM_®º¹Èg¹åT@„‚ D( +N-;Ï,m=/W]ýcÓ#"!¡ð:q›Û„‚èÄé‹Ӫ®ÃéÍ€Ûܧ9 § …Nœ&Χ¹=öíõߤ·þ æþèé¹8Ž_Ôb)Š£ß$ÿþäjÎ_ü"9Š›“_$AM(ˆ8M(¬'M(|8ÍÒàZ; + ÇÖVOÈ1T3í¶ÂØ´`A(@8�¯» ™¥ 0æøü/WM+„‚\!ɽEPs#¹;¨9.rP‹$/÷÷"ß»ë‘5'Šº—ãÖÜÿ²ì%¨ ¹²ò…QeåqZoN{nä6Ç9±$õø·þ¢çdï æʯ½Hò±ý惚+÷?÷—¥×¤5·Ç‘û^ú®E²äÔ)rò÷ÝGÞõø;¨¹_Ž|‹âøýÞZ,AÍí¸²ò8qô¤/ý÷§¯xÔ§^õ¯Ç=ò±„‚8úqɱÿxŽ•ÓQ-£&7ÉÉNŠ¤'G’$Kò“'Y!Q2%UÒBêr—¼ì¥XŽ%Y–å/ϲR¢%¡–ji)õߟÿþÅïÿøÉ_þÿÏ_ùèO¿ú-_Ÿûäg?ÅÓŸãIžåùÏó¬œè™žêi9ueWx¥WÄ +¡ Å-nÞEBAô#Yþ³"¢"šªQ{íµß~{¾ùî»oq‹Ûo¿Ç=nr“»Üå&þþûÜç®ìÊF7ªnUs½9çœwÞ¹ÈEî¹ç#9ÉI^ò’þùÉO^áŽrBå)O¹ÊUnáÞwßwÞ{ï]ìb÷Ý÷±ìd/{Ùÿýìg¯ôJG;ÚÓžvµ«ÝÒ-]ôÜk¯Š¨E‘£P w·œ¼ä$÷\ä\Ýé®ìsÿMòT£º¢+ú“zÔ£öšPàÛâØG>îQŸúÔ£þô§/=é …Ñ{/úî¹ßÞ"ª¢*¢â)žb)’â(z±‹\Ü¢Õžv´Ÿ½ìc;ïº[¸ÊSŽòÏK>r‘w¾¹e +êF÷¹Ë=nq÷½·E«Õ§þºÔºk®·Ë¦•”P8ÕTµ¤ª%µ¤iª¦hŠ¦)š +gZI+gZ¦?ýd:¦>õ©˜ö´ïÔ‚ZPEQô,GTDE´£å¨I( +Õ’ZPKj©XPÔR±T,§å´|Ë·”–r´ +ÞÒ-Ý·E[,ªEUÕTMUT­¨õ«¥Zª¤:ª^Õ®ru«Zµ¤jš¦hZIÏô§eZ¦c:¦„‚�¡P@(¼*ç4G(0<ã^lmuÝÒ‚ƒÌ.Û¾ÖøâV¸M(<¾ÆÎò�#–æjçxÕä–ö¶jŒX-G~¹,Í5šãsŽOÙ¼‚Üψc°ð*q/÷öµ—ÛÛˆ‹Ù—ÛÂdó +¢½/‰ö¾$N&ßâ +çjeðÇZmEO3ë®4Ðì¶+'^Ý•&·ZŽÌ5¯�ÅïܾTÎÙy^9íìba9fA Žs[ד¸ǘ]ìAëýØmüÎ.Ö¿4V€«ÖâƦ ¸]ÁÇàØx¥Y„ s3ðí/n»Ñ@«ÒC(ÄÜvvÛä¾ßfv{io rÛ+Ï.[«½èËU=Pu@­;芻ì<¯4Ëêsq—~äÿükþ÷Ö%Xrœ|µñeEfN qÛXØØ +òH�°­É¿ØÕËUðÙyucv¦ºìœ+ùÈ9Rü›Ó]wN“½äDú¿KNsâß çD²üåö›“äõ.9þûÞŸ÷Q{ Ž$ç lkzI. Vz‹œÈ!sl%`kW³ËÎî‹®Ü6ÆVVä–cv€•S»yJâ¾í|£½2+šÙX¼’V~¯4 }½¿9K[]#6¯œ•È9‘çÖ-Å,í&ÒZGs|®<ë¾�¶ÀöÏ#ßœ(nNô#­õ =çÁï?;¯4¸Æ’ÆOrãæ›KΉšä ò,^kð3TîÛ¶1VT°Ð¤rq9æ¶óÌŽØØZˬHÂÆV¹´ê|ä 1ÛªÝT-E2%ñÒ–ñê@ŽÅ ƒ–’ªêJý¨„ò…EÛi™_¼`½i~ð… :Ë#ÂÙ‡B0ix„‚¬#N ™B2M-ò¹;ñÒ)¢µ@€¬›G(ŒÄPk$˜ÈWb`¦‚{OG'd!öCW+«iSm‡P +Ó™EUêÈ\Ád"ûTx Ë|ÞÉFÑ Õ\n…ßVÄ+~ P[ó»•œÚ$D'EüVÈÙ)Ôm*ƱÌùBmêÀ@'ò‹Åã焳¸ìød +;ž×ö´º{ž1fËä ‹#ùšÃfKötŒæAÒñJtèrS[¡ºŠ¿P¸ 7¨ÕF”šY;j쾡heH ­ð<#ÏÔ4{Ñ&ÉÄàƒÚ—d\ ñÀ#Û@J¡6ÂH‰mÏh2S-É"n¨ËºWžÅV‰Ñ'–é¼Ç:6ƒÝN˜Ë†é0Q¥± ˆõZ#²ŒSíkWèusŒ¯5³y][¹”«3‹"‹ïs:PaÆ“jÂâƒW ”`±sÀ#ÄQ…1p &`¦Ž)똶ÄÀ›fR\ +QF%Ȧ R:˜\R 6ÇHŸD˜JÒ—2t$˜ñ1µDáeTJ°áHSòÔD“°4‰Èƒ>iP¸1Æòoñ?!Ãk)C7˜ª Íó +tKM2 Ã*ã ÅLµ}7CÁ‡kƒô±tÀOš¨y<?à)PÇÓ#‹‘Ÿ§‹T:¼-‘:h¥5;¦n3:&§q*FP¨ð•„ƒŠËgn²Í_YÑÆd@ ÙÈŸÅÆdM2JFi¾kj<üÆÐÄ—A]¥ÌƒqfÌ É‘‰Ñ5Œ©ÊN˜Y J1èækLÌøl—ŽËS]PXPµF«ž]ª¤2eEmÍD¨Ž:,8=eª?šTö|Èôu;!RÓ¥C5ó‡@Ù´¥'b”bÝ”0#P|:òl½d²ñÆ/rÆMyÚ\HP°¼ŸÅTƒL ¾m¤-h­q5‘ÆQX±ŒÖ.ÇI¥ÑɆÃæuìáòŒOXòŠ^¼ø~nÌ>/#º,Ê+ΈÆI4|(˜ $â‡Î¡è +ú3`Ëç S_Õ5ÔK,vC»;J]qàØ89b_ü6Ne€n8M}Mþ)$œŸ­Íã&ÆÝ/º[›“oiwôšÙ2ÆH²C†goPà,2Þž=:®ö=ÔÒi̤ Y£-«ŸèÙ¡ÔµÀ¹Xè–ÈzhJaŸ!ŸÐ�sCCx•aK$z„]ci®†bJ›DpLàÀ´=B„eÖJŒ`§ òš v{ÈDàìÑH±=åMFÛ<lžóq> äã3½ÇcFr Y«æP;Ëåè Êq]Gk‘UGÁûpx2î¨V ‡G("ÃüeçàódÃúŧÎÀGKž¦Yé×2`"ßê-ù§Š1_ÁêªvÖH­´VÀ}QõM„,¢c33iØRÕØ8$ÀÆgK½†/i6†G(LHfËØt/‹1€jNŒ× 1äÔva€²Á„ar8$ô¡!ÃÅV æ2/F]¡-8°æµp­©Ô"1rI 3ý:‹SÄ¢.æò@²€Œ\œ> \tS±ð… e6+VNMñ¡F˜¢#»(àE; ˜˜)â5úd⻩(R‘PDªL¢â²Åc@N([HÝDgc ±Õk¢u $$Ž)áÎNÄÆ4^¡°8[J¢`ƒ ‰ˆp-&B¯™"!®¯.QsÁ`ÄZxc{ðòl3šwš (’#!ÙtÕ܇G(p#⺘¡`Q9"˜ +CPð…î4Ñ/Ä#:2t}ÝçÔqt`bщ壳ÁÆ€äë¦Á×?ð­®eqÙµOL¢ŠkkLÏFÑX>–“ø„Ÿ ì9)|»D]É£©` ¦çõT‰d‡lI]‹.ì¤;Xi§¥A›­,gèm&oª1Ž»•Åà D:S Ñd„p¸,ÞÄù³±*R†Î¬bkòføP8‰’%†]Ç©ñß$µxB®“¢aÇéAUT®Á +š)!J‚ãañ”m�BQg÷lÎw¶N¨‰!JÇ rÀžòE¯l‚Hó T ¥üÁ3ƒ{„Œaðf£úkå(a,F÷y”.b}ª™£S,‹ £Ácò-§ fa¹yŽô‹p¸,N>®”$qªPu²HÁR„˜’NŽ@ìs0Ž•¥åJ`hÌ©G(¬d©¥±rqF†ÓÚq”Rwìz²ÐZ&Ãâ6:5cA&]DH'ËûÔ¢¢€>7•õw`a´Ûñæg¾J0í¡$¡þ +)oÄ'Bqf¡FIBª^Ofx¨ b]UŽc#gñg#²‚Ó”«˜UP>Œe/+±²Hpȇšb1 +™;‰/J2#–"u½—æÔ6sÑùþgrqB{ßÆ3ÐyF—Û%ÙHÜ4VÁ¹3/= ŒÑ�eE–³Ù* +†G(È\’Sbᜂt–ÍRëÆÎÛfòQÛ&ú|BŒBQÛ&º»¥¼;;íù&^ßV+®îƒ÷yó{±í‘H–³;Œrº[ǺŠôtÐú$¾˜ñ\´ÃÂ~ƒÁ›ÉšËäUh‘:y‰F#P™}]„°\Õ5÷|(²ó€ +œ}F‚<#ûyAV–˜7ÙMVúœP!ˆÂ +3IX¼bœNñJ/ ÆgKÙR§Ä¡eX7ê­ ëF ¦NÆÐ ª€i£.F™NÆ7“3™Õ ö€Õ<ñÒÞŒ&^ZÑùBÝ«•í5ÐÅF'…Ñh T6ÞÆ+Mú†”&=ÙÀ‡¯4é=“&]SÓØ>¢÷›FSÛ쉄 zE´nöD3Š2YÅ32YÅ3™Æœ.&2„2³óÃÈæŒÁÄXœÅ·g½NŽÙ‹ŽÀTÃL© žò(M Tr6vŠ*D”$ÔêüB¾Ò`iö[ì +<”4n±$Qp7m<¥SB—qY±RèFÀÆ¢ÁÕb`ˆ´‚É‚!ó܃JF'[E‰àpé0JÅ‘ˆÃØih‹ÞÖ-fˆqŒ*@!&¦¡L‡‰'5˜ +þ²¤N Ë7IÇõJH£o’Ž4ì!ЄtÏR’¤&Ó0¸G(ijÒpE4Jf—²­)‡ˆo'ìPø9Ct¾Ì=БU<"sRê®È­EÅ¢(¹u1MñjÇ«‹-uáÃîÃ~¶-5pE†u£¶ÔÅ”0¥Rêö uAK‰ÑÙØ|&ï™<“Yýš.¨Çx4j Æje«•Õ"d{¥IßÀF2Ù(ÈÒ¤‡ “MßÀáM³55M·}ÄM³5µ…AhjÄ‚ÐÔnš=KR"ǯNŽ‰u.›áêTáŒg;Uö Ô†û2LæÉlÎ(Æ-,«em¤)uë4¥nØ2UõKUƒJ5PfJÝ;-hDiA#-HyZòΗ¦‹øf©-ÎÔÙØ™ÿœTÛatk7ƒÚ‹�e|–ôPQ:Çb�;¹`&–ã"ÊJ4à5‚KX·Å(¨!l&¦deÙ#FOùr­4;qùȳì Jô…PŒ | ë' ¡ð!Ü bÊØÛrœ@|N=B¥ŽNº¾Žr st¤™£C}ú5ΠŸN509ºUÈ}t1™×> +DgCs뜇E×7š% +#%ƒÖÎøU‰âžÅ# ×*Žä#9<Q4Q¹…:¡]nmOñêr:} ˆ¸€Àôr3(øé´u†>Æi£`Œ‚Q0êbšNTJÝ(úI© M3¼ôš.¯é5]Ì×TB=ÎÙبl9}ÌdV—N É]ÜÑet1G£ÑéFaa4º²:\­¬~¬VV×@— Ü… “Åö]SÓpÛGô›fO›í©f×Ô4›=¹Á!kvH&“U\¦P“ÄbV-&‹eµÜN†Uí.ægé0ì@™ªÁå› u1?5M©v (Õ@u `4¥n×2Ó‚˜4n«´À H ±r66\K€LÑgáH¼´7[ÝâNò1°‡Ïëæyì’câU"c1ȪÁÑ ”ÆCª;ŒMLŽ!ú²¶LáÌ;Œ•EÇPpc€Òy9=%ZäQB¥ªð…ŽŠ/ß] PâaüŒ‹~X )ÆL„h-à¡u*À았~µytèÌü:ÐkåènŒ‚EGz­ÝÈÀäèD©£Û‘M£ó…Õ£|tœ™ùu£™£#¢E7‹)ï^ˆ"rŒüL^)·Á+ÎÆ ¨ö™fÞNøI@@þIŒ4J¨HTz–[¨/a@U@¢0ÝA¦;Ù©ÂQ§êTáŠÓéa’(ø¯.{iFoÍ_@`Ú±€< ¦·îÖìÖíèÖmØ0mK]l©‹-u1lÃú] ë¶)`›F™L¦S&¥nÔ¦€é†MÓü›É¬öÉ÷ÊÂ|DÎÆnDÎÆî3ù5]Ì×tyM¥r66ßÍ/’N¤éÄ`€ÇÇX0XîÕÊjP¨.æè´`a4ª8°0ZÑ»d²7¢Wšô.™l`†¤4ÙÀ^bãíÒd7¼Ò¤Ï ÈäÓø~Ó쉦&zMóÓhÛGôÉ4éšÚ† úžhj—o ˆÞ55Жº˜_Æ#d²å ÒØsº˜dŠoVñÌAæ0Ë*^­™¡àÊ*®®Š—Î\¾ù`ô–9Û ‰—F11¾:U8¸:U8F~+°�ƒ³‰ :&Æب‹É‡1ÌNLo™38U¸G(ØÌÙ,�QÁ;Ù0}y™ØV—V+«/¯b&Qðß9T‡É5Ÿ Â/¯EK҆ݟqŒ±îËëòÍ‹G(È'‰‚ÇåÌülbèS�¢0ý-*³£žjn*7·¬ GG¢àŠÛ*ógægño™¼åÖ%,ͬ¦Ä«bÃ4±¹tx`&³Z5HÔ@óK€ VœÍž|ª)¥ÎT‚Áºr¸,ŠÄ㘓ãØ#"NÀ9´¡G(:_hé.S^ +<ª>…<%û’±œ‰ôZ´G(ðšÅ  ÄÔm´£¨øÀͺň‘¸0Ð.Žì$bjš.9>$¯ÿ¸°PâÚi?Þa UH¾,†J|;¯!ó+ò=@7Ä H(#×Y~Ý{çœô$ÉÿØERì"8þýà¾&y)’»{Q{ îñ“]{ïÇ>–¼÷ÿK/ö¯ÿ.˱ƒ}ü=9zpÇÒÒ$øÇ^r=ŠãµèGjò +. jQÔä×#ç좖ÿs¥&ÿAïEîn®wç IŠÜß\ä¥(~ýÁ²ëÍ‘ýs Š¥ÈyRwPõæÆr‹ÿƒû‹œ(‚¥H–àÿ¢&7Ƚޜç~GÿAÑëÍ•¥&; ê=öí·ÿ[Ô¥çþ(zß©ÿ½¨7W–e×dûö nQo’kOr –Dzà¨='núN’¥ÈùÁÏõæFþÅQà/Eî¾ì çzïýGä¥ï$Xn½¹­µöãýXvk½¹QóÑ{$G­A^~­=ÁÒ‹Ýs½;XúÏy/‚ß‹\©Ç¿Ip÷Ï•{P“"Gö?vPïO( ‹bÉ9È¿Èõ¯Ç/öÞE?þ/z°Ôžóâ¸wA^–$¹ÿ,I¾½×bIÑs}ô#)öÑs¯A]–\YŽ¢÷åö£îà5ÈË’ë|ÉÒs½Ô¼ìÜ$w n=ržÁR®Ü"'A¯G’Å öý9O‚¥Ë/êíÁr{Mꑃ|ÜXŠôìüï¿G®Ü¾`É?GnPó±ûüù(îÍE ’üs¢ö{?9RäœwPäŸ#õïžä¤ÿ_ƒ»©Kü[ïQk¯Á’#(îÏ‘d¹Gì|ä|{ÔŸó|ò{ðï±û®A­ÿ/E Š{Ô½ì¾õ÷%'7˱äJOŠà=ç¹î%Hú’~䜗äØA’{Nìb/Ip%çI^’I‘KÒ{_‚äXr¥'ÿ–]äJ¿Go^þþ.r|ô#ùµ'ÿ¸A=jr +¥¡P©pšP€ý’Iòÿ –zä¼×zÿÏç .õ®¸*Üþâ÷[ºä ÷#WzþKíK±wP7ùè#÷zó.úÍI‹Ž,9ÙuéKþÁ²ü$¡P;q½ôú{~=rüs]ŠŸ“ý{Pä%'Šž,ÇM’¤æ`Ù÷ƒÛ{—Ÿÿ_’úwÔ®Üâ÷¤ËR“c÷ƒ=×|ü£÷âzÏ …X¥·Þœ$K’÷7÷»×$ç|Ü¿ºƒúÁiÎó-’âÖ»û>rê· …V…P@?YnþEÑ—žÁ’üÙÅRÜÜ‹e'Aï=Ù58’ÿ—¥rï¹Î7ù9¯{/Ëñ‹œÔ#øÇ/ŠÜóñÿ/ò’ƒü„‚k÷rwp=ÇÅ~PìžDz$¹;÷¾ü#èÉÞÁ½=§ùø¿Hv±“ôÚsÛ“%øÉω|—¤öš$ÿníKMn°$;×dË/rdß#ÈÉïuÿ"×7éߣØE¿Èq²ÿrƒ¢/ÅQùøIð‘ôbÿ$ÅÏý/Š מä.K½õØ78jßENŠ Þ~ì#ØÅOŽ%¸¹×£ÈIr‹äç`ï^,ÉRƒ_ü„*þþÉ>‚¢è·ÖÜkû?’,EßG®5Øýç¼ß|$Aí}×Zô]{{ÏwÉûÞ[»÷œ'IïÁ/þ^Žž—å¿÷ß%éùï$ïìâç<ÉArôœçä¢öå(Šß{¯ÁQüœç£ÇÑëîÒ›s®?øÅ¿5 Š¥çú.yY~>ú_‚¤ÿ„ºÿ×" òÒs~Iúñ.jQ$A]z²ë²üìä/ï]ƒ"鹑~ëq‹[‹`I~½ù8–|ô ½ÈË–ä'RnïM(À”ûÿ—ß—à¨GÞI­=8òÏ•e©·X‚$鹿É=ò.–Û øKBå<ÙÅεÈ7ËÿEñƒ\{Žwÿ·ç½wÍAñ—\$}ßeßÝ‹âîœoù'\Ynro/’}äŸ{r“$¨ÇÏ•åøÉýýî›9)rž,GQw²órÉÿ¹ÿ¿Èw×¼Ô$¸5ɽýø ”Û½‹ìàïž»øIOöïKïI‘ô`IzN;÷c¹Ç=‚$×›ë£÷ß›sqG=rž,79–]ƒãÿ„B+»Ø¹ß»ýz=r}Ô¿ä›÷Ï7¸ÇO(Ä8½å“ …[ãF(°�8qšPXy„BdŽÏ•æ«ïɲìbé»èÉ?–œsRä¤Èwçâ/·Ö¢/û^éS€—fJs|ª'§ —Ã10€7öÒ„B‹ÃiN{NsŸä>ÉyϹ½cv€•órÕ•g@~x ƒÛñ¦G(x¡Z@Ô{ÍC>üãÝ›ñ‡v$"¦‡|‡,ŒÖ!>á‚Bts1ȇ‘;ߌ,ßèWÊÕÓÅ&º™¥+ 0щv×~ÍU¤Œ@– ¸êÛ™’ow‹Î>á ƒ›ï /Dw»g6¬–Þ†«HÙÀ±ÖŽ·9³lly_n)B(8¸ã,9Þ9I(˜8i³è‰„JDIDÎó;Ùf·uJɳ–A,kÙØÜjd&E—’ùá@`¸u±ÁÍEÍ3”,CÅlÊÖBV(óã¨Êt¡:]Cbê=y„ $½6t‚h°q d°Á)ƒ2pM Ž–šY”Jn]R¶Ô¥:¥N‰Yìº[ª«áÛ0 ¡Ü´‚îX=B ã/”±!­4ñ£\@ç²YñØ×@«Ðf´˜¡Ö¯€& %1ÇÞxó{|Ç.x¨{,/ ¢N¾ÍP'¡Åo.æésù&ˆúP?0‰o`¼ù9f2«˜ÕÊêU˜tíÏÆ~ÈdoŒ$ +Þ`?¡v;>~`›C33¿NÀ°@it—œÚÓ#_+^‘o”.ŸLOèé׶¸Nœí +™HÆFá´/ˆp$ŸÍ¤E‘³wÏ50°91'“ú*o~þ»h4)¯ý{–¥cx˜ÈˆÉhXL³æPÛDç¯9Ô{Cʾlm0»ÀÓêòPÒ*Ë(Ca 62Öfž­Ãâ›Æʲêoõ×ÌäL¼e0+˜…§Y¨F4_}m…úå™orƒVAKŸZa©jÇ…ÑOkWÔaEcð 'í*Ô¯LJbË¥ü¡RÃøŽº†uNètùæÂAk˜>XT¨k`â¥óûHÞüúlÔ {(l”@6vø…:þÖ]r¸,–-IVØ”ºF;, P¯( PߺҤoÑ%Ô·YÅ¿TÑxi0s1p ƒ†äjšÇÂhƒý9cD3“A…?P ŠX?‰©`æŸWŒV èŒõ·Í\ê )ÁDÎãÍï±€À>Œ7¿Ï¦€iŒ7¿{°X­¬Á…Ösí#:h˜…ڌŻìpÕò‚¼¹Šlôã¥mÅœ:ŽîÕÏG7)SDç +Cèë4Šð–)¢Kgæ×™á£=Œ.1óÆ+匒ä Ñ7Ó.kÊγtñ„ Ë)ÛU|vÛÊó“�Dãçüj V‡ì|ŠŽ¸MP€%è@‡U‘h ¡‹År$• õ°FÌ9Ö<æT;dC)p-éܽ¡p Fg܈cEPRnBZÝmοlPäe%Ê%PšìLtdw¨‹É‡Òª‹G(Ô4‰M‚eìéô°*“P9‘o’ö‡ 2àp¨|—•Î)9<¡'b²Â­=YG§ˆ œt†,=6óÃå +-†ÇPè|Í£‹ÐZFGIȘÅÃ}q‚ØÇò¦cñÙ¥2£x„ÂÌ)žD“cû]„:çe`q¯iÏ™m¨ÔsµÑT—’1eff ˜¤Aã� ‘J&Óù´¶€J8.TBT*4 Jc8( ˆ„±…a EQ 2åÔ• b 'ܾø3OBƳîÝVßyYåâþò¢¨<:®ÐÒ…Ø$Ãu¤K²»VÙ´hÁ"t¦…ŠDÛˆ“Ó’æÍ~1¬’ÊT¾ÆŒ»ï à~:;˜RSi½´R¼¥<–dŠí⋤ô)RË›Æê‘Ò½Ÿ&çàrÑ-,D.jÙX {<šFw?ÉåÒk¬NŽªd"W$‡ ]Áî‹y"y 29˜X^®(ENì%±X¼uÿÕ½ƒš[æT_à™²9e—㈮øö¦—U ãR:Pþ/°† ¢—û«Ÿˆ§ 60LÛ\’XYô´<�%JE‡°2lºYÂÚôÚ\CBuÞíùðÒùi•=1ºa¨ûÚ†éùÔRòA'i €1Ê‚O8-G? Ç[z‚*ÄGV‰ÃÅF%Ž–#7xå{’ÖXTCÜ×½Þ—(ômeš8³%€XäÏ…MÖ8×½bÔUŸzÞ Û¤¼–MsŽ ,3é;i/µÊ +b¡eô¨Åâ‹Ö–žWgûb <-ñý(ÒÈ 1Í[ì’¬[{;àPí(¡{ç•“;ñšÉ®Ô4ÚŽ2íÞìâ.@0³X¯@pp×…žX0º hÙŽøî?eµ´GÂ%>2ÁÚ¤ÔÜ™øŒ<:gá…XÕ{®Ff©¹-XæÑ12†ø%…0 ·s>¥¨‚57«í‚¦ÿÂ$£¹&ÃÅO<ܧV'ÿ,|Kêh P Âìõ7˜lk¿Ý²,재…ðïZö¢De^s·®Í$­½µK–vOÚK]‚ÞΘ\,0‚›Ê?¿Éæ¨U¼µiN +T99¢=áVqÆùjˉèž3›àDgÚÚX1We æh±«t+4õ>æ«ÀD#Hz¤eG‡#5̲?[ÃJB¶œ£çöD„°lHtö­´È¢�|:…` /T©$vôz_ï¢a^j¸=]XTíËx—µ-v´�“Â2ãÒ3¡h…q´Ê¡÷`¡Ž�Ž�˱ÄÇhƒÞ-µÈ•-×MÉW° ÐE‹ +ŽZ*C…ZlP0!S‰d‰’N ¨éR îay‰®ŸÛ¥8ƒn¡ŸAìVÛñ}sþ‡˜µ¹Ò a³IeS:þ/^<_-®Œn$k¾q¶¾Ñ(ó (oÿø“ð¬àƒîÊè,±+| à&ä-«úò@  V`¢äzNSG\TϱlX6–ó°Sø±!!E„¢ò­c.°¬ßÖ +[0,¶ +3 !ʳ $5z‡S;qÞç §›²QǼÅ?váÉƆ]ßSÃ.‘mÇôb ’&wâ‚T B!É'MEV‚;áè˜7Ù1 Aœ¼´• ÝaÔhØ©qgª;¢ÉU¸3‘Ãh’ßçœI刦 õWgTDS\46ÎôuD“Þ™‰óÛd©ŠIÒTN²yè½8aV•Seó‹“QïzÕå©œÒÔô>š8M•Óåý‚&±îͨœˆ½þ²¬Å$æE¼Ç¿q˜ú¤ø¨­ï#£ž;dÆjIõI, $4’znp1/"±læ¶Pïb\Ñ"73JEm°?;.µO|SãmRsÓ@ÃMvª%§Í=ã"ÏÁ±RæHÿ·a>Æ(ƒWµñê)B´`áúŸB®ˆ<ä„X¯ïhuCuŸe4/® ŸkÝzdïÖˆ ÄÕ¯Dª—_­Óß œD8è¬ËË©p@¡Ñ Þ4m³}ç&¨4•G¡ŒþïzÆì•Êš 0—De  ¶O‹@!žZ— eå9¾sx‹=š$œ&ú,f`-Œy8KÄ�q\•dúI%ø }‹'¡;ºYœbÈ©ñÕG/QãøòJEÔ‰|ž¡b‚Û©ƒƒÝÚÒL 0õ[ œ\òL®¾9¤Áh'8‚4ƒ,x>U“Ò†á]î™<,\.ƒPÅ…¯O,W¹ó|îAVˆߎ! +UæœÁqþ¿Óc››éf¢wÞ£“‹Y5å@ýìâÇ àÅF¨ý:ÝÄÙbS¨¯²ÓþL pU,ý>!¸˜±'æ`vö·ßÑ…\mONPYaÞôÎôJ|­ò¨ÄÎÓW=ùË4h†³GŸ#p­}‰ØÖˆõìÃ%Üs4!4¶³$ý<$‘÷HòÏrEœ½…O2â¤‰Þ +ÕJ¥Ë ³. ÙÒ^gTŒç*œ$óuȾíaHªv\Xr»º¸=#:Ö*ªæ€‡ÇZ[þ{$Ššb éç~u�¯¬ÄãwÅ v06ùì'_‚i›ˆsþeIpg’®?Ƶ\ÇßÊwÓÌ\Šèáƒ;¹ wÈb`Û¼¨Ñi%º²ªéªŽñ#4!ýŽc +ñG*³qÇôIióÖ-ÎÉ]… w¢î4”i׫Êü\I„j¤úaþ˜S‰u¤Ò\®‡ +º +»@äc»6¸(Ñ°ÿS�.ƒ¯ô2Šyßö=õ] +«F5ï5g—?’›Wø}ä9€ëVCs«ÐÍXÑÒ¹.?‘<šÁŠÃ_Þ|!‚‰Óà .Ç×õàÄ£¿u!¯fm©L #éµÈÒÁ[ èJ×"ãÆ9ÖE2{ÌS ‡òì@bK'àÉ—Ÿ8@ ¨lÜŠKR%„y<âýAìÉ}ËԑǯãÃûy´º6Éû ƒ|WÊ/Ôô8ßMmHƒÖ Miøy')Ÿ V®‘’Œ2"Irƒ}V;¥‚ˆà¢“nÁQáŒræȈÊÇ’\¿0¢ €FzHï÷\W#±°ß:MŸ‘0®CÈßtçvÖo;Ú’²(ù½¹ÎÖE£ˆã=!Sè2á‹Wž ~ÒM\ò‘Eœ>5ªgâ´È;È(qf‹{ZP@‘Ñ–`<‚•Å¥„þ�®_ÍŽœÞâf©•MüoW¹¿>’ÞV:…ùšøM¤“:Q(z”6x§[ÑŸ*àf-|‰Dê× Ùc¿u÷-žþ­Þló~?·ËsÉâ…ä¯õ^¿3œ8/_{§ØL¼gì7Ë}·©r8®µ8¼&+Üjˆ×;|¿ÀD»ôï’ŠTGAؽvÅRËþM:¿yÁù ñ°$^ƒBÜoR¿ «‡¹°K¡ù7ë’ …³a½šhCàö½øõ +ÏÕË¢¨ ñÄ®ÂûAN¡è¿ûŠ $ÎOA \õ3À¬À7Ï®EÌ|T¹Ñ8,þ{âu–? !¹ .º¼”f3}u�ˆ%Kb·â;iß3øïm„ÀÝ +ðG¡ÚRìez1ÙÝ¿à:Ícfáòû<Ô.ŽÝM¡È0É\æüÑHCLl%yÃÓ\€i?è“̤ïý($ˆ²8Œ|@$X‰f<‹ÿÿ{„P×W¢d.ITC{7ä-kÁÄSè;²Ï-b0~v=p]Ãýš–‰ú0OwPhápNµEÀ’¯S” ]‚e71*ˆL7+ó63‚ãn‹ U„æÎ'\J%PE±c!Ú,&)ñ¦º¼ àŸÁ½ð©©g‘Ç8°šÄ_HÜmð]È&‰ƒ/“ÓJÉÍ-W’Kª˜A—´ŸY’m.øKžQØ9‡ ±·i…_ÚœÚbØ3j‘7A’#¹gI+‚ÝÜ,=DÃrÕ€�Ë^áY[aÒŽµ> _pi®¤é>¯¯…—@Zúþ»˜Pþ:‡€­ÕÐÅÃùeŽ¯¦ãMàGYF×îiŽ“Z炬r©÷ª3kN?cÙ?wG™gÇÙMˆàû¶*/öÖšXÛ]‘§•Ømî@°LT3¿½%wo[¸zÄ-ùÛxTª/(nœ@ÀòÃÚôìgè¦Do†"#%Ƴšgœ@¢m½¬ÐšÛ–áÍDd}ÀÔ´ÍSz÷×üº(ðíÜû8›'¸zú=zA1øI*¬¶"©ä—Rׯï'ºeq Žf?CÅ&HÞÅÿ*@nbtœ}y—³höysz¦è0ŸŒðöžÀ7Ç9[¥v›™ÀåÎ$÷rVwèÏt ìi`›æW ƒ]räQ JË ^`Ãò�qN(`QÅãŸ6X!ñ1î8QoT=q +Tƒ6¼‹9)PS¤5ÊÒRlß;�7lœDô¾¾ÏP2\õf_Pyߪ#ÝÂ*¼Ù8ëk÷2Ù0ÄC…U\ÐÕŸVlf%`ÈÇN~{£~P³G’†Ó†Hºrõíâ±¹7™ÜØJ\q½ò$ts}áוOÊrˆ› ÿÄw&@|·Rj¸œ©® ffþÄ[ÁÙG�à^l2+}]눴w8NNÉË ¸þüÄI™²È_Û¿W@:àò‡+p×pGÓ§ÌxH*^ƒýBŽkmêü##/·ÈÚoV ¼!MÌ*±Ú¹é±;7k›ðÏ�ÎÈ#A³Œ¸Ý1TÙŠ]ß±ÝD³DãjNÑ;e)àùE+…¥«M®åæ´M«ò†àNáDäÆ™³Õ¸sJsØ—~íJ”¡EÉf%Mi5>P®ˆPhk/yÅmÜ”Žù J™šlPZôÍ­=uã“*v¤VxM?Ñ’š§¥ñ˜1ß~´ý°ùÚ®iewU›ËAN?*®¦Óèí̇æ³Êv F¤±$o£}¦F|„ÔåÝãÃò°º¾Ž³H…^‡¶=ÿůÊ#4ÃTÂwªuUbR×’²òk’§Ø`M‚_Bï®@cK©Ìi¨‘«„\¸»ÑP³Yð%ÒHé•‘ˆK�äJc Ôy׋Þßú +ÙÿÚÜEy‚¼´ó(=¬-–Âà£Æ:*‹=0)L|sNªiéa¨N¦W8…Û…ˆD$ØtÃ3l°§Qwµ“yI¸Ê¤;ÌkWˆâ(/øÒ(@q±ý.è˜ +wl3çM$Ídþ®¥àpžþ¢Þ1*ér/Þ jbŸê×>“–/]‡Sɬ™Õ âòÅú´Pv]›L‘[. nmæî=24AvÎ?YçT˜­ÚŠ,')~S„¶ŒóÐ4ûtXR{³Ñj D@T Ë’ò‡s7Ÿe²¬C/©UºÔ%¨×ÒŠi—¨¾`T–”)¼ ºDÃq~`IõYŸXÓ_R‰Ò $.Ž’…-³ûKjMÛˆuH•bœŒ‹ëÙ!†öL¼óË”¥¸ê£YšËm`c‚ó— DXªi¦æÂ_d Ýü³ùœù‡O«dy]Q …m‡3ôsrQ¥Q6ò¿öIÌ~Éäj8õ¹>Ž,êÐOÕ´Ø jäØŽl”Ç +Yr=Mzw=KÑ€´b¶Ì}8X6Ë:êoXù�ìàiÿl8¶Æ–´ZØ°%t>OŠ²o$Àäf–4ReW¯óo±~.†y”ú³A„à8š”O"e„—´6*Ò[RnAbþ­JÂq’Þ…V|l`,íù$œàŽ­{D"ŒÂ< *EJ;çuå)#û¼õ'Ü=¥Ä…ZÔI4æ~2p´BJ„*Í…à‘´0+rx å l® Êu7KF–ÞMVç5Ñf‹“oxd_{«ftõZgre÷øDÏ’KLŠ·hRk,ô¾1©½(ß™¸©bbR.ÄIšêP—ç’@^ô©Ñ¤Š¯Õ€q}¢ŠFcLªí3aøHì6H²n-y ûhRT'p¬Ä¤\fvŠ|$mºbRZº‘ƒkÓ¤„Ñk\½½~hR¼YÎÔ¾â6»ËiÚËt¡ñþ²CŸ•gÔ¯qw~!4ªR:#ÌE’¨l?PɶîP¹&(‰,êõTáyÃ@©ŽuO§©¾ð5ÍÉú¶Å{HLG2¶ƒ1à~¥ÂÒJK¯)vô™uÊì,”ù¼zf8AÝÿŒ1ñ6m­À©Tóê-^_ Ûá`âE†Iëï”fóRµ323kt'¢ +ž?‰:‚ ¢PJ«¡¨©E.r>µV쨉Ž>FcP‘JÍàÕë4[0nDž_e­ë!ûKEV«ÿ…£ÔF0¡ÅáþÛÛ«1®8ðy ¥‡CVÎì3¢ßÀ§Oƒ &éâ3;8ªôßn`k 073Cžo|½hȦtcxÔ©Û@Œž¢ðùx¿\¯€6†¾÷câ÷Ñãdh‰MÁ&ÎëÍp’ç…dŶlÙXgwsâ|,úË­Ô¸þ®p'\:±s»T§‡j>YÇb£,Bq¬á–öùâèìCÑ1…§4ˆ†¸A};"৷Å%²„Ù2º>jøüv¦R%cåT9)Οù`Þ'äŠS6¾¤‚@‘iÊÚíÕw!ØzoH .>†Àx i“ÊÂ;è£<_côg?áp…q‚[`´ÂÙ¦ûÈ;¯.4ó| +~Í$ÿÖ&÷B_xòƒú¡ i¶ö~4”þò7d—έ"³~¤X‹à¬„u«(ReÀM? ž´Âæ +ž…— MŸì]àЊ‰#Ñ¹Õ ª„ôLv +†Š¦áИín:|B:ÕhèSx3šœL]ÆüJôòž_“*qñä ¨WINº¡Í¨ÀDy¾‰+äpð»fÔ›×»p"MØhöQ©hO̤ëäRRV>•Ëº´_Ý· ™ŠÊ?aáçm²zT!uCŸžƒ`›kÒŸ)cFâK'„ó!ÎU¿*𱕶Jˆüðh×!ÆPQ^VXd¤ÉHÌUn*uò=I%ûQÖ–‹¢Ï“ûªÉʇXÓ‹Œœ¾„MD9:9c‚*'Xö­‘™">Öƒ@æДÞ.íz,ôŒ-ÇY§±ôöÐÐ×f5lˆò§Z\b‡¬aB<ƒj¡Ä ã¥>Ê•ê!Äá;H…ÿkÀ!–ÂèNÈÞ‹7A%byãËwþH{ 3Îp°™kÖ(ˆ,ÒÁ!>&¡ðõö[Ä!^ú¢B”šøik}´>±UôS '¿•ë±¥:Cˆ9wñ!fѨ™_A„Æj5ȱ=¡û~P÷hþ!¶h b9f¯Aˆw$  ¡ÂŸžC¨kÞ­ñ¥_ZÚ.ÄÖVÇPŒQÇÆg‡ DV§¶m žõZr`1ƒâHz:œžt@“,·ÍŒÊ¦JF¼†p I½I)Á#z¯àQ�’Ĥ.ŽÁ@€Ú‡hæ¢Ðg§&´ü4uð)¡±ê»o)@Ñî…FZÅ\&rüúè¿óîÏ/G¤5Þqr“—¦J®dÔcIW„ŸÌ¸|Û*ÅãäbÆȈi%µ“Uú ×yL,ÂV¨ ˜üË•uæuÍr¢¨¿†×øÜXÔänÊËÛ‡ü褹‡Ð„„ðcðM朵À-²x³±ÆôÄËÏŽ‚Íà\A ƒ€û™cüž]߸ÆרM^—cÜÖ}XK +N,W +°’©*ÓžÙ/ + y=µJ +4 '+ý›GI”Ìë#›Ž%Op0Ua:T­LˆGô‡ÕqM‘¨gƒó>•¿ à “ ÎtÔ¼®ç§È\D}‚_w!¢ÒôXòãa5Î8<š+‚5ë¶|ƒ‡ˆ®¶*G]­é%À£À.fÀ­» ZÞàRŸG $Ûz|¥ŸbS’­®1œ0Þ`„mÄ€@Ó®ƒ(ã`eÈ öR”!ˆÖ¢ܱl³ÁŠÎ1CÈsú ö�\«ïª»ßŽ¾¢Ì&Ê*!HA(ÐíE™y$lòæÅð7ã[˜bBÔŠ|”ëÚè‘€?‹m²NjŽ…;ÛÛ +ê³uhvU}ÿsóo«iGs^vÎøNœD꘲¯*—¸Ö�%èl–zxØÈUEàŽŽ“ÇÔ·bAMõ#Åü‰4I𙿟9Œ~,«*w”VEºŽÕƒŽ)ÝÝ’ +o3VW¹Fˈù>*çP÷8Á®Òù^ß¾eMM©ì2î-¯ðÜ×ßÐ4ŽÈ<õψXR…yõVã 8e•°¦ÿë°?7˜‡,HF¥©Ø8 ×EAw„ÈWžeZvÔDB™,4CpÉXVçº<™ iy©<8’)©\o/zM;ÍüDô„^ïžmÉ÷‰Û!€ òIy¡FÕ18 ¤¤. +Ùà90 &4‚à”‰´òŸj¸îprUátpó„{.€×º ²Ý¥ÂÓ’QÏ•Õ à¢ÉºÌàò0úà „¥iS ÀÄï!ñ亮à¸�ÎTä+©Ó%f¾ù0’\vÒ +ôO<ÈÛŒÔae` +ÓÙÚ 0•÷ Åá?ú†×D€18ÂÙ–n°†zŒþUã„W)€ï=þ§µÓþ¨du|¼ãµ½#À¼ƒ~DGjYŽ0 w~±UJùc?�0pj`1Y$þ2À°^ëš*XäˆÞèú‘âiúOÝŒ²ˆúÓå“uRµ­énq²a:Ç—,ò·†'í¯sŠÅ|¢[5­~yfðþ%Îà‰+b×D,œ1ÆfRì:¯ù|1e㲎±ó_F¦Ñ © Èý$„™4dv�WŒkW›õxS|<Úsªq¡‹óëË¥6Y½k5’õ²3ÿœ/øº¦}"5)ù†+•_r­¸}H3^Ñ&‡Šãd\†iDÐ6b jÅ\⧻çœâÃôÛ0 Ïf1ËZ…ɒݩӬ̯ÝX^}Üu£?UG$Ÿ Å©n}v\­yü¤z£´m„Á«ì.tL XÁÈþÌ•âÛ€_»~ÔéÔÈ6[\ô3¸—8ý#{ÐHîódý¶0m9v•2á`Z…øyÑŠ“€£¾õ“ R’­%]%5õ7öy âÑtŸº2Ä¡`ÐÓ :D—“uð^zÈ=“ômåd|7&/–¾ã`ŸÃhÙ£öYo*H^»°Z–©€óÙ ŒQ‘¾Ä›ò|û2æUœD3é n0ˆÀ:¨O°¤oßÒf Aôóí}€¸È™wÂÂ>8C2¤ôµ´Ö¢œ RÈÊÂ1Ôþ’Tú¬¤yjS>Ê.5‡Â§VB€^¢¿(Sd¶<&ÿhkòsÔ@œˆ¯MÞ@‘$˜ÜêfðÉ:v[‘ŒkhËÏÁðô’£!é5)Œ±Éi ¸³¼Y§ÝÌhñÈ1ÎvþW‰;9V6WöëþL½Ìm>8J‘aÐmûûI·ÀœéŠßîó¹‡DI+Γ¼EO!jû!Šð^¢é   EAø@®ê…ð^ïË8Àg ‚õ…_JC×w˦Ô§¥¨©ƒú +2 +×WG©5ˆ¸_ß©V;Ô‘’»¾ÃŸ¸8£³à®Õûo!NŽë‹¢G-§|@‰Ü¸¾–Ée´htä ³o×7yTÕT ©ï ÌiH±ÁÀ¬ 0 ¢ óKdç-°”VŽÖ›~DÔÁù"8ؾ;ê]P¬S7 .näÍALVŒÏ¡æ ¹¬"„G©qh>Ypf/¨¤êŽ“D²û•^,Y< gP$7ÑàÐän˜Ø³èË9…ÃÜJl/oÑÈ®#êe£=¹§ÙÜÆ ¿ˆžÏ²Qgy‹XÜY(e§+~pxjvÄÃÓ?±/6¹¡©Z.¸Ž0ïšuhøp—‹Xf¾FvÐ r ÿé錜—®ª¡š,(DbmÖxÇNÓŒ*ÁƒÚ­?õ¢<Õ8&óÞüÂKùìZbòÒSç+ô4ÌèØ9³ƒîáÔ¹pW”7ÝáLH8 _Êök…É àðé…ÀVbGŒN'>3.ÏßÑS&O¢1§ˆÎÃ_ÏCò(Y4^ªPdæ©ï[Ã5³]¯§ø2ìè¤ü|VSäè_7ŸÝëÏ­ø Dcÿä€[wnœÌôàmÓßo©­Õßl¡®¨Ï2mà zàH°€Cˆp-‰4T‰¾•µ8ŽýxpªúÉxÃòç~ækëˆê‚ÄÚ«ô=Zº¦Ž`†´9sÒ=ú•ÏáÀï@> Yqrx)XQ}v‘0”™ ]¸ðÝ%`¹5ѽU壶úyå²L§å ZÇ ´ÕZ4éÛÔ=EùÜéö’LëwºÆž˜¦ƒ‘Wrµõ3dÌ;f. ´R0Ÿ1°PpÓ ÕùGa5Ô¯Œ@Ö§·YçF¶Ñ쥅 O— wd½ðŒWEµ¡Å6†óãD ûáôòi6/Z9£¦«/1ã©)p2XÚ*Y"ú1c°SïËè‚-”ííú+bQi®év$ŸµKU ¢Q@}žƒ^¸gw×ò*£ö•Hjîö€/!J¸ +ê1À††˜1Ñ|–7³1¿ù‰4/Vƒsì`-  çfŽÙ{ýÍç=äöã«# ¬S™†KHÅP[×4ã`~1Çgéi^È3éZšÎàÏw_>•ËÅ?¦hÁ,ÏQ¬†42¥7ycëÿ]Õd og¨.é±”!tnñõS{aΰa;Bê ž×53øê>¿¿ ˆÄS‰º±;†‹Ï…¬Z7ˆßœë/©°ª=p†˜¬šÁ.¢”ÿ¾~dŠ°²˜ŽÇ€:Ò07äˆg»u¹N € +žß‘CÆ73î¸"|9ëR©çíîbwgmÝ^¦Aúr_Lд)ÃKÔ3{®_©Ø–‰Ó‘íÅ廑awÊÀa~ 2bÿú…[Eò1_Ý¢o¹ÛDyPÌê.¡2pˆ‘/Ë +Ãr6”+6:„ñÍŽ³êb>ª! W+¼ª_¿}’àߪ¥J6%Ö—ë¨ÅÈÿ»në!þ65ËX †^†¿½»gŒ íJê…S=ªùúN1\ÞkÈÌÑa,CXrUöÄŽöoð=È M¢RÏÞ˜bÝ8Æìårnšã½&¹«,g½=âµ3[ÕvîÅlóUyX•¯«Ë/y²Q +ÆVuúª<(M×;òŠŸyÑÐ…”7 (ö½ò;ÏDw ™15F›’ŽÊÄnNâ˜)˜•¸þhaz “ Š‰¾T“Žfý‰×§ÆFcìUQVšëVe(yœwhºYæÈE³¡$f©ã–Sw*{àªAŽÔ ŠãO@F­#WÆ«1!J«–s+´}VnK9 l(}–¾1åቢ#îŽþ£±tK$¥+ýAw OLšb둽 D˜÷r¦_ÅcXÀß\ß0³VD–·T=@.bG@ºÉ:ÕEò&‡Ý“C›Œóùbîl?dÄo«&Æ4Eå½ øå[!iÍ?ÝCL›Ý?pæzSÔ½©æòAÍbê®çuèaÞ6ãF!êúÕbá…Ùáu=·J¼è[.× Én›¾£÷ R|:äà–u¬à©%ƒæ©ç¼B6¤,‡¢».£EÃ(0{$·qpùýÀ\Z;rl¢ùµç\¯„¡ +øBЭ>ÇW +áÌ™Ž•ä¡î$ð)µE ùÏ#+¼°À +Ç]áèà³­ÎP!Œùƒ)ÏÑNvéÓé´›ºŸ¶ø‡ø_€¢˜¼é¹ +ªKt› {p eX m`ZÀøXoQ´ÇL ù&H2Ó+ÑZ‹Æº¦ xïàá:&+s¤fiœyH«èȽÔ2u£‹»FŸù[4C¸gíHôŒÙ^~é$¼Q±\:µÊ/E,]]Ý[ÀZxÿ€IÕF’¯ßmٜþmhïmÓazàí+Ï°zx´Êv0ù|‹¢ò4‡üQö‰v'n›2˜Úùu”Go4¯ü‹Ç‰ì—²ßÏJ ä… yhÛ—Wô +ÉR +q©SÅ´ÍÜ ÐHÍIHuL˜x-š“8Ž.RSmL*–¼lÄ×Ø#èo|£íÜ(­‰Õ§Xñ{´¿nþ\òq†oP´Ü X`%ƒ˜²T×gCè5௸f°²RÀ…¹*Ñw×<Lrs暇%G…!¡Ù:üÎM¥9SRzH%ùÚ Ÿ×ŽC:îw½v†ûáÓ@¬y¤rÖQ!ÓPa +>§s§ÊABÄá`G›;ù”Ôœõu`] N’®N€Ü'³Šææ7 Qè¼u¡„2½Ôo1 hâ< Çt±¸Ô.¨zƒÆ&³8¼7 ´©j£à¤xÌg­ŠEaòÐ'óõôã\Ò °c1WƒG›7— k×lÚÈ9ù€!®½ˆ°‰Ñæ90]šÉN ]ÜEîûtá6Jø+d©_Cþn‰‹Î„qüÄÒ‘µ®T†÷Ÿ·#4Æ€ísà]á°êl«bIX³¿'ÜbÍè¡ê wKú` 8\‚“vy—ÉAf3>~2‘†þ­£ë’MÄ+h8ýïY“‰òÎGÙ³v|£eQ9ûN¤Ê±…°&Üé=MÝ)T‚H¢7ŸsZ@š2,»ÜXÄXYk3:lli·”J5éý«Ãwr¼Ðn䆾*7ÞÅ„gY‹C«•ÜüK—ÅÑž¹_Jå-*fŠ`¸(O‰ªgÖ¦¼òr¿¯5#‡H‰·žô¦« ä|œLsâsG7ËÌÐ#ЯÍd‘ƒwÔÆ%ÐvCÀO“5è pÚÑ\®“v ÑÅäpx›=§¶@F†ªH2yÂÑáŠz¼G膸KX¸´¢|ØfmÀÎÕ=݇—¢Örj%sV{g,­mî8Ô»¬ÈJØ„€åj0Äó?Á?z€cºÄg€.½6¤gj¼{êšm4îtvÝ•S¬è—¸AêüYBªmGÀa?ÂÕ†@X+Õ@,ÿ* €Ï¡ù’æƒVáß¹ +HMÙ ¼X°_RkËpŠX§-|,Kñ7Œ\øX<ŸT!Ç?Î@H¨B-v²¡Ð{œ™Ež õðžF2oÑqÜÞ!îê£[ z¶µÓl˜üåQ ~Öy<%Aÿ a´mü•(0ñxÀ6nÀF¸E­^¶*éXÕî1¦]|o.8.·>î!¿ƒ}𬒩ì<‘¾è§®“Þ†c쭘ÎLð\ás¬BÛ‹Ó•ˆqì©ßÈÝ_±ÂÊTF›Ö5 ÛXÓÊn& úèU*fËŒæš>‚HÁ8rر!Õù8ÀëBd<¬~GÓ[$ä%x¼ÐãÅ}ÃÄàÁ÷Eh~ÀH5 Fè6‡E¬zMQÓÆk&ä&“i(X˜ê9"E²ï£U vX*g XTšÐFZ×;Öy.ðQ`ðξ‡0tXÝ0—sÂ…2Û§ƒÌHx{*‚Ý ô6ÆÖó`Åž¬Ïê”›rÄ¡œµyüµ8Fii&JÜ“d´™÷±í؇š ¶-Ì¥€S©‚à í-í-}N#  BÇŠ@~jš{#?·­èf)·oõ°QÁ`‡)‘¥‰õå'ÉnÄ烸˜Îi ¢pœú‘cÅÞÒUš“A¾(fCpëéÉJ—û +°A ³¹|HŸ¡A£óÍö¥)­"˜R#\DX CtÀS\«’•[%’ÿÊÌcv± âmÕL0 ì×e> Ðù‘¼ÏIÕhIJÝDD 1NøãàÃêÛ5Ÿ[ »ðMN|ÏF—ÿÒêtåƲÉìÍØÓ}ÿÝÃÙËé:[Ì&A\V@^}O,,UîŠv‰ù¶yµ‡ìP3Û7tÖ±AËn…bdc®‘ ¯¼–¶y8t©¯Ó8uŸ%AÑÑä/«ƒªøþ™$—†"ßþ@Î_ÿ­5TëÜ„W¢Ç­¥%±_ðÊèh¼®Ñö.J¥÷H—Óí×dé,Ï[TryôXÃ<'R^\Õ#wï>Ѹ ½ D9“Žƒ°áAA¡óvÕÛ`çv™3”Ç”¼‹ uî—[E¤[æ\äïšGzLN›ú•ûaJIfx¨,ñ\Œ]•Ñ:Y8)LøÌB£Š)àKR&YÛsû×  $3­ÇŽdiv )”˜¢hì”\àöÀ„êÀFøã¾ý®”B'6{ttÌæ›KY„¡žÐ©†ßÕKo¶<ÿ&î>”œFˆ—ËxX“àˆI q@ivFãŸí9MÏ`Â=k2|‡ä(í Dx.Àx®’É¡ys P«Ð¥îD<  v3& +¼c­ûŠ_ìë>Ðý@júÕ+•3PCYjp1†Íy³åÀÏ f¦Ÿ¨èÌ©—á¡Vc±”¦Šr*Ä‹2¾fóy²ðËo¢‹ Ÿ¿-ÔÛÈà ¡“´FI€@jˆ&DæêÌ°Â5C[¯©ÝÙ#}‘¬Tkœ%õë¿Ô~-ã15žtIˆ4+?DªFºDžÌ@àÍ˧HŸ‰ÖK–øU¦frÈÃ8nœ¡©¯¤…}ií;„/”¦ 2*³¥1ÔAä/¥ñ=”k£<ª#1É %÷èÒš¸¬©1°d7X>QþÅ[$1ÅÚ‘ýŠ4DC“–hcYc i™KçØ¢×”ûüyÿGí7”Ô¼?¦#`n:HhDI… kh=îìD0ˆ1œÞ ñâ»t +žPîd̨1¶»§‚i¬/@Ú㤻ú»TÜ€Òÿ¡!(î x˜#²±s„n;‚@Áb«á[ç`•TfÓ6óÕJ‘ˆ¥Ï‚ƒâ馆 Ö®7}\{—i´Þ^Ð*rîÎÚd!¨¡‰<@{-I›3Ô¼‡˜¼bŒg ­ WÞ‡OøñXìû˜ð ð®Zùuó}™ôÓ˜¿:’‡Ó$Z¹&/ŽqÓ+“¯ÂëF˜ÿ¶ðíÇ™®ŠÐѲêÿÂÑcBY¸óë¢WÔɆ¨'›\íò˜ˆ÷P“ÁQÄòÄÝs8ØP½YÙ÷ ² "1å’*i­7zIá3%x@ÚHñy#­dµ¡QTîÿþžÜ` +©·uH¼Ö®Â¾»yh];ï?DÁZ +{fã GüËùm¦¾éκ'™£èEðÄ8ŒÆÆC¨} úœ‰I"Qqd„“>á¥}zñ¶RXŘ)àYvÕ9£„‡qc_¥/ûͫ‚4Á°ÔÅÕ'G+ŠXš‡™C2<2‡ , €QÜ©d`õÒÙy§VµÆ.‰æ§ÁeqsÊU¨r’u¢º.9t¶wÅé½kIü‚Û%›4GÜxK¿ö22°¦ˆ'3¢0¨ÆÇÇÜ’ 57:qÔQٳɆ"a6Cþ‰8‚õ‹„Ø—<ºm1]ʯòVµê)©ŠÂh8©‹^{… ()$8PˆÓ߬€ldÊHep]|=p/JÐEãéK~`çZ‹¡[Òn«ÖPÖ3BólR–n˜Bã—1ë/sIÇ4ø©SnkãO|÷è(ôK ÙžXÔó€á”8x4ƒQÂjœ%ð5æJÔ€W(Ùñ²¢$ןÉÖŒ¶;³¸[9Ã{¿SS¿›í[Ì÷\ç–ôÄÚ!ˆø&‘úc¾¦¥Ÿ’ÏüŽê<jëU!Ÿ +lîå¹q»…hhû òtdlE«ƒ§(%W{²³©®êz4 !P$O¨Wà*Ú>hŠ(àÓ'è¨Ú¸*u×Ç”QI©‰JscðÛó¨$­6÷a¼Þ\“»X¿û~‚ƒœÖ<¬^î·• +3^O”C¬Dms·ráÛ˜&4S9Fê7TË_>4äJ>`0[Ö‰š¢-šp ¶>“;hÖÊ4^âîôKÞ>2)_U_[¹ÅLšÒnŸÃWm.D•,2Šî³o)aÜÙ~Nzâã¼+ý6 ìïÿª‰@^¨@CkÃXjšï©¥–(óQ¸Nˆå™¸¼\=ÿã²½Ø2…~ëÑ¡&u·Ô€n¬¤1̼Š/¸<"þŽô†ƒáµ?ãYÆòV18FüMÄ`¤ä¡ñƒYCéMâtS/ ¯Tׄ PÆlaÇ$}¥¡Š”V!5!Ò$yÏØ슖b7¹I™U<åz(Š©£k¹ZH-óU=êçšÅˆ§@Î_bîá âñÙf±}rÎ*b b~S_ñAœ÷ÿ‰°^[g8-} !‡Ýër ‰FÜßÆm]kIlþ÷ ¿ÜK™Ôü˜é¢3T¢ÈÒÆ’¼>~¸dÝÊXM Ës»–®!<êþéAÑ•œ˜ïiCj›ïd&Â¥y^øÕ½ j¤³ðÿÃ'“Ʊ>wú˜ +ζ?gôsŽÈìçÀ5òp,i¸ÙwløÔ:’=µ<‘`ßr&}ÏŸò¿Ý­ð³üÜCþjâIqM‡´žÃOÈœ´œÆþÂÅÛ戎£n!øý§Þd‹é%¥Ž(oB¢SäŸF•Ì‚Zœ?£0(vS͘ÃëÒ A² Ý^éÿ)Ïaö;VÉÍ5«¹bEwŽ^×á”öè¶E8È°ðOŽÇ{šÓpSÇ[ÄÅŒÍjy%!žw HèGw1ßFæç0¾H²§ÚýᆦŸ——z- Jê¡f´ó©Nu!Io€ ;o˜ èoÙöÔ´²ä8 棵"¿C¸ å|ö wÖÊqz©YœÅÅðų„Ý?¬4Fjí«Q—À_m1¹¯^áôK(®F4—þ÷o_þy*åÎaÅÙiÎq¦w½D5Ã%Ìcªdyµ%ƒóæݨÜÇškË?Ú¥S¯5©R‚Ëyk‡Ó~¯T#²PÕëBè×K¸àH¥$ž»¸)òô'z¶‹4Ö„n‘¡ÁÞpœÄ¥´‹ÓC'u´c¢^^öë†À+¥×B¤ãŽjv,íS®q“XÒHåÏç:ôvÞi‰ñý1å7ûH]Ù„-„yºF4û‚²PwÒ?¬(/xŸ‡¬oZ]¬A=FLþ‹`ÇÆsRü|Í´xl“Ó<å½½‘Ä1ªÞá“3¤Ä¶âƒJ€±*ö‚³pÅg²G܆hÎN,iï ÉM2´[ôoÊjŸbþòm…–ÖBV‡F¾‚‰4­u)¥ü«šÕ^çãŠ+Ž‡×ôé·å._Ÿç³ ŽCÑ“[šŽ'(ºJXr“;÷åÚ»öbˆ¡BrÂýßyB¦ø¡ûÀõ) ©­q ŒeŽ\®^y‚Š§ aœ®Ù= ŽòÚÓÛµsŽ½v€Ža=­WVtyÆøéðr¾ËÂïò.Aès Ìm¨ÉÒä*ë”/«ýÁ -ž€Ò°÷¾‘èöw¹^4b£æÚcÕL*d!PÊ 0Z¶G×·Gâ±ë3—´3Ev·pÞ˜~U +òz˜¥yÑt±„ìa7%é+Ù/v·ý¹ùd–úaXµÉr–Rw‘ôK’ÃãM‰ï‚Œ0Q5ŽL¥~´29ÌKÌžIGKù¢$ÆZ•‰}3u[ +}6/zQÒ¿”Ë;õqg^ìÊFURý”à= /õÆ_™>0ï~(83Û¤œÏîLMþG]:GI:ç°Ïœ¡ƒ‰ŽˆZ¢“¼,jX §Rf’«£mÆ]’¥uôUs2¶+ã?mrv7Én!ÊÎï!QJ‹H½rš*…Žâœ±æÆÒzutµ^BV AÕ›ÛJè5=†?ŸùœÛaÖXZ¥wtÅÓ—Btÿð•%7¼!¢œåx¥ì¨M†KSwñ¹.Æ×*TŽËŠûÀ<éÅ’Ò_;" º47ÊØŸC)VÊË\}Y8®ŸA–i(íɵ‘mQ4÷ä4CºÖ ‘4?’ÝYšŠírsÔøªG(ÎÁ;昛µrfeV‘åÕœ8TÆô!Z5oWîÔ0姢ñÔÚ¡¹Ó§×M-+­#„2™KŒy¤<_Ó÷ñ$š!5%ô´#“œ 쩤žauåCë•L]œ² +IÊ®<)hCÙz¥wGq‡Â(í#„(ö{ÊHNK.±•Ä‰s#çæŒPZ+ù¡hIbkHðCF‹ß VîC‘7·ÊFbbJH,×Vš$-`ð ŽÍ'T6ò(ƒCÑ|ƒäª³ôz]±7ú{È—ySl¤"¢ ‡Nê†QoÄp(L¿j£¬YR"š,Ak3ó @Ð"8DC…   D +  Ñ0ƒ„ *4@ ¡‚äრ+"<€¡Ã 4T ¡Aƒ``  €ð<0!ÂCT P¯æ(²e46V?ÊÑ‘vÝ?C'…ƒ u¯Ï¤áXµÖž`¾7–EyØŠÍQ¾‹˜\Eü=ÌŒÊkb¸p¸µö¦©E ð¶(ª LØÜ$w‡¡ý¤8r´RiœÔt%&ОpÒo§å0CD–˜T8ìWƾ3'çC*ªïrZZý áH°£ +9}¸j.”ÊIº2)P&ÿ€]#í(vad²}ß$‰xQŠs!ÿ Ö+¨MµÔp6ž)"¦ÐÕzDÊw¹úœÇ“Oaغrù;€,‰6£÷¯e{XN“Ùn1}kµ™G$]˜O효 )ÑÖÙÏäÄ ‹a@å¡cA\-Ãñ}K™ 8pY1#0%hsI¦¿£$ qz +"q3uîvÚÂ| O8V"áKJ}I+M{vr%—Iág‹^ÔïüxÚ裵’Â"Ž†á[×üç€!tt;uð¹STȬz’lÂü·ô;súªÄ\À–.œ/ÍÜIBŸÂÚøÈ-“e…*:~¢ÞZ>CÝw ‡¡Ì®-H,™úÊ }¢“l›œäͧi¼2_Í¡bL×1™ U½™¨1HI+¬0ÕÛÓ’žÄ¤ÇL 4&’}Pë9 ¬×*+ ½Gh¹T–”›¿3*fX…Ñ1ŸX&yc;B×´—Nü‰t¡Ê¨XLp73I;wÀoö@N·¦,´5Äm.€6¯cãñã*a€ÒÉ̹ØÄš/„Üú2ÈÜ7LWà´¶ÛÐþióŒæiíEvÇu¡ß%æpúwžµ5Ñ»Ÿå‡°,·¸Æ››x +u €Ìvomý©t± .í­ï<+z% ˆW¿ ê¢Ð;c[ OH(!ªJÓF?YÎŒ‹Ë(ß }s½Üx\!ÄæØú}ö.·ÇFx/­K£yô•3Ÿc$5û˜Kd]²jÏzð”dŸÇÚ{Þ‚O–Á¸H´²ÇÞ19¯Ý;ä1}¹ðàpe¼PpÃqÈæîǪ´Ž[…3r“Ö³ý–º®P²ð¢¥ »ÂŽ…NÓ2h”Ê–¬æä3 ĸkMfÏzô•œñ°PK€Žà<‹Åì+Nq ¯î*@\O¬$²8mW $½ðC1ï6­U†*¬ÈíCѬ>š¨ñöÁÔ¹I`©Ë½B5‘ä-(-§CýÍàüM“^"gßÆ 3vǤ‹ÌÀn±QsJ Êf>¤} +c°•>6³‚4Au/k‚eà2ˆL)YZ4Ô”ØßEh1€`çQOBX€->ò9VߤB|ŠË‰ø—ÒÍ’~‡Ë²™!=g% ddA%â…UÐãÌü­³#îas#Žb‡ÄŸI›: :F:ÄœQ;¤mÖ67ÒNÿØóóx³(.[C¿Ÿé¿¨›{+°ƒJ—€¾í`/ ÂtñWP´ +<‘À@ +endstream endobj 27 0 obj [/Indexed/DeviceRGB 255 28 0 R] endobj 28 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 25 0 obj <> endobj 23 0 obj [/ICCBased 30 0 R] endobj 29 0 obj <> endobj 31 0 obj <> endobj 30 0 obj <>stream +H‰œ–yTSwÇoÉž•°Ãc [€°5, ‹ì ˆBHBK!aPªVÊX·Ñ=uº¸Žµ:X÷©KÔè£ãÐZ\;v^àõ´™N¿üÞçÜß½÷ý~÷Þw΀.MÑh«aUZƒ>31[”_€‘& (€DȵºÔ¬„l€K/Ájq'ðVO¯›V®¥éþ?±:½O“Žs€RU«À¹çÊzƒÎdŸÁ™WRab5±? Ζ&Vϳ÷œÏSº7åÁâT¥rc¥3ÕMQ]YmÔcµ:¹B… :Ä¿9ð—Ïá©*UéUZ<"Ÿ2V·[«Ô4ÕZL£ýOMüa?Ñü\ã⎽¼"ÀºÈÈ?.”KHá6|zÓ·J.HÇŸy÷æç~NÐϳÂ}¦¥V£ž‹“dfc +£¾n~ÏôY &à+`œ;ÂA4ˆI dƒ|°(@¨zPZ@;è=`=؆Áv0vƒýà ƒàÏà<ø\·À$˜Á x +^AD‚²‚ WÈ ò‡ÄP$¥@™P>T ©!-d„Z PÔ C; ÝС£Ð èt ú +š‚@ßA/a¦Ã<Øvƒ}a1'ÃÙðX ×ÀMp'¼‚Gá}ðaø|¾OÂáY 4„8"BDŒH4¤)EôH+Ò "£È~är¹‚L"(å¢*DÃQ)šƒ*дíE‡Ñ]èaô4zBgÐ×Á–àE#È‹jB=¡‹0HØIøˆp†p0MxJ$ùD1„(%æˉÍÄ^âVââqâ%â]â,‰D²"y‘"Hi$9É@ê"m!í#}FºLš&='ÓÈdr¹€¬%wÉ{ÈŸ’/“ï‘_QXWJ%¢¤4Rú(c”c”‹”iÊ+*›* FP³©åÔvêu?õ õ6õ Fs¢…Ò2hÚrÚí´ÏiS´tÝ“.¡ÒôuôéÇé_ÑŸ0 7F4£€a`¬cìfœb|ÍxnÆ5ó1“™)ÍÚÌFÌ›]6{̤0]™1Ì¥Ì&æ óó"ó‹ÂrcIXrV+k„u”uƒ5Ëæ²Eì4v»—½‡}Ž}ŸCâ¸qâ9JN'çÎ)Î].ÂuæJ¸ +î +î÷ wšGä x2^9¯‡÷{ÞoÆœchžkÞ`>bþ‰ù$á»ñeüJ~ÿ ÿ:ÿ¥…EŒ…ÊbÅ~‹ËÏ,m,£-U–Ý–,¯Y¾´Â¬â­*¬6X[ݱF­=­3¬ë­·YŸ±~dó ·QØtÛ´¹i ÛzÚfÚ6Û~`{ÁvÖÎÞ.ÑNg·Åî”Ý#{¾}´}¹ý€ý§ö¸‘‡‡ÏþŽ™c1X%6„Æfm¥ŽFÇŽŽ¯œN9NNœî8SÅÎ¥ÎÎ'g\\R]Z\öºÜt¥¸Š]Ë\7»žu}æ&pËs[å6îv_`) š{·ÝîQî5î£îW=ˆb +­_zžAžež#ž½`¯`/×V¯KÞïPo­÷¨÷ !]#¬îNùð}R|:|Æ}ûºøønð=ëûÚ/ȯÒoÌï–ˆ#JuˆŽ‰¾ó÷ôWøø_ `$´ ø6Ð+P¸-ð¯AÜ Ô UA'ƒþ¬Þü Ä%¤8ä½bž8]Ü+þ<”Úúqè‹°à0CØÁ°† Ã+Â÷„ß_ X Z0¶àn„S„PE¨úU÷J#JûKï«#ÔÕÊ¢ÊËi$šaÍ·åÒòíåÏ*Ò*>¬ø±2¯ò@¹ª¸ê¨–£­Ðž®¶¯n¨¾¤óÒué&kÂj6ÕÌè“õ;k¡Ú%µG <ügê‚ÑݸÒ8UY7R÷¼>·þP»AÛp¡Ñ³qM㽦„¦ß5£ÍŠæ“-Ž-í-SËb–íh…ZKZO¶9·u¶M/O\¾«Ú^Ñþ—¿ŽþŽïWä­8Öi×¹¼óîÊÄ•{»Ìºô]7V…¯Ú¾]­Y=±&`Í–5¯»•Ý_ôøõ öüЫèýb­híÐÚו®›è îÛ¶ž¸^»þú†¨ »úÙýMýw7¦n<<€ t|¿©hÓ¹ÁÀÁ훩››'‡þ ¥ZþL˜¸™$™™üš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 20 0 obj <> endobj 32 0 obj [/View/Design] endobj 33 0 obj <>>> endobj 24 0 obj <> endobj 21 0 obj [20 0 R] endobj 34 0 obj <> endobj xref +0 35 +0000000004 65535 f +0000000016 00000 n +0000000147 00000 n +0000031549 00000 n +0000000000 00000 f +0000031600 00000 n +0000000000 00000 f +0000000000 00000 f +0000034984 00000 n +0000035056 00000 n +0000035196 00000 n +0000036741 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000074340 00000 n +0000074643 00000 n +0000032013 00000 n +0000071439 00000 n +0000074530 00000 n +0000071296 00000 n +0000034394 00000 n +0000070734 00000 n +0000070782 00000 n +0000071474 00000 n +0000071690 00000 n +0000071569 00000 n +0000074414 00000 n +0000074445 00000 n +0000074668 00000 n +trailer +<<3F9D57520422354FAF7DE2FF9AF072C8>]>> +startxref +74850 +%%EOF diff --git a/docs/static/images/branding/logo.png b/docs/static/images/branding/logo.png index 2d95bf303..66b52591e 100644 Binary files a/docs/static/images/branding/logo.png and b/docs/static/images/branding/logo.png differ diff --git a/docs/static/images/branding/logo.psd b/docs/static/images/branding/logo.psd index 227f7cc04..f3df15a6a 100644 Binary files a/docs/static/images/branding/logo.psd and b/docs/static/images/branding/logo.psd differ diff --git a/docs/static/images/branding/logo.svg b/docs/static/images/branding/logo.svg index f96242fc8..9ccefe8cb 100644 --- a/docs/static/images/branding/logo.svg +++ b/docs/static/images/branding/logo.svg @@ -1,3 +1,70 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/images/branding/title.ai b/docs/static/images/branding/title.ai new file mode 100644 index 000000000..3e5a9ff70 --- /dev/null +++ b/docs/static/images/branding/title.ai @@ -0,0 +1,442 @@ +%PDF-1.6 %âãÏÓ +1 0 obj <>/OCGs[20 0 R 21 0 R 22 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator 27.0 (Windows) + 2022-12-15T21:09:27+11:00 + 2022-12-15T21:09:28+11:00 + 2022-12-15T21:09:28+11:00 + + + + 256 + 72 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgASAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4ql2v+YdH0DTZNS1a5 S1tI9uTdWY9FRRuzHwGWYsUskqiLKJSAFl4L5s/5yB8z6vc/UPKds1hFI3CKXgJryWvQKtGRK+AD H3zd4ezIQF5Df3OJLOTsEph/J/8AN7zWwu9XdouXxLJqtw5bfwjHquvyKjJS1uDHtH7Ax8Kcub2D 8oPyxvPItnqK3l+t5PqDxMY4gwijEIYfDy3JbnuaDoM1Ws1QykUKpycWPheg5htrsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqB13W9P0PSbnVdQk9K0tULyN 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 xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kv/2Q== + + + + 3 + + + xmp.did:33ff98ee-93c4-e448-90bf-017ad67f2b0f + xmp.did:feeeff93-18d2-154f-91b1-dcb9a891b83b + + + application/pdf + + + title + + + uuid:4c58594d-e54e-45cb-9326-ea8664fbdb6c + xmp.did:13c369db-b32e-6c42-8256-cc013e6bc61e + xmp.did:bb445aef-f4e7-0a4b-92cd-a45b02125d73 + proof:pdf + + + + created + xmp.iid:bb445aef-f4e7-0a4b-92cd-a45b02125d73 + 2022-12-15T12:47:03+11:00 + Adobe Photoshop 24.1 (Windows) + + + saved + xmp.iid:13c369db-b32e-6c42-8256-cc013e6bc61e + 2022-12-15T21:09:24+11:00 + Adobe Illustrator 27.0 (Windows) + / + + + + + xmp.iid:bb445aef-f4e7-0a4b-92cd-a45b02125d73 + xmp.did:bb445aef-f4e7-0a4b-92cd-a45b02125d73 + xmp.did:bb445aef-f4e7-0a4b-92cd-a45b02125d73 + + 1 + 900000/10000 + 900000/10000 + 2 + 1 + 1280 + 640 + 1 + False + False + + 1024.000000 + 512.000000 + Points + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + AIRobin + Adobe PDF library 16.07 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 5 0 obj <>/ExtGState<>/Properties<>/Shading<>>>/Thumb 28 0 R/TrimBox[0.0 0.0 1024.0 512.0]/Type/Page/PieceInfo<>>> endobj 24 0 obj <>stream +H‰Ä—ÍŽ$Ç „ïýõ][ùŸyÕZðI0¬ûÀöz¬÷ý¬î™ZÛgAÀj¢+™É$ƒA槿}Þ>ýòùØ~úËçíöívl-å-¹nwýõïÜþ¾ýqûôù·c{û¾{®ƒKšü;Ò¶}ãë_ùú¯ï·o[ÚþKÛJu_“MrY{kemo_oúôõv?ö£¥ížòžÛÚúÞGÙî9í³oiì)/PÝk›ÛÛ-c½ôÃ`—¶Õ´÷ÒxÀ÷Z÷y´í>öup­νÕ–cd­m=o,mÇÜòÜŸrÙûÊ,MeOüá} W9Æ–°+Ã`«ÊVs+y_eâum{íÕ›6ö +wòØZÙë,þ¦­ÛØ«¯}l=ïãkÞëh['*BÇ^SaiïûÚÊô.½á!'â‘j}ãþÜ—…mŸÛ øñe>îÞ§Ñ "¥+Þ±rpÒSŠ]û sÞ:'ϰȃÖ÷9küPu“¬Ýp~õ­.‚UâÛÔâÚñ`ú‡²þL ï¾xdƒ¤ÜËØ;'³¼Ù¯NPù6�lVuîûê¼ò˜ýC›„/zÀŽ7œ¶DŠ"J™$/^fÎèdÝIÊ‚#wH$ë4Iƒ¼›£i’É3D‹c&W(J³²M8¼²)sÇOû5yqu“ +Ÿ³™.$—•Q’7“#ñV ?ª2ÔÈ»ôµøÃ< +¿µs;èŒÈõÃ}B墕–Ü­:Gj[ƒ$IšD!á_KÞSÂ?¹¨a¢M±Zs€”±I¿§D£·0N#UØá«,5„`¸n¡~wÙÓD²ZˆyKªM•’bfÁÏœ”ÕZª‘·fIN ·èqÕkôë5búYg_W´D÷åù õÈ›<éh¯G%Á±Î¦o÷]Ä +@M‘€ó›¶ÎÎOÀ,1IÍHbù?B~þ… ðS̃)æA(|ëIÆ +A|}â´ R…´LB¢ÿÆ‹»lFxzR¸ó[>¥ÊäŠOÛF8‹f!*%K ³‘'¸äŠÃÖFáz1ÍGÕ†ôuˆ/´Mf2ýˆeŠ¯Y÷ØÓ5H°¹IJ µ]‚êŒ}ÄØ¢‡fRÃIüq*7Ï EÚ/JŒ{ñùÈ0å\-‘Tï[FP ‡©+[ &­ÏÕú;çu/ÓY•ª FiÖô}¬4z!Ú¶xÅ'¦m)S}J#œ²êmeqû´}ÇaËå5ôIæ5g5’>ÔÝ@„Â7¸à¸ü@2²W—¨ö@¢6-vG¼â‡³Oêtí%Á‡"™VðF}kPÉ'Ç^ðñ„g)Až¤]W{aØ_6£eEêI‘ ¹3^1¶-êG8±ú9òÔ`Ô²C¸–m?⇱CŠ~¯‘u™þ²EëS𬮦¡c’A µð7>¹)]±,»²-ì>2]ðúÚ}sMvÞnWüxbU€µ£u;ž¸Aˆ`2ª+˜BÉO„ Æv:niuq°M˃ʇàEÑZ¿¯øa¬`d‡OH/Öby0 +)‰˜_ðãÓYÏ“†%,Ìáëæç±ïSFš\þ&¢›¬éS•m+F + »â0•”²«5"5ê@g¡Óö‡­28¦2úÚ™ûÀÖUÅ‹i²Èô”eÑ`›g6ßæÔqf. I¸ÜÙ®XaÓÌ8ÒEªµQ $©¡:xœVÒÙFÄ ”öDŒOjs§é ?^8å?I6ª‚œ#FMS'’vDX˜ò+ÉN¡dµŠçZåüŠSûaÑŸ›ªA¸DnN9õÔtÅa{t+ªž{ %£»M57^ñŠÃgs+ʺffCÔÝ>ñ±3­ÓöË6Iý³æ|Î…¾9Ú%i¯PDO¦ +uX*ߪè¦WùmKð‘k5r|+Ö™ &íIïo…D4ͪMáœ#ÈWŒ)}‰:Ï<]%o ªP CÍþíva8›!¿jÛH,ÞΩH¨Ùò#Æ”I«·g¢[r%šøËÄz®-¶½àÇ S×C­sØ*q‡ÿTùi»¼`X©Ä@$T5N¨E4=UÙ?ŸãßËôÐØ”“Gv4{£çTA%K©… _±R|ìžâkС:žÉ”­è… +‡Ðø…{ÅØJƒ€îÀuF@‹5ÆÈwóËò† +¯úaõÚÓP +tŽ,£ž¦ï8l»UM¡©S\ïgqS [©õ…ßn?þòð/4š‹M*gQ·²]õâíOP¬BOnõy篷R»g1"tèUjý7¨ÃÒܪsr,õüˆ·B{:ÔÑ]žE•­öˆS!’z0R=à ~KÁŽª¶Xá¤ò¢oT=TÈéÑ¢Ù\ñãëµèÕMõ* šÝoÆ –mU[Ô$¬Šª1²sk¡˜OŠÙñb˜ýšò€ÂZ°¦mpA/ŸñD˜^ðã‰5 ¸Ñ>q®j_FÒ¤.–ÕÆs¯~¼0±Ÿ²õ¸­FÀLZKµ”Ã\w˜P–Ä;™qªª+}ßJíM=*EÎå£øEAÐcã©ed9—×–¥+,y? "2wÁýújqï 9o%ÞžK¯8ørÎÂE«¿RGtcih”Hz0»blPMN:ˆ¡ü‡ø²Ù‘ãÈ𽟢_ F•ÿ™Wk}4‹½ø>°áCË€Wïl|ÁêQWÁ:é`ÙYY™d0Ü.Å9˜O“]˜t¹‹C@‡Áêë­eÞT…ç¢b&”TW‘éÔ-æ9¥ŽÕ̺Ù=¼¨¶‰h­Ljz÷dSdÉíº54.'A$P®C7ÉÜŸv`¬œm.îM3W¼ár5zR'ËMa¾E²Oö‘*.¥”WQkUm: tîr×· ËÃ>¾þâÑÙÅ°ßó)J…ж~ŽÒ?A†nœ÷´«6žþ÷›ñ鳎ðþõŽ¦ú+‚ÓߢJ¸}ÿóã„ÝÓ}׿tïô¶´'Ó ürãþnÖÖú+÷–À²ž¥Óõ<ÀÚ–Ý`Ã||˜p6D#@ýø!Ó†y+!Ö„'® E·RGÊÚ_ÊÇÂÅ ¿5C·ÊߊùL@ªÞ‘¼ß¥ µz«÷ÝÒc«Æc;jkk1 +Z–b(Цp?SL0j¬=�`è+ÉìnC@C Ä:ºÆ[}þ »ë\O#ÁôZ6Lea>žfÒŽÔˆ?6®æ(1Ò)µ4]q…Š“ë¨U©ŠßVMæ´ñéT4ž`)rvTýÌgw¾«uVÐ,ÀöÙ§Õ»uÑfaÝŽ‰MYhÿ@d40ñ~ûè}@ç2 ~�Ç)r»Ø9üÖ€N<Î#µê™bÈ06EµUš‹X‹5Çüf•hm¶]=þ©“=éýn«F‰•ç7$T6î:ý¾v‚ÙÌb�+5#MU/U 7 ÈYý«±V —°`Ø“êèjb‚G˜�Q±™*7túÀ 'lµÐÄeñáJÍiOr‚Á-*3 …´âzþ $¾Íç²ÎUc•Šn½l-&ði«ëIFªÇa,a$cŒúñ<Ç:UÃF>˜ÜΦŠ.Ïo¦Êc4æ&ƒˆ„ˆIŒ±È€ÂšÒ3«É§Ôóò;.-cøÁ�¸¦†ûºY¬˜Ýöûi;•ÒàAuÕjàº~£ú‡û[¸ž†¤'Z)8 +ñV[oË„§F·‰;úˆºá R. uµÍˆSµ×!w]n¢Ua{«ùù+À¨Óü 7½§XJCÍ6‘Y™ÁóxFQºª[¹Áª teqG{²¶;^¤wð¼ˆ&¬¢æ<Ó +0Òç(™ÌR¿‹·A¢n\†°éÔ•cøî6ê/Pü¯¯Ã0Í•—ŽAå2ÜÜÖ°¨ˆNGM ŘyXâIn;¨+jz1+ cÈSk±pF«3�³ˆÉ¥x¶oîc(wM7oÙ*RÝâ ÉYñÝáÏæ¢Oò¨L'Ïg““PpéxÇ PkF¯”™÷šä@éÏ¿|¾ß>ýûóýÓ/Ÿóý§ÉB¾&Eg2G6‚"ìQ[`Ò 5©“eÅ#ÍÅÆIªg +|˜»ÕçÕó¸¡Í5?É£Ó1<*{zŽ™-°ëò7«éèêy„Gú5k Ø÷º.S2}E‰–JÂ!vÏÅç8{öìÊÀÓc[r²k½ìñêÑQõÜõž,†J‹K_§-¨%Å> 2M0Q@…üÎ, PôŠ„t ³ÔøÒ]ù9K¢gÁi¬é-ÎÂz›_¦46à ªuß>”=rÛ\rõ°…^%â`§ }fù@%KëÜ…A‹É2‚qñh½¹u+Á虆rbÊí^™´÷‚"-ö8{HŠ¦ a·ì$Rw™”V³ÝÕùÒ¢}$¿‘âöX"8!ÞßMŒL:)æ\Þäœ3N^ Ò‹G{èÝæéþt_Ùrb[kñËÞàäà}Ñ…¨•Tí¬OEØÏÜCM@Ca1¬æœ\<܃ƒŒ7¦U#ï´‡Î!* ·Œd«æ΋‡c Oð$Z~šê)ÌL–Uœ;eÑÕq”뫇Œ ¿{lÁ$>®”ibº+÷+¢ß=àþõ1Ãf1þ¨}æîCO¥Õóãë’†bR•Y•5zéËí§_ïŸþûÇ~ÿúÇýç_ïÿ ~*šUÿEr¢øi© 5ŠØã›4[12¦Ð¥«­AYH^y2¼87Æ/­GKƒzy‡ãUãM{)vM1ÌÅšåýv¶|¹–Ž@éŽõúÊSq¢8ÇÙ§âÅ#Z“˜ªN­1{·pÍä¢J鮯žP|å̆YcZÂ÷èøB­µ„j¼xáᵉ=«‚@k-4MHæŠ"8;³.ƒè€ûví Q’²Àž•¢}…¬f†ICb¡Êãc•, +ÝZ°ÐUÚ…=tuÔZ1\=ð0 )]¥d¬]QóÞ3PR°Jìqö€Œe=¥oŠ†•ïűXÁÌ0<ë-³a[ ]<®Ió=²6`ê(en’û×™7$‘ŒÒ¥² d›ùíî"§«¤ÇP/� ?ä¶ËlÀ•›ÓSŽ[àI%íô}š9w÷®„Ò.~ Kµ?HÓ绪ɺ‘Gäœg‹]¹Óu1WYšI¹·êµDÏšö…y‰‘~õ€0$.cš’Ut÷ºñšRû¶§áS¤,]D>4QÐ{RK»ã&¥ÍN”á%‘ö§+¢3R¶h²È÷õ“áz¦â’E’ + w£U¦6ŒTæ€BŠ^wþ›æÈVÚwÍWd²+‰ŸÏtÝg5=ãÜVNÿŸO#4“žtB)·«ÑÿΧûã¶IU/�$Jb +endstream endobj 28 0 obj <>stream +8;Z\56#smd%%Ec+s'f>-*lH>&SJp/mZH9Oo-E%kA$`AHeK-Im'RbFk0B:LlS9BDMCWPUVT.!&Sj7V(bR2V#" +*)>sI"r!I2l4P:#951/td\lqp$U!SlKN"7F'EuK0^k=L#l +1q^k1YGEsL@#$bR19L5`DM_WE-UjWjn6YG]Sse*XToHX0LLS$h*dfVX9?NAE^<;_K +qh +endstream endobj 8 0 obj <> endobj 9 0 obj <> endobj 10 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 24.0 +%%AI8_CreatorVersion: 27.0.1 +%%For: (James Elliott) () +%%Title: (title.psd) +%%CreationDate: 12/15/2022 9:09 PM +%%Canvassize: 16383 +%%BoundingBox: 492 408 1430 670 +%%HiResBoundingBox: 492.981939697265 408.981283239038 1429.06233724903 669.38122757422 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 14.0 +%AI12_BuildNumber: 620 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 448 284 1472 796 +%AI3_TemplateBox: 959.5 540.5 959.5 540.5 +%AI3_TileBox: 564 234 1356 846 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 2 +%AI24_LargeCanvasScale: 1 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 3 +%AI17_Begin_Content_if_version_gt:24 4 +%AI10_OpenToVie: -253.696202531646 1297.08860759494 1.46296296296296 0 8009.08860759494 8107.51898734177 3030 1948 18 0 0 84 145 0 0 0 1 1 1 1 1 0 1 +%AI17_Alternate_Content +%AI9_OpenToView: -253.696202531646 1297.08860759494 1.46296296296296 3030 1948 18 0 0 84 145 0 0 0 1 1 1 1 1 0 1 +%AI17_End_Versioned_Content +%AI5_OpenViewLayers: 777 +%AI17_Begin_Content_if_version_gt:24 4 +%AI17_Alternate_Content +%AI17_End_Versioned_Content +%%PageOrigin:0 0 +%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 11 0 obj <>stream +%AI24_ZStandard_Data(µ/ý�XŒ¾ît:'D¦ù�ð0æ}¡Ì¬’E@�6T1ø¡µ”J… ñ̈D�‚�€À Šy°+ì Ø°¥F':‰Ý„0ðuà³èæ«è âH¢£p¢ó´mä@]÷*½NõyC·Y…Îa:ºC×u×èºn€éRØ’/n¸9'ÚB×u)1`�¡ë§cÑÉFEG0-÷%ÒujÍvH°vÝA…Eèb«°Ð5º¢Ð €j4“õ—­•�6ÌT…P%_£î)¥åÙÉ÷êfŸtÎ0>ée€Ðu˜NØ×-«:ý-;,K•7Æ“K≧m ˲ œÉw ¥­ “Î\År*¶å¡ uƒX)~-L;Ø8$“¶UÀ–û]A´+=m»Y.X•%ŒOê¸Èe}£_‡¹ÀÂV3Ã'7m†ýÊUD&é û9*X­0$ɱ´íÌ5ÇRìÀò´3`À€ L’I,l’"KÊb4X ]¿“Ì&o Ç!ñTÄCÇ ê®Û<~¦ i}&ÚsÛÇYá„ëGQR‡š\:çŒíºîž7!ÇzYõ¼z=!÷ çûÃq îÁ­–Pˆ»ë4Á=6!Ê—h2ŒXFm D,‰Úªb,É#�™ ¢H:> ÆÌ)LÐE< ­‚+`2±è�]×uÝ€ÐdáðXóê]GÓbQ?iÈÁ“W�|»ñë¿ÝûcÃ"înM±Ìz5 û~m;}c•{×3�Þ+x}íV‹Óz3Ý<Íñ–áš®_3]š£»*N@£Ͳ—%ëUÅX»†[Ž]¾e—¼gô=ãp§%ý6Ç‚k'ÀJ~k—¶e·¾¹Ó’º¸{6ÃV³ {c÷Þn<Û0Çõ®â^ö«áNKÚ]œ7½èÇšëœ÷§y‚}ºdøeò+âƱ{З¤iÛoMÇfur¿\°¾]:6«íÚ±ë÷~cnív,)ìn½/Š&çÏnÆîêÓ¹~ÃrÈs·ÞÌG„bÁ5eŽç•Ë–t†o7žÅ`›«_Ú¥¹³~oÛõpó=K9Kš¸gÚf¹t‚ašUÂl7ÇnÏ+‘õÞ«7~?«%j½4}7?k4î݆G±ñ¾âªáû¹ê®ªLxÑôÿ,9n’%¬v5¸1mëméò ß°=wÊÓ6Ï Š_Ï-Ãs‡žçIÈõÛ�´ìûýÜïǽÝõé˜k;8bómÏV([>ô7V¹0ë…­æXžåcs¿ŸÚà;¬Š¹²-¿5+†_+¯xص+�eˇDwë:µß{¦‚ëûv´�÷-[BîDyÚÆàï,v¼¬Yn¼¬YŽc$8— ×÷'äPkÞd4#jWžá{;¸åi›{»ëÉ’Y”èEÛpfÒѶUGÛ´mÀHÕyïûÝKfQçƒk½kÈiÛ#Ô6Öˆë\×6ψã‹ã&NÃñÎÀuî€ãÜ…ãÚ&ÀˆãÚ–Ž8Îuò÷‘Ÿ½ÅÎOs'9žæèE’vßÿ]ìbûØÉNö²—ÝìÚfö³Ÿ=íiŸôIW»ÚÙÎö¶·{î»ïÞ{ï¿ÿ^ô¢ýèIOúÒ—¦?ýéSŸú‰×¶‰W½êW¿¶¾õüóßÿþû/~ñüä'ùËo~óŸÿüéOÿäO¾úÕ¿þõ³Ÿý~äc+®b*žbéÕ¯m“þÓ—~ô"Û×®ö´Ÿbÿ½¯\MKNò‘kÛÈEþùçžû.’Ÿôd'9ÉIv\GuœŒéxŽæ¨mäHŽâøÇ?vVTEULES,EREQüb¹Èþõ«?ýæ/¿øýï¿õ¬g½êSozÒþûî¹×6¶«}ÒÍNö±ÿÞ;ï,Wù„ŸÜä%¹ÈEîyç#¹šk¹šë©m©ºNÔU]Ùµ]9Ë®ìºNVuU×th[ºNÒÕ\Íõ\Kr%×qWqý}UUUMMRUQýªW½Šj›¶µ-Û²íÚ®ª:IÛ³5Û²-[²Õ6²Û±[±õ­o{Û[Þò–eYveWVeUv¦ìÉš¬É–,ÉŠ¬È~Ö³ål»²ëºªëdM×s=×r-WmÐ6mcM8ÏqNÛ¼s.ŽõÆ\Y%8Ç-¿0Ë­)ò„ëÚÖhŒ±÷¶ø¼ñ +¾k·³áxVÅø¼àŒÍ’ßxõ¹ëô®Ó×ívd·S¼´ûúp,y6Ó±ù½áÙ‡«_– ·^·Û‰çÏ3ˆ{Ù³z­àíÖ.8Ž]ut¿²wnv3µ+»±­‚3¯Õíð©çf±œ\¿÷írà{õÒvývœÂ%Ã+·q Nq¯Þ‡c½àz¾W¯ˆžãW€ÌÆê¹õ® +vÁ§àÞÚÛ„¶Í-ÙBÏæš"îYÜA™msÉð-ÃuGž7#=»ßkŽçº#î׾å7›U–Ìzž¶}4 çå»üÞ··¨Ó‹Ý;Yž§?¹?{ç&hr¾dÁ5UZRîa\s^—Ûñʲà…E#ëE±d€ó½]¹~ï8E•fçLñìÿüseÙÅ_š§ÙG°äÝ<979ΞÁΉ§xŽ%'M“ƒåé;GŠdÿ£çž¹X¼ä1¨05ó´í#†ü©<¾¢’@~Ühøá5ðrbå¾<¦ˆb}€$�ª-nùHL!ímpD^œ‰uZ–Ów/ÒÃR¹·Uá×5jT¿ƒ§m¶Š‚~33óADcè^¤²±çI …^ź¶3_È ’“ªZéªX/èåSåëe¦.ZÕÙ Ká]é¤#9dJ¾øÈçi™šx\Z@A£V•.ú¡r¢1eD?z%Xiã“:ç•crxÚÖò;”|DmÁ*ÑÜ#eËgEVRÍL“šÌºH]«/ªÂÑ'"Ê9–zI¥Óö쀯$Aú[{õõ2kB¾eáQxRI§$mòž¶Ù"+І@'NÚ•(-µ&ñÎMƒ‚{Ç€€ÈQ;© +]Fôk¬¾ÈʈH0åÇoRƒ×Y=ÇXI+c[°ÊXU°aeºŠ`¬øp }ûJŸ˪CxÚ†ÈldØÀ€Š’×5,~‰baçõþ«›m˜ uøp\–ï¿ëKZ°ÖlDÀi­d•ßò<Ôø@:ïÈ/â«0ÅX5_ °\ ’åZ0óÊ ÛŸ•§m¢{c®<ªE­êˆX"U§ãy¨:–™ûéH +\‘$â–Tƒ»º N)X—ÕÔÌ"*Rßk´B•=aA±¡ˆ +-JøÔ*è8§銧2ͦÌg dR96“§mÐÔ™PZU*ÀžZêVE UX'×Ç,ìV7È(ØXÁì`€ +"™—£ »]é L$UÈ´’JCê#­40×è‘ø8£S…±h«& xfA¨åJ ÒE<”ñSïPô´s¢éÊ|‰á4ýˤìüPjTJ!’_þ¬Š(dd¾ü¼,O#O:©³3ê?Äû–y^Ô©È}V»ªûru w-ý¥ø@z¨Øôîi[&añ:¬¡‘ùøTœ`u‰x¡s_xëŽ+„>H ®:udáˆ0´ÂÓ%TþÛÁ O•™Ž–ª<žF(ð/„0–/1X a\Ð  ô´­¤_0VHPc0ù@^àš5^ÖДR_E¹c²MÚHŽ²ñ¡^£É„Lc°?µbüŽ‰Ä(Ø+nm–a07Kë“*Áð´­ôî45Ÿgܯi¾xel¾O­ŸŠPy|¨ÙôŸÉ¥P|¨ù^˜`Ø¢äƪÅéI w> ,^ï,`b%²­&rQ08€‹O¶z‹ÑŒe +OÛ" V`º9¥ P/# vö*£(@ûQ ™L©è|j¨X½„‚€™Ü ’OâD†¾°+·TJ>2(®Ÿ&1z´lâ6 y’‰ÑÙE$Œ¯ë ÂÜ=¨(ã�:È°‘怑”ƒ§m‰– zÇqxJñ@Çàa€CD—Õb«íuR¨„Xž Ÿ¼ÑM y°üx +Fã½^ïÓâ=l¼/½IOv7Ý+!fŸ—ÙŒž§mÙ£ó@ÊMfv +fxa4-ƒAÁá:¢°d 8@Äfx #Á§14Ò_1 úª:ƒd¨Òiˆ…ºÑp€ypËrú .•0´"‚Á•ìÂKõÈOÛ0þ û¸ÞBívÜ>M„¢@*4  ‚8Pê 0‚L¡åŸJsÙ¬…‚¤Ðz¤ +¶3 ß?Œ“ô{¡B~¬(¼"â¡`¨?„BÜOÛ,f‡&˜èBŒ #…`‚·b_Dæ#üµ@ð18ȉzÚ´óÈ&…§m¯$…´™´-Xo Á²+eO,1Ì@£¤0±lBCÝ%0sÁè7û430I8±9ù¤˜ÅþlHõ>ó h'?ÖRÍòåÌ`JCCÐÙkö +q +F¤T[ Pm‰ ¯‚ G«F)F£ÅŽ†â“•d%‚Ñ¡ "¸]õP·«„Þâ#†¢pPE´8M¢I”O“D£ÅâƒÙ +˜ýòÅ{ðr`qïV,ŽÐ|!ÿ +”ûþX‡‚~FŸ˜ªp5Ö‰u +ã…"C;B‘?àÀÐ…/ù~ƒ"ÿ»ÈNÃÿ³Ë%†é‘ è0ü‰ÇÅôÈ…_¶É[^¶É[,Š{MDl‡ä~)èW±Ñ»Rq¥N>åûɧX£‰¯ôDç hi–Ø„_ý¡³®‡Î +I}U" röž_êX¤8Wÿ¬ö´Í‡Å¬ft oð"ÌÆôTÌ‚Â�…4PP©u#z²#€i9超DŠ×èÇŽ©è\ Ê‚(Ÿ&™žÒP 5 ÞòîHÍj…X×$ÕVÌITˆlVŠð¬¶4êP¾ÈJ~©ú|‘õsy +Á%œ¨¶‚  +(“xÚ¦pe‹o¬ªÃ—•PMÚ’]úëƒLnØ ¥ÇdŒXb(D4)Bc›üÃΔØ>±U‰ CUI¶Š‚ŠjT¯QY‰â„þ„Þ tY‰`D`{nWe%Šè *•Øîi¢E¢¨¡Ã']t³;̆Ù/ŸEÕS4±Žå¾”ûrÌ¡½PächŒbÀÁ ÊPä8"˜¡ÃÙ¥_b—/; ³K¿Ä¢Ãp‰] ‡á›]ú )‰™5šøŠë{ Q£‰¯T<ÙhÒG8ì£!rGnô&z+Ѻ­»XKlçk‰í4ƒ„²'ö[ÙSƒÄžØZb{_ Æj°X V¿¬^ó­«A¢žµ±DZJ}ò9#ö$+rlvŠ± +TÅù‚&I‡È´°x•‰!J1(¢ÝšHâÉÇ<IÍj’ f¡ó}lOÛ>“ÉZ¡.ýP ýgÓjûA[@=mpyLÍêAÀÓ¶Óá bŬ½n×Ùù §mªgetpõu’ƒ£¼é¼°ç¥Ñ~ÚèØ“ˆÑ¡äFç²=bTYý¢À8üF¤,ÓMå°z€d&JɪkÌÌ«Ï®ˆÂ{ÚF¯¿ÅC¥ ä+3>U5U[E‘ßVuPG5Š2} ‡˜p´xÂ1;A~4ê<>BoqšD“hM¢I4‰‚ŠFR‰íªÊ)±  Ñ>4‹(³hQÐYR½LºèªÝ¦‹®6`öËC£…$(ò‡ò¡ ŸÏg4“¤*\u_¢Ü—7PîËc +†î‘™Dvþ%vñ²Óðg—A`ºÇ¢ÿ»`zdFŸûÒ^/Ûä_69$nS"â-,¨²M¾b£7ú øJÅe£ž{4ñ‘Ä@¿òåDÑ».)ö<‘?O† ¼á„y ++q‰Ü³†Â¢Ø&ÌSX_ÛºílDpÙŽ‚~í§i eO”=Ð$ +ú±k‰í4ƒÔ ±'–A¢ÕÛe ] àj°˜¡Vb5XÔ2IºètìÐA=œãÀâ 5«;‡ð8¬Ù¦ÑCŒN¨QKK°Y£‘…RW —];8ÅU‰B˜W +¦–»Hô‚@²xvnBñãóHLS'àiÛ'ÕÊØQN$±@rÈI˧–PRÀ<U‚ž ›‡3Ñ Àf:¢0N…¡_×a¡ÝLaè@,£ûœDŒŽÀ³2ºþÀ,:OÛP ³Ñe`è×}^Œ®4xÝmf>¸áLŸ-, +O é“Ÿæ«W>¸÷øc\¸ µlBNÈó)e"pø!â0ù ÚV‘¾4Õ¨¶øÕï^£‰'¤ÑÄ#F£†‚ðd¢ô„£Å_u@>áhqFÂÑ ôï\CpCPCp;CCp;¡·¸¬D‘•(²%eîG!¸]†h1dš$‰F–ÛU¢Å2D‹ûf¿ÜÓ6È7¿Âl<ÒE_<ÒEÿ0{QÐYD™E¡Ù‘.ºbLÝX\@#ÐH¡�ŒO‘P¤*\í(÷垶Å:ô3J¤*\ERŽøÝ€#‚¡1¢ŠünÀÁÐ +H(‚¡½Æ롆^x¡È¿;ŽÈwÿìÒ#—˜gQÐïÂe§ák@¢È¿ÄºÃð{䣜(Áaøÿ=m“•(ègñ´íe·“E¿×DÄr @|·É[,…Û6ù‰Çµ(´M¶Mžu,n9 œhCñUè-sX\­¸M�³_Ξ±ý`çå…FÓ#+*±7ƒtP¤( J3Hè7ƒ4'z‹Ó$ +ã{üùСËÅ ¥pDþýê:ž¶Íô`° |a}_¡·¾¯p¢¦‹>ñ¸•Dƒ„ΆǢèG±Ml_ ('ºŽ\ïªðNˆr¢ž¶µˆú­öL8QÕ8Q=mØ‚Dj VRµ*â%^ÿ˜=5‰*¯oÄ8½Sb´&dÈuH¯J_,…ï+L2àQIÌcÜž¶¨6ä´BíÆØS ,®.ª‡!N£­é$edј¶§mõ¡DØ ‚€H.ЊÙN肽px‚Xêó fu¤X¸™EÅ÷ Ó•ŽN ƒQ|, .$4 DŒHÉøˆüeʯùŒõSÏ ˆ)@`d­—ëò¸-ÛÓ¶'æý¢ØMÑü½“ýƒ'¹xþN‚½Ÿ#øûïÚ¶âÆvS4Á²ÿΕ§ØÁnŠ¾‹`÷¿s¤9zÒ— ÷žŸžƒ¤)’ ÷¿s#çÝô yŠæEÐûÏýùG÷ÒìeïãyŠg z?šb/ËôžŸ¡?=ÈÅ‘û‘ƒŸüý—¼ƒ}Ųƒd)z°Gnûù;÷EñüâXrÒÿÑ$G?‚½ƒc¹Ñ¥Yús<;ø¹ÙIPäbçLÓš%7z’Ÿ¦ïåÈ;8’#7–&)Š ÉÅ®m1Îü''E_–ýAr¹±ü'ïåçK.šž4ɱûósóô"éù)ŽgùOs,O‘“ÝwÓ4Ëo‚vÊý®m³ÅLÛ^�F×6”§m»NQÅ9¸Õºë”M¹®mr†S¸pü&´M•á8ÇGŽsgÉ£çÎ’ó½~p3,™Eyè�vc“(:Y3¢ž¶yž¶…-¨Ž#÷¡ ÿù?¢õ§j b凾‡© +ç!6ávBC!ØÒ3EB†°ÓðÝzMD>ŽÁ¬ô±×”ÌøL‘„ÂE +©Ê²K#ú}”mE£‰g€'ÆJp{7x~ãQb;l†Ä”LI;£Q»˜)”@¨|Ò™ð6bP?f(l‘íS•ÐqÚy”ØÞfÙ&ÿ¦°”Z•ènFô 4¥×k"²ѯž¾ÍB‰\¸J3:ˆÑÏ‚2$(í©ŒŽIÉœÑ1µ2¢^X)�O”ÊN×TFôã¢ÑÄ—•Ï1*Ä´Á?tpÍ„‰�œTÈ;¬cÅ䢙°‰™cr`.äë\ä0TŸÎÜ|õö[a’–¦5aâ%I¢>ùž¤÷…#<%ø¹¨?% `ø`!Uá¤C5Æî›" Û¶ +ó[U’(Õˆ¦ýD—æð»iD¿ ý¸iD?ÎQ>hуAÄ’“âd°Þ'ödÁx�3ÀÖ_�Ÿ|Êó‚°`…*ÑŒ=X/Ìö<ù>Áˆ~3A'ÑOaR¡' Fô ÕÕ¬ÊÈêEÐ?‘:hD?Þa°°aöI]f‰ò:÷8dÚŠÂO<Õž'ŸÎ‚Y3­U'õ´máã‰ç!‰( ôãh¢%¶ú5ÐÛý†~Š¢r¨Ì|]Û™‹/8t;dû£dៈ@]×ëFô‘ðòÊA©ë†wRuŸ!+}ƒQ<ÌP¸Ê6ùFKѤ8ñ“P@B†Ò›—ÅÐè­Lˆ'1ì[4ä|¸¬!ÄÅè˜ý_†Ñ X'¶'ŽD‚ÅAÒhâ"òƒ"lG q(' +ªcÈd\TFôcÀì—'*(÷å.Kù|L½ñ²M~ñ üâå„\ÖŒ‡CËúu3º½ðσ¶øƒÆ!aUÊË5§eΧ“ªÓo å=ms…VóŸÑ 䓉¸ç‘þï­0ie$b?Ò4¢ßøQ.¼´Q‡zšT«!4DåU,ZÑ=ŠwÈeÂ{ÖòîÞ¡¤S:?Ý+pt‡Ü,˜ñ„Ó’/µ¥8½2ódš”Ç(P-êw'¯ú,š‰ ¼ê3€…#XÈ…TÅYßU…|ö–õ'•ŠTaHrF!Uá ŽÊ% ]R+¼Åƒúˆr–e½IK1Ïó¢83^• n?3#ʉˆ¬@BÈ.ÇAÀ ×FA*C +y <°xA €~hD¿ûhÂoÐ ¡cL=ätB^sn73ÞM'o‰í‹BªÂm'ä(I'ä³.ùÝC ùìÀ6ù¯´`X´PN •rZ@(!½T…Ÿ:'u= ?´DBßP!ªÁý ¨‰€@Q¢çíV¸‰€€[ÆŸ2ØŠ½¡–˜iTFôk$­¯2¢ß'C´xeD¿Å{@¹/Áçwì4|� 9êr1º©ñl;wFõèêçM™[ië§.b®†ÎÓ¶ aàë.ˆ°š«¡[aè׉a£7Šîp{B‚tá4 Õ¤VRé…B䕾$'Ox¥¯q-N«îµ)è½FB‘Ò”š¡;êi Q 4© äâ ´› b ÖMŠ¬¤dl¬¤ìw`$r[°ÞÝìiÛeÕþJ§C¹êõÈá4zXýÓšð8|K§û¤Œî“–4¶É3ØDä#qÅÓ¶ØåÐA- 㥛Ôd"0"¨læñEÖ¯É<@Úâ³wõóÈð 1QG¢.^ŒN‰3ÉldU4øtâ(Ì•§m*…X×OÛ4ç¥Ñ=bXÑIv%Aø`/H] ‡ª—Ã(ˆŽÄÓ¶ÍiÙ„öY»ºìk Hn›¬t„%Õû¨ËLjV{ÚfÆJÚ +„ZOø}(¦ÜîlUp—¤’N1¬ÞâYã~`LGò9ý ÖÇ©Æ…{dY¦')&7:^}ÑP=mku\•Ñ=mÛØž¶¹«>º=m»¬3úyÚæieAxQ-‚êš=*…‹Iey g‹Ž…³å$«°:Öùà�CŠ;[�2j;h®ú‚"êH*‹”'ô„ ß¿="8…MÄ(ñ´­Bt$3TMé0CƒÎ螶y ÕAù¨º [nÏa +ºD!´âi›Ä»<$Ýt£Z\=‰~¶kv1”÷¨VöWP +ƒP(ki5`ž¶¡ž¶Í$„)苶C 7+ii$Š)¨œ)xœ§še¬Lö”T<;ù¬“Zwc%ÅDîP’ùLØOŸ?3ÙsSؤ&ž¶MÈJ*!ÉJzj:&GéêˆϪ„ò Ö&å šÂ&´,‡ßˆ¯G3 ߤ +šôäŠÜ Ì ¹‡!zÚ6ž1íb³!7··gÞ÷´äAˆ$©P&K`lÊe%î‰Ñž¶yT/·t’7ЮEWˆ@é«�þX»@¢ŠH¿g»G¤®_2™l¨”µÑPW’1#33Ú ã� JF³ù¶¶€I6.V@T*4 Jc8( ˆ„±Åa EQ 2å˜+Yr€”'\¤zÆhç Í”¢ +B¯±±ÿJ…`Jx¸^ýA"‚W®ÑÕ”ŽIw¸G5ÄzX¬ÖÅh¿8ùZÝ$þŸ\ .%"æ¯lWu@TáÒâ&8 G9À{Ñd“Ïç¿›pÏ9$¸xuÊiÜÅI´;Òìgè¼ÃÊh¼«Û-P7¨#|�bp8kfkqEóILVÇzÓÓw�Â}òq#Ó4Æz¸öû¥í|z¨]Ôv ¼1šJ-gwy;yf¦Mì1Ö!J;\NÁJCSO!½<Å‚ÌÍCðDþO™Cˆ1ÃÈâ©(+½ˆäŠ»C‘Ñ’‹ÌçÓIy ¢…h¿ûmb†ìí”Y£ÐùÕ:v%¥' ¹ÎQ8ʶ%Ó±@»5V¦‘#¢ÙT¦è‘HS‰µ% Dò`\ÄeèÇdçÂ^Ô–"%] áU!*0œ[B.Y–XæþU0͸YSêcòp3ƒ?ïÏÒÔjRnÛ_Ã’\”`Å|êÖ‡‹i7]Îy§åãPwfŽ“w”±êîÉÓÒgzÈÜôò©q÷h{¦ò¿ç(a¾×L^PI£½7쯶Ùü:‚ûÒÊÀ_ÿH³»"fìîé‚&”ß�4…MèW´ä‚M(÷6‚cL(Ž7iP#'˜Úk˜ê³•“­;õâ$p©œàÔ¥8YîT +•ÞhÉ!uå´§¬«rŠâ°‹Ó—S*p*™ÜmŠ45ºœ^æ=I’ .å”j‚ §iT9åq¶Ä‰‡/'¡&#Ni|9e/0ieÌ(§ZïP‰•S}êìxäû&kÂ<€|%4¡ `sÉ…íœl‘‘ ¤˜éQ£O¼ù>Upbª h‹¨Ê#Êþ“X¼³Þ™ÖHj´ ÝÏGE=š_½´ï*é:@ŠQ›Œ”‰„m\Œ™:´Y€…5™q³IpZï>RzÛíÄNÚ¡ µj#n;Ø›¹Ó¢ÒúB6ý Š1pí#HP˜Ç ›ÅKb®…Šo¡šh¹ð…\€ÌE‹XQ±¶*/t© t÷ ¿oE¡Tƒ½ûGoy ` abët/Ü Ê„¾?q½ûJÄ~¢„)ókò&Šâa¾1z‘)‡ÒÙ©#²ƒ†u1ö%’S¡Ä*‘2Â0SoV yc&Å¥«ãc“Tï?Ù]Øx–ƒ ¨ÚuY¨Ý·‹ã_ÝÄÅ€Ë˾hZ_ùHe® Îty÷Ëéœ^´9å\¡.zjþ 9?žG¢J/á°<â)ŒD0·X³ñ㧅žX0º&hÙŽøâ?e­¹GÂ%62€Ød5šøÞ=:oáU[±s®va©A-çÑ=5†þm ê܆Kã:¥ªò47cgA›ÿÂìIô1*TÐè‚q Š2bFéWR²M’Ÿå~Êýíøê´0tõØAKð3fTî@ΚÑ\-ÃEH<Î?Ó ’“Ÿ˜¾%Í ´(ŒpýúKO¶Á¿ß¨Y¦Ý‡Zý;W^|¹2¯_»kC'5LuÉž…öŠ]â†gL¼Ù!ùÈojjÆmm†§m:©áž,Îüˆ|íD(ßÑ sFçm æªÛsØÂUšv–ÿ*É\dÏŲÐ:Ï!Ë%£•J–l±ºüì½DfYÃèìîi‰øÜ„`‹êZâãè%؆\;C½Ôp<]Xäê±ñ.½-v®ƒIáÉÆÅ¿hÙãhmÇ";B✴G¡V�¯[Ë“ ¸Ñ/ +z7o"7� è!7e£¥‰&ýNTð|SëTßâAA LŽÖÂàäIå(µpî†&ÊK4üÜ6„gÆ +}ÇîÀopm"6çÏ8D)«…ÉôzD˜Tè—I·ÆàÚç›s—±VƒòË7rÃH‘#–e^mDÜbÒ‚õeÐ=‰�Öan_nG…ùì–£¾*õИ˜SdSåÕÂó$â ‹\Ãråw"plßLQT‚uÌ'ŒõÛsc ë·@Q`¡âæQQ–4 èpª'Λ¨íÞ¹ïcÃúÝ@ÙFw@eάÖý‘Ö –¨JPur;=PÕ‚‰BáHíÒ,] Þéó@̽Ʉ BÁIÿ@¨¨Å“ÃND‰¥MEQ„δٌ¦”}ŽæLYE4!ªè‰Ê"š°¢Q9ÓQ#šL δÆÅHÝ&UÌ@I’S9Eá¡·‹Òªœz”]Kœ8¸ÓTE妗ÑÄT9ýT4躷Cåt:9ËZ_bÀå¨8Žr‰Ã¤AŠoqlÝLõZ'"“uÔ •µ!sr ~_*>R‹÷BÏþ±u?n€¾$"ÂiT4A�bÉ(LYC611Ö¢dêø¦äZªm*¤€ÇºòD‰uÏ0˜w›ä8²é$}ò¾¡6yŸ¢Õ +Èót„f7!Y7dâŸQùô’©‹ËØ©1 `?J/áy·À™Jî^(ýYáØ5âXÅÝ^|‡£¹ˆÇJÐ|ŒX™]Ÿ›"Ñ Kú¿×34*§+û`RˆÌDI/ >)…èiÝTN’éÀëðv÷gšp¦è`1»O»8"æá6þØ„‘VHéS +"¢Oæ fÁܳ +ˆš¢Æ*ŽX*~ù$¬ˆ©±S{»mDcPDLRiÿäù™,ÈæP*„¢@jÍÅ¿ ä5š˜6ƒ}¹Ó]òX8DÊ,ø kŸXèÙåùd‘ÊP"¸=†¬Ì‰®rË^çÛ„£¢n&.¦½Í- ]Ìžá…Ya+è¡ÓM +‹M›We‡öÝ€£X*xBÐ]Î +NÌ…ÙiÎ~GcäXbrâHecÈé;]Ò+µ^ðÙ³G­•ç¥=¬5ÓJø̘€5§æKDšFÅgà<–Ê=§BÅ;K¢óCRÍ$ˆ-W°a4>I}Š¨(zm>•JôÓ¢~Ypg+§Î Ìž+spƧG„@¾@ahÏ=1âÅFAŸ¬rËJÂ*j=Ü2*„T•ç(Ò^êàÑÒö‚2ó„· ¨0oÅnUï³p„ãèÇÜZ‡ûô57ßÙX«ÐV¡/߀¶M¨½f4 y2”‡/x#´¯Oê>f\K …þ%ÃúÒ`“§;>ÓEàÒIæÃÉÌ6£÷T$,ˤ”‰Ê*ÒEå'8oäù›ƒ‹…í¡S7ÂE‰6ÿî¬!h• +)á ™()×Àa›‚[§Ze¦ÑÞH—:ÙˆŠRm¢q(™ß³à;ƒý6â"×`";¤Ø?‡¯0qýŸ=¶æ¦Ëx7Ô :6ö½S4ðØ¢M´ý‚†«K^Y“Æõ{´F°',º´Ò‹‰„uû·@åW¶@ß ôÐaÌ!Ö×›îî#XÕzó!Êj7Dö¤XÚD㔯"íæ—Ö%å¶Çe‰|.åŒ÷_¯�ÿ*H‰µ«©eu¾euXúÌÍÁÑÜì¸`ÕUvuñϘ(,]Ô²#Ö~Bï)uŽAeÒïœê`…µ6(6jêÈCfÛQÙäW@¾”’ÉïÉ: ¦¹''j²¢9‹ŸºÈàž¸Ø/‹TÚÔÆÎÄ™±Hq»¦dÖWvAAû— ZÃM­ÅÝz\ ÌÖK=‹û]+AO<Æ®Í;Á¥èS5ñB§“q¢àí0 W·Ò3ª€6^XÓð…©@…æÐ~sÁ¶øøë`½9žýªßîzu‹›“¿`UŒ~›xâÔZ|ˆNÑ;ñ>±_”ûö^¤Æå'¯Å³šxYçVã[½“á˜L´ðÿî£H9ú»ÊÅ—®)4µÁ¿¹â7w[!N,hPDúMW"Ú&:ì‚ÿα.‘¥pÖëµ{ŸïÅîW¸î^6CÅÞ ¼­r +Òüû´' ƒüÔB´�äÿ,ï œÇà^ÄN‚§("{á¿)ƒÃjgìæ-wUGW2i–Wg7±|IŒ«¾ƒð „ÿ>8Ú­´(Õ´ +»‡´/âguî’²¦å˜¹¼z¿L 5pc÷)Iâ,s3šòçBI`¹47}íë$¶ô½ÏNG‰ÉEGŠþ„ ÐU2¥g„ú£!ô¦JÖL™ÛŠêÛÁ-¼aËZ ñˆ¾“ì»JËãH‚A¨q¸õ¥e€ÂóÓÕZ€\§œ;Q +X~ý‹²áOwKvQ‰ªÊtS2Üf^cp·eA¬¹#‹K)ªÄv¬•¶ÝŠ nÞòÙÒ}�þ¹ØOMúùÂIÚüB$Ü‹…,K>}ùV*ÝÜêÈnáŠ]”ø̽ä~s5¾dÂÊá€_ ÜvÓ8PUJÓöç 9R?›y !±(’JKö9 ©æž¯‡f–‹¤«õ + µ%§@¤²B+½ +öåÜ´åTfXßr$1ðƒ4jTÜców‚Å'C+p 7æôMUªËÁÿydns«ÅõïæMw¨^!ËÖï}"¬ {¹2 ávebÀÆN ]Þ8^£¯WÊ—§‚ó6ì' &Lw×__'”B/ـ¿˜ó}hy@¼(¹ÿ¬ñý–K¿–f·¿-°|€j ýoL 0êÑ6㪆PÎÈ8ÛŽÇäÇ]ïÒ,&O®:�ä²¢Tûœ¸^ ýœó2dzþ"‚£ÔªRà­á¦I¼Ýð<õyb÷3o<ˤÁý6<¹{xÛÐ¥¡ß¾¥ÒzA)Ÿ–Öæ&Õ¢í½éª·›@Â*‹l“èm²@+fl£ ïÃùõ£©s@j¬F¨w9pá^·6¾Ùµ¦x…€ v¿O/(iŸäzj«3•R*¥ú†>Ý‚.9Ðìí¨�€¤2”mÎ&^ƹ*ï¢Í¢.oiîM?áá× ˆÃ)sÅÑœã«T$f2_bYêîü  +6áÕiÂ*a7&÷T}*H©HÄmpû@Ú +ôSqÒç`+Ä 6*F'žEUN%d¡ ü}'…;Šô2!Ó&ðàïú.:P2xNÌ^¾Â¾ ×G¤µ]h²Á°Ü1îÒ²AŽ ·W¸%ªO:ÚÐJ‚)/ùÇJ}FÏi.Ž+"IrU·7—ÍæÔl²å§âp%±Íõ…¶®äRV-nšø'ß 3ÝÆ$pÜ@•¡ÃÁq\陎ómù>\÷�רÉêUGLªÃrJdðÏ4^Ê®<âÚDø© �˜£(“5ÇpÙvЙ]Ê ‡ð| rÌ©ô¡x¹²@YþUÛn)•»=4š¼Ë“(…>Ìê²îÜô²7k`ÐÏ�ƒGN[6œÝ@¯`ƒ]÷Û± DV¤âãjFÓ;h)Goö‰"€Øˆð‘F™Z=#A®0bøY‘´IÇý°ÃÈÆz)MSå)¡Ã Gši®F‡Dï8}rávÖSòJú·¾M“Ds%*¸õ†p^§2ŠŒãh5“<¥Vü°oVûs»eiW²ÉLÈœ”â“Ú¶ßÆqc._mC™„¥&‹þôÖžúŠ©;è)Ü«¦WV¥aæíbüN™¿MZ?‹}-›+¢ì–jóZѱ¤«¦W)]#sæœÕYʱHôi8þ ‹Ñî©RjSÝã¥ö°&w¾ŽW¢Š]Gk)ÿU"ÊS)¥Tªîôuš)©Y^uDFôïØØE‚ùß]jÛØœótW阑»x«Ù¬¦Ðˆö +¤BÀKcÕyÛßú*²××ÜbÈ´styX{—ÂóC'}ü©¼¸H´Ê¤ppçý©nŽ¡:2¶zZõ 1„.^`7¼ÆC;:u;™‘¡ÝµÃ¼€‹(ý‚ßLŠËàoôOĤpÇ–sær`4%zô·SZ�ç/꣞.7òæ�öqjüˆÅ.¯ˆ±¦©œÖÌzPñÌb-›-”Ý‘®Í®È­P‡6»wÁ 9#ÏæßÜò*칶ø*Ë°ß<Ñ?š-£{4éÏ–”Él„¯‘Óa›*>,)aÃ)ñy'Ë×ë%…™.M׉éX:Kí’`wà fIQƒ·ýK�§c,)õ¹Ãc*ÑKª’(ÜJ¢TP²\Ð2Á^R¨¹l„T™ÀÀÎð^ÜhbÏ +;[‹k MyÇUS¸üÓóS 05b#¶©/Â-)ÄAæ{x<(»˜œÑB‘*Röz‹5æÒ’“`W*³ÌöšIÎÑé¯ùR>CÔ +IË¥µ¨No Ç +2mŽ\zÇ +õ1íwi AA˜;¦ñ<Ú´0Ì|)ÒêœÑ O1ìòVvÃ}«H$R©M_ZÑ1÷…!¤dRå¿¥ÅA}¼‚Cse®ÃË,)P%mr´×@¸¤L³G¾S€E5£SÔ;?“+]é“uwˆM1©B¢Imc²h@ƤöDùfâ†ÊŒII‘¿4)ô…º|N$^ô§ I9ºV³âúŠŠæõ˜”gÎÐ +ð1±Û g]æó@eѤ†MÀΈIùÛìÖ‘z¢Ä¤¤T‘Ûêò¦IIëµõ¾½JÒ¤¶.g3©}ÙmÄz‹Ç´t¡Í!œ dÍOkoÔqÕv~ËS4ªF;£è�‘lTöÖ©d-îPÉ' +”,õ•ðüÃ{BÅÀº7¥©Zøš~sü¹åçu$¦/Y¤ƒßàn¨ð@…°×BøÌ&fÆHçó|–<³TPûfLlÊ6ƒ(ðÕ s‹›WÃñC¥šxËa w‰…¥Y'ª«ŒFËÙÒR]ãѤ֟4 g*”vÁPQj1†œ¼ö+vn"b?â0¸v©Px5| VÈÝÆ×(ëJ(DŠÒwÔJÿ¿þÂAo†ÒâÝÿ…4&¤+Â>M‹CÒÎ •ÓÊV§`÷ð�¦A[Iºü™0GU²Û Tàf¦?/)¨_ô¸)< Ï´}™”ÉE/h|`%¶_Ž7 GHÄÞ³!ñûô ™b³ž†#é ,IàóB´bKV”XÝ y|œ õV[-¸S†:q¹¹[=é!!§šÊ=4ÐH%Ž¥.ÝÿÊ¢|…Öø›iW$ó4úUmNj8Í(n¢ÄÛ:äÕÈͨޚ÷ p$B§°Úф踟9Ìtr-RöñS.ié.Ýu QÕ—÷þ:òïm·z´%uxŸ—™ƒ6›Ö¬’æc^ÄŸK'†sB,¡ñq•¦EˆA÷ðÅ!ŽVÑÊUPd$ÅHŒCn*ù6„½5’ª8ö(k(6¢“«©Ë‡ºGF +ý‚žˆª‹Ç= Röí—™2?Æ„ƒÅ¡)ß.M|,X[ÎZ§åôö”Ð×Ê5¸"å¤Zœ⸇Œ$!æHµ¢À …RÃÏ•ˆâ©8H>þÏàÏá ïNLß Nbi:Ä%¤3m8Ìš“d „ ÿé0‡/Iôwý3öÓ9ÄðmÑú=°~æg­ÏMŸ*:€áÊÜê/‡XC©, q9uˆsH4UÌo !n]µjz ¶Ç¾Wûé•Ü-Ý™CìDŽÙ2qˆIÓ2 xPKÏ¡jÄ8ûbY‡¸Æ-­èÝ%ß¡]˜K¼Ô3÷;³¿ðs…ñµõ.?qlj‹J(cµõ8ß·‚†™…0­ceåLDÆ!¶9»ˆÓ{–¦BWÃ[A¹f3»OaûÅy#…BWvІ">m\F_>%d@Y£.ìÃ"×lºk;F*f½eeþhÄX㢅ƒXQ¡âòZé%xÊ×ddB­T£Íç(뤾Äî‘Ø—û`–ÍÞ˜'ì®Åµ´ð±]†°ù]:¼‚Æš&ùŸo²0w77i–ž7kœ.÷^@eZôî8lˆo¹Ÿ~:fñSÀFªf1±=m專ʜÏl«PÏÛ0þ¾hHYEzÇвŠN^‚Uxû¬ÚäX=ÈølL»»ÍR«“-¢÷ùàÉÂUÿ…Û:º~£°¹.Ô–cá@Ìß2bÄ{È Mg Òº~8å7áqÙÞ×M˜Ì–o-;"Z/C[¼?•�èôÖô^¡%†È3Ž­d[ xí¨b¿6 8uµ öåK¨$Q#$�‚1t¶-Hêá`;# ‚l¨WH GÒ‚Ü€©jÏ`1Å c¦O’‚>@÷å†@v¥†×�ÿB+dÀ|¬gUƒ5õç`ä<Ö4WR´jÎàùÜ‹‡ü©Á¨�%¸pX††PIaÀü6u ÙA{@Y/Ü„Mh&ì`oƒ÷gr»ü °@lò«Aú8§Ë‚Ó•E¡dí!«ˆ¸#ñǨYê—³K" Ù¶è¨ó<Â%Ù‘ 0]Í 9’,^“Ë£Œ:Ë µQq­’k¯ÉýPéoÖXðl¢S¼—ä€t)©ë:a FúP’¹äëóŒP»›Ÿ~¯Qæ”0B}¯(4b÷²"-R—D"³’>¢}´û]�AÐuœ|ÉÀex%d[hÛo¢·˜ŸüW©Ÿ ¥òp2˜ˆ3bQÉ~2K•ÂuõêhˆEpu0&K¸2u^êœ( ×d·?7Ì7îfyÛ$o iîmÁ©%üp|qB‚³üƬB(oæ¹Ö˜»·üÀ1NQ2ç"°|L ìr„—¦F”æõF Ý<•°V¡`¹í&*UÅ€e™=ä.œ×MŠ/*æªe¥·z”¬„y=X阧 ¹PÕ§„ª‘†8Ê75PU˱z68È0!‘Iñ«:œ¸°ÁaE©úz~Š¼ÁEÔgæu šÚJo$opT3èŒáÑÜ"T³nÏØ0%ý³ UPôýaó–ÁÎéWßx‚'à@Eùcˆ$)1¿(td6± ™)V¦¤‡p7 ­Ol#º¸¥#ve iu¥"½ƒ.eþ¨òCE�ɳ@Ùù.Ÿ}Ã2•œÙ…«x™ä_a•¯qŠiÔ’yÈ>}±¤¶ÓWXÓAQÄ*ØRÿ×n0ûÜ`lšS±pF®KÏÙ ç»–ÉÄhaD|°ÀÁ 5•yâ ¤«JZ‘ zt½DôqšF#â›b='·åñ BÝ¡î Òr`‰ª7a0À¤T(ZÄá9^ÞiM;‘÷?Õ_ÏáD÷jÍhà{ÎÓ]�‡ÌJtY+j¶ +Ò%S+o(€u’Aì@€‡‡M¶ßæå,€Ýï·áß¡Þ +Y¬Pñï0 Ò¨žps–`“%9EJ+"‰˜ ÈÓCce¤0ÈÙ'³°+K÷0+çŸ~1A€W8Š´-mo ¥mÛ«f S�gzĨ‡&§¢d¯xWÆ«M#À½‚¼Žä^ŽT w=¤UR>%~ð`àd`5YJ<9νâlj8· éqV’âYë¿Ñ �ŽzÉ +˜Õjus·º·ñAè Y,o pÚÿ攵¢ÛXjzryëñ^$Î;úˮɛWbº!XsRtc^gù|±¥ÄåKÎÎwLóãWÁÔ (ƒÓ’ Dô¾•O‰ ˜_Oƒ¸£Ë[üz}@ûw’@þ_ ÚrG¥:î)*è š*ßþŽ›_ôNXFJKWƒ‘j*lÄX…Œ€¢NÞÏõ¾9ØJ]¿=nÆÞÚ¿RxòçÜBãï~+ûMíæî⤾«AèçihÇö‘ßm-òM¨Ášué«…Q\˜puÃyVçŸ1ç–õi´šVñÓ<ºËj{BnÇ]p+™º³‚Ñ­–5²Ã72¿~>jÕSCö¢¸98B .U ¸ æΠ#\lýiÊ$JÂ#*6ã0­ æ·IÑ“'3þ]&A• ]ñ=êñ7$z Ë£ Ÿ 3Í!_è‘ ACôÌ“›ð^+áqŸô™ì±Ž&ã¤o–DŸ»íöh›@ÛÏÅ$$¡ÕîM-²þ*8Oÿ‹bZYYâ=?ßvŒ™,NNúfZA"sAŽê3éëÿóçÜZ�ÚCý|M _„ó®±"|!ç¤ô­ÙZâ'Ø*dÆ8†:•BÐJ2Ú †Á%ƒÓª•4¤—fÑ_VÜFѹ‰Éˆ´…}–2Щif ·pL–®²?yˆ®«Z$0Ée‰Ô®±" Ù�ç}($ÇŒ‚<½pèäA Xgë˜ ì)øÔ‘ b¥à„µ)‚8nÍÉAW (ØÛ Îa×h§L;öZ™|ÒI¢$ à`5W~eÆá¦Ä˜˜ÁÙcðíQ¬?(qÇ€,_ÐEM´ áj1§&äX¦71ähyšæô£"Ó—‰ÿó)»÷æÁu%¶H•ûbNˆà«üÙ^}%8nŸ`T…£ÀV<@ÒÈ—Å «·0œ4÷ãÎöõÒºxäê|ÏA½ ßhÖé7c,«ä ƒMY^þ%1ó°xL#3üUB1é—Íáí3csË-?xˆÆÀŒ·=;Qx^A]™‰ùK·ÙΑҊUJ*•èIxÚnEŽZhêioh¢:èÈÉ• +îà}ôx‚¡K˜J}›—’ýúÚÞtDû 5ü©op}…*5¿"®Úë²a³(¤®±ëûðùþIXBa=îZ¨æâÔ»¾QODQ_ÊW™h×÷­\®}U@z3z}[a¦Aå®êK}O¬ÁñÊCÇ4eK˜_Xvs´ð‚¥ÈÿZ[óǶîPÖƒ#êd¯w b½´qsa¬È?‡à'8&»ŠX9JIâ¨|ZgÀØ‚:”©;'‰žª@x³Ê"ÆçHî¬à5,ÁŒ¥gqç4„yn[y´EÙ]Wöòd³°©Ìò":7ËòÎRˆc1½PrL·ýÁAµPç}æ¿çB€¦¼à”0»k„Ð÷\̱,¹…¤B¢øŸ¤3€—†5N°÷S‰õ¼Çû.M[*0Ô„ê +yZè˜`Èbó;)9„ó·kÅÄ §õEU&A4¸»è#çdÌáàÆÐT䢾“Ê€J”c`Ø +òàÍéÅtÀ&ä0Ú¢|ö¥<Ë£¡LID̤Æú": ·8£DÑð)š"³ HµÚ™'wýVÙ“Ñ£í¿ _MË¢xóq×ÃâãÔaûC]l]MÄ^tp⦧LBÿÌP]¾þ>‰º0M–0k‹èKÁRœôù¹ûi®Åw+í:Îýñ�U5ÖñÃ2çîÌoÖVU UiHµôΠ±gÆÕý*ŸÂñ{ü½ Û[ñYõTQìRjP™+G8§PÀ”HÑB«êQ…êÒL§†Š¬e-3ÕÛì>±úôòö|• ÖwÊز™•§ƒÙ+qzë3t:f $  )0’1)8Ïr×™r°§>ÔWáùé®Î¾#EÑ!J£ O C‚ºOxæXE“ðÅVŒÔð¯@_Ãiþ´ß^Ô[Gõ!+1Q“*c°p³UU&Zb²sòe(­Œ÷vÃ+ü¢NW­i½I~ÈOUžÒ¨¨>Ûã’¸ç¹åi¦f®’_õ€2!Ê®;êýÀMi®Ì.h~/oi1(.4×q9« s^¼VÄ 8 ²¬²G=Ík{”ãK_ìâÐ)ì6¤¢«� Ô4p¿<Ó÷ï‹:t‡MçþÏ_-;Âå$¦0gÖa‰Ì¯†>CÒUy#äÿösf¢oBª.z,6út1[üòS’°íø6;‚i†Sàn^Ÿg)yã)‰Ýt ÃIæRc­_CyN +—Öد=¬A„8ùš/QÊ_1dʲY¬þã +I˜›aĽÕN®³IP`ŸçÈeƒ¨bâ4®˜5(ukQªPr½2¦´¶âÀ ;½/Úha©)Ǻ¦¢mÖï@l«„zÔþeó¥‘aeàX>F=å°~3Ö”ñ¢Wwž_¹±€àº{3¡2"ÄHtÂðÛ>Ë ØaYÿ­QÌMU +Ã9¡'q×ïżþ·D ‡„•Á:<þu šú_Cí= kœÚ;~Z¯5Áßlî`€6RCË‚©~ih½“Ï—] Ts¤Æ‚¼%F”}Lj_Ù#íEƒÀÖ3§˜OK761;Lˆ›ãy/LnÏõ–{{Ä·×øZ˜Võ}ìˆrÖã`´jW%ëê’-ìÅ!¸UƒmU"K3õNyè™m§!44E!¥§aÞroQüN#ECHNí¢Æ¦æâ1™8æ 3¥t›­/ŒûÇÒAªÐ?4©È¬.ñ¢3õÃe®)Ì0%£{;7 9PƬò¸èN´ˆ1H7-ô‘K8‹äR9òؼz QàVí-‚¶MØ.Q¹Ó,¥Oæ ¦æ¯=QpÇU{·êʨ2ôv¸IŸny7Pa€!(whçéu†¯üGôAW\�ÕÖŠ™¼•×ÈL½�šœÜ[] ãw.Tm‚óÏ$`AxB,v¶êC&(+âm0E¾’þÙüÓ=ÄÂÙ¡gª7½×—…«íVÝ^†ms1*\X]kÄ^V;ÔT<áÄK¿µÁr]U7ÙôEIqOg +ô„´z²Î„�Y2û~Q—#/dNþqP(j½kõEhvX*Ì…ñªäÆ®ü�åµKy“5¾Gûàúã!Upà1%pb‡BGhÎŽpÔ:ê­À÷IÛ~üÔ>¶bË$š$VáÈ +'!§`e þ„ +™˜¿B1"Ü…µ³õŸá•  ê>p`+2ÄÊjX+ŠWªžÁSLGË·ƒ¨·#Ã—È Æ q{ Íøg$å›=A(»’Š-êáš&j@ºƒˆ1Í6GMJK€Ìû‘NœŸ“•¥mÔ.Ó[ø×–ïî Ÿ5‡hzötoÆô»E8Ý`¹ŸÔdÙAº*oþ$à·ܧ®tN~D¿'ÚØÚà� ôÆÁ6«±îu�®¯oNýa£)[âÁŠÿˆe“×!òಇ”h¢t’”¥h'RGέ!rej=žAd/-ûÚ]‚/aVnÛþï<Ы¯—R…¤B²mS7`¢Dêº$ßÖ1IŃ¾hÅâèw‘‘|8Fò4c#šbOZ€(™ønó «à[i°+¬IÆŠçCàÃÖíúgú¥b¥!K<A<3ð“¦úøkB¶q÷~…ƒü•‚ÍÌ%‹¾§æ¿8X}bB›¾–x8¢p8±É®ù;»*§UIîQ*E¯Eðw|9è/½ËÚ3#wð Uƒü +CAjð螊:“)¿" îmjŽ§”îï¬<õªýt E›=/ìEß�Gu Î­sÔ×P ÐÞåwñˆ;þóØ œˆl©™zA…ù¦S6Éà0倦úsÁïä1*\Zƒi$•è�¢Ïü‹Å§_nUÊŽ à ;e8Xˆ³isšàq5s\Qˆ.ç ©Ò(wž!ÙûZ"ùå? ö½O·‘t""¥¾NuD4WA0â'£Ž°u±ÜÞCºMc^�`>ß% �ø¿Î,Ðìáæ`„³QÉfROtu¡MÇJçЮÈÑŇªÈ|&ÂпËèœ@GÓ]´@Ö Pˆc’=2iÇÅh W®k>¶xŽxÏî|*Q6b³‹Ò/ø«Œg— ="Vâð|@Ï[ƒ•$Þ#îÍ*üG+JûˆSï$_ +¨„Q¢¤‰}û†öj‰š)ºGhä¦+Î|wüåÙÛàYº|%NHO„žšÜuˆ„6þ¤uîn3±máR¥®aFû¢„m)ÈðP@hŠ–¤6æݯÀƒÚ(÷˜­ óÑëNb!3Rþ‹\ +åºpà€]²¢¿¦ñ4Dgý»w.z×d÷¶q²9ÙfFz„àe³þ ì€Ó€X­vµR 1¢o.‡n|…ºð,Í9µ•0ÆE¢rGá¹á¥ÐѪ0B¨òk‰N2¾˜)Ý`F›jáÎh5EvJ탹F˜@Š.º7͘{} Q¨ÜC”Œ81˜Ã¹3•Õ¢ .Ÿ¬L„˜Õ,mõóT‘ 5q +ËŽeãÊ`‡cq:|¨gv©Ëï§ oNˆ^Ä@gÞ²Z-@Ñ2M +÷ÖD^C`@ásÑèø;Bó1½e !6×ã/‰ÈÈŠW=MÉZ ¡Þ !‘¢ÏÃ%¼“ÿlÓƒ(¤ö‡ ġ߇ 9UoÀÅÿôéú:fÿìуל½Zí•„>QÕà rv'Q,ß!? L:؆ǖRä]Ñ„·�ÏH)òÐîám·²?Û¸!¹™{™Š¡ñN­Ovè’è”2ïËG.ÿKÀ%þÙ +ˆy¬qż—O7gw^èÇY[BÊæRÚ,¯¬i÷¹†ŠìJÑOý¡ª nquøVÀØŽí9FiZŒÀÉúkrÿNQQ*J3ßý¸ioét$ø'á7UªkígA=Uúø·ˆ¯?¼ 2ÜBå;=œ:‹:ÊA­Tœq¹RZá©Ýß ïðøÕ™I0Û¢‡òF<'˜“_N¾×pË“[óMÏ„w¡§c.õÈ%ɹÞYñRºº¯éLêO ôɃ›"´øM¸Æô £1ì +Šœqpñö<¥ª3 ]»Ú]M‡>k‚«Ð‹Cýáh輸‡p°4yŒ¹Ø2Ëd[ï¹÷0”TímèÖ\M­w~qÚƒZã)¡¯)ÅEžzM‡ë] +úôÃèx䨪GKŸ2÷ù5œZ7ãt¼Óî0&ÿÒ‰%Zþ½³ñY2­-âÁáíÄŽt%˜°L/ÕP‰ß)?äl|A£>§S}nU9„þ>ø6\ØÓ–KpV½jäÚ²6¬›­ø F~/òœT¬màf›J¼ fæ!OPÇ1Œä~�ƒ•Ä§Œ©X¸¿?Ò¸ò‘¡&+6¶‘é”ßå‚Y/$É +.<Èrlcíâ‚ zpu_ö€GÔb÷BåàĆäSWceì{rÔÀq°P]ð{âçf•Òe·M0Ôp9ÔåìÕp¼x+Í│©ÈÉ+ëèåt½a×=ù¹†xU™ÈÈðMÌÊXSFM³½r;ÁéV¶JÅjÝàðDÌEæ/0w 6‘A:¿Žÿ¿;{´[ò”f þ^R/Ð.^¤»ÛiAÃ}0á¾ +!\P£m°ÃF·Døwl‘mÚÐsòn1-Ø€ØT C€sQ0#Û:­É)­ÕAÑ‘N¥ÿ [tŽƒ Æs‰ ºŠ1ÇCd:áôŽÕGœæm7\ز}d±BÕ—S±‰@©C·žÑW¬d=Gn†#æ¡[ÐÀŽ?ºI3·â %ûñHˆ}˜¶ø["‹J*žÑßÝ’9U‹™ÊqVl�ò4«Uëæ¸}ˆ.:l­íçjP)‚@ýØÙ’&* !)é†ìä*êŒ�"wŒS<òçÚ÷­ ßû$Ò0¶ŒÖ\’·Î*Lþ\ÄL s’IÃuáÁA†“w ßh»‰£‹OY8Ï4¤«)ëìƒ{eä”_y]ԯ)Ï|ý,³5OÉyª3YÒÜQ• ;9Å¿”ãÆ0¦\Ûˆdû´³›ó™æ ýöwð”—%_öÙ5%4v[ó>Fj•2ÔúöܘЖåÙÑ5r‚/Àè0‹5„’lSqjv›®ÓJ¢{þ–Z¨Ræ@ÆlFFù$ ªÒ8‹ÆRÏd˜Єr‘2$/˜3€M~[ÞSеúç…ðxµ¶3ÝÃÄT,JÿÝM¬R$,ô¯Ë,.à€Ø:¿±ÒmÝY‹7‰HÊ?[è«ñ)\ñ–lLÎ‰Ä ¿&kÒΓ»3d7߇y¦î-t%dóŸ5«iÎ+ÒèÛöáWžã­[Ä/æ×€%AÜJñ]´\Á� ;±f»áâ»Ñ‘®I`5 ½[FÀÏþúJ™â†]ЗÑ-Ž“êE±uêÆr2ôbÌî{513ƒ‘"]:c×DŒvÆvå›ñÝâ3Œñ¯Ø'ÚÉÀˆ*c$æS`åi(ƒ?rAÃ"+æ²èd_Ÿ@$ÿgŽî2ÒžŒT¬ìþØȠY£Ì’ëTJï65°éäfW9²Š6 Ô<‰ð®{Ÿ“vx“ +,Þ#`áMpJæ\v¢Ëˆƒ]T+•²ÒÛŒ‘nKKiÔ_S9`ݧ”¼È„®L'{©O‡gêø㾕òòH)wOX¿[YH‡o5ΆcêÓ=1äŠ)8VòrI¼”x9‰ê�ðôœ˜|RÞTµ4¢Ñ¯g†à‘£+™÷ØÐîª~y¢r ç÷ä›Sú7€@§¯š-öyÍ#"€F²Ò¹þM~KØâ·sx´À/‡4Ñ2uÈ;GXŒbÒ±0l)P åç0và$z_ +–U=|ŽiW¯xîF0ƒ¬ùmpƒp|w•‡Œáï5¸‚­ ‹" m¬·æ>£„óKH±Vâîɞ؃vå!³và·—;žÚãÍ‘šp�˜K%}¹>ž½¦÷ÓªsV;´U �Šã†ÀP…ØW€™Nè¡k$gÄÁJ¶ë«ÞK°–¿æ ¸údƒ6 ~ˆ›éñà€¦1øè‚A5{¯Ìå 9]{¡“3¯šÚ©EäÙ3dn×"XçI| ^·uŽK€$oý9)¥ª4“:íµÌ¢‡@ +§�z×ù{�H’L ©Ü®2Š/þ]÷ƃŠžžfd¦À$¤µP»Å,]µ€¥¶Ýrck€ðß4R)8?ÓQPTB„pœµ„Ÿ0è¶6þ90QçV°(œíE½öNÂYµŒò²Æ%£N®qd~”Cõ¯,êŠäÅšÑô™=Üú±xH¦wÿkê¸Û>gtχf§l'ˆÝw¨¿BÆ]nZ±$·$sŽŒ}gf«¡X½ +Ùù$¾ùkçÒ›m¤á5mHÚ§;t7v0ÒE9%ÏN8_Õ¶G(�1„LåÊk]!3Eqí ”My1}¾qLŠÔ6´ƒQÇÆú„jé§ïä¥o‹£êm”]ÜÓ—ûwÁ—Xúµþ DOc¾°²¿3�=P¹P¶½ÑÀ²¾™†F]…¬‹º3]äò¯úi°ÌA8æ³DƒùõixRùgý»“>ˆË¾£äÃÙa=¬®¿¹MüDèã6Hë|1U%XÍ-™ÒÐ;úH~•ÝBüÊÂP„æüiCeôô¨ÏÓî'YRa'ðž¯Ú¢NK¸ZßÀÑæ-Q-uƒ¸P0‰›6ÉgÎe !×ÜzÁ&±Êp‘ºÜÓ½iÀVJ®`e¾ªE!nÁ0½!­EøWC%j$Ï V+ïð•ð¨;¯Ät“vÛQâ¨%Ø0W@kòéS¤ ‚[i_–Q Ù‹ñ$†ç&ØlGh õx“UrA(E×!¶\5�×%Ž*_uÐÛ3EÖ@¦W1ÒYéÓؘuëIgω‚=;Ðâø �éOŸ‚¯M6eÚßÙxÕ+òešr?Nx‰saIìzé1Æ^¾¾2izÌô»²=r]Äe ‘¾]òãnE#Sðë²(ooK£‰ð˜t�»>­“?JNÚ¹Ü0lwJ¶'œJË+ïS³Xtáë:‹ÿ?ðäz|´ºé'Täì÷—Ìl2'v9>§èÄš…Û­CôC×Ò9ßi\gNú­uÖ÷ðSúÛP +EχÎ<5\•‚Èt±D»‹ýŸ3®h¬ç\˜”aæp6é„€:¬y'ó_KʃE¹„¤QÓ<� ‹ÂÕ:ø§ï$2gäkèž?šcî×U̓9j#úz-”"´Ò +;Û¹]n‡ Yâ€&òïpFë‘  ‡”R=«{óô€-BÞ)'s 4AÜ_ºX®ºÛE2 ™c‡@6fÛùܪ"L´V>áxÝ/@S‚o"o}bLŽ‹áPüÐ$}j}‡ÊûKú=�N±»6 E…j¼#:fb±ÒøR«»°¤%Å[øb°:¨ÀA¬•¦Y›¸q[PŠ½—ÿÛdˆ•/ú¤Áõ§ö˜“iÍ·úÝ;YïHñâïÿø¶éKOnÒ‹jS¢8ß”4‡«8ÏkžÑ + Ωõ?­öÚ?q;†jâ^ôï|hŸ¼¾N·”÷…Ià °[ öÏØ[¿í_òÚ¦öYïÚâ Qf:dW¥¬Lxœ,DãC:˲S7¤¨”&º`jäphuT+isiÿrå4»`EòG*œë®¶ò'åjŒûÑ«ÜlGIôV SZ& kÐìu0«³oKû°:°à+þ¾}uMÇÃç1uû¯ãä[ÚKƒ2÷ÜIE2vXîR¸'/cø.pd)K°9Q#8ýóŠ†kÁÕgÒqíp ‰;%Òæ(Lg9ñ+ß-ÇzfºáÛmÁÃØI—R"ÇEGjÒ¸”ü·vµGùgw)Û@ÃêgïNn{þ µ‹*3PÞä—�9ø74YgÇš` Òb0A}«ÛLƒj«Êþpܯù¿¾f®hÙJk +=Á0ç©sáÉŒP¼~º„A”pí«"&צ޾:w!kGÎòRê\ÿj +y?5]4Zþy×ÞŇýÕ‡ 9û0»û™g +È*­48!½SJXÂ^s”»ð^øÓòõG§+õÝý�úz10'o ’6�;J®Ô­Ò?ì_P?@Žü@³ì)rÛZ~a� +Ðÿ½Ú +è8C%I!” +QÍx8å2-½q:òfãiÆJæþ‚vž;3$ç,’¼1¹ô zJ((0“VÎÅÐ3íðÌÊG’7R"³Õ’7'ySBáåJáô)¶ÃÁÌI©ó´Ã.In85rSó¨C™ÎTe³—«ýÌûá•]l`Ôi›Ù²Sf^í2Óc&/D3%)4¡ê•màØd 4`��ãÓ´”y`6=ŠðÎPŽ-¡pø\ÒÜK43I³àP…Ì÷%›'6Tjeòt)U®øZ7Ô_|íè”Ü5OHríH^[rõ`¶UEc‡{Z^Ôa¶“\Ý’,êø¯j¤†E7Rò({+5"AóI:l$E–gI+g{ì/c.™ÜíQKŠ<êÊ$­M¡±¥Ü™£Lšüí¸³–ü ¥ØŽšhÄg£ K2„fœ“ÕO&m”%‰:è…笛3¡²õUŠ‹j#«dŠ:pÌ#4EïÅD&64R¢[Œ‚¥“‰Ç”$×:ÞàI½Ä¥L#Kõ­«\šÍšúåÒF5±âl­®ÚKa;°&ËòñÅ®%”ÕÈÕÇ”º–rìºÄv§þR—RTVÉ•µhdŠæÄrý¤ÒÝ'Gæ8µ‹ÑþÚÞ¸³)sz¹HìÔAÇ^ŠÆ<ÝLU½'E3¦ôêŠâ£ŽN6S-%:l2 á$5ŸRÂB,Õä<ˆÿÜ(”eVw”&<Ë“Aê‰Ó—Á³ žÔQIî4ö*¹tJšr$&–TÖ‡ñ,™¿“l’ýÒòÌ„ZuJ¦çµ'ÖS*=’I%ÔÉ䈼L2â -6ºŽP™…îfÉV&Ž•`©v&®zRŒ¶ÅTµB‹‹|Fº4WZ¢14ßcsR:²Ò ¶jåK±û#Öê¨ÚxÄ?uLÒæĆn¡©,1©ÙÝ’«9'vU‹¡U{I)E»tªã®èŠPhîn6ñDADA´ +¢ +¢ +ÂAADADADA,(ˆ‚( +DAÿáQ›·;C—V_‘§hà@�[2slw¯£Ä¤£ña•ÌC¦#›±ùñýÛ´øz†¾gc8xék-eJÞ/‰†lúaO­~¿ñÕîùD†Iƒ2 [žØ0°¦Ì\x;IÓÛ|ž©žÒÒ½pZ&Sã°¾}Wˆ>ÊZyúd‚­m¹´^¢ÉŒÇ±w¥ØÖåó“Ö5÷á±GÚÃÉSª„ˆòÉäú3ºäŠ&:©m4'º;ËBËç£È¬Ü‹§p~÷¤P?LΧd?|«”Ö TÁó0¥`½%s®3ÉíÃgÕgÝ}B´¼n7[^Y”U¤ß.6bzK5E†½I7RgX(¦Â£:›üð VÓeXih3ò£ü8´x^s¡ŸPP0èGtÓÇÖ/ž#¤»’Däç9¹jI{¬}€´\Eœq«ìNrÝàPS’è (ˆDADAXADADADADAL   +¢ +¢ +¢ +¢ +¢„Â`�‚hÀ�ƒ Xà" xàA ``4`€Á<`0T€A  +4ˆ€ P�"ðÀ¡ &€hà ˆààÀƒxÀàAhpÐÀ<€>à4@@éf¬õ¯Wh¿—fxry£uTÙÊI1œ3 ùÈW5 [élB:IôÖÍŒ`Õ²^‰Å›|RíXr4 ´ý¦êE)á _W—:‘ÕÚkæÐÈ¡:CÏ¡IòŒ†ªåÂña©n©¡ À&GÎJÖ»KÕ2ÛUÚË‹ËFy*tæ³þÉ´OMNE¢ž˜lÜÔÕØ{Êé%W«R¹J¨9ú%"¦ÉÔ‰V&É‘© ŸÉø'­ ÊÊù£0MŒÌiS’wÎt0\ˆ=9_]ö¯^»lµƒ-ñ/AÒ™Qå…#§ÆÓzÖ;:ãMfKuR÷as?ôµgqËfnï¥E†‘7Õ^Õ:º¼ŽPM¥Ë. ë72k©f5O«¢{ ¯bgƒ(íÕ´{+X + +¬zUf9§–”Ù¨rÖr³~,i6Œµ£³ +~PnNAÛ8Ù’ÊdnÃ.IÈÜÛÞ)cN«Ôm´’ÌNRš6²÷êdÑsJ>6«Ìö8tW§Žl¤tIž³[Ò~ ÎGŒuÏ1‹Bþ¨kÓRþpçÄüñježý4w1:¡p0»’úG’‡ÄèÊE3¹d‡U¨#&Ê\LÃ(uŒF¤I’ÖÓ@ @8ʨ¤‘âÔ�â±@Js8fŒ1„!B!3$#""aXkT%ºÀÝn>º¥A'í :‹�‚°³•©X á&Ь½1.ú#–N˜÷p1çÑú †¾¢ ¢Nvåˆ0”«ry¿ú(ÑCvq@1g¶?R§f¿7Œý´IQ.`úÍ~Ä,ò~÷ónc°o–kq ©{ºL3\jêÆšÊ ‹°ÒD¹‚l†œk^íü¡èô‰–’€wHÈŽë9Å<ç¾Ç A·!ðŒ|þ§2BÑÉ>PƒG ~åp› ¢ÍeÌA÷˱p·ûrp|°#¦ ×'H,\’yž©@6ÍÁþ®•îÐ2¸žì-ØÂEóç³¾6•û{²¸‰Ó6Œ£¾Èô—ºÃ,¸Ÿ¦õ0'ʃš‰Ï®h˜(¤Ï›6‘!% r*Ó»„ü!ؾ‰Ô¼&¹n¨Pœg*Ÿk³íÖ¦ßEøŒ ƒ7PËDöéùU¾5:Ôø«Å›#w¡qNàÆäÀ2øm8í#1“851ÂâéD‚ØÆ´vÄë½ÿ.ጃ;ôD‹/néÿÏ?y¢ (ñÝóWõTd×éô<õ<ÍCiW]ó ›OVÜ Ï~åewô0&ŽÒÚÖNøbX(ýƒ¬È/R#»XD'؆!Äk/ø?Û¯²å"9[9zí…|¯ˆ¯±u ­©6G¡8¨_g0±Ê@¾â»#6·ŒäºÔ­}}ªæÖµ—‹u«;Ã’<%1Ç÷>tl^Úëõ+×�äVI1H—tvþû.WJ5ðŽR9ž…ÁW‚àÀ¦’‚C-lÚ¹ÛÄo,iCšþËZÀ=í»š;àB#ItPèÛ `ÅB†tÕÈ‘”®D×Û>±‘8p™ýAtÊÍ·ƒXËß•¸”\ÑëªäþÞt÷À'bU?'¶£Á•°÷qüÚ’µì‹Â£0í?Ü$†]ñˆ}Et{ž+~ýs`+\a'q—ïÁ°ûEñ´ Ž-Òƒ«önÇ®§)%'Žt�ê8±>æ7«|×-úiGªÐe§@-qëppÇ<'ªsWr +D¨ˆ²t:ÿXß“À0$¢¾ý!C…„‡orÁi~àâ5Xáƒ`2Ò4Î=ÇOú$„>¬Žç-ý¼h ƒýä*'f›í/ü‹5é­ññ«}Ó9®àZ‹tá±ß4¬ÁÆõ%i9Å£ððøÿs 6¥Ú½¼£. �^í9ÖlÌr# Má`ª»áªD(1Ö>é÷Êw?“‚œ3é€.ùÔŠdâötÓJø0™… üÿLBfNnÖ63­ª*½üØfP§×ÒwàM ›"4Þo§�™_ÞnÉÆ?öøÃZÊÁ¢©¸Jò徟;hÎø&í¸ê\6÷:"¶ŒVRØÍÍzl¬âª•¦øXHO’/wÔ‹(pûa›SùçÊ­ó·vZxÈ)»ú7N‰•²´Õ®!ÛÉðÂPð׿øP 3enûû¥b”‘»gÖL&6ª’öc´ÞœÒXö* +Ú†€«˜L!_ŠàÈNXš©°TUfæTRÈþñæ5 ÓMéUF⌛9C¿Šu°:¢.ëø —ŽU]õÅçéØN5!1`@2û9Ù.œe—”Q³@ˆ¸‡`冀âP +ÃÉýS cç»ÞHÙ ÜBZ…ÉÖ|hUÒÑ?,UÂ7ù¦¼“¼–üa\+°WƒbâÄ|£+o¢ûTÑúŒ:'Q!ZVÀGÜÙ5íðËqé‡^yëkùÃ¥yèjzcJõbgifN½èT©Á4ã@›é, æT(¿¼QQ.Õà݉¯tm¼Ýåñ]øfrù]&·–™Zþô6Ë»áÕÄò»Ü¼r¸XZù_Ó*Ï•G#}æK©—˜±»Ì)?7¦”Ãõd”ÿÅ å¹,>9²°VYkV =ù”ð‡u³^G?ÐÇzŒz@ü¯£Ä¡Õ»ëömV}/Vu+Õœµò¯gdÃÝ·Ñ{G³®[û£Þ”ùÊ +õE‡~Û’—Oß4µÓšnúoeâÈôÞf\ú[¼JÝ…~™eè&ýì Îbw‡*ÒGe¢b*Σ…ß裞t=ü›U³ü’¦"dÌIŠ¹°�Kà +4J +9°B»U œ"¨@œ  )ñ Üö¢�ìÖ +PQbü�QôÝp§ M Å"`âTÜK@DV0²Š¼ßÈî p$‚NéÖ¦¸ +Å31ïÑ5Ü71%X÷øšÄŒùkÒþfê‹2•$Ýð¹:2v#ãJíKP°‹4˜¢ˆ.D‡ö¹Ù™Fð_`þaÜïSXr·Zÿî åø²K$…Ëì:!¶K9R¶€HwRû¤ëg ¡†nd ]Î0ø¯!B×/¥¡ 7DûÊCìÇë‚Iv¯%X6@îæ²Sƒ%¤d?ñ±kMôÆù2,¢ñÙôÿaîÅ£€uCÎ!²ë`h;â]‹XF‡tñ^¯[.¸ÞÚP|Ã~@ÝÕ5íª2yÅe|æÑ5=¬·­Þ©‹/‘ñ?¥¾Ó€?ÖÂ. %Â22»EzÇöUUD6‘Jú÷Ø´aÿœ²ˆšÛSâê¦ qÈ‚AÙöýL±EáwÁÙrª;õäšxÄ ú pVRÄÓªóhUHeN•äDPζ-íÅà܈j³xnêkI± +ñ•ÍUœW‡Öˆlùà¼áସ¸O‚¢æs£8v +rP`]}鱞hzQÒéÄBå'{mr´u (‰âƯµCDå?Ã]Ÿ„|«F7d|›>¢À˜О@*ãt08ŽtýÖêe®©ý¤XÅ�üø¯^«ùäÁÁ#.δ¤[í;Ž¸DŸ§‹æ2†ƒ@:/ïr‚“¿ùþÂLxÄ^•+a ?eìXE½C$ŒóUJ4 +b%4ÕMµãUü~J™^ÜŒ|ÿ³´%×…ÕI¼Ò{w”=àªÀüÕ%ruGݘ)þDW¶ +ë°Ôxyk©IQ¥µ$ 0à ]¹ëéÆvaTÀäíCú’|“ÒÏà‘ÿ€NšÂôtj•@úbÆu16MQÈà­RýÌ¢ïï:¼:$íåD3öH槬¥™d=bû9¨”‚àgùW­—?´øõƒŸºÞWËÂÕœõ}!;ˆHwXü5ìwã¯>¿„þuc˦Oª^ò®ÅkR4 +- ǦŒág^�P›¸=>,Ê·Açà8)òÊp&ßtdø/î™D iiŸ#gªáéËlX•Ê®�ØV ñóÄ¥++Léõ&…,¼òQzŸ[âòyNÿ<-óç¤+¸¶Ãµ;²²!ÏòBýuMƧ¿ü2eþ«›?“èöH{x'hOÍ‚P�‘Ç‚l(Ýå~GØ7äˆsቪ¡4ÉxßÍö`mEâ䚥 ïÞÿŠ‹CÄ.f²fK$K&½µpUIr=”Ãto÷郠兵dzn#ÏŠq©ÊúT€qÁÙžyŒäZÈ`ø×^ùDð*rPOiå1ÁŽzú)ßÍQºæ³“‚¹ZØ —¢jæQP&\œø6.k‰ÛÀ()îfì¡:ïJ +±å0ö9œh¾îÌôh‘ñÆ+hˆ:cŠÞG¾˜ �ªuÐÄ5A@Œ>'#¼.Šë LúåEè’•òóáO±HÅr$ŠOÔÙž­þꌡ»«ø=äåOa ‚ 9‚¨-î÷ûðß‘| %0êÝÛ_\µdV˜'ƒMˆ:¡Q‰Q¯ê©ÓMSå*¼ÓìÈÈÎ,yßêºÏê[?SR­Æ…„ÖēU õ%øÖ*œ¦yp’¨‚È]RrúI{áT_á}Ê*”Cù¯qMH Çå^!¢NmK*MÄ"]h࿃C£X¿ØA€Š ‚oØN—ƒOšúDG„ƒ] h›ýåà"¿.絨4j?™ š·<©Æ¶¾S‘¯ƒa¦ô$°!„õ·­l“•QI®Jzø憔ŸÆ«ÙR3ËðGÈ­$]Q ÜÕi¡œTN¨íºÉd´Xx»Ðd˜÷}ëX'ä•_Af‰“�0™ÿ;ø˜3Â"5*’µI ¹âÐ2ïE‹è&Rë8ÿ¥iŸñÆ«H÷ÒZ‡Ý ïºr,Yâ +œâfˆÒæð¨|Y"Q4®ºŽ$ÙÀ›g­"µ%.4­ªª‚êᜠøwÓãC“¼iEë̦Ò¶Þï_)NU^¼.Ø^ä§D°F'pü¬ .eÈ•`eD†¸; +”œÑuðøÕ­�|è¸dþolE¬;ʪÇT—ÑewåQ�w„Uaìí=’ö¡@Ij¿œ1ØÍòFƒ’áBD‚jHâ‘à×ê¼Õ„PÕ wYçôŽïá^ø}Wô UP6æ2ŒªNl†Tô¡Ùú 4#?ÿ™ýµÆ`@À³Ñ³'¯³àÆ`Ž‡E?žÒ(26W'hîm% 8¡TB,‰4Œ…*E£µ œèC‘k#‡>tMZîãXíº ‰Wlñtˆxƒäl’Ù( œ˜È‰ý"HžøÍ"ø±ì6©ðíl1c@’óÔËýžŒâMtIˆöeÖÈÐÛÌíÀ·2Ê-Î.v‰£¼ó»)•¥ó˜w‹Œ‡üúE†eGàn´ádàãN$æêKŽ:æQ‹=Ž =öÑðo‰ë¶üP¯¼jñ¸Ì¡y…ºÏÒ“»a@ŽÞ‡’°ð]…êÔßiz>Šgሣ0^yåâ«ŽÙæ¯B_„²‚n¶Om±kuÖR@¦tI!ÆᣠÓйe¹¼­mÙ~^Œ&Tb™W? ƒ'Ã}e›¶Ii]„HHÓ:ä!wÇjowÆ^D…¬$®:¾p9SŒu™`l纡ë xÆÄAÀ§ËÓS‹WPÍÖVå#Æ/ñ–õS)7[¹9“SVU}²›?gRDG0']…¡zü 5 a*ÍЛ𡢦ܹñÔÙvΉ´vmÆ+AÕñÔzWFÚoã£M’‰yX5ŸæTž”‘Wãt\Ìmþx—XŠj2ζtÝ`àþàó#…D¿®6!•+¼(f že@zˆ÷9—:.áý?ìæìJíS‘z‘pàÆÃ{í¸p÷/ó—“€@¬ù¡Qæ0EjŸÇhTuœ0ð1/ ÑÓeÙ2¦¤%¶ „ª ŸË´‚Ô7åÑòéûzË>^GÐ5Œ*ˆ¼ Àà»ÈŽ²NN„`ŠK×Ö \™:MEõ«11Œ´QJ6ècÌú#¤¨îãݼ~ Û +–CÀ.»Í¾éŒ-h4Ô ›„?c›g¥éКûß$ùQŽipbðšÕ4ZqÕ-òÀ 0²ÓW£A£Ø”éG×A²ÔDÀ@Ñ +endstream endobj 29 0 obj [/Indexed/DeviceRGB 255 30 0 R] endobj 30 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 27 0 obj <> endobj 25 0 obj [/ICCBased 32 0 R] endobj 31 0 obj <> endobj 33 0 obj <> endobj 32 0 obj <>stream +H‰œ–yTSwÇoÉž•°Ãc [€°5, ‹ì ˆBHBK!aPªVÊX·Ñ=uº¸Žµ:X÷©KÔè£ãÐZ\;v^àõ´™N¿üÞçÜß½÷ý~÷Þw΀.MÑh«a�UZƒ>31[”_€‘&� (€D�ȵºÔ¬„l€K/Ájq'ðV�O¯›V�®¥éþ?±:½O“Žs€RU«À¹çÊzƒÎdŸÁ™WRab5±? Ζ&Vϳ÷œÏSº7åÁâT¥rc¥3ÕMQ]YmÔcµ:¹B… :Ä¿9ð—Ïá©*UéUZ<"Ÿ2V·[«Ô4ÕZL£ýOMüa?Ñü\ã⎽¼"ÀºÈÈ?.�”KHá6|zÓ·J.HÇŸy÷æç~NÐϳÂ}¦¥V£ž‹“dfc +£¾n~ÏôY &à+`œ;ÂA4ˆI dƒ|°(@¨zPZ@;è=`=؆Áv0vƒýà ƒàÏà<ø\·À$˜Á x +^AD‚²‚ WÈ ò‡ÄP$¥@™P>T ©!-d„Z PÔ C; ÝС£Ð èt ú +š‚@ßA/a¦Ã<Øvƒ}a1'ÃÙðX ×ÀMp'¼‚Gá}ðaø|¾OÂáY 4„8"BDŒH4¤�)EôH+Ò "£È~är¹‚L"(å¢*DÃQ)šƒ*дíE‡Ñ]èaô4zBgÐ×Á–àE#È‹jB=¡‹0HØIøˆp†p0MxJ$ùD1„(%æˉÍÄ^âVââqâ%â]â,‰D²"y‘"Hi$9É@ê"m!í#}FºLš&='ÓÈdr¹€¬%wÉ{ÈŸ’/“ï‘_QXWJ%¢¤4Rú(c”c”‹”iÊ+*›* FP³©åÔvêu?õ õ6õ Fs¢…Ò2hÚrÚí´ÏiS´tÝ“.¡ÒôuôéÇé_ÑŸ0 7F4£€a`¬cìfœb|ÍxnÆ5ó1“™)ÍÚÌFÌ›]6{̤0]™1Ì¥Ì&æ óó"ó‹ÂrcIXrV+k„u”uƒ5Ëæ²Eì4v»—½‡}Ž}ŸCâ¸qâ9JN'çÎ)Î].ÂuæJ¸ +î +î÷ wšGä x2^9¯‡÷{ÞoÆœchžkÞ`>bþ‰ù$á»ñeüJ~ÿ ÿ:ÿ¥…EŒ…ÊbÅ~‹ËÏ,m,£-U–Ý–,¯Y¾´Â¬â­*¬6X[ݱF­=­3¬ë­·YŸ±~dó ·QØtÛ´¹i ÛzÚfÚ6Û~`{ÁvÖÎÞ.ÑNg·Åî”Ý#{¾}´}¹ý€ý§ö¸‘‡‡ÏþŽ™c1X%6„Æfm¥ŽFÇŽŽ¯œN9NNœî8SÅÎ¥ÎÎ'g\\R]Z\öºÜt¥¸Š]Ë\7»žu}æ&pËs[å6îv_`) š{·ÝîQî5î£îW=ˆb +­_zžAžež#ž½`¯`/×V¯KÞïPo­÷¨÷ !]#¬îNùð}R|:|Æ}ûºøønð=ëûÚ/ȯÒoÌï–ˆ#JuˆŽ‰¾ó÷ôWøø_ `$´ ø6Ð+P¸-ð¯AÜ Ô UA'ƒþ¬Þü Ä%¤8ä½bž8]Ü+þ<”Úúqè‹°à0CØÁ°† Ã+Â÷„ß_ X Z0¶àn„S„PE¨úU÷J#JûKï«#ÔÕÊ¢ÊËi$šaÍ·åÒòíåÏ*Ò*>¬ø±2¯ò@¹ª¸ê¨–£­Ðž®¶¯n¨¾¤óÒué&kÂj6ÕÌè“õ;k¡Ú%µG <ügê‚ÑݸÒ8UY7R÷¼>·þP»AÛp¡Ñ³qM㽦„¦ß5£ÍŠæ“-Ž-í-SËb–íh…ZKZO¶9·u¶M/O\¾«Ú^Ñþ—¿ŽþŽïWä­8Öi×¹¼óîÊÄ•{»Ìºô]7V…¯Ú¾]­Y=±&`Í–5¯»•Ý_ôøõ öüЫèýb­híÐÚו®›è îÛ¶ž¸^»þú†¨ »úÙýMýw7¦n<<€ t|¿©hÓ¹ÁÀÁ훩››'‡þ ¥ZþL˜¸™$™™üš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 20 0 obj <> endobj 21 0 obj <> endobj 22 0 obj <> endobj 38 0 obj [/View/Design] endobj 39 0 obj <>>> endobj 36 0 obj [/View/Design] endobj 37 0 obj <>>> endobj 34 0 obj [/View/Design] endobj 35 0 obj <>>> endobj 26 0 obj <> endobj 23 0 obj [22 0 R 21 0 R 20 0 R] endobj 40 0 obj <> endobj xref +0 41 +0000000004 65535 f +0000000016 00000 n +0000000175 00000 n +0000018477 00000 n +0000000000 00000 f +0000018528 00000 n +0000000000 00000 f +0000000000 00000 f +0000025639 00000 n +0000025711 00000 n +0000025851 00000 n +0000027410 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000069897 00000 n +0000069972 00000 n +0000070047 00000 n +0000070576 00000 n +0000018968 00000 n +0000066996 00000 n +0000070463 00000 n +0000066853 00000 n +0000024872 00000 n +0000066291 00000 n +0000066339 00000 n +0000067031 00000 n +0000067247 00000 n +0000067126 00000 n +0000070347 00000 n +0000070378 00000 n +0000070231 00000 n +0000070262 00000 n +0000070115 00000 n +0000070146 00000 n +0000070615 00000 n +trailer +<]>> +startxref +70798 +%%EOF diff --git a/docs/static/images/branding/title.png b/docs/static/images/branding/title.png index 37c850dd7..8555e3525 100644 Binary files a/docs/static/images/branding/title.png and b/docs/static/images/branding/title.png differ diff --git a/docs/static/images/branding/title.psd b/docs/static/images/branding/title.psd index cce5f7036..dd9184a97 100644 Binary files a/docs/static/images/branding/title.psd and b/docs/static/images/branding/title.psd differ diff --git a/docs/static/images/branding/title.svg b/docs/static/images/branding/title.svg index ba49465ea..ab93f2439 100644 --- a/docs/static/images/branding/title.svg +++ b/docs/static/images/branding/title.svg @@ -1,3 +1,173 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/compose/lite/docker-compose.yml b/examples/compose/lite/docker-compose.yml index 99f530af9..5d0cc450d 100644 --- a/examples/compose/lite/docker-compose.yml +++ b/examples/compose/lite/docker-compose.yml @@ -45,7 +45,7 @@ services: - TZ=Australia/Melbourne traefik: - image: traefik:v2.9.5 + image: traefik:v2.9.6 container_name: traefik volumes: - ./traefik:/etc/traefik diff --git a/examples/compose/local/docker-compose.yml b/examples/compose/local/docker-compose.yml index 51de7d24d..59619d41e 100644 --- a/examples/compose/local/docker-compose.yml +++ b/examples/compose/local/docker-compose.yml @@ -32,7 +32,7 @@ services: - TZ=Australia/Melbourne traefik: - image: traefik:v2.9.5 + image: traefik:v2.9.6 container_name: traefik volumes: - ./traefik:/etc/traefik diff --git a/go.mod b/go.mod index c3aabac45..d98f82dda 100644 --- a/go.mod +++ b/go.mod @@ -11,27 +11,27 @@ require ( github.com/fasthttp/session/v2 v2.4.13 github.com/fsnotify/fsnotify v1.6.0 github.com/go-asn1-ber/asn1-ber v1.5.4 - github.com/go-crypt/crypt v0.1.14 + github.com/go-crypt/crypt v0.2.3 github.com/go-ldap/ldap/v3 v3.4.4 github.com/go-rod/rod v0.112.2 - github.com/go-sql-driver/mysql v1.6.0 + github.com/go-sql-driver/mysql v1.7.0 github.com/go-webauthn/webauthn v0.5.0 github.com/golang-jwt/jwt/v4 v4.4.3 github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-retryablehttp v0.7.1 - github.com/jackc/pgx/v5 v5.1.1 + github.com/jackc/pgx/v5 v5.2.0 github.com/jmoiron/sqlx v1.3.5 github.com/knadh/koanf v1.4.4 github.com/mattn/go-sqlite3 v1.14.16 github.com/mitchellh/mapstructure v1.5.0 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 - github.com/ory/fosite v0.43.0 + github.com/ory/fosite v0.44.0 github.com/ory/herodot v0.9.13 - github.com/ory/x v0.0.517 + github.com/ory/x v0.0.520 github.com/otiai10/copy v1.9.0 github.com/pkg/errors v0.9.1 - github.com/pquerna/otp v1.3.0 + github.com/pquerna/otp v1.4.0 github.com/prometheus/client_golang v1.14.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 @@ -40,8 +40,8 @@ require ( github.com/trustelem/zxcvbn v1.0.1 github.com/valyala/fasthttp v1.43.0 golang.org/x/sync v0.1.0 - golang.org/x/term v0.2.0 - golang.org/x/text v0.4.0 + golang.org/x/term v0.3.0 + golang.org/x/text v0.5.0 gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -63,7 +63,7 @@ require ( github.com/ecordell/optgen v0.0.6 // indirect github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect - github.com/go-crypt/x v0.1.3 // indirect + github.com/go-crypt/x v0.1.10 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/revoke v0.1.6 // indirect github.com/golang/glog v1.0.0 // indirect @@ -110,7 +110,7 @@ require ( golang.org/x/mod v0.6.0 // indirect golang.org/x/net v0.1.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sys v0.2.0 // indirect + golang.org/x/sys v0.3.0 // indirect golang.org/x/tools v0.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 // indirect diff --git a/go.sum b/go.sum index add7ef375..8db52bafa 100644 --- a/go.sum +++ b/go.sum @@ -162,10 +162,10 @@ github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrt github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-crypt/crypt v0.1.14 h1:Pd8iBYlbwDXJNi0lz8CS/qYvpvxCfP0XO/f5PYvVQ4o= -github.com/go-crypt/crypt v0.1.14/go.mod h1:VNLdWMD0go46arq5WVZB2MV/9Vw02FOWhKDORXl7K2c= -github.com/go-crypt/x v0.1.3 h1:3YSlHqOZsw4gcPzfqrcc5kg4GIhTKmkjl/ZVqJ3CbbU= -github.com/go-crypt/x v0.1.3/go.mod h1:/6X1DjQki055ajXV/7pCHZM0OmMR1+csiXFkxK73Kc8= +github.com/go-crypt/crypt v0.2.3 h1:g9OPe39VmqonsTXP/zo4byEoxrxAAUG+DzBvjzGWvuw= +github.com/go-crypt/crypt v0.2.3/go.mod h1:mbhOIjybuVuh0Vxveb//7UbGV8OCugJC7UPzqs1awYw= +github.com/go-crypt/x v0.1.10 h1:HN8oQGrWcg5xPtIIGwPDWs9MvdYEUJrP7JeNkC46dvM= +github.com/go-crypt/x v0.1.10/go.mod h1:OI04rm/Ojti3mrUFZAJnx66nFbnZ0CVPF7qG49mBZgI= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -184,8 +184,9 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-rod/rod v0.112.2 h1:dwauKYC/H2em8/BcGk3gC0LTzZHf5MIDKf2DVM4z9gU= github.com/go-rod/rod v0.112.2/go.mod h1:ElViL9ABbcshNQw93+11FrYRH92RRhMKleuILo6+5V0= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -338,8 +339,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgx/v5 v5.1.1 h1:pZD79K1SYv8wc2HmCQA6VdmRQi7/OtCfv9bM3WAXUYA= -github.com/jackc/pgx/v5 v5.1.1/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= +github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= +github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= github.com/jandelgado/gcov2lcov v1.0.5 h1:rkBt40h0CVK4oCb8Dps950gvfd1rYvQ8+cWa346lVU0= github.com/jandelgado/gcov2lcov v1.0.5/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -449,8 +450,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/ory/fosite v0.43.0 h1:9H1O3I7CFxS2Y6j9FDAx2W3I5uAyEubc9hECS0UTOgI= -github.com/ory/fosite v0.43.0/go.mod h1:BTd8+oG1mRtezZbQq0S4D2HBc815bedZHjjs2KRs39Y= +github.com/ory/fosite v0.44.0 h1:Z3UjyO11/wlIoa3BotOqcTkfm7kUNA8F7dd8mOMfx0o= +github.com/ory/fosite v0.44.0/go.mod h1:o/G4kAeNn65l6MCod2+KmFfU6JQBSojS7eXys6lKGzM= github.com/ory/go-acc v0.2.6/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= github.com/ory/go-acc v0.2.8 h1:rOHHAPQjf0u7eHFGWpiXK+gIu/e0GRSJNr9pDukdNC4= github.com/ory/go-acc v0.2.8/go.mod h1:iCRZUdGb/7nqvSn8xWZkhfVrtXRZ9Wru2E5rabCjFPI= @@ -460,8 +461,8 @@ github.com/ory/herodot v0.9.13 h1:cN/Z4eOkErl/9W7hDIDLb79IO/bfsH+8yscBjRpB4IU= github.com/ory/herodot v0.9.13/go.mod h1:IWDs9kSvFQqw/cQ8zi5ksyYvITiUU4dI7glUrhZcJYo= github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE= github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM= -github.com/ory/x v0.0.517 h1:20FrwHie18q78WGaHcaH0+XoPNdE88zqSXCQNPNlYUs= -github.com/ory/x v0.0.517/go.mod h1:xUtRpoiRARyJNPVk/fcCNKzyp25Foxt9GPlj8pd7egY= +github.com/ory/x v0.0.520 h1:ryfKHQEViUBv/UdlZhePOG52RpPAooZtK/I7+x58lBI= +github.com/ory/x v0.0.520/go.mod h1:7f32P5XMBLCy6aVT+fUYq3WPcMVpzsjC0C+FovlMNqY= github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4= github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -493,8 +494,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= -github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg= +github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -846,12 +847,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -862,8 +863,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/internal/authentication/file_user_provider.go b/internal/authentication/file_user_provider.go index 1099b47be..9da2c4178 100644 --- a/internal/authentication/file_user_provider.go +++ b/internal/authentication/file_user_provider.go @@ -8,7 +8,12 @@ import ( "sync" "time" - "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm" + "github.com/go-crypt/crypt/algorithm/argon2" + "github.com/go-crypt/crypt/algorithm/bcrypt" + "github.com/go-crypt/crypt/algorithm/pbkdf2" + "github.com/go-crypt/crypt/algorithm/scrypt" + "github.com/go-crypt/crypt/algorithm/shacrypt" "github.com/authelia/authelia/v4/internal/configuration/schema" "github.com/authelia/authelia/v4/internal/logging" @@ -17,7 +22,7 @@ import ( // FileUserProvider is a provider reading details from a file. type FileUserProvider struct { config *schema.FileAuthenticationBackend - hash crypt.Hash + hash algorithm.Hash database *FileUserDatabase mutex *sync.Mutex timeoutReload time.Time @@ -145,39 +150,50 @@ func (p *FileUserProvider) setTimeoutReload(now time.Time) { } // NewFileCryptoHashFromConfig returns a crypt.Hash given a valid configuration. -func NewFileCryptoHashFromConfig(config schema.Password) (hash crypt.Hash, err error) { +func NewFileCryptoHashFromConfig(config schema.Password) (hash algorithm.Hash, err error) { switch config.Algorithm { case hashArgon2, "": - hash = crypt.NewArgon2Hash(). - WithVariant(crypt.NewArgon2Variant(config.Argon2.Variant)). - WithT(config.Argon2.Iterations). - WithM(config.Argon2.Memory). - WithP(config.Argon2.Parallelism). - WithK(config.Argon2.KeyLength). - WithS(config.Argon2.SaltLength) + hash, err = argon2.New( + argon2.WithVariantName(config.Argon2.Variant), + argon2.WithT(config.Argon2.Iterations), + argon2.WithM(uint32(config.Argon2.Memory)), + argon2.WithP(config.Argon2.Parallelism), + argon2.WithK(config.Argon2.KeyLength), + argon2.WithS(config.Argon2.SaltLength), + ) case hashSHA2Crypt: - hash = crypt.NewSHA2CryptHash(). - WithVariant(crypt.NewSHA2CryptVariant(config.SHA2Crypt.Variant)). - WithRounds(config.SHA2Crypt.Iterations). - WithSaltLength(config.SHA2Crypt.SaltLength) + hash, err = shacrypt.New( + shacrypt.WithVariantName(config.SHA2Crypt.Variant), + shacrypt.WithIterations(config.SHA2Crypt.Iterations), + shacrypt.WithSaltLength(config.SHA2Crypt.SaltLength), + ) case hashPBKDF2: - hash = crypt.NewPBKDF2Hash(). - WithVariant(crypt.NewPBKDF2Variant(config.PBKDF2.Variant)). - WithIterations(config.PBKDF2.Iterations). - WithSaltLength(config.PBKDF2.SaltLength) + hash, err = pbkdf2.New( + pbkdf2.WithVariantName(config.PBKDF2.Variant), + pbkdf2.WithIterations(config.PBKDF2.Iterations), + pbkdf2.WithSaltLength(config.PBKDF2.SaltLength), + ) case hashSCrypt: - hash = crypt.NewScryptHash(). - WithLN(config.SCrypt.Iterations). - WithP(config.SCrypt.Parallelism). - WithR(config.SCrypt.BlockSize) + hash, err = scrypt.New( + scrypt.WithLN(config.SCrypt.Iterations), + scrypt.WithP(config.SCrypt.Parallelism), + scrypt.WithR(config.SCrypt.BlockSize), + scrypt.WithKeyLength(config.SCrypt.KeyLength), + scrypt.WithSaltLength(config.SCrypt.SaltLength), + ) case hashBCrypt: - hash = crypt.NewBcryptHash(). - WithVariant(crypt.NewBcryptVariant(config.BCrypt.Variant)). - WithCost(config.BCrypt.Cost) + hash, err = bcrypt.New( + bcrypt.WithVariantName(config.BCrypt.Variant), + bcrypt.WithIterations(config.BCrypt.Cost), + ) default: return nil, fmt.Errorf("algorithm '%s' is unknown", config.Algorithm) } + if err != nil { + return nil, fmt.Errorf("failed to initialize hash settings: %w", err) + } + if err = hash.Validate(); err != nil { return nil, fmt.Errorf("failed to validate hash settings: %w", err) } diff --git a/internal/authentication/file_user_provider_database.go b/internal/authentication/file_user_provider_database.go index 4d710e34b..509f025e0 100644 --- a/internal/authentication/file_user_provider_database.go +++ b/internal/authentication/file_user_provider_database.go @@ -8,6 +8,7 @@ import ( "github.com/asaskevich/govalidator" "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm" "gopkg.in/yaml.v3" ) @@ -203,7 +204,7 @@ func (m *FileUserDatabase) ToDatabaseModel() (model *DatabaseModel) { // DatabaseUserDetails is the model of user details in the file database. type DatabaseUserDetails struct { Username string - Digest crypt.Digest + Digest algorithm.Digest Disabled bool DisplayName string Email string @@ -308,7 +309,7 @@ type UserDetailsModel struct { // ToDatabaseUserDetailsModel converts a UserDetailsModel into a *DatabaseUserDetails. func (m UserDetailsModel) ToDatabaseUserDetailsModel(username string) (model *DatabaseUserDetails, err error) { - var d crypt.Digest + var d algorithm.Digest if d, err = crypt.Decode(m.HashedPassword); err != nil { return nil, err diff --git a/internal/authentication/file_user_provider_test.go b/internal/authentication/file_user_provider_test.go index 4b6039f69..feb26700b 100644 --- a/internal/authentication/file_user_provider_test.go +++ b/internal/authentication/file_user_provider_test.go @@ -252,7 +252,7 @@ func TestShouldRaiseWhenLoadingDatabaseWithBadSHA512HashesForTheFirstTime(t *tes provider := NewFileUserProvider(&config) - assert.EqualError(t, provider.StartupCheck(), "error decoding the authentication database: failed to parse hash for user 'john': sha2crypt decode error: provided encoded hash has an invalid option: option 'rounds00000' is invalid") + assert.EqualError(t, provider.StartupCheck(), "error decoding the authentication database: failed to parse hash for user 'john': shacrypt decode error: parameter pair 'rounds00000' is not properly encoded: does not contain kv separator '='") }) } @@ -263,7 +263,7 @@ func TestShouldRaiseWhenLoadingDatabaseWithBadArgon2idHashSettingsForTheFirstTim provider := NewFileUserProvider(&config) - assert.EqualError(t, provider.StartupCheck(), "error decoding the authentication database: failed to parse hash for user 'john': argon2 decode error: provided encoded hash has an invalid option: option 'm65536' is invalid") + assert.EqualError(t, provider.StartupCheck(), "error decoding the authentication database: failed to parse hash for user 'john': argon2 decode error: parameter pair 'm65536' is not properly encoded: does not contain kv separator '='") }) } diff --git a/internal/commands/crypto_hash.go b/internal/commands/crypto_hash.go index 282abbd45..317a875af 100644 --- a/internal/commands/crypto_hash.go +++ b/internal/commands/crypto_hash.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -272,8 +273,8 @@ func newCryptoHashValidateCmd() (cmd *cobra.Command) { func cmdCryptoHashGenerateFinish(cmd *cobra.Command, args []string, flagsMap map[string]string) (err error) { var ( - algorithm string - configs []string + algName string + configs []string c schema.Password ) @@ -294,25 +295,25 @@ func cmdCryptoHashGenerateFinish(cmd *cobra.Command, args []string, flagsMap map break case legacy: if sha512, _ := cmd.Flags().GetBool(cmdFlagNameSHA512); sha512 { - algorithm = cmdUseHashSHA2Crypt + algName = cmdUseHashSHA2Crypt } else { - algorithm = cmdUseHashArgon2 + algName = cmdUseHashArgon2 } default: - algorithm = cmd.Use + algName = cmd.Use } - if c, err = cmdCryptoHashGetConfig(algorithm, configs, cmd.Flags(), flagsMap); err != nil { + if c, err = cmdCryptoHashGetConfig(algName, configs, cmd.Flags(), flagsMap); err != nil { return err } - if legacy && algorithm == cmdUseHashArgon2 && cmd.Flags().Changed(cmdFlagNameMemory) { + if legacy && algName == cmdUseHashArgon2 && cmd.Flags().Changed(cmdFlagNameMemory) { c.Argon2.Memory *= 1024 } var ( - hash crypt.Hash - digest crypt.Digest + hash algorithm.Hash + digest algorithm.Digest password string random bool ) diff --git a/internal/configuration/decode_hooks.go b/internal/configuration/decode_hooks.go index a5872627f..5f059e8be 100644 --- a/internal/configuration/decode_hooks.go +++ b/internal/configuration/decode_hooks.go @@ -12,7 +12,7 @@ import ( "strings" "time" - "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm/plaintext" "github.com/mitchellh/mapstructure" "github.com/authelia/authelia/v4/internal/configuration/schema" @@ -486,7 +486,7 @@ func StringToPrivateKeyHookFunc() mapstructure.DecodeHookFuncType { } // StringToPasswordDigestHookFunc decodes a string into a crypt.Digest. -func StringToPasswordDigestHookFunc(plaintext bool) mapstructure.DecodeHookFuncType { +func StringToPasswordDigestHookFunc() mapstructure.DecodeHookFuncType { return func(f reflect.Type, t reflect.Type, data interface{}) (value interface{}, err error) { var ptr bool @@ -514,11 +514,11 @@ func StringToPasswordDigestHookFunc(plaintext bool) mapstructure.DecodeHookFuncT var result *schema.PasswordDigest if !strings.HasPrefix(dataStr, "$") { - dataStr = fmt.Sprintf(crypt.StorageFormatSimple, crypt.AlgorithmPrefixPlainText, dataStr) + dataStr = fmt.Sprintf(plaintext.EncodingFmt, plaintext.AlgIdentifierPlainText, dataStr) } if dataStr != "" { - if result, err = schema.NewPasswordDigest(dataStr, plaintext); err != nil { + if result, err = schema.DecodePasswordDigest(dataStr); err != nil { return nil, fmt.Errorf(errFmtDecodeHookCouldNotParse, dataStr, prefixType, expectedType.String(), err) } } diff --git a/internal/configuration/koanf_callbacks_test.go b/internal/configuration/koanf_callbacks_test.go index 43461fe28..561038efd 100644 --- a/internal/configuration/koanf_callbacks_test.go +++ b/internal/configuration/koanf_callbacks_test.go @@ -2,7 +2,6 @@ package configuration import ( "fmt" - "os" "path/filepath" "runtime" "testing" @@ -58,8 +57,7 @@ func TestKoanfSecretCallbackWithValidSecrets(t *testing.T) { "AUTHELIA__STORAGE_MYSQL_FAKE_PASSWORD": "storage.mysql.fake_password", } - dir, err := os.MkdirTemp("", "authelia-test-callbacks") - assert.NoError(t, err) + dir := t.TempDir() secretOne := filepath.Join(dir, "secert_one") secretTwo := filepath.Join(dir, "secret_two") @@ -108,8 +106,7 @@ func TestKoanfSecretCallbackShouldErrorOnFSError(t *testing.T) { "AUTHELIA_THEME": "theme", } - dir, err := os.MkdirTemp("", "authelia-test-callbacks") - assert.NoError(t, err) + dir := t.TempDir() secret := filepath.Join(dir, "inaccessible") diff --git a/internal/configuration/provider.go b/internal/configuration/provider.go index e64a3b661..b19585bd6 100644 --- a/internal/configuration/provider.go +++ b/internal/configuration/provider.go @@ -66,7 +66,7 @@ func unmarshal(ko *koanf.Koanf, val *schema.StructValidator, path string, o any) StringToPrivateKeyHookFunc(), StringToCryptoPrivateKeyHookFunc(), StringToTLSVersionHookFunc(), - StringToPasswordDigestHookFunc(true), + StringToPasswordDigestHookFunc(), ToTimeDurationHookFunc(), ), Metadata: nil, diff --git a/internal/configuration/provider_test.go b/internal/configuration/provider_test.go index b5eb50ecc..147f71eff 100644 --- a/internal/configuration/provider_test.go +++ b/internal/configuration/provider_test.go @@ -19,8 +19,7 @@ import ( func TestShouldErrorSecretNotExist(t *testing.T) { testReset() - dir, err := os.MkdirTemp("", "authelia-test-secret-not-exist") - assert.NoError(t, err) + dir := t.TempDir() testSetEnv(t, "JWT_SECRET_FILE", filepath.Join(dir, "jwt")) testSetEnv(t, "DUO_API_SECRET_KEY_FILE", filepath.Join(dir, "duo")) @@ -36,7 +35,7 @@ func TestShouldErrorSecretNotExist(t *testing.T) { testSetEnv(t, "IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE", filepath.Join(dir, "oidc-hmac")) val := schema.NewStructValidator() - _, _, err = Load(val, NewEnvironmentSource(DefaultEnvPrefix, DefaultEnvDelimiter), NewSecretsSource(DefaultEnvPrefix, DefaultEnvDelimiter)) + _, _, err := Load(val, NewEnvironmentSource(DefaultEnvPrefix, DefaultEnvDelimiter), NewSecretsSource(DefaultEnvPrefix, DefaultEnvDelimiter)) assert.NoError(t, err) assert.Len(t, val.Warnings(), 0) @@ -162,15 +161,14 @@ func TestShouldRaiseIOErrOnUnreadableFile(t *testing.T) { testReset() - dir, err := os.MkdirTemp("", "authelia-conf") - assert.NoError(t, err) + dir := t.TempDir() assert.NoError(t, os.WriteFile(filepath.Join(dir, "myconf.yml"), []byte("server:\n port: 9091\n"), 0000)) cfg := filepath.Join(dir, "myconf.yml") val := schema.NewStructValidator() - _, _, err = Load(val, NewYAMLFileSource(cfg)) + _, _, err := Load(val, NewYAMLFileSource(cfg)) assert.NoError(t, err) require.Len(t, val.Errors(), 1) @@ -390,14 +388,13 @@ func TestShouldNotReadConfigurationOnFSAccessDenied(t *testing.T) { testReset() - dir, err := os.MkdirTemp("", "authelia-config") - assert.NoError(t, err) + dir := t.TempDir() cfg := filepath.Join(dir, "config.yml") assert.NoError(t, testCreateFile(filepath.Join(dir, "config.yml"), "port: 9091\n", 0000)) val := schema.NewStructValidator() - _, _, err = Load(val, NewYAMLFileSource(cfg)) + _, _, err := Load(val, NewYAMLFileSource(cfg)) assert.NoError(t, err) require.Len(t, val.Errors(), 1) @@ -408,11 +405,10 @@ func TestShouldNotReadConfigurationOnFSAccessDenied(t *testing.T) { func TestShouldNotLoadDirectoryConfiguration(t *testing.T) { testReset() - dir, err := os.MkdirTemp("", "authelia-config") - assert.NoError(t, err) + dir := t.TempDir() val := schema.NewStructValidator() - _, _, err = Load(val, NewYAMLFileSource(dir)) + _, _, err := Load(val, NewYAMLFileSource(dir)) assert.NoError(t, err) require.Len(t, val.Errors(), 1) diff --git a/internal/configuration/schema/authentication.go b/internal/configuration/schema/authentication.go index 9d118c091..5eeba76b0 100644 --- a/internal/configuration/schema/authentication.go +++ b/internal/configuration/schema/authentication.go @@ -191,7 +191,7 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = UsernameAttribute: "sAMAccountName", MailAttribute: "mail", DisplayNameAttribute: "displayName", - GroupsFilter: "(&(member={dn})(sAMAccountType=268435456))", + GroupsFilter: "(&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912)))", GroupNameAttribute: "cn", Timeout: time.Second * 5, TLS: &TLSConfig{ diff --git a/internal/configuration/schema/types.go b/internal/configuration/schema/types.go index ee4ed3934..342a81fc7 100644 --- a/internal/configuration/schema/types.go +++ b/internal/configuration/schema/types.go @@ -16,6 +16,8 @@ import ( "time" "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm" + "github.com/go-crypt/crypt/algorithm/plaintext" ) // NewAddressFromString returns an *Address and error depending on the ability to parse the string as an Address. @@ -110,27 +112,32 @@ func (a Address) Listener() (net.Listener, error) { return net.Listen(a.Scheme, a.HostPort()) } -// NewPasswordDigest returns a new PasswordDigest. -func NewPasswordDigest(value string, plaintext bool) (digest *PasswordDigest, err error) { - var d crypt.Digest +var cdecoder algorithm.DecoderRegister - switch { - case plaintext: - d, err = crypt.DecodeWithPlainText(value) - default: - d, err = crypt.Decode(value) +// DecodePasswordDigest returns a new PasswordDigest if it can be decoded. +func DecodePasswordDigest(encodedDigest string) (digest *PasswordDigest, err error) { + if cdecoder == nil { + if cdecoder, err = crypt.NewDefaultDecoder(); err != nil { + return nil, fmt.Errorf("failed to initialize decoder: %w", err) + } + + if err = plaintext.RegisterDecoderPlainText(cdecoder); err != nil { + return nil, fmt.Errorf("failed to initialize decoder: could not register the plaintext decoder: %w", err) + } } - if err != nil { + var d algorithm.Digest + + if d, err = cdecoder.Decode(encodedDigest); err != nil { return nil, err } - return &PasswordDigest{d}, err + return &PasswordDigest{Digest: d}, nil } // PasswordDigest is a configuration type for the crypt.Digest. type PasswordDigest struct { - crypt.Digest + algorithm.Digest } // NewX509CertificateChain creates a new *X509CertificateChain from a given string, parsing each PEM block one by one. diff --git a/internal/configuration/template_test.go b/internal/configuration/template_test.go index e4a02a5ee..3be14868f 100644 --- a/internal/configuration/template_test.go +++ b/internal/configuration/template_test.go @@ -13,8 +13,7 @@ import ( ) func TestShouldGenerateConfiguration(t *testing.T) { - dir, err := os.MkdirTemp("", "authelia-config") - assert.NoError(t, err) + dir := t.TempDir() cfg := filepath.Join(dir, "config.yml") @@ -31,8 +30,7 @@ func TestShouldNotGenerateConfigurationOnFSAccessDenied(t *testing.T) { t.Skip("skipping test due to being on windows") } - dir, err := os.MkdirTemp("", "authelia-config") - assert.NoError(t, err) + dir := t.TempDir() assert.NoError(t, os.Mkdir(filepath.Join(dir, "zero"), 0000)) @@ -44,8 +42,7 @@ func TestShouldNotGenerateConfigurationOnFSAccessDenied(t *testing.T) { } func TestShouldNotGenerateConfiguration(t *testing.T) { - dir, err := os.MkdirTemp("", "authelia-config") - assert.NoError(t, err) + dir := t.TempDir() cfg := filepath.Join(dir, "..", "not-a-dir", "config.yml") diff --git a/internal/configuration/validator/authentication.go b/internal/configuration/validator/authentication.go index 62fe289b2..5aa74bba6 100644 --- a/internal/configuration/validator/authentication.go +++ b/internal/configuration/validator/authentication.go @@ -5,7 +5,11 @@ import ( "net/url" "strings" - "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm/argon2" + "github.com/go-crypt/crypt/algorithm/bcrypt" + "github.com/go-crypt/crypt/algorithm/pbkdf2" + "github.com/go-crypt/crypt/algorithm/scrypt" + "github.com/go-crypt/crypt/algorithm/shacrypt" "github.com/authelia/authelia/v4/internal/configuration/schema" "github.com/authelia/authelia/v4/internal/utils" @@ -91,46 +95,48 @@ func validateFileAuthenticationBackendPasswordConfigArgon2(config *schema.Passwo switch { case config.Argon2.Iterations == 0: config.Argon2.Iterations = schema.DefaultPasswordConfig.Argon2.Iterations - case config.Argon2.Iterations < crypt.Argon2IterationsMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "iterations", config.Argon2.Iterations, crypt.Argon2IterationsMin)) - case config.Argon2.Iterations > crypt.Argon2IterationsMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "iterations", config.Argon2.Iterations, crypt.Argon2IterationsMax)) + case config.Argon2.Iterations < argon2.IterationsMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "iterations", config.Argon2.Iterations, argon2.IterationsMin)) + case config.Argon2.Iterations > argon2.IterationsMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "iterations", config.Argon2.Iterations, argon2.IterationsMax)) } switch { case config.Argon2.Parallelism == 0: config.Argon2.Parallelism = schema.DefaultPasswordConfig.Argon2.Parallelism - case config.Argon2.Parallelism < crypt.Argon2ParallelismMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "parallelism", config.Argon2.Parallelism, crypt.Argon2ParallelismMin)) - case config.Argon2.Parallelism > crypt.Argon2ParallelismMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "parallelism", config.Argon2.Parallelism, crypt.Argon2ParallelismMax)) + case config.Argon2.Parallelism < argon2.ParallelismMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "parallelism", config.Argon2.Parallelism, argon2.ParallelismMin)) + case config.Argon2.Parallelism > argon2.ParallelismMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "parallelism", config.Argon2.Parallelism, argon2.ParallelismMax)) } switch { case config.Argon2.Memory == 0: config.Argon2.Memory = schema.DefaultPasswordConfig.Argon2.Memory - case config.Argon2.Memory < 0: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "memory", config.Argon2.Parallelism, 1)) - case config.Argon2.Memory < (crypt.Argon2MemoryMinParallelismMultiplier * config.Argon2.Parallelism): - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordArgon2MemoryTooLow, config.Argon2.Memory, config.Argon2.Parallelism*crypt.Argon2MemoryMinParallelismMultiplier, config.Argon2.Parallelism, crypt.Argon2MemoryMinParallelismMultiplier)) + case config.Argon2.Memory < argon2.MemoryMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "memory", config.Argon2.Memory, argon2.MemoryMin)) + case uint64(config.Argon2.Memory) > uint64(argon2.MemoryMax): + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "memory", config.Argon2.Memory, argon2.MemoryMax)) + case config.Argon2.Memory < (config.Argon2.Parallelism * argon2.MemoryMinParallelismMultiplier): + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordArgon2MemoryTooLow, config.Argon2.Memory, config.Argon2.Parallelism*argon2.MemoryMinParallelismMultiplier, config.Argon2.Parallelism, argon2.MemoryMinParallelismMultiplier)) } switch { case config.Argon2.KeyLength == 0: config.Argon2.KeyLength = schema.DefaultPasswordConfig.Argon2.KeyLength - case config.Argon2.KeyLength < crypt.Argon2KeySizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "key_length", config.Argon2.KeyLength, crypt.Argon2KeySizeMin)) - case config.Argon2.KeyLength > crypt.Argon2KeySizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "key_length", config.Argon2.KeyLength, crypt.Argon2KeySizeMax)) + case config.Argon2.KeyLength < argon2.KeyLengthMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "key_length", config.Argon2.KeyLength, argon2.KeyLengthMin)) + case config.Argon2.KeyLength > argon2.KeyLengthMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "key_length", config.Argon2.KeyLength, argon2.KeyLengthMax)) } switch { case config.Argon2.SaltLength == 0: config.Argon2.SaltLength = schema.DefaultPasswordConfig.Argon2.SaltLength - case config.Argon2.SaltLength < crypt.Argon2SaltSizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "salt_length", config.Argon2.SaltLength, crypt.Argon2SaltSizeMin)) - case config.Argon2.SaltLength > crypt.Argon2SaltSizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "salt_length", config.Argon2.SaltLength, crypt.Argon2SaltSizeMax)) + case config.Argon2.SaltLength < argon2.SaltLengthMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashArgon2, "salt_length", config.Argon2.SaltLength, argon2.SaltLengthMin)) + case config.Argon2.SaltLength > argon2.SaltLengthMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashArgon2, "salt_length", config.Argon2.SaltLength, argon2.SaltLengthMax)) } } @@ -147,19 +153,19 @@ func validateFileAuthenticationBackendPasswordConfigSHA2Crypt(config *schema.Pas switch { case config.SHA2Crypt.Iterations == 0: config.SHA2Crypt.Iterations = schema.DefaultPasswordConfig.SHA2Crypt.Iterations - case config.SHA2Crypt.Iterations < crypt.SHA2CryptIterationsMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSHA2Crypt, "iterations", config.SHA2Crypt.Iterations, crypt.SHA2CryptIterationsMin)) - case config.SHA2Crypt.Iterations > crypt.SHA2CryptIterationsMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSHA2Crypt, "iterations", config.SHA2Crypt.Iterations, crypt.SHA2CryptIterationsMax)) + case config.SHA2Crypt.Iterations < shacrypt.IterationsMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSHA2Crypt, "iterations", config.SHA2Crypt.Iterations, shacrypt.IterationsMin)) + case config.SHA2Crypt.Iterations > shacrypt.IterationsMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSHA2Crypt, "iterations", config.SHA2Crypt.Iterations, shacrypt.IterationsMax)) } switch { case config.SHA2Crypt.SaltLength == 0: config.SHA2Crypt.SaltLength = schema.DefaultPasswordConfig.SHA2Crypt.SaltLength - case config.SHA2Crypt.SaltLength < crypt.SHA2CryptSaltSizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSHA2Crypt, "salt_length", config.SHA2Crypt.SaltLength, crypt.SHA2CryptSaltSizeMin)) - case config.SHA2Crypt.SaltLength > crypt.SHA2CryptSaltSizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSHA2Crypt, "salt_length", config.SHA2Crypt.SaltLength, crypt.SHA2CryptSaltSizeMax)) + case config.SHA2Crypt.SaltLength < shacrypt.SaltLengthMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSHA2Crypt, "salt_length", config.SHA2Crypt.SaltLength, shacrypt.SaltLengthMin)) + case config.SHA2Crypt.SaltLength > shacrypt.SaltLengthMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSHA2Crypt, "salt_length", config.SHA2Crypt.SaltLength, shacrypt.SaltLengthMax)) } } @@ -176,19 +182,19 @@ func validateFileAuthenticationBackendPasswordConfigPBKDF2(config *schema.Passwo switch { case config.PBKDF2.Iterations == 0: config.PBKDF2.Iterations = schema.DefaultPasswordConfig.PBKDF2.Iterations - case config.PBKDF2.Iterations < crypt.PBKDF2IterationsMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashPBKDF2, "iterations", config.PBKDF2.Iterations, crypt.PBKDF2IterationsMin)) - case config.PBKDF2.Iterations > crypt.PBKDF2IterationsMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashPBKDF2, "iterations", config.PBKDF2.Iterations, crypt.PBKDF2IterationsMax)) + case config.PBKDF2.Iterations < pbkdf2.IterationsMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashPBKDF2, "iterations", config.PBKDF2.Iterations, pbkdf2.IterationsMin)) + case config.PBKDF2.Iterations > pbkdf2.IterationsMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashPBKDF2, "iterations", config.PBKDF2.Iterations, pbkdf2.IterationsMax)) } switch { case config.PBKDF2.SaltLength == 0: config.PBKDF2.SaltLength = schema.DefaultPasswordConfig.PBKDF2.SaltLength - case config.PBKDF2.SaltLength < crypt.PBKDF2SaltSizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashPBKDF2, "salt_length", config.PBKDF2.SaltLength, crypt.PBKDF2SaltSizeMin)) - case config.PBKDF2.SaltLength > crypt.PBKDF2SaltSizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashPBKDF2, "salt_length", config.PBKDF2.SaltLength, crypt.PBKDF2SaltSizeMax)) + case config.PBKDF2.SaltLength < pbkdf2.SaltLengthMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashPBKDF2, "salt_length", config.PBKDF2.SaltLength, pbkdf2.SaltLengthMin)) + case config.PBKDF2.SaltLength > pbkdf2.SaltLengthMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashPBKDF2, "salt_length", config.PBKDF2.SaltLength, pbkdf2.SaltLengthMax)) } } @@ -205,53 +211,58 @@ func validateFileAuthenticationBackendPasswordConfigBCrypt(config *schema.Passwo switch { case config.BCrypt.Cost == 0: config.BCrypt.Cost = schema.DefaultPasswordConfig.BCrypt.Cost - case config.BCrypt.Cost < crypt.BcryptCostMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashBCrypt, "cost", config.BCrypt.Cost, crypt.BcryptCostMin)) - case config.BCrypt.Cost > crypt.BcryptCostMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashBCrypt, "cost", config.BCrypt.Cost, crypt.BcryptCostMax)) + case config.BCrypt.Cost < bcrypt.IterationsMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashBCrypt, "cost", config.BCrypt.Cost, bcrypt.IterationsMin)) + case config.BCrypt.Cost > bcrypt.IterationsMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashBCrypt, "cost", config.BCrypt.Cost, bcrypt.IterationsMax)) } } +//nolint:gocyclo func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.Password, validator *schema.StructValidator) { switch { case config.SCrypt.Iterations == 0: config.SCrypt.Iterations = schema.DefaultPasswordConfig.SCrypt.Iterations - case config.SCrypt.Iterations < crypt.ScryptIterationsMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "iterations", config.SCrypt.Iterations, crypt.ScryptIterationsMin)) + case config.SCrypt.Iterations < scrypt.IterationsMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "iterations", config.SCrypt.Iterations, scrypt.IterationsMin)) + case config.SCrypt.Iterations > scrypt.IterationsMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "iterations", config.SCrypt.Iterations, scrypt.IterationsMax)) } switch { case config.SCrypt.BlockSize == 0: config.SCrypt.BlockSize = schema.DefaultPasswordConfig.SCrypt.BlockSize - case config.SCrypt.BlockSize < crypt.ScryptBlockSizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "block_size", config.SCrypt.BlockSize, crypt.ScryptBlockSizeMin)) - case config.SCrypt.BlockSize > crypt.ScryptBlockSizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "block_size", config.SCrypt.BlockSize, crypt.ScryptBlockSizeMax)) + case config.SCrypt.BlockSize < scrypt.BlockSizeMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "block_size", config.SCrypt.BlockSize, scrypt.BlockSizeMin)) + case config.SCrypt.BlockSize > scrypt.BlockSizeMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "block_size", config.SCrypt.BlockSize, scrypt.BlockSizeMax)) } switch { case config.SCrypt.Parallelism == 0: config.SCrypt.Parallelism = schema.DefaultPasswordConfig.SCrypt.Parallelism - case config.SCrypt.Parallelism < crypt.ScryptParallelismMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "parallelism", config.SCrypt.Parallelism, crypt.ScryptParallelismMin)) + case config.SCrypt.Parallelism < scrypt.ParallelismMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "parallelism", config.SCrypt.Parallelism, scrypt.ParallelismMin)) + case config.SCrypt.Parallelism > scrypt.ParallelismMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "parallelism", config.SCrypt.Parallelism, scrypt.ParallelismMax)) } switch { case config.SCrypt.KeyLength == 0: config.SCrypt.KeyLength = schema.DefaultPasswordConfig.SCrypt.KeyLength - case config.SCrypt.KeyLength < crypt.ScryptKeySizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "key_length", config.SCrypt.KeyLength, crypt.ScryptKeySizeMin)) - case config.SCrypt.KeyLength > crypt.ScryptKeySizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "key_length", config.SCrypt.KeyLength, crypt.ScryptKeySizeMax)) + case config.SCrypt.KeyLength < scrypt.KeyLengthMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "key_length", config.SCrypt.KeyLength, scrypt.KeyLengthMin)) + case config.SCrypt.KeyLength > scrypt.KeyLengthMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "key_length", config.SCrypt.KeyLength, scrypt.KeyLengthMax)) } switch { case config.SCrypt.SaltLength == 0: config.SCrypt.SaltLength = schema.DefaultPasswordConfig.SCrypt.SaltLength - case config.SCrypt.SaltLength < crypt.ScryptSaltSizeMin: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "salt_length", config.SCrypt.SaltLength, crypt.ScryptSaltSizeMin)) - case config.SCrypt.SaltLength > crypt.ScryptSaltSizeMax: - validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "salt_length", config.SCrypt.SaltLength, crypt.ScryptSaltSizeMax)) + case config.SCrypt.SaltLength < scrypt.SaltLengthMin: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooSmall, hashSCrypt, "salt_length", config.SCrypt.SaltLength, scrypt.SaltLengthMin)) + case config.SCrypt.SaltLength > scrypt.SaltLengthMax: + validator.Push(fmt.Errorf(errFmtFileAuthBackendPasswordOptionTooLarge, hashSCrypt, "salt_length", config.SCrypt.SaltLength, scrypt.SaltLengthMax)) } } diff --git a/internal/configuration/validator/authentication_test.go b/internal/configuration/validator/authentication_test.go index 5f589063c..61482b53a 100644 --- a/internal/configuration/validator/authentication_test.go +++ b/internal/configuration/validator/authentication_test.go @@ -409,18 +409,22 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenSCryptOptio } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenSCryptOptionsTooHigh() { + suite.config.File.Password.SCrypt.Iterations = 59 suite.config.File.Password.SCrypt.BlockSize = 360287970189639672 + suite.config.File.Password.SCrypt.Parallelism = 1073741825 suite.config.File.Password.SCrypt.KeyLength = 1374389534409 suite.config.File.Password.SCrypt.SaltLength = 2147483647 ValidateAuthenticationBackend(&suite.config, suite.validator) suite.Assert().Len(suite.validator.Warnings(), 0) - suite.Require().Len(suite.validator.Errors(), 3) + suite.Require().Len(suite.validator.Errors(), 5) - suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: scrypt: option 'block_size' is configured as '360287970189639672' but must be less than or equal to '36028797018963967'") - suite.Assert().EqualError(suite.validator.Errors()[1], "authentication_backend: file: password: scrypt: option 'key_length' is configured as '1374389534409' but must be less than or equal to '137438953440'") - suite.Assert().EqualError(suite.validator.Errors()[2], "authentication_backend: file: password: scrypt: option 'salt_length' is configured as '2147483647' but must be less than or equal to '1024'") + suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: scrypt: option 'iterations' is configured as '59' but must be less than or equal to '58'") + suite.Assert().EqualError(suite.validator.Errors()[1], "authentication_backend: file: password: scrypt: option 'block_size' is configured as '360287970189639672' but must be less than or equal to '36028797018963967'") + suite.Assert().EqualError(suite.validator.Errors()[2], "authentication_backend: file: password: scrypt: option 'parallelism' is configured as '1073741825' but must be less than or equal to '1073741823'") + suite.Assert().EqualError(suite.validator.Errors()[3], "authentication_backend: file: password: scrypt: option 'key_length' is configured as '1374389534409' but must be less than or equal to '137438953440'") + suite.Assert().EqualError(suite.validator.Errors()[4], "authentication_backend: file: password: scrypt: option 'salt_length' is configured as '2147483647' but must be less than or equal to '1024'") } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenArgon2OptionsTooLow() { @@ -437,13 +441,14 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenArgon2Optio suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: argon2: option 'iterations' is configured as '-1' but must be greater than or equal to '1'") suite.Assert().EqualError(suite.validator.Errors()[1], "authentication_backend: file: password: argon2: option 'parallelism' is configured as '-1' but must be greater than or equal to '1'") - suite.Assert().EqualError(suite.validator.Errors()[2], "authentication_backend: file: password: argon2: option 'memory' is configured as '-1' but must be greater than or equal to '1'") + suite.Assert().EqualError(suite.validator.Errors()[2], "authentication_backend: file: password: argon2: option 'memory' is configured as '-1' but must be greater than or equal to '8'") suite.Assert().EqualError(suite.validator.Errors()[3], "authentication_backend: file: password: argon2: option 'key_length' is configured as '1' but must be greater than or equal to '4'") suite.Assert().EqualError(suite.validator.Errors()[4], "authentication_backend: file: password: argon2: option 'salt_length' is configured as '-1' but must be greater than or equal to '1'") } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenArgon2OptionsTooHigh() { suite.config.File.Password.Argon2.Iterations = 9999999999 + suite.config.File.Password.Argon2.Memory = 4294967296 suite.config.File.Password.Argon2.Parallelism = 16777216 suite.config.File.Password.Argon2.KeyLength = 9999999998 suite.config.File.Password.Argon2.SaltLength = 9999999997 @@ -455,6 +460,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenArgon2Optio suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: argon2: option 'iterations' is configured as '9999999999' but must be less than or equal to '2147483647'") suite.Assert().EqualError(suite.validator.Errors()[1], "authentication_backend: file: password: argon2: option 'parallelism' is configured as '16777216' but must be less than or equal to '16777215'") + suite.Assert().EqualError(suite.validator.Errors()[2], "authentication_backend: file: password: argon2: option 'memory' is configured as '4294967296' but must be less than or equal to '4294967295'") suite.Assert().EqualError(suite.validator.Errors()[3], "authentication_backend: file: password: argon2: option 'key_length' is configured as '9999999998' but must be less than or equal to '2147483647'") suite.Assert().EqualError(suite.validator.Errors()[4], "authentication_backend: file: password: argon2: option 'salt_length' is configured as '9999999997' but must be less than or equal to '2147483647'") } @@ -468,7 +474,19 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenArgon2Memor suite.Assert().Len(suite.validator.Warnings(), 0) suite.Require().Len(suite.validator.Errors(), 1) - suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: argon2: option 'memory' is configured as '4' but must be greater than or equal to '32' or '4' (the value of 'parallelism) multiplied by '8'") + suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: argon2: option 'memory' is configured as '4' but must be greater than or equal to '8'") +} + +func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenArgon2MemoryTooLowMultiplier() { + suite.config.File.Password.Argon2.Memory = 8 + suite.config.File.Password.Argon2.Parallelism = 4 + + ValidateAuthenticationBackend(&suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Errors(), 1) + + suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: file: password: argon2: option 'memory' is configured as '8' but must be greater than or equal to '32' or '4' (the value of 'parallelism) multiplied by '8'") } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenBadAlgorithmDefined() { diff --git a/internal/configuration/validator/identity_providers_test.go b/internal/configuration/validator/identity_providers_test.go index fad289432..32118a066 100644 --- a/internal/configuration/validator/identity_providers_test.go +++ b/internal/configuration/validator/identity_providers_test.go @@ -838,7 +838,7 @@ func TestValidateOIDCClientRedirectURIsSupportingPrivateUseURISchemes(t *testing } func MustDecodeSecret(value string) *schema.PasswordDigest { - if secret, err := schema.NewPasswordDigest(value, true); err != nil { + if secret, err := schema.DecodePasswordDigest(value); err != nil { panic(err) } else { return secret diff --git a/internal/handlers/handler_oidc_authorization.go b/internal/handlers/handler_oidc_authorization.go index 567999e01..1bf85a25f 100644 --- a/internal/handlers/handler_oidc_authorization.go +++ b/internal/handlers/handler_oidc_authorization.go @@ -52,13 +52,7 @@ func OpenIDConnectAuthorization(ctx *middlewares.AutheliaCtx, rw http.ResponseWr return } - if issuer, err = ctx.IssuerURL(); err != nil { - ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: error occurred determining issuer: %+v", requester.GetID(), clientID, err) - - ctx.Providers.OpenIDConnect.WriteAuthorizeError(ctx, rw, requester, oidc.ErrIssuerCouldNotDerive) - - return - } + issuer = ctx.RootURL() userSession := ctx.GetSession() diff --git a/internal/handlers/handler_oidc_consent.go b/internal/handlers/handler_oidc_consent.go index bc5a81d62..98935cba0 100644 --- a/internal/handlers/handler_oidc_consent.go +++ b/internal/handlers/handler_oidc_consent.go @@ -130,12 +130,7 @@ func OpenIDConnectConsentPOST(ctx *middlewares.AutheliaCtx) { query url.Values ) - if redirectURI, err = ctx.IssuerURL(); err != nil { - ctx.Logger.Errorf("Failed to parse the consent redirect URL: %+v", err) - ctx.SetJSONError(messageOperationFailed) - - return - } + redirectURI = ctx.RootURL() if query, err = url.ParseQuery(consent.Form); err != nil { ctx.Logger.Errorf("Failed to parse the consent form values: %+v", err) diff --git a/internal/handlers/handler_oidc_wellknown.go b/internal/handlers/handler_oidc_wellknown.go index 1ac819817..7c2f3d3b3 100644 --- a/internal/handlers/handler_oidc_wellknown.go +++ b/internal/handlers/handler_oidc_wellknown.go @@ -20,13 +20,7 @@ func OpenIDConnectConfigurationWellKnownGET(ctx *middlewares.AutheliaCtx) { err error ) - if issuer, err = ctx.IssuerURL(); err != nil { - ctx.Logger.Errorf("Error occurred determining OpenID Connect issuer details: %+v", err) - - ctx.ReplyStatusCode(fasthttp.StatusBadRequest) - - return - } + issuer = ctx.RootURL() wellKnown := ctx.Providers.OpenIDConnect.GetOpenIDConnectWellKnownConfiguration(issuer.String()) @@ -52,13 +46,7 @@ func OAuthAuthorizationServerWellKnownGET(ctx *middlewares.AutheliaCtx) { err error ) - if issuer, err = ctx.IssuerURL(); err != nil { - ctx.Logger.Errorf("Error occurred determining OpenID Connect issuer details: %+v", err) - - ctx.ReplyStatusCode(fasthttp.StatusBadRequest) - - return - } + issuer = ctx.RootURL() wellKnown := ctx.Providers.OpenIDConnect.GetOAuth2WellKnownConfiguration(issuer.String()) diff --git a/internal/handlers/response.go b/internal/handlers/response.go index 33599ea8e..8669597f1 100644 --- a/internal/handlers/response.go +++ b/internal/handlers/response.go @@ -144,11 +144,7 @@ func handleOIDCWorkflowResponseWithTargetURL(ctx *middlewares.AutheliaCtx, targe return } - if issuerURL, err = ctx.IssuerURL(); err != nil { - ctx.Error(fmt.Errorf("unable to get issuer for redirection: %w", err), messageAuthenticationFailed) - - return - } + issuerURL = ctx.RootURL() if targetURL.Host != issuerURL.Host { ctx.Error(fmt.Errorf("unable to redirect to '%s': target host '%s' does not match expected issuer host '%s'", targetURL, targetURL.Host, issuerURL.Host), messageAuthenticationFailed) @@ -221,11 +217,7 @@ func handleOIDCWorkflowResponseWithID(ctx *middlewares.AutheliaCtx, id string) { form url.Values ) - if targetURL, err = ctx.IssuerURL(); err != nil { - ctx.Error(fmt.Errorf("unable to get issuer for redirection: %w", err), messageAuthenticationFailed) - - return - } + targetURL = ctx.RootURL() if form, err = consent.GetForm(); err != nil { ctx.Error(fmt.Errorf("unable to get authorization form values from consent session with challenge id '%s': %w", consent.ChallengeID, err), messageAuthenticationFailed) diff --git a/internal/logging/logger_test.go b/internal/logging/logger_test.go index cd1baead7..0976b494e 100644 --- a/internal/logging/logger_test.go +++ b/internal/logging/logger_test.go @@ -3,7 +3,6 @@ package logging import ( "fmt" "io" - "log" "os" "runtime" "testing" @@ -16,15 +15,10 @@ import ( ) func TestShouldWriteLogsToFile(t *testing.T) { - dir, err := os.MkdirTemp("/tmp", "logs-dir") - if err != nil { - log.Fatal(err) - } - - defer os.RemoveAll(dir) + dir := t.TempDir() path := fmt.Sprintf("%s/authelia.log", dir) - err = InitializeLogger(schema.LogConfiguration{Format: "text", FilePath: path, KeepStdout: false}, false) + err := InitializeLogger(schema.LogConfiguration{Format: "text", FilePath: path, KeepStdout: false}, false) require.NoError(t, err) Logger().Info("This is a test") @@ -39,15 +33,10 @@ func TestShouldWriteLogsToFile(t *testing.T) { } func TestShouldWriteLogsToFileAndStdout(t *testing.T) { - dir, err := os.MkdirTemp("/tmp", "logs-dir") - if err != nil { - log.Fatal(err) - } - - defer os.RemoveAll(dir) + dir := t.TempDir() path := fmt.Sprintf("%s/authelia.log", dir) - err = InitializeLogger(schema.LogConfiguration{Format: "text", FilePath: path, KeepStdout: true}, false) + err := InitializeLogger(schema.LogConfiguration{Format: "text", FilePath: path, KeepStdout: true}, false) require.NoError(t, err) Logger().Info("This is a test") @@ -62,15 +51,10 @@ func TestShouldWriteLogsToFileAndStdout(t *testing.T) { } func TestShouldFormatLogsAsJSON(t *testing.T) { - dir, err := os.MkdirTemp("/tmp", "logs-dir") - if err != nil { - log.Fatal(err) - } - - defer os.RemoveAll(dir) + dir := t.TempDir() path := fmt.Sprintf("%s/authelia.log", dir) - err = InitializeLogger(schema.LogConfiguration{Format: "json", FilePath: path, KeepStdout: false}, false) + err := InitializeLogger(schema.LogConfiguration{Format: "json", FilePath: path, KeepStdout: false}, false) require.NoError(t, err) Logger().Info("This is a test") diff --git a/internal/middlewares/authelia_context.go b/internal/middlewares/authelia_context.go index 862f16d4d..e30e58399 100644 --- a/internal/middlewares/authelia_context.go +++ b/internal/middlewares/authelia_context.go @@ -5,7 +5,6 @@ import ( "fmt" "net" "net/url" - "path" "strings" "github.com/asaskevich/govalidator" @@ -81,7 +80,7 @@ func (ctx *AutheliaCtx) ReplyError(err error, message string) { ctx.Logger.Error(marshalErr) } - ctx.SetContentTypeBytes(contentTypeApplicationJSON) + ctx.SetContentTypeApplicationJSON() ctx.SetBody(b) ctx.Logger.Debug(err) } @@ -90,7 +89,7 @@ func (ctx *AutheliaCtx) ReplyError(err error, message string) { func (ctx *AutheliaCtx) ReplyStatusCode(statusCode int) { ctx.Response.Reset() ctx.SetStatusCode(statusCode) - ctx.SetContentTypeBytes(contentTypeTextPlain) + ctx.SetContentTypeTextPlain() ctx.SetBodyString(fmt.Sprintf("%d %s", statusCode, fasthttp.StatusMessage(statusCode))) } @@ -108,7 +107,7 @@ func (ctx *AutheliaCtx) ReplyJSON(data any, statusCode int) (err error) { ctx.SetStatusCode(statusCode) } - ctx.SetContentTypeBytes(contentTypeApplicationJSON) + ctx.SetContentTypeApplicationJSON() ctx.SetBody(body) return nil @@ -145,7 +144,7 @@ func (ctx *AutheliaCtx) XForwardedProto() (proto []byte) { } // XForwardedMethod return the content of the X-Forwarded-Method header. -func (ctx *AutheliaCtx) XForwardedMethod() (method []byte) { +func (ctx *AutheliaCtx) XForwardedMethod() []byte { return ctx.RequestCtx.Request.Header.PeekBytes(headerXForwardedMethod) } @@ -171,79 +170,61 @@ func (ctx *AutheliaCtx) XForwardedURI() (uri []byte) { return uri } -// XAutheliaURL return the content of the X-Authelia-URL header. -func (ctx *AutheliaCtx) XAutheliaURL() (autheliaURL []byte) { +// XOriginalURL returns the content of the X-Original-URL header. +func (ctx *AutheliaCtx) XOriginalURL() []byte { + return ctx.RequestCtx.Request.Header.PeekBytes(headerXOriginalURL) +} + +// XOriginalMethod return the content of the X-Original-Method header. +func (ctx *AutheliaCtx) XOriginalMethod() []byte { + return ctx.RequestCtx.Request.Header.PeekBytes(headerXOriginalMethod) +} + +// XAutheliaURL return the content of the X-Authelia-URL header which is used to communicate the location of the +// portal when using proxies like Envoy. +func (ctx *AutheliaCtx) XAutheliaURL() []byte { return ctx.RequestCtx.Request.Header.PeekBytes(headerXAutheliaURL) } // QueryArgRedirect return the content of the rd query argument. -func (ctx *AutheliaCtx) QueryArgRedirect() (val []byte) { - return ctx.RequestCtx.QueryArgs().PeekBytes(queryArgRedirect) +func (ctx *AutheliaCtx) QueryArgRedirect() []byte { + return ctx.RequestCtx.QueryArgs().PeekBytes(qryArgRedirect) } // BasePath returns the base_url as per the path visited by the client. -func (ctx *AutheliaCtx) BasePath() (base string) { +func (ctx *AutheliaCtx) BasePath() string { if baseURL := ctx.UserValueBytes(UserValueKeyBaseURL); baseURL != nil { return baseURL.(string) } - return base + return "" } -// ExternalRootURL gets the X-Forwarded-Proto, X-Forwarded-Host headers and the BasePath and forms them into a URL. -func (ctx *AutheliaCtx) ExternalRootURL() (string, error) { - protocol := ctx.XForwardedProto() - if protocol == nil { - return "", errMissingXForwardedProto +// BasePathSlash is the same as BasePath but returns a final slash as well. +func (ctx *AutheliaCtx) BasePathSlash() string { + if baseURL := ctx.UserValueBytes(UserValueKeyBaseURL); baseURL != nil { + return baseURL.(string) + strSlash } - host := ctx.XForwardedHost() - if host == nil { - return "", errMissingXForwardedHost - } - - externalRootURL := fmt.Sprintf("%s://%s", protocol, host) - - if base := ctx.BasePath(); base != "" { - externalBaseURL, err := url.ParseRequestURI(externalRootURL) - if err != nil { - return "", err - } - - externalBaseURL.Path = path.Join(externalBaseURL.Path, base) - - return externalBaseURL.String(), nil - } - - return externalRootURL, nil + return strSlash } -// IssuerURL returns the expected Issuer. -func (ctx *AutheliaCtx) IssuerURL() (issuerURL *url.URL, err error) { - issuerURL = &url.URL{ - Scheme: "https", +// RootURL returns the Root URL. +func (ctx *AutheliaCtx) RootURL() (issuerURL *url.URL) { + return &url.URL{ + Scheme: string(ctx.XForwardedProto()), + Host: string(ctx.XForwardedHost()), + Path: ctx.BasePath(), } - - if scheme := ctx.XForwardedProto(); scheme != nil { - issuerURL.Scheme = string(scheme) - } - - if host := ctx.XForwardedHost(); len(host) != 0 { - issuerURL.Host = string(host) - } else { - return nil, errMissingXForwardedHost - } - - if base := ctx.BasePath(); base != "" { - issuerURL.Path = path.Join(issuerURL.Path, base) - } - - return issuerURL, nil } -// XOriginalURL return the content of the X-Original-URL header. -func (ctx *AutheliaCtx) XOriginalURL() []byte { - return ctx.RequestCtx.Request.Header.PeekBytes(headerXOriginalURL) +// RootURLSlash is the same as RootURL but includes a final slash as well. +func (ctx *AutheliaCtx) RootURLSlash() (issuerURL *url.URL) { + return &url.URL{ + Scheme: string(ctx.XForwardedProto()), + Host: string(ctx.XForwardedHost()), + Path: ctx.BasePathSlash(), + } } // GetSession return the user session. Any update will be saved in cache. @@ -264,7 +245,7 @@ func (ctx *AutheliaCtx) SaveSession(userSession session.UserSession) error { // ReplyOK is a helper method to reply ok. func (ctx *AutheliaCtx) ReplyOK() { - ctx.SetContentTypeBytes(contentTypeApplicationJSON) + ctx.SetContentTypeApplicationJSON() ctx.SetBody(okMessageBytes) } @@ -377,7 +358,7 @@ func (ctx *AutheliaCtx) SpecialRedirect(uri string, statusCode int) { statusCode = fasthttp.StatusFound } - ctx.SetContentTypeBytes(contentTypeTextHTML) + ctx.SetContentTypeTextHTML() ctx.SetStatusCode(statusCode) u := fasthttp.AcquireURI() @@ -400,3 +381,18 @@ func (ctx *AutheliaCtx) RecordAuthentication(success, regulated bool, method str ctx.Providers.Metrics.RecordAuthentication(success, regulated, method) } + +// SetContentTypeTextPlain efficiently sets the Content-Type header to 'text/plain; charset=utf-8'. +func (ctx *AutheliaCtx) SetContentTypeTextPlain() { + ctx.SetContentTypeBytes(contentTypeTextPlain) +} + +// SetContentTypeTextHTML efficiently sets the Content-Type header to 'text/html; charset=utf-8'. +func (ctx *AutheliaCtx) SetContentTypeTextHTML() { + ctx.SetContentTypeBytes(contentTypeTextHTML) +} + +// SetContentTypeApplicationJSON efficiently sets the Content-Type header to 'application/json; charset=utf-8'. +func (ctx *AutheliaCtx) SetContentTypeApplicationJSON() { + ctx.SetContentTypeBytes(contentTypeApplicationJSON) +} diff --git a/internal/middlewares/authelia_context_test.go b/internal/middlewares/authelia_context_test.go index ab8882f03..bd857c835 100644 --- a/internal/middlewares/authelia_context_test.go +++ b/internal/middlewares/authelia_context_test.go @@ -21,7 +21,6 @@ func TestIssuerURL(t *testing.T) { name string proto, host, base string expected string - err string }{ { name: "Standard", @@ -36,7 +35,7 @@ func TestIssuerURL(t *testing.T) { { name: "NoHost", proto: "https", host: "", base: "", - err: "Missing header X-Forwarded-Host", + expected: "https:", }, } @@ -52,21 +51,14 @@ func TestIssuerURL(t *testing.T) { mock.Ctx.SetUserValue("base_url", tc.base) } - actual, err := mock.Ctx.IssuerURL() + actual := mock.Ctx.RootURL() - switch tc.err { - case "": - assert.NoError(t, err) - require.NotNil(t, actual) + require.NotNil(t, actual) - assert.Equal(t, tc.expected, actual.String()) - assert.Equal(t, tc.proto, actual.Scheme) - assert.Equal(t, tc.host, actual.Host) - assert.Equal(t, tc.base, actual.Path) - default: - assert.EqualError(t, err, tc.err) - assert.Nil(t, actual) - } + assert.Equal(t, tc.expected, actual.String()) + assert.Equal(t, tc.proto, actual.Scheme) + assert.Equal(t, tc.host, actual.Host) + assert.Equal(t, tc.base, actual.Path) }) } } diff --git a/internal/middlewares/const.go b/internal/middlewares/const.go index 88ef4472b..83f832545 100644 --- a/internal/middlewares/const.go +++ b/internal/middlewares/const.go @@ -20,6 +20,7 @@ var ( headerXForwardedURI = []byte("X-Forwarded-URI") headerXOriginalURL = []byte("X-Original-URL") + headerXOriginalMethod = []byte("X-Original-Method") headerXForwardedMethod = []byte("X-Forwarded-Method") headerVary = []byte(fasthttp.HeaderVary) @@ -67,13 +68,17 @@ var ( const ( strProtoHTTPS = "https" strProtoHTTP = "http" + strSlash = "/" + + queryArgRedirect = "rd" + queryArgToken = "token" ) var ( protoHTTPS = []byte(strProtoHTTPS) protoHTTP = []byte(strProtoHTTP) - queryArgRedirect = []byte("rd") + qryArgRedirect = []byte(queryArgRedirect) // UserValueKeyBaseURL is the User Value key where we store the Base URL. UserValueKeyBaseURL = []byte("base_url") diff --git a/internal/middlewares/identity_verification.go b/internal/middlewares/identity_verification.go index 92775cbad..ea63d1893 100644 --- a/internal/middlewares/identity_verification.go +++ b/internal/middlewares/identity_verification.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/mail" + "path" "time" "github.com/golang-jwt/jwt/v4" @@ -62,7 +63,7 @@ func IdentityVerificationStart(args IdentityVerificationStartArgs, delayFunc Tim token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - ss, err := token.SignedString([]byte(ctx.Configuration.JWTSecret)) + signedToken, err := token.SignedString([]byte(ctx.Configuration.JWTSecret)) if err != nil { ctx.Error(err, messageOperationFailed) return @@ -73,23 +74,23 @@ func IdentityVerificationStart(args IdentityVerificationStartArgs, delayFunc Tim return } - var ( - uri string - ) - - if uri, err = ctx.ExternalRootURL(); err != nil { - ctx.Error(err, messageOperationFailed) - return - } - disableHTML := false if ctx.Configuration.Notifier.SMTP != nil { disableHTML = ctx.Configuration.Notifier.SMTP.DisableHTMLEmails } + linkURL := ctx.RootURL() + + query := linkURL.Query() + + query.Set(queryArgToken, signedToken) + + linkURL.Path = path.Join(linkURL.Path, args.TargetEndpoint) + linkURL.RawQuery = query.Encode() + values := templates.EmailIdentityVerificationValues{ Title: args.MailTitle, - LinkURL: fmt.Sprintf("%s%s?token=%s", uri, args.TargetEndpoint, ss), + LinkURL: linkURL.String(), LinkText: args.MailButtonContent, DisplayName: identity.DisplayName, RemoteIP: ctx.RemoteIP().String(), diff --git a/internal/middlewares/identity_verification_test.go b/internal/middlewares/identity_verification_test.go index 87bcdb5fe..d4c56ec8e 100644 --- a/internal/middlewares/identity_verification_test.go +++ b/internal/middlewares/identity_verification_test.go @@ -124,24 +124,6 @@ func TestShouldFailSendingAnEmail(t *testing.T) { assert.Equal(t, "no notif", mock.Hook.LastEntry().Message) } -func TestShouldFailWhenXForwardedHostHeaderIsMissing(t *testing.T) { - mock := mocks.NewMockAutheliaCtx(t) - defer mock.Close() - - mock.Ctx.Configuration.JWTSecret = testJWTSecret - mock.Ctx.Request.Header.Add("X-Forwarded-Proto", "http") - - mock.StorageMock.EXPECT(). - SaveIdentityVerification(mock.Ctx, gomock.Any()). - Return(nil) - - args := newArgs(defaultRetriever) - middlewares.IdentityVerificationStart(args, nil)(mock.Ctx) - - assert.Equal(t, 200, mock.Ctx.Response.StatusCode()) - assert.Equal(t, "Missing header X-Forwarded-Host", mock.Hook.LastEntry().Message) -} - func TestShouldSucceedIdentityVerificationStartProcess(t *testing.T) { mock := mocks.NewMockAutheliaCtx(t) diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go index 01722d21a..1f1a7b860 100644 --- a/internal/oidc/client_test.go +++ b/internal/oidc/client_test.go @@ -227,7 +227,7 @@ func TestClient_IsPublic(t *testing.T) { } func MustDecodeSecret(value string) *schema.PasswordDigest { - if secret, err := schema.NewPasswordDigest(value, true); err != nil { + if secret, err := schema.DecodePasswordDigest(value); err != nil { panic(err) } else { return secret diff --git a/internal/oidc/config.go b/internal/oidc/config.go index 5be51eed8..7da84d4ef 100644 --- a/internal/oidc/config.go +++ b/internal/oidc/config.go @@ -66,6 +66,7 @@ type Config struct { JWTScopeField jwt.JWTScopeFieldEnum JWTMaxDuration time.Duration + Hasher *AdaptiveHasher Hash HashConfig Strategy StrategyConfig PAR PARConfig @@ -413,13 +414,13 @@ func (c *Config) GetTokenEntropy(ctx context.Context) (entropy int) { } // GetGlobalSecret returns the global secret. -func (c *Config) GetGlobalSecret(ctx context.Context) (secret []byte) { - return c.GlobalSecret +func (c *Config) GetGlobalSecret(ctx context.Context) (secret []byte, err error) { + return c.GlobalSecret, nil } // GetRotatedGlobalSecrets returns the rotated global secrets. -func (c *Config) GetRotatedGlobalSecrets(ctx context.Context) (secrets [][]byte) { - return c.RotatedGlobalSecrets +func (c *Config) GetRotatedGlobalSecrets(ctx context.Context) (secrets [][]byte, err error) { + return c.RotatedGlobalSecrets, nil } // GetHTTPClient returns the HTTP client provider. @@ -513,7 +514,7 @@ func (c *Config) GetTokenURL(ctx context.Context) (tokenURL string) { // GetSecretsHasher returns the client secrets hashing function. func (c *Config) GetSecretsHasher(ctx context.Context) (hasher fosite.Hasher) { if c.Hash.ClientSecrets == nil { - c.Hash.ClientSecrets = &AdaptiveHasher{} + c.Hash.ClientSecrets, _ = NewAdaptiveHasher() } return c.Hash.ClientSecrets diff --git a/internal/oidc/hasher.go b/internal/oidc/hasher.go index 7aad32b25..746f92ced 100644 --- a/internal/oidc/hasher.go +++ b/internal/oidc/hasher.go @@ -4,13 +4,34 @@ import ( "context" "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm" + "github.com/go-crypt/crypt/algorithm/plaintext" ) -// Compare compares the hash with the data and returns an error if they don't match. -func (h AdaptiveHasher) Compare(_ context.Context, hash, data []byte) (err error) { - var digest crypt.Digest +func NewAdaptiveHasher() (hasher *AdaptiveHasher, err error) { + hasher = &AdaptiveHasher{} - if digest, err = crypt.DecodeWithPlainText(string(hash)); err != nil { + if hasher.decoder, err = crypt.NewDefaultDecoder(); err != nil { + return nil, err + } + + if err = plaintext.RegisterDecoderPlainText(hasher.decoder); err != nil { + return nil, err + } + + return hasher, nil +} + +// AdaptiveHasher implements the fosite.Hasher interface without an actual hashing algo. +type AdaptiveHasher struct { + decoder algorithm.DecoderRegister +} + +// Compare compares the hash with the data and returns an error if they don't match. +func (h *AdaptiveHasher) Compare(_ context.Context, hash, data []byte) (err error) { + var digest algorithm.Digest + + if digest, err = h.decoder.Decode(string(hash)); err != nil { return err } @@ -22,6 +43,6 @@ func (h AdaptiveHasher) Compare(_ context.Context, hash, data []byte) (err error } // Hash creates a new hash from data. -func (h AdaptiveHasher) Hash(_ context.Context, data []byte) (hash []byte, err error) { +func (h *AdaptiveHasher) Hash(_ context.Context, data []byte) (hash []byte, err error) { return data, nil } diff --git a/internal/oidc/hasher_test.go b/internal/oidc/hasher_test.go index bc3dfac1b..04f1b0f41 100644 --- a/internal/oidc/hasher_test.go +++ b/internal/oidc/hasher_test.go @@ -5,32 +5,46 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestShouldNotRaiseErrorOnEqualPasswordsPlainText(t *testing.T) { - hasher := AdaptiveHasher{} + hasher, err := NewAdaptiveHasher() + + require.NoError(t, err) a := []byte("$plaintext$abc") b := []byte("abc") ctx := context.Background() - err := hasher.Compare(ctx, a, b) + assert.NoError(t, hasher.Compare(ctx, a, b)) +} - assert.NoError(t, err) +func TestShouldNotRaiseErrorOnEqualPasswordsPlainTextWithSeparator(t *testing.T) { + hasher, err := NewAdaptiveHasher() + + require.NoError(t, err) + + a := []byte("$plaintext$abc$123") + b := []byte("abc$123") + + ctx := context.Background() + + assert.NoError(t, hasher.Compare(ctx, a, b)) } func TestShouldRaiseErrorOnNonEqualPasswordsPlainText(t *testing.T) { - hasher := AdaptiveHasher{} + hasher, err := NewAdaptiveHasher() + + require.NoError(t, err) a := []byte("$plaintext$abc") b := []byte("abcd") ctx := context.Background() - err := hasher.Compare(ctx, a, b) - - assert.Equal(t, errPasswordsDoNotMatch, err) + assert.Equal(t, errPasswordsDoNotMatch, hasher.Compare(ctx, a, b)) } func TestShouldHashPassword(t *testing.T) { diff --git a/internal/oidc/types.go b/internal/oidc/types.go index 41f35373b..58328d119 100644 --- a/internal/oidc/types.go +++ b/internal/oidc/types.go @@ -4,7 +4,7 @@ import ( "net/url" "time" - "github.com/go-crypt/crypt" + "github.com/go-crypt/crypt/algorithm" "github.com/ory/fosite" "github.com/ory/fosite/handler/openid" "github.com/ory/fosite/token/jwt" @@ -103,7 +103,7 @@ type Store struct { type Client struct { ID string Description string - Secret crypt.Digest + Secret algorithm.Digest SectorIdentifier string Public bool @@ -184,9 +184,6 @@ type KeyManager struct { jwks *jose.JSONWebKeySet } -// AdaptiveHasher implements the fosite.Hasher interface without an actual hashing algo. -type AdaptiveHasher struct{} - // ConsentGetResponseBody schema of the response body of the consent GET endpoint. type ConsentGetResponseBody struct { ClientID string `json:"client_id"` diff --git a/internal/server/const.go b/internal/server/const.go index f4a774674..d07c355e8 100644 --- a/internal/server/const.go +++ b/internal/server/const.go @@ -11,6 +11,9 @@ const ( fileOpenAPI = "openapi.yml" fileIndexHTML = "index.html" fileLogo = "logo.png" + + extHTML = ".html" + extJSON = ".json" ) var ( @@ -47,6 +50,7 @@ var ( ) const ( + environment = "ENVIRONMENT" dev = "dev" f = "false" t = "true" diff --git a/internal/server/handlers.go b/internal/server/handlers.go index 4f7ef38d1..11c7e1e1e 100644 --- a/internal/server/handlers.go +++ b/internal/server/handlers.go @@ -3,7 +3,6 @@ package server import ( "net" "os" - "strconv" "strings" "time" @@ -92,21 +91,11 @@ func handleNotFound(next fasthttp.RequestHandler) fasthttp.RequestHandler { } func handleRouter(config schema.Configuration, providers middlewares.Providers) fasthttp.RequestHandler { - rememberMe := strconv.FormatBool(config.Session.RememberMeDuration != schema.RememberMeDisabled) - resetPassword := strconv.FormatBool(!config.AuthenticationBackend.PasswordReset.Disable) + optsTemplatedFile := NewTemplatedFileOptions(&config) - resetPasswordCustomURL := config.AuthenticationBackend.PasswordReset.CustomURL.String() - - duoSelfEnrollment := f - if !config.DuoAPI.Disable { - duoSelfEnrollment = strconv.FormatBool(config.DuoAPI.EnableSelfEnrollment) - } - - https := config.Server.TLS.Key != "" && config.Server.TLS.Certificate != "" - - serveIndexHandler := ServeTemplatedFile(assetsRoot, fileIndexHTML, config.Server.AssetPath, duoSelfEnrollment, rememberMe, resetPassword, resetPasswordCustomURL, config.Session.Name, config.Theme, https) - serveSwaggerHandler := ServeTemplatedFile(assetsSwagger, fileIndexHTML, config.Server.AssetPath, duoSelfEnrollment, rememberMe, resetPassword, resetPasswordCustomURL, config.Session.Name, config.Theme, https) - serveSwaggerAPIHandler := ServeTemplatedFile(assetsSwagger, fileOpenAPI, config.Server.AssetPath, duoSelfEnrollment, rememberMe, resetPassword, resetPasswordCustomURL, config.Session.Name, config.Theme, https) + serveIndexHandler := ServeTemplatedFile(assetsRoot, fileIndexHTML, optsTemplatedFile) + serveSwaggerHandler := ServeTemplatedFile(assetsSwagger, fileIndexHTML, optsTemplatedFile) + serveSwaggerAPIHandler := ServeTemplatedFile(assetsSwagger, fileOpenAPI, optsTemplatedFile) handlerPublicHTML := newPublicHTMLEmbeddedHandler() handlerLocales := newLocalesEmbeddedHandler() @@ -115,7 +104,7 @@ func handleRouter(config schema.Configuration, providers middlewares.Providers) WithPreMiddlewares(middlewares.SecurityHeaders).Build() policyCORSPublicGET := middlewares.NewCORSPolicyBuilder(). - WithAllowedMethods("OPTIONS", "GET"). + WithAllowedMethods(fasthttp.MethodOptions, fasthttp.MethodGet). WithAllowedOrigins("*"). Build() diff --git a/internal/server/locales/fi-FI/portal.json b/internal/server/locales/fi-FI/portal.json index 88510732d..f994691aa 100644 --- a/internal/server/locales/fi-FI/portal.json +++ b/internal/server/locales/fi-FI/portal.json @@ -3,12 +3,12 @@ "Access your email addresses": "Käytä sähköpostiosoitteitasi", "Access your group membership": "Käytä ryhmän jäsenyyttä", "Access your profile information": "Käytä profiilitietojasi", - "An email has been sent to your address to complete the process": "Prosessin loppuun saattamiseksi on lähetetty sähköpostiosoite. @ info", + "An email has been sent to your address to complete the process": "Prosessin loppuun saattamiseksi sinulle on lähetetty sähköpostia.", "Authenticated": "Todennettu", "Automatically refresh these permissions without user interaction": "Päivitä nämä oikeudet automaattisesti ilman käyttäjän vuorovaikutusta", "Cancel": "Peruuta", - "Client ID": "Asiakkaan tunnus: {{client_id}}", - "Consent Request": "Hyväksyntä Pyyntö", + "Client ID": "Asiakas-ID: {{client_id}}", + "Consent Request": "Hyväksyntäpyyntö", "Contact your administrator to register a device": "Ota yhteyttä järjestelmänvalvojaan rekisteröidäksesi laitteen.", "Could not obtain user settings": "Käyttäjän asetuksia ei saatu", "Deny": "Estä", @@ -16,23 +16,23 @@ "Enter new password": "Syötä uusi salasana", "Enter one-time password": "Syötä kertakäyttösalasana", "Failed to register device, the provided link is expired or has already been used": "Laitteen rekisteröinti epäonnistui, annettu linkki on vanhentunut tai sitä on jo käytetty", - "Hi": "Hi", + "Hi": "Hei", "Incorrect username or password": "Virheellinen käyttäjätunnus tai salasana.", "Loading": "Ladataan", "Login": "Kirjaudu", "Logout": "Kirjaudu Ulos", - "Lost your device?": "Unohtuiko laitteesi?", + "Lost your device?": "Kadotitko laitteesi?", "Methods": "Menetelmät", "Must be at least {{len}} characters in length": "Täytyy olla vähintään {{len}} merkkiä pitkä", - "Must have at least one UPPERCASE letter": "Täytyy olla vähintään yksi UPPERCASE kirjain", + "Must have at least one UPPERCASE letter": "Täytyy olla vähintään yksi ISO kirjain", "Must have at least one lowercase letter": "Täytyy olla vähintään yksi pieni kirjain", "Must have at least one number": "Täytyy olla vähintään yksi numero", "Must have at least one special character": "Täytyy olla vähintään yksi erikoismerkki", - "Must not be more than {{len}} characters in length": "Ei saa olla enempää kuin {{len}} merkkiä", - "Need Google Authenticator?": "Tarvitsetko Googlen Todennus?", + "Must not be more than {{len}} characters in length": "Ei saa olla yli {{len}} merkkiä pitkä", + "Need Google Authenticator?": "Tarvitsetko Google Authenticatorin?", "New password": "Uusi salasana", "No verification token provided": "Vahvistusmerkkiä ei ole annettu", - "OTP Secret copied to clipboard": "OTP salainen kopioitu leikepöydälle.", + "OTP Secret copied to clipboard": "OTP salaisuus kopioitu leikepöydälle.", "OTP URL copied to clipboard": "OTP URL kopioitu leikepöydälle.", "One-Time Password": "Kertakäyttöinen Salasana", "Password has been reset": "Salasana on nollattu.", @@ -46,27 +46,27 @@ "Remember me": "Muista minut", "Repeat new password": "Toista uusi salasana", "Reset password": "Nollaa salasana", - "Reset password?": "Palauta salasana?", - "Reset": "Reset", - "Scan QR Code": "Scan QR Code", + "Reset password?": "Nollaa salasana?", + "Reset": "Nollaa", + "Scan QR Code": "Skannaa QR-koodi", "Secret": "Salainen", "Security Key - WebAuthN": "Suojausavain - WebAuthN", "Select a Device": "Valitse laite", "Sign in": "Kirjaudu sisään", "Sign out": "Kirjaudu ulos", - "The above application is requesting the following permissions": "Edellä mainittu hakemus pyytää seuraavia käyttöoikeuksia", + "The above application is requesting the following permissions": "Edellä mainittu sovellus pyytää seuraavia käyttöoikeuksia", "The password does not meet the password policy": "Salasana ei vastaa salasanakäytäntöä", "The resource you're attempting to access requires two-factor authentication": "Resurssi, jota yrität käyttää vaatii kaksivaiheisen todennuksen.", "There was a problem initiating the registration process": "Rekisteröintiprosessin käynnistämisessä tapahtui ongelma", "There was an issue completing the process. The verification token might have expired": "Prosessin loppuun saattamisessa tapahtui virhe. Vahvistusmerkki saattaa olla vanhentunut.", "There was an issue initiating the password reset process": "Salasanan nollausprosessin käynnistämisessä tapahtui virhe.", "There was an issue resetting the password": "Salasanan palauttamisessa tapahtui virhe", - "There was an issue signing out": "Sisäänkirjautuminen ulos tapahtui virhe", + "There was an issue signing out": "Uloskirjautumisessa tapahtui virhe", "This saves this consent as a pre-configured consent for future use": "Tämä tallentaa tämän suostumuksen ennalta määritettynä suostumuksena tulevaa käyttöä varten", - "Time-based One-Time Password": "Aikaperusteinen Kertasalasana", - "Use OpenID to verify your identity": "Käytä OpenID:tä tunnistaaksesi henkilöllisyytesi", + "Time-based One-Time Password": "Aikaperusteinen Kertakäyttösalasana", + "Use OpenID to verify your identity": "Käytä OpenID:tä vahvistaaksesi henkilöllisyytesi", "Username": "Käyttäjätunnus", "You must open the link from the same device and browser that initiated the registration process": "Sinun on avattava linkki samasta laitteesta ja selaimesta, joka käynnisti rekisteröintiprosessin", - "You're being signed out and redirected": "Sinut kirjaudutaan ulos ja ohjataan uudelleen", + "You're being signed out and redirected": "Sinut kirjataan ulos ja ohjataan uudelleen", "Your supplied password does not meet the password policy requirements": "Syötetty salasana ei täytä salasanakäytännön vaatimuksia." } diff --git a/internal/server/template.go b/internal/server/template.go index 0042f8856..02928f4ff 100644 --- a/internal/server/template.go +++ b/internal/server/template.go @@ -6,11 +6,13 @@ import ( "os" "path" "path/filepath" + "strconv" "strings" "text/template" "github.com/valyala/fasthttp" + "github.com/authelia/authelia/v4/internal/configuration/schema" "github.com/authelia/authelia/v4/internal/logging" "github.com/authelia/authelia/v4/internal/middlewares" "github.com/authelia/authelia/v4/internal/utils" @@ -19,7 +21,7 @@ import ( // ServeTemplatedFile serves a templated version of a specified file, // this is utilised to pass information between the backend and frontend // and generate a nonce to support a restrictive CSP while using material-ui. -func ServeTemplatedFile(publicDir, file, assetPath, duoSelfEnrollment, rememberMe, resetPassword, resetPasswordCustomURL, session, theme string, https bool) middlewares.RequestHandler { +func ServeTemplatedFile(publicDir, file string, opts *TemplatedFileOptions) middlewares.RequestHandler { logger := logging.Logger() a, err := assets.Open(path.Join(publicDir, file)) @@ -37,55 +39,40 @@ func ServeTemplatedFile(publicDir, file, assetPath, duoSelfEnrollment, rememberM logger.Fatalf("Unable to parse %s template: %s", file, err) } - return func(ctx *middlewares.AutheliaCtx) { - base := "" - if baseURL := ctx.UserValueBytes(middlewares.UserValueKeyBaseURL); baseURL != nil { - base = baseURL.(string) - } + isDevEnvironment := os.Getenv(environment) == dev + return func(ctx *middlewares.AutheliaCtx) { logoOverride := f - if assetPath != "" { - if _, err := os.Stat(filepath.Join(assetPath, fileLogo)); err == nil { + if opts.AssetPath != "" { + if _, err = os.Stat(filepath.Join(opts.AssetPath, fileLogo)); err == nil { logoOverride = t } } - var scheme = schemeHTTPS - - if !https { - proto := string(ctx.XForwardedProto()) - switch proto { - case "": - break - case schemeHTTP, schemeHTTPS: - scheme = proto - } - } - - baseURL := scheme + "://" + string(ctx.XForwardedHost()) + base + "/" - nonce := utils.RandomString(32, utils.CharSetAlphaNumeric, true) - switch extension := filepath.Ext(file); extension { - case ".html": - ctx.SetContentType("text/html; charset=utf-8") + case extHTML: + ctx.SetContentTypeTextHTML() + case extJSON: + ctx.SetContentTypeApplicationJSON() default: - ctx.SetContentType("text/plain; charset=utf-8") + ctx.SetContentTypeTextPlain() } + nonce := utils.RandomString(32, utils.CharSetAlphaNumeric, true) + switch { case publicDir == assetsSwagger: ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, fmt.Sprintf(tmplCSPSwagger, nonce, nonce)) case ctx.Configuration.Server.Headers.CSPTemplate != "": ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, strings.ReplaceAll(ctx.Configuration.Server.Headers.CSPTemplate, placeholderCSPNonce, nonce)) - case os.Getenv("ENVIRONMENT") == dev: + case isDevEnvironment: ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, fmt.Sprintf(tmplCSPDevelopment, nonce)) default: ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, fmt.Sprintf(tmplCSPDefault, nonce)) } - err := tmpl.Execute(ctx.Response.BodyWriter(), struct{ Base, BaseURL, CSPNonce, DuoSelfEnrollment, LogoOverride, RememberMe, ResetPassword, ResetPasswordCustomURL, Session, Theme string }{Base: base, BaseURL: baseURL, CSPNonce: nonce, DuoSelfEnrollment: duoSelfEnrollment, LogoOverride: logoOverride, RememberMe: rememberMe, ResetPassword: resetPassword, ResetPasswordCustomURL: resetPasswordCustomURL, Session: session, Theme: theme}) - if err != nil { + if err = tmpl.Execute(ctx.Response.BodyWriter(), opts.CommonData(ctx.BasePath(), ctx.RootURLSlash().String(), nonce, logoOverride)); err != nil { ctx.RequestCtx.Error("an error occurred", 503) logger.Errorf("Unable to execute template: %v", err) @@ -128,3 +115,62 @@ func writeHealthCheckEnv(disabled bool, scheme, host, path string, port int) (er return err } + +// NewTemplatedFileOptions returns a new *TemplatedFileOptions. +func NewTemplatedFileOptions(config *schema.Configuration) (opts *TemplatedFileOptions) { + opts = &TemplatedFileOptions{ + AssetPath: config.Server.AssetPath, + DuoSelfEnrollment: f, + RememberMe: strconv.FormatBool(config.Session.RememberMeDuration != schema.RememberMeDisabled), + ResetPassword: strconv.FormatBool(!config.AuthenticationBackend.PasswordReset.Disable), + ResetPasswordCustomURL: config.AuthenticationBackend.PasswordReset.CustomURL.String(), + Theme: config.Theme, + } + + if !config.DuoAPI.Disable { + opts.DuoSelfEnrollment = strconv.FormatBool(config.DuoAPI.EnableSelfEnrollment) + } + + return opts +} + +// TemplatedFileOptions is a struct which is used for many templated files. +type TemplatedFileOptions struct { + AssetPath string + DuoSelfEnrollment string + RememberMe string + ResetPassword string + ResetPasswordCustomURL string + Session string + Theme string +} + +// CommonData returns a TemplatedFileCommonData with the dynamic options. +func (options *TemplatedFileOptions) CommonData(base, baseURL, nonce, logoOverride string) TemplatedFileCommonData { + return TemplatedFileCommonData{ + Base: base, + BaseURL: baseURL, + CSPNonce: nonce, + LogoOverride: logoOverride, + DuoSelfEnrollment: options.DuoSelfEnrollment, + RememberMe: options.RememberMe, + ResetPassword: options.ResetPassword, + ResetPasswordCustomURL: options.ResetPasswordCustomURL, + Session: options.Session, + Theme: options.Theme, + } +} + +// TemplatedFileCommonData is a struct which is used for many templated files. +type TemplatedFileCommonData struct { + Base string + BaseURL string + CSPNonce string + LogoOverride string + DuoSelfEnrollment string + RememberMe string + ResetPassword string + ResetPasswordCustomURL string + Session string + Theme string +} diff --git a/internal/suites/action_login.go b/internal/suites/action_login.go index cb327b2d4..9eaf193a7 100644 --- a/internal/suites/action_login.go +++ b/internal/suites/action_login.go @@ -10,22 +10,38 @@ import ( func (rs *RodSession) doFillLoginPageAndClick(t *testing.T, page *rod.Page, username, password string, keepMeLoggedIn bool) { usernameElement := rs.WaitElementLocatedByID(t, page, "username-textfield") - err := usernameElement.Input(username) + passwordElement := rs.WaitElementLocatedByID(t, page, "password-textfield") + buttonElement := rs.WaitElementLocatedByID(t, page, "sign-in-button") + +username: + err := usernameElement.MustSelectAllText().Input(username) require.NoError(t, err) - passwordElement := rs.WaitElementLocatedByID(t, page, "password-textfield") - err = passwordElement.Input(password) + if usernameElement.MustText() != username { + goto username + } + +password: + err = passwordElement.MustSelectAllText().Input(password) require.NoError(t, err) + if passwordElement.MustText() != password { + goto password + } + if keepMeLoggedIn { keepMeLoggedInElement := rs.WaitElementLocatedByID(t, page, "remember-checkbox") err = keepMeLoggedInElement.Click("left", 1) require.NoError(t, err) } - buttonElement := rs.WaitElementLocatedByID(t, page, "sign-in-button") +click: err = buttonElement.Click("left", 1) require.NoError(t, err) + + if buttonElement.MustInteractable() { + goto click + } } // Login 1FA. diff --git a/internal/suites/action_reset_password.go b/internal/suites/action_reset_password.go index 112771ed4..8980ceb70 100644 --- a/internal/suites/action_reset_password.go +++ b/internal/suites/action_reset_password.go @@ -2,7 +2,6 @@ package suites import ( "testing" - "time" "github.com/go-rod/rod" "github.com/stretchr/testify/require" @@ -23,16 +22,25 @@ func (rs *RodSession) doCompletePasswordReset(t *testing.T, page *rod.Page, newP link := doGetLinkFromLastMail(t) rs.doVisit(t, page, link) - time.Sleep(1 * time.Second) + password1 := rs.WaitElementLocatedByID(t, page, "password1-textfield") + password2 := rs.WaitElementLocatedByID(t, page, "password2-textfield") - err := rs.WaitElementLocatedByID(t, page, "password1-textfield").Input(newPassword1) +password1: + err := password1.MustSelectAllText().Input(newPassword1) require.NoError(t, err) - time.Sleep(1 * time.Second) + if password1.MustText() != newPassword1 { + goto password1 + } - err = rs.WaitElementLocatedByID(t, page, "password2-textfield").Input(newPassword2) +password2: + err = password2.MustSelectAllText().Input(newPassword2) require.NoError(t, err) + if password2.MustText() != newPassword2 { + goto password2 + } + err = rs.WaitElementLocatedByID(t, page, "reset-button").Click("left", 1) require.NoError(t, err) } diff --git a/internal/suites/action_totp.go b/internal/suites/action_totp.go index 78636eafb..10fdcaaa4 100644 --- a/internal/suites/action_totp.go +++ b/internal/suites/action_totp.go @@ -6,6 +6,7 @@ import ( "time" "github.com/go-rod/rod" + "github.com/go-rod/rod/lib/input" "github.com/pquerna/otp/totp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -31,7 +32,8 @@ func (rs *RodSession) doEnterOTP(t *testing.T, page *rod.Page, code string) { inputs := rs.WaitElementsLocatedByID(t, page, "otp-input input") for i := 0; i < len(code); i++ { - inputs[i].MustInput(string(code[i])) + err := inputs[i].Type(input.Key(code[i])) + require.NoError(t, err) } } diff --git a/internal/suites/const.go b/internal/suites/const.go index 4d2d9258c..8a8f11cda 100644 --- a/internal/suites/const.go +++ b/internal/suites/const.go @@ -58,6 +58,12 @@ const ( testPassword = "password" ) +const ( + namespaceAuthelia = "authelia" + namespaceDashboard = "kubernetes-dashboard" + namespaceKube = "kube-system" +) + var ( storageLocalTmpConfig = schema.Configuration{ TOTP: schema.TOTPConfiguration{ diff --git a/internal/suites/environment.go b/internal/suites/environment.go index bbdbd5909..9cf51979b 100644 --- a/internal/suites/environment.go +++ b/internal/suites/environment.go @@ -58,6 +58,15 @@ func waitUntilAutheliaFrontendIsReady(dockerEnvironment *DockerEnvironment) erro []string{"dev server running at", "ready in"}) } +func waitUntilK3DIsReady(dockerEnvironment *DockerEnvironment) error { + return waitUntilServiceLogDetected( + 5*time.Second, + 90*time.Second, + dockerEnvironment, + "k3d", + []string{"API listen on [::]:2376"}) +} + func waitUntilSambaIsReady(dockerEnvironment *DockerEnvironment) error { return waitUntilServiceLogDetected( 5*time.Second, diff --git a/internal/suites/example/compose/authelia/Dockerfile.backend b/internal/suites/example/compose/authelia/Dockerfile.backend index e221a9f52..d7670ffb7 100644 --- a/internal/suites/example/compose/authelia/Dockerfile.backend +++ b/internal/suites/example/compose/authelia/Dockerfile.backend @@ -1,4 +1,4 @@ -FROM golang:1.19.3-alpine +FROM golang:1.19.4-alpine ARG USER_ID ARG GROUP_ID diff --git a/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml b/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml index 176f1dc1d..cc7056037 100644 --- a/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml +++ b/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml @@ -14,7 +14,7 @@ services: volumes: - './example/compose/authelia/resources/:/resources' - '../../web:/app' - - '~/.pnpm-store:/tmp/.pnpm-store' + - '~/.local/share/pnpm/store:/tmp/.pnpm-store' labels: # Traefik 1.x - 'traefik.frontend.rule=Host:login.example.com' diff --git a/internal/suites/example/compose/caddy/Caddyfile b/internal/suites/example/compose/caddy/Caddyfile index 18fd9eed9..c0fc6d90e 100644 --- a/internal/suites/example/compose/caddy/Caddyfile +++ b/internal/suites/example/compose/caddy/Caddyfile @@ -8,6 +8,7 @@ :8085 { log reverse_proxy authelia-backend:9091 { + header_up X-Forwarded-Proto https import tls-transport } } diff --git a/internal/suites/example/compose/duo-api/package-lock.json b/internal/suites/example/compose/duo-api/package-lock.json index 06cb0628c..d7ea29901 100644 --- a/internal/suites/example/compose/duo-api/package-lock.json +++ b/internal/suites/example/compose/duo-api/package-lock.json @@ -5,45 +5,59 @@ "requires": true, "dependencies": { "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "requires": { - "mime-types": "2.1.22", - "negotiator": "0.6.1" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", + "bytes": "3.1.2", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "1.6.16" + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" } }, "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } }, "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } }, "content-type": { "version": "1.0.4", @@ -51,14 +65,14 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "debug": { "version": "2.6.9", @@ -69,220 +83,258 @@ } }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", - "content-type": "1.0.4", - "cookie": "0.3.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.1", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", - "qs": "6.5.2", - "range-parser": "1.2.0", - "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" } }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", - "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.22", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", - "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.38.0" + "mime-db": "1.52.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } }, "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "0.1.2", - "ipaddr.js": "1.8.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" } }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } }, "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", @@ -290,69 +342,91 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } } }, "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.16.2" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" } }, "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } }, "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.22" + "mime-types": "~2.1.24" } }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" } } } diff --git a/internal/suites/example/compose/envoy/docker-compose.yml b/internal/suites/example/compose/envoy/docker-compose.yml index 61d80a37c..ef1b18363 100644 --- a/internal/suites/example/compose/envoy/docker-compose.yml +++ b/internal/suites/example/compose/envoy/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: envoy: - image: envoyproxy/envoy:v1.24.0 + image: envoyproxy/envoy:v1.24.1 volumes: - ./example/compose/envoy/envoy.yaml:/etc/envoy/envoy.yaml - ./example/compose/nginx/portal/ssl:/etc/ssl diff --git a/internal/suites/example/compose/haproxy/Dockerfile b/internal/suites/example/compose/haproxy/Dockerfile index c42df2bc3..fb2096be7 100644 --- a/internal/suites/example/compose/haproxy/Dockerfile +++ b/internal/suites/example/compose/haproxy/Dockerfile @@ -1,4 +1,4 @@ -FROM haproxy:2.6.6-alpine +FROM haproxy:2.7.0-alpine USER root RUN \ diff --git a/internal/suites/example/compose/k3d/docker-compose.yml b/internal/suites/example/compose/k3d/docker-compose.yml new file mode 100644 index 000000000..0f463249b --- /dev/null +++ b/internal/suites/example/compose/k3d/docker-compose.yml @@ -0,0 +1,26 @@ +--- +version: '3' +services: + k3d: + image: ghcr.io/k3d-io/k3d:5.4.6-dind + volumes: + - './example/kube:/authelia' + - './example/kube/authelia/configs/configuration.yml:/configmaps/authelia/configuration.yml' + - './common/ssl:/configmaps/authelia/ssl' + - './example/compose/ldap/ldif:/configmaps/ldap' + - './example/compose/nginx/backend:/configmaps/nginx-backend' + privileged: true + networks: + authelianet: + aliases: + - public.example.com + - secure.example.com + - login.example.com + - admin.example.com + - dev.example.com + - mail.example.com + - kubernetes.example.com + - traefik.example.com + # Set the IP to be able to query on port 443 + ipv4_address: 192.168.240.100 +... diff --git a/internal/suites/example/compose/kind/Dockerfile b/internal/suites/example/compose/kind/Dockerfile deleted file mode 100644 index 5051892d2..000000000 --- a/internal/suites/example/compose/kind/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM alpine:3.17.0 - -WORKDIR /kind - -RUN apk add --no-cache bash curl docker && \ - curl -Lo kind https://github.com/kubernetes-sigs/kind/releases/download/v0.10.0/kind-linux-amd64 && chmod +x kind && \ - curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.20.2/bin/linux/amd64/kubectl && chmod +x kubectl - -ADD entrypoint.sh entrypoint.sh -ADD patch-kubeconfig.sh patch-kubeconfig.sh - -ENV HOME=/kind/config -ENV KUBECONFIG=/kind/config/.kube/kind-config-kind - -VOLUME /kind/config - -ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/internal/suites/example/compose/kind/config.yml b/internal/suites/example/compose/kind/config.yml deleted file mode 100644 index a6a8b70f3..000000000 --- a/internal/suites/example/compose/kind/config.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -containerdConfigPatches: - # yamllint disable-line rule:indentation - - |- - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["http://registrycache.internal:5000"] -... diff --git a/internal/suites/example/compose/kind/docker-compose.yml b/internal/suites/example/compose/kind/docker-compose.yml deleted file mode 100644 index d8d599880..000000000 --- a/internal/suites/example/compose/kind/docker-compose.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -version: '3' -services: - authelia-kind-proxy: - build: - context: ./example/compose/kind - volumes: - - 'kind-volume:/kind/config' - - '/var/run/docker.sock:/var/run/docker.sock' - - './example/kube:/authelia' - - './example/compose/kind/config.yml:/etc/kind/config.yml' - command: 'kubectl port-forward --address 0.0.0.0 -n authelia service/nginx-ingress-controller-service 8080:443' - environment: - - KIND_EXPERIMENTAL_DOCKER_NETWORK=authelia_authelianet - networks: - authelianet: - aliases: - - public.example.com - - secure.example.com - - login.example.com - - admin.example.com - - dev.example.com - - mail.example.com - # Set the IP to be able to query on port 443 - ipv4_address: 192.168.240.100 - - kube-dashboard: - build: - context: ./example/compose/kind - volumes: - - 'kind-volume:/kind/config' - - './example/compose/kind/entrypoint-dashboard.sh:/entrypoint-dashboard.sh' - command: '/entrypoint-dashboard.sh' - environment: - - KIND_EXPERIMENTAL_DOCKER_NETWORK=authelia_authelianet - networks: - authelianet: - aliases: - - kubernetes.example.com - ipv4_address: 192.168.240.110 - -volumes: - kind-volume: # yamllint disable-line rule:empty-values -... diff --git a/internal/suites/example/compose/kind/entrypoint-dashboard.sh b/internal/suites/example/compose/kind/entrypoint-dashboard.sh deleted file mode 100755 index e94c5e0ec..000000000 --- a/internal/suites/example/compose/kind/entrypoint-dashboard.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -# Retries a command on failure. -# $1 - the max number of attempts -# $2... - the command to run - -retry() { - local -r -i max_attempts="$1"; shift - local -r cmd="$@" - local -i attempt_num=1 - until $cmd - do - if ((attempt_num==max_attempts)) - then - echo "Attempt $attempt_num failed and there are no more attempts left!" - return 1 - else - echo "Attempt $attempt_num failed! Trying again in 10 seconds..." - sleep 10 - fi - done -} - -kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}') -retry 10 kubectl port-forward --address 0.0.0.0 -n kubernetes-dashboard service/kubernetes-dashboard 443:443 \ No newline at end of file diff --git a/internal/suites/example/compose/kind/entrypoint.sh b/internal/suites/example/compose/kind/entrypoint.sh deleted file mode 100755 index c93edc815..000000000 --- a/internal/suites/example/compose/kind/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -export PATH=/kind:$PATH - -exec "$@" \ No newline at end of file diff --git a/internal/suites/example/compose/kind/patch-kubeconfig.sh b/internal/suites/example/compose/kind/patch-kubeconfig.sh deleted file mode 100755 index e103a5b7c..000000000 --- a/internal/suites/example/compose/kind/patch-kubeconfig.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# This script patches the kubeconfig generated by Kind in order to access the cluster container via this container - -echo "Patching Kubeconfig to target Kube container without link" -sed -i "s/127.0.0.1:.*/$(docker inspect -f '{{(index .NetworkSettings.Networks "authelia_authelianet").IPAddress}}' kind-control-plane):6443/" ${KUBECONFIG} \ No newline at end of file diff --git a/internal/suites/example/compose/traefik2/docker-compose.yml b/internal/suites/example/compose/traefik2/docker-compose.yml index af291082d..3c61ce86a 100644 --- a/internal/suites/example/compose/traefik2/docker-compose.yml +++ b/internal/suites/example/compose/traefik2/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: traefik: - image: traefik:v2.9.5 + image: traefik:v2.9.6 volumes: - '/var/run/docker.sock:/var/run/docker.sock' labels: diff --git a/internal/suites/example/kube/README.md b/internal/suites/example/kube/README.md deleted file mode 100644 index 395fa1960..000000000 --- a/internal/suites/example/kube/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Authelia on Kubernetes - -Authelia is now available on Kube in order to protect your most critical -applications using 2-factor authentication and Single Sign-On. - -This example leverages [ingress-nginx](https://github.com/kubernetes/ingress-nginx) -to delegate authentication and authorization to Authelia within the cluster. - -## Getting started - -You can either try to install **Authelia** on your running instance of Kubernetes -or deploy the dedicated [suite](/docs/suites.md) called *kubernetes*. - -### Set up a Kube cluster - -The simplest way to start a Kubernetes cluster is to deploy the *kubernetes* suite with - - authelia-scripts suites setup kubernetes - -This will take a few seconds (or minutes) to deploy the cluster. - -## How does it work? - -### Authentication via Authelia - -In a Kube clusters, the routing logic of requests is handled by ingress -controllers following rules provided by ingress configurations. - -In this example, [ingress-nginx](https://github.com/kubernetes/ingress-nginx) -controller has been installed to handle the incoming requests. Some of them -(specified in the ingress configuration) are forwarded to Authelia so that -it can verify whether they are allowed and should reach the protected endpoint. - -The authentication is provided at the ingress level by an annotation called -`nginx.ingress.kubernetes.io/auth-url` that is filled with the URL of -Authelia's verification endpoint. -The ingress controller also requires the URL to the -authentication portal so that the user can be redirected if he is not -yet authenticated. This annotation is as follows: -`nginx.ingress.kubernetes.io/auth-signin: "https://login.example.com:8080/"` - -Those annotations can be seen in `apps/apps.yml` configuration. - -### Production grade infrastructure - -What is great with using [ingress-nginx](https://github.com/kubernetes/ingress-nginx) -is that it is compatible with [kube-lego](https://github.com/jetstack/kube-lego) -which removes the usual pain of manually renewing SSL certificates. It uses -letsencrypt to issue and renew certificates every three month without any -manual intervention. - -## What do I need to know to deploy it in my cluster? - -Given your cluster already runs a LDAP server, a Redis, a SQL database, -a SMTP server and a nginx ingress-controller, you can deploy **Authelia** -and update your ingress configurations. An example is provided -[here](authelia). - -## Questions - -If you have questions about the implementation, please post them on -[![Gitter](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/authelia/general?utm_source=share-link&utm_medium=link&utm_campaign=share-link) diff --git a/internal/suites/example/kube/apps/apps.yml b/internal/suites/example/kube/apps/apps.yml deleted file mode 100644 index 498292ffb..000000000 --- a/internal/suites/example/kube/apps/apps.yml +++ /dev/null @@ -1,154 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: test-app - namespace: authelia - labels: - app: test-app -spec: - replicas: 1 - selector: - matchLabels: - app: test-app - template: - metadata: - labels: - app: test-app - spec: - containers: - - name: test-app - image: nginx:alpine - command: ["/entrypoint.sh"] - ports: - - containerPort: 80 - volumeMounts: - - name: config-volume - mountPath: /entrypoint.sh - subPath: entrypoint.sh - - name: config-volume - mountPath: /etc/nginx/nginx.conf - subPath: nginx.conf - - name: config-volume - mountPath: /tmp/html.tar.gz - subPath: html.tar.gz - volumes: - - name: config-volume - configMap: - name: nginx-config - items: - - key: entrypoint.sh - path: entrypoint.sh - mode: 0755 # yamllint disable-line rule:octal-values - - key: nginx.conf - path: nginx.conf - - key: html.tar.gz - path: html.tar.gz -... ---- -apiVersion: v1 -kind: Service -metadata: - name: test-app-service - namespace: authelia - labels: - app: test-app -spec: - selector: - app: test-app - ports: - - port: 80 - name: http - - port: 443 - name: https -... ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: insecure-ingress - namespace: authelia - annotations: - kubernetes.io/ingress.class: "nginx" - kubernetes.io/ingress.allow-http: "false" - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" -spec: - tls: - - secretName: test-app-tls - hosts: - - home.example.com - rules: - - host: home.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 -... ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: secure-ingress - namespace: authelia - annotations: - kubernetes.io/ingress.class: "nginx" - kubernetes.io/ingress.allow-http: "false" - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - nginx.ingress.kubernetes.io/auth-url: "https://authelia-service.authelia.svc.cluster.local/api/verify" - nginx.ingress.kubernetes.io/auth-signin: "https://login.example.com:8080/" -spec: - tls: - - secretName: test-app-tls - hosts: - - public.example.com - - admin.example.com - - dev.example.com - - mx1.mail.example.com - - mx2.mail.example.com - - singlefactor.example.com - rules: - - host: public.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 - - host: admin.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 - - host: dev.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 - - host: mx1.mail.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 - - host: mx2.mail.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 - - host: singlefactor.example.com - http: - paths: - - path: / - backend: - serviceName: test-app-service - servicePort: 80 -... diff --git a/internal/suites/example/kube/apps/configs/entrypoint.sh b/internal/suites/example/kube/apps/configs/entrypoint.sh deleted file mode 100644 index 971912ff2..000000000 --- a/internal/suites/example/kube/apps/configs/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#! /bin/sh - -rm -rf /usr/share/nginx/html && \ -tar xfz /tmp/html.tar.gz -C /usr/share/nginx/ && \ -nginx "-g daemon off;" \ No newline at end of file diff --git a/internal/suites/example/kube/apps/configs/html.tar.gz b/internal/suites/example/kube/apps/configs/html.tar.gz deleted file mode 100644 index c0f308e48..000000000 Binary files a/internal/suites/example/kube/apps/configs/html.tar.gz and /dev/null differ diff --git a/internal/suites/example/kube/apps/configs/nginx.conf b/internal/suites/example/kube/apps/configs/nginx.conf deleted file mode 100644 index 37d20fdae..000000000 --- a/internal/suites/example/kube/apps/configs/nginx.conf +++ /dev/null @@ -1,51 +0,0 @@ -worker_processes 1; - -events { - worker_connections 1024; -} - - -http { - server { - listen 80; - root /usr/share/nginx/html/home; - server_name home.example.com; - } - - server { - listen 80; - root /usr/share/nginx/html/public; - server_name public.example.com; - } - - server { - listen 80; - root /usr/share/nginx/html/secure; - server_name secure.example.com; - } - - server { - listen 80; - root /usr/share/nginx/html/admin; - server_name admin.example.com; - } - - server { - listen 80; - root /usr/share/nginx/html/dev; - server_name dev.example.com; - } - - server { - listen 80; - root /usr/share/nginx/html/mail; - server_name mx1.mail.example.com mx2.mail.example.com; - } - - server { - listen 80; - root /usr/share/nginx/html/singlefactor; - server_name singlefactor.example.com; - } -} - diff --git a/internal/suites/example/kube/apps/nginx.yml b/internal/suites/example/kube/apps/nginx.yml new file mode 100644 index 000000000..a604ade1f --- /dev/null +++ b/internal/suites/example/kube/apps/nginx.yml @@ -0,0 +1,138 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-backend + namespace: authelia + labels: + app: nginx-backend +spec: + replicas: 1 + selector: + matchLabels: + app: nginx-backend + template: + metadata: + labels: + app: nginx-backend + spec: + containers: + - name: nginx-backend + image: nginx:alpine + ports: + - containerPort: 80 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + - name: nginx-html + mountPath: /usr/share/nginx/html + volumes: + - name: nginx-config + hostPath: + path: /configmaps/nginx-backend/nginx.conf + type: File + - name: nginx-html + hostPath: + path: /configmaps/nginx-backend/html + type: Directory +... +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-backend-service + namespace: authelia + labels: + app: nginx-backend +spec: + selector: + app: nginx-backend + ports: + - port: 80 + name: http + - port: 443 + name: https +... +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: nginx-backend-ingress + namespace: authelia + annotations: + kubernetes.io/ingress.class: traefik + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: authelia-forwardauth-authelia@kubernetescrd +spec: + rules: + - host: home.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 + - host: public.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 + - host: admin.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 + - host: dev.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 + - host: mx1.mail.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 + - host: mx2.mail.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 + - host: singlefactor.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx-backend-service + port: + number: 80 +... diff --git a/internal/suites/example/kube/apps/ssl/server.cert b/internal/suites/example/kube/apps/ssl/server.cert deleted file mode 100644 index 0fd2ff140..000000000 --- a/internal/suites/example/kube/apps/ssl/server.cert +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDEzCCAfugAwIBAgIUJZXxXExVQPJhc8TnlD+uAAYHlvwwDQYJKoZIhvcNAQEL -BQAwGDEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTAgFw0xOTA5MjYyMDAwMTBaGA8y -MTE5MDkwMjIwMDAxMFowGDEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3DFTAdrxG6iOj5UjSeB5lMjMQQyeYm -OxUvswwwBzmQYPUt0inAJ9QmXJ8i9Fbye8HHYUeqE5zsEfeHir81MiWfhi9oUzJt -u3bmxGLDXYaApejd18hBKITX6MYogmK2lWrl/F9zPYxc2xM/fqWnGg2xwdrMmida -hZjDUfh0rtoz8zqOzJaiiDoFMwNO+NTGmDbeOwBFYOF1OTkS3aJWwJCLZmINUG8h -Z3YPR+SL8CpGGl0xhJYAwXD1AtMlYwAteTILqrqvo2XkGsvuj0mx0w/D0DDpC48g -oSNsRIVTW3Ql3uu+kXDFtkf4I63Ctt85rZk1kX3QtYmS0pRzvmyY/b0CAwEAAaNT -MFEwHQYDVR0OBBYEFMTozK79Kp813+8TstjXRFw1MTE5MB8GA1UdIwQYMBaAFMTo -zK79Kp813+8TstjXRFw1MTE5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBALf1bJf3qF3m54+q98E6lSE+34yi/rVdzB9reAW1QzvvqdJRtsfjt39R -SznsbmrvCfK4SLyOj9Uhd8Z6bASPPNsUux1XAGN4AqaGmlYI8b7j3LhKCdRBZQ0I -zWgPhocyWwp5VkFe68zR06NHme/2B6eBRFsdd/69DIOv9YnEGUHk3A/9v1zvolt9 -krW57Oz63zWGYXmtPPTD8of/Ya6NKqwonVx1MUQ5QzqH3WySYhRsIYqwUEXm9jt5 -GEM3Nx0phEltaOLXa71nqS/Rhg/5Kod0cFaNoSKb6N93I8bqKKTK0m5wMJ5Fisrm -Pw5+AIar7RT5gHU2DD2/OTb9bXXww8I= ------END CERTIFICATE----- diff --git a/internal/suites/example/kube/apps/ssl/server.key b/internal/suites/example/kube/apps/ssl/server.key deleted file mode 100644 index 268a2a1c3..000000000 --- a/internal/suites/example/kube/apps/ssl/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAvcMVMB2vEbqI6PlSNJ4HmUyMxBDJ5iY7FS+zDDAHOZBg9S3S -KcAn1CZcnyL0VvJ7wcdhR6oTnOwR94eKvzUyJZ+GL2hTMm27dubEYsNdhoCl6N3X -yEEohNfoxiiCYraVauX8X3M9jFzbEz9+pacaDbHB2syaJ1qFmMNR+HSu2jPzOo7M -lqKIOgUzA0741MaYNt47AEVg4XU5ORLdolbAkItmYg1QbyFndg9H5IvwKkYaXTGE -lgDBcPUC0yVjAC15Mguquq+jZeQay+6PSbHTD8PQMOkLjyChI2xEhVNbdCXe676R -cMW2R/gjrcK23zmtmTWRfdC1iZLSlHO+bJj9vQIDAQABAoIBAEZvkP/JJOCJwqPn -V3IcbmmilmV4bdi1vByDFgyiDyx4wOSA24+PubjvfFW9XcCgRPuKjDtTj/AhWBHv -B7stfa2lZuNV7/u562mZArA+IAr62Zp0LdIxDV8x3T8gbjVB3HhPYbv0RJZDKTYd -zV6jhfIrVu9mHpoY6ZnodhapCPYIyk/d49KBIHZuAc25CUjMXgTeaVtf0c996036 -UxW6ef33wAOJAvW0RCvbXAJfmBeEq2qQlkjTIlpYx71fhZWexHifi8Ouv3Zonc+1 -/P2Adq5uzYVBT92f9RKHg9QxxNzVrLjSMaxyvUtWQCAQfW0tFIRdqBGsHYsQrFtI -F4yzv8ECgYEA7ntpyN9HD9Z9lYQzPCR73sFCLM+ID99aVij0wHuxK97bkSyyvkLd -7MyTaym3lg1UEqWNWBCLvFULZx7F0Ah6qCzD4ymm3Bj/ADpWWPgljBI0AFml+HHs -hcATmXUrj5QbLyhiP2gmJjajp1o/rgATx6ED66seSynD6JOH8wUhhZUCgYEAy7OA -06PF8GfseNsTqlDjNF0K7lOqd21S0prdwrsJLiVzUlfMM25MLE0XLDUutCnRheeh -IlcuDoBsVTxz6rkvFGD74N+pgXlN4CicsBq5ofK060PbqCQhSII3fmHobrZ9Cr75 -HmBjAxHx998SKaAAGbBbcYGUAp521i1pH5CEPYkCgYEAkUd1Zf0+2RMdZhwm6hh/ -rW+l1I6IoMK70YkZsLipccRNld7Y9LbfYwYtODcts6di9AkOVfueZJiaXbONZfIE -Zrb+jkAteh9wGL9xIrnohbABJcV3Kiaco84jInUSmGDtPokncOENfHIEuEpuSJ2b -bx1TuhmAVuGWivR0+ULC7RECgYEAgS0cDRpWc9Xzh9Cl7+PLsXEvdWNpPsL9OsEq -0Ep7z9+/+f/jZtoTRCS/BTHUpDvAuwHglT5j3p5iFMt5VuiIiovWLwynGYwrbnNS -qfrIrYKUaH1n1oDS+oBZYLQGCe9/7EifAjxtjYzbvSyg//SPG7tSwfBCREbpZXj2 -qSWkNsECgYA/mCDzCTlrrWPuiepo6kTmN+4TnFA+hJI6NccDVQ+jvbqEdoJ4SW4L -zqfZSZRFJMNpSgIqkQNRPJqMP0jQ5KRtJrjMWBnYxktwKz9fDg2R2MxdFgMF2LH2 -HEMMhFHlv8NDjVOXh1KwRoltNGVWYsSrD9wKU9GhRCEfmNCGrvBcEg== ------END RSA PRIVATE KEY----- diff --git a/internal/suites/example/kube/authelia/authelia.yml b/internal/suites/example/kube/authelia/authelia.yml new file mode 100644 index 000000000..da1366902 --- /dev/null +++ b/internal/suites/example/kube/authelia/authelia.yml @@ -0,0 +1,153 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authelia + namespace: authelia + labels: + app: authelia +spec: + replicas: 1 + selector: + matchLabels: + app: authelia + template: + metadata: + labels: + app: authelia + spec: + containers: + - name: authelia + image: authelia:dist + ports: + - containerPort: 443 + readinessProbe: + httpGet: + scheme: HTTPS + path: /api/health + port: 443 + initialDelaySeconds: 3 + periodSeconds: 3 + volumeMounts: + - name: authelia-config + mountPath: /config/configuration.yml + readOnly: true + - name: authelia-ssl + mountPath: /config/ssl + readOnly: true + - name: secrets + mountPath: /config/secrets + readOnly: true + env: + # We set secrets directly here for ease of deployment but all secrets + # should be stored in the Kube Vault in production. + - name: AUTHELIA_JWT_SECRET_FILE + value: /config/secrets/jwt_secret + - name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE + value: /config/secrets/ldap_password + - name: AUTHELIA_SESSION_SECRET_FILE + value: /config/secrets/session + - name: AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE + value: /config/secrets/sql_password + - name: AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE + value: /config/secrets/encryption_key + - name: ENVIRONMENT + value: dev + volumes: + - name: authelia-config + hostPath: + path: /configmaps/authelia/configuration.yml + type: File + - name: authelia-ssl + hostPath: + path: /configmaps/authelia/ssl + type: Directory + - name: secrets + secret: + secretName: authelia + items: + - key: jwt_secret + path: jwt_secret + - key: session + path: session + - key: sql_password + path: sql_password + - key: ldap_password + path: ldap_password + - key: encryption_key + path: encryption_key +... +--- +apiVersion: v1 +kind: Service +metadata: + name: authelia-service + namespace: authelia + annotations: + traefik.ingress.kubernetes.io/service.serverstransport: authelia-skipverify@kubernetescrd +spec: + selector: + app: authelia + ports: + - protocol: TCP + port: 443 + targetPort: 443 +... +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: authelia + namespace: authelia + labels: + app: authelia +data: + jwt_secret: YW5fdW5zZWN1cmVfc2VjcmV0 # an_unsecure_secret + ldap_password: cGFzc3dvcmQ= # password + session: dW5zZWN1cmVfcGFzc3dvcmQ= # unsecure_password + sql_password: cGFzc3dvcmQ= # password + encryption_key: YV9ub3Rfc29fc2VjdXJlX2VuY3J5cHRpb25fa2V5 +... +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: authelia-ingress + namespace: authelia + annotations: + kubernetes.io/ingress.class: traefik + traefik.ingress.kubernetes.io/router.entrypoints: websecure +spec: + rules: + - host: login.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: authelia-service + port: + number: 443 +... +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: forwardauth-authelia + namespace: authelia + labels: + app.kubernetes.io/instance: authelia + app.kubernetes.io/name: authelia +spec: + forwardAuth: + address: https://authelia-service.authelia.svc.cluster.local/api/verify?rd=https://login.example.com:8080 + authResponseHeaders: + - Remote-User + - Remote-Name + - Remote-Email + - Remote-Groups + tls: + insecureSkipVerify: true +... diff --git a/internal/suites/example/kube/authelia/configs/configuration.yml b/internal/suites/example/kube/authelia/configs/configuration.yml index b4d3ece18..08a91542f 100644 --- a/internal/suites/example/kube/authelia/configs/configuration.yml +++ b/internal/suites/example/kube/authelia/configs/configuration.yml @@ -35,6 +35,8 @@ access_control: rules: # Rules applied to everyone + - domain: home.example.com + policy: bypass - domain: public.example.com policy: bypass - domain: secure.example.com diff --git a/internal/suites/example/kube/authelia/deployment.yml b/internal/suites/example/kube/authelia/deployment.yml deleted file mode 100644 index 6a4156ecf..000000000 --- a/internal/suites/example/kube/authelia/deployment.yml +++ /dev/null @@ -1,76 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: authelia - namespace: authelia - labels: - app: authelia -spec: - replicas: 1 - selector: - matchLabels: - app: authelia - template: - metadata: - labels: - app: authelia - spec: - containers: - - name: authelia - image: authelia:dist - ports: - - containerPort: 443 - volumeMounts: - - name: config-volume - mountPath: /config - - name: ssl-volume - mountPath: /config/ssl - - name: secrets - mountPath: /app/secrets - readOnly: true - env: - # We set secrets directly here for ease of deployment but all secrets - # should be stored in the Kube Vault in production. - - name: AUTHELIA_JWT_SECRET_FILE - value: /app/secrets/jwt_secret - - name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE - value: /app/secrets/ldap_password - - name: AUTHELIA_SESSION_SECRET_FILE - value: /app/secrets/session - - name: AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE - value: /app/secrets/sql_password - - name: AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE - value: /app/secrets/encryption_key - - name: ENVIRONMENT - value: dev - volumes: - - name: config-volume - configMap: - name: authelia-config - items: - - key: configuration.yml - path: configuration.yml - - name: ssl-volume - configMap: - name: authelia-ssl - items: - - key: cert.pem - path: cert.pem - - key: key.pem - path: key.pem - - name: secrets - secret: - secretName: authelia - items: - - key: jwt_secret - path: jwt_secret - - key: session - path: session - - key: sql_password - path: sql_password - - key: ldap_password - path: ldap_password - - key: encryption_key - path: encryption_key -... diff --git a/internal/suites/example/kube/authelia/ingress.yml b/internal/suites/example/kube/authelia/ingress.yml deleted file mode 100644 index 5d7f78cbf..000000000 --- a/internal/suites/example/kube/authelia/ingress.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: authelia-ingress - namespace: authelia - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" -spec: - tls: - - secretName: authelia-tls - hosts: - - login.example.com - rules: - - host: login.example.com - http: - paths: - - path: / - backend: - serviceName: authelia-service - servicePort: 443 -... diff --git a/internal/suites/example/kube/authelia/secret.yml b/internal/suites/example/kube/authelia/secret.yml deleted file mode 100644 index de5e501e5..000000000 --- a/internal/suites/example/kube/authelia/secret.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: authelia - namespace: authelia - labels: - app: authelia -data: - jwt_secret: YW5fdW5zZWN1cmVfc2VjcmV0 # an_unsecure_secret - ldap_password: cGFzc3dvcmQ= # password - session: dW5zZWN1cmVfcGFzc3dvcmQ= # unsecure_password - sql_password: cGFzc3dvcmQ= # password - encryption_key: YV9ub3Rfc29fc2VjdXJlX2VuY3J5cHRpb25fa2V5 -... diff --git a/internal/suites/example/kube/authelia/service.yml b/internal/suites/example/kube/authelia/service.yml deleted file mode 100644 index af7686132..000000000 --- a/internal/suites/example/kube/authelia/service.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: authelia-service - namespace: authelia -spec: - selector: - app: authelia - ports: - - protocol: TCP - port: 443 - targetPort: 443 -... diff --git a/internal/suites/example/kube/authelia/ssl/cert.pem b/internal/suites/example/kube/authelia/ssl/cert.pem deleted file mode 100644 index 9fabcb421..000000000 --- a/internal/suites/example/kube/authelia/ssl/cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/jCCAeagAwIBAgIRAKF0IRxC55eee6icERVf6fgwDQYJKoZIhvcNAQELBQAw -EjEQMA4GA1UEChMHQWNtZSBDbzAgFw0yMDAzMDExMjMzMzlaGA8yMTIwMDIwNjEy -MzMzOVowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMi7/oSazFIxP3rHsSLjw5XPnpMKEaVwU1zLRzW6W80BDa/ER5to -I3POGLv8lAhtUwB6WvyilrCZfs/D5lkcCxswafU/2LNppFuODnW+PG9eobgOy6Nv -f+KbnZFPRV7PB2yK6DqMyb+tbTQ7F6rEf4i6n28DI0dNyNvUCk0ld3o93LZBvC/D -/+Ulf3Vtdfsd2TckXvdA8lH4VGQJ+FIxhboTlbW8VJlk1V7FZef7+m867kOnPSaj -zv5yygrIA0XPaMAZC/SZrXHMdhvcs43fgmmTel7JD4Sy/Z/pmFlrZr5Xa8jcWycJ -ILLuPnXhgKstgq5wtDkTMZ6rpgMrKcjMKcMCAwEAAaNNMEswDgYDVR0PAQH/BAQD -AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8w -DYILZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBABdWkbipzPivAvvamMmQ -5iPPeStfdr5MBxJGT9nPbeXdtS/13FJnspLBMMYOw/2AZk7VFrNjxkXc4NHZSlGz -FcGMlSO40fyirdYaQTDtS230ucLB+LzfZx37y9dKpEKVmQ151kKJjJ4hAZ47LmAQ -aFoDLRo7PA2HmnJ60GrI9wVp96uy1sQ6PcToIyMcVEQ/tLEEow+ykSeiZb9+qBKV -K9GUcu2LorhBtUMmEWs0TJElaf6eKUoG6JXM2byulDg24w5b9gC26kAlHWc5WDU5 -pAXOjlN/OYHB0sDbYViWIL390376fYIfu2N5EDKY4QjEYsWEs4Wm9HVS9IgHP/Gi -Xbo= ------END CERTIFICATE----- diff --git a/internal/suites/example/kube/authelia/ssl/key.pem b/internal/suites/example/kube/authelia/ssl/key.pem deleted file mode 100644 index a190f8b44..000000000 --- a/internal/suites/example/kube/authelia/ssl/key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDIu/6EmsxSMT96 -x7Ei48OVz56TChGlcFNcy0c1ulvNAQ2vxEebaCNzzhi7/JQIbVMAelr8opawmX7P -w+ZZHAsbMGn1P9izaaRbjg51vjxvXqG4Dsujb3/im52RT0Vezwdsiug6jMm/rW00 -OxeqxH+Iup9vAyNHTcjb1ApNJXd6Pdy2Qbwvw//lJX91bXX7Hdk3JF73QPJR+FRk -CfhSMYW6E5W1vFSZZNVexWXn+/pvOu5Dpz0mo87+csoKyANFz2jAGQv0ma1xzHYb -3LON34Jpk3peyQ+Esv2f6ZhZa2a+V2vI3FsnCSCy7j514YCrLYKucLQ5EzGeq6YD -KynIzCnDAgMBAAECggEAC13R0LJvRWwyewJZvm8FQTNreEoGq8aLgeKk2p792cLo -gn5ry5n+/+y4q9RmkX+XRpynEE0omUFn09306jDTVCvOpCuEWsxtmR2XJgWqqGfE -Yoa78zo6FJvZNUQ22mKAuh23frFAL1FjsKRz96B+1EA1DPUxhzUZXZFJMAsiE9LZ -PxqPmnqXbPZsOb1XG33TAdCp6CC3H8KHICC+i4IC8prjKHGH/Q1saoNw8jmgwv0S -DelQUbEtqfmE6BmyTGxdeu4uW2Nv/wcENwySAOPKi5gstlbSKTa4IpKGp7CdquWi -stUW6pnSiEeDrDAzwC8uWdncOvnkAy2lRJkz/F9YoQKBgQDrCCqYdvGshecBBnfQ -fowxak2YBfG2jhAKPMHzrvQn5FIb+11x/jeXPEfOB6FShIzZ97JpFIpH3tcONlj3 -OVzGCTD6WdRTcltzXVneJtNog7DliNFY4YmIPmQJ+y+EvJW1rSZTZAZI1Nbijg3n -fSd0PTzvgOGHSl1//RI1mFx7MwKBgQDapIPPSF0yf1UJ6Hhzam5NHGZ9fSqV5Qs0 -Gi7uM08iDV5K7xiPglBkbN2EuMlgVnHaa5g8X897uwRSYR6nL4PRvcJiNSvnhWhe -+K3x7iHewIPYVfcghoqzuPKsXH2Zm26usdXHxBBa3IBbKtGaHnAd9h65AOUYAmAx -C2BzN90XMQKBgE2MjEFyPZunMulrsOziVG+Zm7ClhXOuvCwkj/pPp8/hzhXdgp+y -ObV09lxMuDX59l+VExEI7fd414yg8gngq3PMZJS2PxCpkvMlwhlCxk6d5ShXVHv3 -LuH9dBS3BJ7PerZPQ24QeuJdF+n45S2UZgg8jHaaF9AEAYXRgsicVSdxAoGAJI0U -K/bg/awjv0BJwqGsRt/Ukm32TJC5ysAF0HRrajnp5YULChKy9dbtQV7S63QIHIeY -L5+kw/6DvnHV+gULeGjMsjZJXK8Ev7u6+JLivqZYZDYa1iknztvAVegwZxmA61t3 -bantQgNSwerql2U3QQsAH9Vydw0On6RTP2+7WkECgYBWD3u64hBKmAxPkqPotkgI -w/jdOlv8FLHO79+oH1PtKvkzspcYaecKGDm/RNLIXLYnt0AmZEK4qQ4/zDFaR/rc -AhoxK2cKTRltMrhp1ivtFfLggVGogtYNxEnjnsD4KMvH3SjSNdt06YgtZ92++fOp -UsE8Mpf4/G5X7DmcHJHk+w== ------END PRIVATE KEY----- diff --git a/internal/suites/example/kube/bootstrap-authelia.sh b/internal/suites/example/kube/bootstrap-authelia.sh deleted file mode 100755 index 80ad7c1e1..000000000 --- a/internal/suites/example/kube/bootstrap-authelia.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -start_authelia() { - kubectl create configmap authelia-config --namespace=authelia --from-file=authelia/configs/configuration.yml - kubectl create configmap authelia-ssl --namespace=authelia --from-file=authelia/ssl/cert.pem --from-file=authelia/ssl/key.pem - kubectl apply -f authelia -} - -start_authelia \ No newline at end of file diff --git a/internal/suites/example/kube/bootstrap-dashboard.sh b/internal/suites/example/kube/bootstrap-dashboard.sh deleted file mode 100755 index bbaddf893..000000000 --- a/internal/suites/example/kube/bootstrap-dashboard.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -start_dashboard() { - kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml - kubectl apply -f dashboard.yml - - echo "Bearer token for UI user." - kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}') -} - -start_dashboard diff --git a/internal/suites/example/kube/bootstrap.sh b/internal/suites/example/kube/bootstrap.sh deleted file mode 100755 index bdc087e70..000000000 --- a/internal/suites/example/kube/bootstrap.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -start_apps() { - # Create TLS certificate and key for HTTPS termination - kubectl create secret generic test-app-tls --namespace=authelia --from-file=apps/ssl/server.key --from-file=apps/ssl/server.cert - kubectl create configmap nginx-config --namespace=authelia --from-file=apps/configs/entrypoint.sh --from-file=apps/configs/nginx.conf --from-file=apps/configs/html.tar.gz - - # Spawn the applications - kubectl apply -f apps -} - -start_ingress_controller() { - kubectl apply -f ingress-controller -} - -# Spawn Redis and storage backend -# Please note they are not configured to be distributed on several machines -start_storage() { - kubectl apply -f storage -} - -# Create a fake mailbox to catch emails sent by Authelia -start_mail() { - kubectl apply -f mail -} - -start_ldap() { - kubectl create configmap ldap-config --namespace=authelia --from-file=ldap/base.ldif --from-file=ldap/access.rules - kubectl apply -f ldap -} - -# Create the Authelia namespace in the cluster -create_namespace() { - kubectl apply -f namespace.yml -} - -create_namespace -start_storage -start_ldap -start_mail -start_ingress_controller -start_apps diff --git a/internal/suites/example/kube/dashboard.yml b/internal/suites/example/kube/dashboard.yml deleted file mode 100644 index 4abe4a715..000000000 --- a/internal/suites/example/kube/dashboard.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: admin-user - namespace: kubernetes-dashboard -... ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: admin-user -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: - - kind: ServiceAccount - name: admin-user - namespace: kubernetes-dashboard -... diff --git a/internal/suites/example/kube/dashboards.yml b/internal/suites/example/kube/dashboards.yml new file mode 100644 index 000000000..9735a2c51 --- /dev/null +++ b/internal/suites/example/kube/dashboards.yml @@ -0,0 +1,346 @@ +# Kubernetes Dashboard +--- +apiVersion: v1 +kind: Namespace +metadata: + name: kubernetes-dashboard +... +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard +... +--- +kind: Service +apiVersion: v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard +spec: + ports: + - port: 443 + targetPort: 8443 + selector: + k8s-app: kubernetes-dashboard +... +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-certs + namespace: kubernetes-dashboard +type: Opaque +... +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-csrf + namespace: kubernetes-dashboard +type: Opaque +data: + csrf: "" +... +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-key-holder + namespace: kubernetes-dashboard +type: Opaque +... +--- +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-settings + namespace: kubernetes-dashboard +... +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard +rules: + # Allow Dashboard to get, update and delete Dashboard exclusive secrets. + - apiGroups: [""] + resources: ["secrets"] + resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"] + verbs: ["get", "update", "delete"] + # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. + - apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["kubernetes-dashboard-settings"] + verbs: ["get", "update"] + # Allow Dashboard to get metrics. + - apiGroups: [""] + resources: ["services"] + resourceNames: ["heapster", "dashboard-metrics-scraper"] + verbs: ["proxy"] + - apiGroups: [""] + resources: ["services/proxy"] + resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"] # yamllint disable-line rule:line-length + verbs: ["get"] +... +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard +rules: + # Allow Metrics Scraper to get metrics from the Metrics server + - apiGroups: ["metrics.k8s.io"] + resources: ["pods", "nodes"] + verbs: ["get", "list", "watch"] +... +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kubernetes-dashboard +subjects: + - kind: ServiceAccount + name: kubernetes-dashboard + namespace: kubernetes-dashboard +... +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubernetes-dashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kubernetes-dashboard +subjects: + - kind: ServiceAccount + name: kubernetes-dashboard + namespace: kubernetes-dashboard +... +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard +spec: + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s-app: kubernetes-dashboard + template: + metadata: + labels: + k8s-app: kubernetes-dashboard + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: kubernetes-dashboard + image: kubernetesui/dashboard:v2.7.0 + imagePullPolicy: Always + ports: + - containerPort: 8443 + protocol: TCP + args: + - --auto-generate-certificates + - --namespace=kubernetes-dashboard + # Uncomment the following line to manually specify Kubernetes API server Host + # If not specified, Dashboard will attempt to auto discover the API server and connect + # to it. Uncomment only if the default does not work. + # - --apiserver-host=http://my-address:port + volumeMounts: + - name: kubernetes-dashboard-certs + mountPath: /certs + # Create on-disk volume to store exec logs + - mountPath: /tmp + name: tmp-volume + livenessProbe: + httpGet: + scheme: HTTPS + path: / + port: 8443 + initialDelaySeconds: 30 + timeoutSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 1001 + runAsGroup: 2001 + volumes: + - name: kubernetes-dashboard-certs + secret: + secretName: kubernetes-dashboard-certs + - name: tmp-volume + emptyDir: {} + serviceAccountName: kubernetes-dashboard + nodeSelector: + "kubernetes.io/os": linux + # Comment the following tolerations if Dashboard must not be deployed on master + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule +... +--- +kind: Service +apiVersion: v1 +metadata: + labels: + k8s-app: dashboard-metrics-scraper + name: dashboard-metrics-scraper + namespace: kubernetes-dashboard +spec: + ports: + - port: 8000 + targetPort: 8000 + selector: + k8s-app: dashboard-metrics-scraper +... +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + labels: + k8s-app: dashboard-metrics-scraper + name: dashboard-metrics-scraper + namespace: kubernetes-dashboard +spec: + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s-app: dashboard-metrics-scraper + template: + metadata: + labels: + k8s-app: dashboard-metrics-scraper + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: dashboard-metrics-scraper + image: kubernetesui/metrics-scraper:v1.0.8 + ports: + - containerPort: 8000 + protocol: TCP + livenessProbe: + httpGet: + scheme: HTTP + path: / + port: 8000 + initialDelaySeconds: 30 + timeoutSeconds: 30 + volumeMounts: + - mountPath: /tmp + name: tmp-volume + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 1001 + runAsGroup: 2001 + serviceAccountName: kubernetes-dashboard + nodeSelector: + "kubernetes.io/os": linux + # Comment the following tolerations if Dashboard must not be deployed on master + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + volumes: + - name: tmp-volume + emptyDir: {} +... +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: admin-user + namespace: kubernetes-dashboard +... +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: admin-user +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: admin-user + namespace: kubernetes-dashboard +... +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: kubernetes-dashboard-ingress + namespace: kubernetes-dashboard +spec: + entryPoints: + - websecure + routes: + - match: HostSNI(`kubernetes.example.com`) + services: + - name: kubernetes-dashboard + port: 443 + tls: + passthrough: true +... +# Traefik Dashboard +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: traefik-dashboard-ingress + namespace: authelia +spec: + entryPoints: + - websecure + routes: + - match: Host(`traefik.example.com`) + kind: Rule + services: + - name: api@internal + kind: TraefikService +... +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: ServersTransport +metadata: + name: skipverify + namespace: authelia +spec: + insecureSkipVerify: true +... diff --git a/internal/suites/example/kube/ingress-controller/deployment.yml b/internal/suites/example/kube/ingress-controller/deployment.yml deleted file mode 100644 index 432941e22..000000000 --- a/internal/suites/example/kube/ingress-controller/deployment.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-ingress-controller - namespace: authelia - labels: - app: nginx-ingress-controller -spec: - replicas: 1 - revisionHistoryLimit: 0 - selector: - matchLabels: - app: nginx-ingress-controller - template: - metadata: - labels: - app: nginx-ingress-controller - annotations: - prometheus.io/port: '10254' - prometheus.io/scrape: 'true' - spec: - terminationGracePeriodSeconds: 60 - serviceAccountName: nginx-ingress-controller-serviceaccount - containers: - - image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.23.0 - name: nginx-ingress-controller - imagePullPolicy: Always - ports: - - containerPort: 80 - - containerPort: 443 - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - args: - - /nginx-ingress-controller - - --ingress-class=nginx - - --election-id=ingress-controller-leader -... diff --git a/internal/suites/example/kube/ingress-controller/rbac.yml b/internal/suites/example/kube/ingress-controller/rbac.yml deleted file mode 100644 index d4ec42faa..000000000 --- a/internal/suites/example/kube/ingress-controller/rbac.yml +++ /dev/null @@ -1,141 +0,0 @@ ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: nginx-ingress-controller-serviceaccount - namespace: authelia - labels: - app: nginx-ingress-controller -... ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: nginx-ingress-controller-clusterrole - labels: - app: nginx-ingress-controller -rules: - - apiGroups: - - "" - resources: - - configmaps - - endpoints - - nodes - - pods - - secrets - verbs: - - list - - watch - - apiGroups: - - "" - resources: - - nodes - verbs: - - get - - apiGroups: - - "" - resources: - - services - verbs: - - get - - list - - watch - - apiGroups: - - "extensions" - resources: - - ingresses - verbs: - - get - - list - - watch - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - - apiGroups: - - "extensions" - resources: - - ingresses/status - verbs: - - update -... ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: Role -metadata: - name: nginx-ingress-controller-role - namespace: authelia - labels: - app: nginx-ingress-controller -rules: - - apiGroups: - - "" - resources: - - configmaps - - pods - - secrets - - namespaces - verbs: - - get - - apiGroups: - - "" - resources: - - configmaps - resourceNames: - # Defaults to "-" - # Here: "-" - # This has to be adapted if you change either parameter - # when launching the nginx-ingress-controller. - - "ingress-controller-leader-nginx" - verbs: - - get - - update - - apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - apiGroups: - - "" - resources: - - endpoints - verbs: - - get -... ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: nginx-ingress-controller-role-nisa-binding - namespace: authelia - labels: - app: nginx-ingress-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: nginx-ingress-controller-role -subjects: - - kind: ServiceAccount - name: nginx-ingress-controller-serviceaccount - namespace: authelia -... ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: nginx-ingress-controller-clusterrole-nisa-binding - labels: - app: nginx-ingress-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: nginx-ingress-controller-clusterrole -subjects: - - kind: ServiceAccount - name: nginx-ingress-controller-serviceaccount - namespace: authelia -... diff --git a/internal/suites/example/kube/ingress-controller/service.yml b/internal/suites/example/kube/ingress-controller/service.yml deleted file mode 100644 index ce299dd43..000000000 --- a/internal/suites/example/kube/ingress-controller/service.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-ingress-controller-service - namespace: authelia - labels: - app: nginx-ingress-controller -spec: - selector: - app: nginx-ingress-controller - type: NodePort - ports: - - port: 80 - name: http - - port: 443 - name: https -... diff --git a/internal/suites/example/kube/ldap/access.rules b/internal/suites/example/kube/ldap/access.rules deleted file mode 100644 index 8762639e2..000000000 --- a/internal/suites/example/kube/ldap/access.rules +++ /dev/null @@ -1,7 +0,0 @@ -olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou - s auth by * none -# olcAccess: {1}to dn.base="" by * read -# olcAccess: {2}to * by * read - -olcPasswordHash: {CRYPT} -olcPasswordCryptSaltFormat: $6$rounds=50000$%.16s diff --git a/internal/suites/example/kube/ldap/base.ldif b/internal/suites/example/kube/ldap/base.ldif deleted file mode 100644 index e1a198e8a..000000000 --- a/internal/suites/example/kube/ldap/base.ldif +++ /dev/null @@ -1,67 +0,0 @@ -dn: ou=groups,dc=example,dc=com -objectClass: organizationalUnit -objectClass: top -ou: groups - -dn: ou=users,dc=example,dc=com -objectClass: organizationalUnit -objectClass: top -ou: users - -dn: cn=dev,ou=groups,dc=example,dc=com -cn: dev -member: uid=john,ou=users,dc=example,dc=com -member: uid=bob,ou=users,dc=example,dc=com -objectClass: groupOfNames -objectClass: top - -dn: cn=admins,ou=groups,dc=example,dc=com -cn: admins -member: uid=john,ou=users,dc=example,dc=com -objectClass: groupOfNames -objectClass: top - -dn: uid=john,ou=users,dc=example,dc=com -uid: john -cn: john -objectClass: inetOrgPerson -objectClass: top -mail: john.doe@authelia.com -sn: John Doe -userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/ - -dn: uid=harry,ou=users,dc=example,dc=com -uid: harry -cn: harry -objectClass: inetOrgPerson -objectClass: top -mail: harry.potter@authelia.com -sn: Harry Potter -userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/ - -dn: uid=bob,ou=users,dc=example,dc=com -uid: bob -cn: bob -objectClass: inetOrgPerson -objectClass: top -mail: bob.dylan@authelia.com -sn: Bob Dylan -userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/ - -dn: uid=james,ou=users,dc=example,dc=com -uid: james -cn: james -objectClass: inetOrgPerson -objectClass: top -mail: james.dean@authelia.com -sn: James Dean -userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/ - -dn: uid=blackhat,ou=users,dc=example,dc=com -uid: blackhat -cn: blackhat -objectClass: inetOrgPerson -objectClass: top -mail: billy.blackhat@authelia.com -sn: Billy BlackHat -userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/ diff --git a/internal/suites/example/kube/ldap/deployment.yml b/internal/suites/example/kube/ldap/ldap.yml similarity index 67% rename from internal/suites/example/kube/ldap/deployment.yml rename to internal/suites/example/kube/ldap/ldap.yml index 996895be6..654de99e2 100644 --- a/internal/suites/example/kube/ldap/deployment.yml +++ b/internal/suites/example/kube/ldap/ldap.yml @@ -18,7 +18,7 @@ spec: spec: containers: - name: ldap - image: osixia/openldap:1.3.0 + image: osixia/openldap:1.5.0 ports: - containerPort: 389 - containerPort: 636 @@ -41,19 +41,24 @@ spec: - name: LDAP_TLS_VERIFY_CLIENT value: try volumeMounts: - - name: config-volume - mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom/base.ldif - subPath: base.ldif - - name: config-volume - mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom/access.rules - subPath: access.rules + - name: ldap-config + mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom volumes: - - name: config-volume - configMap: - name: ldap-config - items: - - key: base.ldif - path: base.ldif - - key: access.rules - path: access.rules + - name: ldap-config + hostPath: + path: /configmaps/ldap + type: Directory +... +--- +apiVersion: v1 +kind: Service +metadata: + name: ldap-service + namespace: authelia +spec: + selector: + app: ldap + ports: + - protocol: TCP + port: 636 ... diff --git a/internal/suites/example/kube/ldap/service.yml b/internal/suites/example/kube/ldap/service.yml deleted file mode 100644 index e932f4e77..000000000 --- a/internal/suites/example/kube/ldap/service.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: ldap-service - namespace: authelia -spec: - selector: - app: ldap - ports: - - protocol: TCP - port: 636 -... diff --git a/internal/suites/example/kube/mail/deployment.yml b/internal/suites/example/kube/mail/deployment.yml deleted file mode 100644 index 6bec15f5d..000000000 --- a/internal/suites/example/kube/mail/deployment.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mailcatcher - namespace: authelia - labels: - app: mailcatcher -spec: - replicas: 1 - selector: - matchLabels: - app: mailcatcher - template: - metadata: - labels: - app: mailcatcher - spec: - containers: - - name: mailcatcher - image: schickling/mailcatcher - ports: - - containerPort: 1025 - - containerPort: 1080 -... diff --git a/internal/suites/example/kube/mail/ingress.yml b/internal/suites/example/kube/mail/ingress.yml deleted file mode 100644 index ed2291f95..000000000 --- a/internal/suites/example/kube/mail/ingress.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailcatcher-ingress - namespace: authelia - annotations: - kubernetes.io/ingress.class: "nginx" -spec: - tls: - - secretName: mail-tls - hosts: - - mail.example.com - rules: - - host: mail.example.com - http: - paths: - - path: / - backend: - serviceName: mailcatcher-service - servicePort: 1080 -... diff --git a/internal/suites/example/kube/mail/mail.yml b/internal/suites/example/kube/mail/mail.yml new file mode 100644 index 000000000..b26464e72 --- /dev/null +++ b/internal/suites/example/kube/mail/mail.yml @@ -0,0 +1,64 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mailcatcher + namespace: authelia + labels: + app: mailcatcher +spec: + replicas: 1 + selector: + matchLabels: + app: mailcatcher + template: + metadata: + labels: + app: mailcatcher + spec: + containers: + - name: mailcatcher + image: schickling/mailcatcher + ports: + - containerPort: 1025 + - containerPort: 1080 +... +--- +apiVersion: v1 +kind: Service +metadata: + name: mailcatcher-service + namespace: authelia +spec: + selector: + app: mailcatcher + ports: + - protocol: TCP + port: 1080 + name: ui + - protocol: TCP + port: 1025 + name: smtp +... +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: mailcatcher-ingress + namespace: authelia + annotations: + kubernetes.io/ingress.class: traefik + traefik.ingress.kubernetes.io/router.entrypoints: websecure +spec: + rules: + - host: mail.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: mailcatcher-service + port: + number: 1080 +... diff --git a/internal/suites/example/kube/mail/service.yml b/internal/suites/example/kube/mail/service.yml deleted file mode 100644 index 1d33a5c5e..000000000 --- a/internal/suites/example/kube/mail/service.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: mailcatcher-service - namespace: authelia -spec: - selector: - app: mailcatcher - ports: - - protocol: TCP - port: 1080 - name: ui - - protocol: TCP - port: 1025 - name: smtp -... diff --git a/internal/suites/example/kube/registry.yml b/internal/suites/example/kube/registry.yml new file mode 100644 index 000000000..32cb0459e --- /dev/null +++ b/internal/suites/example/kube/registry.yml @@ -0,0 +1,6 @@ +--- +mirrors: + "docker.io": + endpoint: + - http://registrycache.internal:5000 +... diff --git a/internal/suites/example/kube/storage/mariadb.yml b/internal/suites/example/kube/storage/mariadb.yml index 711dee245..5e0837665 100644 --- a/internal/suites/example/kube/storage/mariadb.yml +++ b/internal/suites/example/kube/storage/mariadb.yml @@ -18,12 +18,14 @@ spec: spec: containers: - name: mariadb - image: mariadb:10.4.10 + image: mariadb:10.10.2 ports: - containerPort: 3306 + readinessProbe: + tcpSocket: + port: 3306 + periodSeconds: 1 env: - - name: SLAPD_ORGANISATION - value: MyCompany - name: MYSQL_ROOT_PASSWORD value: rootpassword - name: MYSQL_USER @@ -32,13 +34,6 @@ spec: value: password - name: MYSQL_DATABASE value: authelia - volumeMounts: - - name: data-volume - mountPath: /var/lib/mysql - volumes: - - name: data-volume - hostPath: - path: /data/storage/mysql ... --- apiVersion: v1 diff --git a/internal/suites/example/kube/storage/redis.yml b/internal/suites/example/kube/storage/redis.yml index 7cb4fb3d9..15c9b007f 100644 --- a/internal/suites/example/kube/storage/redis.yml +++ b/internal/suites/example/kube/storage/redis.yml @@ -18,9 +18,13 @@ spec: spec: containers: - name: redis - image: redis:3.2.11-alpine + image: redis:6.2-alpine ports: - containerPort: 6379 + readinessProbe: + tcpSocket: + port: 6379 + periodSeconds: 1 ... --- apiVersion: v1 diff --git a/internal/suites/example/kube/test.yml b/internal/suites/example/kube/test.yml deleted file mode 100644 index af95181a2..000000000 --- a/internal/suites/example/kube/test.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: test-app1 - namespace: kube-public - labels: - app: test-app1 -spec: - replicas: 1 - selector: - matchLabels: - app: test-app1 - template: - metadata: - labels: - app: test-app1 - spec: - containers: - - name: test-app1 - image: authelia/authelia:kube - imagePullPolicy: Never -... diff --git a/internal/suites/example/swarm/docker-compose.yml b/internal/suites/example/swarm/docker-compose.yml deleted file mode 100644 index 4a082bc0e..000000000 --- a/internal/suites/example/swarm/docker-compose.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- -version: '3.4' -services: - authelia: - image: authelia/authelia:latest - # Used for Docker configs - configs: - - source: authelia - target: /config/configuration.yml - uid: '0' - gid: '0' - mode: 0444 # yamllint disable-line rule:octal-values - environment: - - NODE_TLS_REJECT_UNAUTHORIZED=0 - # Where the authelia volume is to be mounted. To only use a single volume, the minimal config - # needs to be changed to read the users_database.yml also from this subdirectory. - # Otherwise a second volume will need to be configured here to mount the users_database.yml. - volumes: - - authelia:/config/storage - networks: - - overlay - deploy: - # Configure Authelia to automatically restart on failure. - restart_policy: - condition: on-failure - delay: 5s - max_attempts: 3 - window: 120s - # Mode: global would start authelia on all available nodes, - # replicated limits it to how many replicas are configured. - mode: replicated - # How many replicas are wanted. Can be any number >0 up to however many nodes are available. - replicas: 1 - placement: - constraints: - - node.role == worker - -# The volume for authelia needs to be configured. -# There are many drivers available. Such as local storage, ceph-rdb, nfs, cifs etc. -volumes: - authelia: - driver: default - name: volume-authelia - -networks: - overlay: - external: true - -# This is needed if Docker configs are being used to provide Authelia with its configuration. -configs: - authelia: - external: true -... diff --git a/internal/suites/kubernetes.go b/internal/suites/kubernetes.go index c68da2495..82bda5d43 100644 --- a/internal/suites/kubernetes.go +++ b/internal/suites/kubernetes.go @@ -3,53 +3,41 @@ package suites import ( "fmt" "os/exec" + "regexp" "strings" "time" "github.com/authelia/authelia/v4/internal/utils" ) -var kindImageName = "authelia-kind-proxy" -var dockerCmdLine = fmt.Sprintf("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml run -T --rm %s", kindImageName) +var k3dImageName = "k3d" +var dockerCmdLine = fmt.Sprintf("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/k3d/docker-compose.yml exec -T %s", k3dImageName) -// Kind used for running kind commands. -type Kind struct{} +// K3D used for running kind commands. +type K3D struct{} -func kindCommand(cmdline string) *exec.Cmd { +func k3dCommand(cmdline string) *exec.Cmd { cmd := fmt.Sprintf("%s %s", dockerCmdLine, cmdline) return utils.Shell(cmd) } // CreateCluster create a new Kubernetes cluster. -func (k Kind) CreateCluster() error { - cmd := kindCommand("kind create cluster --config /etc/kind/config.yml") - if err := cmd.Run(); err != nil { - return err - } - - cmd = kindCommand("patch-kubeconfig.sh") - if err := cmd.Run(); err != nil { - return err - } - - // This command is necessary to fix the coredns loop detected when using user-defined docker network. - // In that case /etc/resolv.conf use 127.0.0.11 as DNS and CoreDNS thinks it is talking to itself which is wrong. - // This IP is the docker internal DNS so it is safe to disable the loop check. - cmd = kindCommand("sh -c 'kubectl -n kube-system get configmap/coredns -o yaml | grep -v loop | kubectl replace -f -'") +func (k K3D) CreateCluster() error { + cmd := k3dCommand("k3d cluster create --registry-config /authelia/registry.yml -v /authelia:/var/lib/rancher/k3s/server/manifests/custom -v /configmaps:/configmaps -p 8080:443") err := cmd.Run() return err } // DeleteCluster delete a Kubernetes cluster. -func (k Kind) DeleteCluster() error { - cmd := kindCommand("kind delete cluster") +func (k K3D) DeleteCluster() error { + cmd := k3dCommand("k3d cluster delete") return cmd.Run() } // ClusterExists check whether a cluster exists. -func (k Kind) ClusterExists() (bool, error) { - cmd := kindCommand("kind get clusters") +func (k K3D) ClusterExists() (bool, error) { + cmd := k3dCommand("k3d cluster list") cmd.Stdout = nil cmd.Stderr = nil output, err := cmd.Output() @@ -58,63 +46,27 @@ func (k Kind) ClusterExists() (bool, error) { return false, err } - return strings.Contains(string(output), "kind"), nil + return strings.Contains(string(output), "k3s-default"), nil } // LoadImage load an image in the Kubernetes container. -func (k Kind) LoadImage(imageName string) error { - cmd := kindCommand(fmt.Sprintf("kind load docker-image %s", imageName)) +func (k K3D) LoadImage(imageName string) error { + cmd := k3dCommand(fmt.Sprintf("k3d image import %s", imageName)) return cmd.Run() } // Kubectl used for running kubectl commands. type Kubectl struct{} -// StartProxy start a proxy. -func (k Kubectl) StartProxy() error { - cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml up -d authelia-kind-proxy") - return cmd.Run() -} - -// StopProxy stop a proxy. -func (k Kubectl) StopProxy() error { - cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml rm -s -f authelia-kind-proxy") - return cmd.Run() -} - -// StartDashboard start Kube dashboard. -func (k Kubectl) StartDashboard() error { - if err := kindCommand("sh -c 'cd /authelia && ./bootstrap-dashboard.sh'").Run(); err != nil { - return err - } - - err := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml up -d kube-dashboard").Run() - - return err -} - -// StopDashboard stop kube dashboard. -func (k Kubectl) StopDashboard() error { - cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml rm -s -f kube-dashboard") - return cmd.Run() -} - -// DeployThirdparties deploy thirdparty services (ldap, db, ingress controllers, etc...). -func (k Kubectl) DeployThirdparties() error { - cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap.sh'") - return cmd.Run() -} - -// DeployAuthelia deploy Authelia application. -func (k Kubectl) DeployAuthelia() error { - cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap-authelia.sh'") - return cmd.Run() +// GetDashboardToken generates bearer token for Kube Dashboard. +func (k Kubectl) GetDashboardToken() error { + return k3dCommand("kubectl -n kubernetes-dashboard create token admin-user;echo ''").Run() } // WaitPodsReady wait for all pods to be ready. -func (k Kubectl) WaitPodsReady(timeout time.Duration) error { +func (k Kubectl) WaitPodsReady(namespace string, timeout time.Duration) error { return utils.CheckUntil(5*time.Second, timeout, func() (bool, error) { - cmd := kindCommand("kubectl get -n authelia pods --no-headers") + cmd := k3dCommand(fmt.Sprintf("kubectl get -n %s pods --no-headers --field-selector=status.phase!=Succeeded", namespace)) cmd.Stdout = nil cmd.Stderr = nil output, _ := cmd.Output() @@ -129,10 +81,12 @@ func (k Kubectl) WaitPodsReady(timeout time.Duration) error { } for _, line := range nonEmptyLines { - if !strings.Contains(line, "1/1") { + re := regexp.MustCompile(`1/1|2/2`) + if !re.MatchString(line) { return false, nil } } + return true, nil }) } diff --git a/internal/suites/scenario_default_redirection_url_test.go b/internal/suites/scenario_default_redirection_url_test.go index 6dd521309..31fca33d0 100644 --- a/internal/suites/scenario_default_redirection_url_test.go +++ b/internal/suites/scenario_default_redirection_url_test.go @@ -30,6 +30,18 @@ func (s *DefaultRedirectionURLScenario) SetupSuite() { } s.RodSession = browser + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer func() { + cancel() + s.collectScreenshot(ctx.Err(), s.Page) + + s.collectCoverage(s.Page) + s.MustClose() + }() + + s.Page = s.doCreateTab(s.T(), HomeBaseURL) + s.secret = s.doLoginAndRegisterTOTP(s.T(), s.Context(ctx), "john", "password", false) } func (s *DefaultRedirectionURLScenario) TearDownSuite() { @@ -59,9 +71,7 @@ func (s *DefaultRedirectionURLScenario) TestUserIsRedirectedToDefaultURL() { targetURL := fmt.Sprintf("%s/secret.html", AdminBaseURL) - s.doVisit(s.T(), s.Context(ctx), HomeBaseURL) - s.verifyIsHome(s.T(), s.Page) - s.secret = s.doRegisterAndLogin2FA(s.T(), s.Context(ctx), "john", "password", false, targetURL) + s.doLoginTwoFactor(s.T(), s.Context(ctx), "john", "password", false, s.secret, targetURL) s.verifySecretAuthorized(s.T(), s.Context(ctx)) s.doLogout(s.T(), s.Context(ctx)) diff --git a/internal/suites/scenario_inactivity_test.go b/internal/suites/scenario_inactivity_test.go index 778b183cd..5f6a4bdfe 100644 --- a/internal/suites/scenario_inactivity_test.go +++ b/internal/suites/scenario_inactivity_test.go @@ -12,6 +12,7 @@ import ( type InactivityScenario struct { *RodSuite + secret string } diff --git a/internal/suites/scenario_oidc_test.go b/internal/suites/scenario_oidc_test.go index 65b867471..a79d9bf59 100644 --- a/internal/suites/scenario_oidc_test.go +++ b/internal/suites/scenario_oidc_test.go @@ -16,6 +16,7 @@ import ( type OIDCScenario struct { *RodSuite + secret string } diff --git a/internal/suites/scenario_two_factor_test.go b/internal/suites/scenario_two_factor_test.go index 7672aab7e..c22c8549b 100644 --- a/internal/suites/scenario_two_factor_test.go +++ b/internal/suites/scenario_two_factor_test.go @@ -12,6 +12,8 @@ import ( type TwoFactorSuite struct { *RodSuite + + secret string } func New2FAScenario() *TwoFactorSuite { @@ -28,6 +30,18 @@ func (s *TwoFactorSuite) SetupSuite() { } s.RodSession = browser + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer func() { + cancel() + s.collectScreenshot(ctx.Err(), s.Page) + + s.collectCoverage(s.Page) + s.MustClose() + }() + + s.Page = s.doCreateTab(s.T(), HomeBaseURL) + s.secret = s.doLoginAndRegisterTOTP(s.T(), s.Context(ctx), "john", "password", false) } func (s *TwoFactorSuite) TearDownSuite() { @@ -60,7 +74,7 @@ func (s *TwoFactorSuite) TestShouldAuthorizeSecretAfterTwoFactor() { // Login and register TOTP, logout and login again with 1FA & 2FA. targetURL := fmt.Sprintf("%s/secret.html", AdminBaseURL) - _ = s.doRegisterAndLogin2FA(s.T(), s.Context(ctx), username, password, false, targetURL) + s.doLoginTwoFactor(s.T(), s.Context(ctx), username, password, false, s.secret, targetURL) // And check if the user is redirected to the secret. s.verifySecretAuthorized(s.T(), s.Context(ctx)) @@ -81,9 +95,6 @@ func (s *TwoFactorSuite) TestShouldFailTwoFactor() { s.collectScreenshot(ctx.Err(), s.Page) }() - // Register TOTP secret and logout. - s.doRegisterThenLogout(s.T(), s.Context(ctx), testUsername, testPassword) - wrongPasscode := "123456" s.doLoginOneFactor(s.T(), s.Context(ctx), testUsername, testPassword, false, "") diff --git a/internal/suites/suite_cli_test.go b/internal/suites/suite_cli_test.go index 93e65d0a0..95c26d1d2 100644 --- a/internal/suites/suite_cli_test.go +++ b/internal/suites/suite_cli_test.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/stretchr/testify/suite" - yaml "gopkg.in/yaml.v3" + "gopkg.in/yaml.v3" "github.com/authelia/authelia/v4/internal/model" "github.com/authelia/authelia/v4/internal/storage" diff --git a/internal/suites/suite_kubernetes.go b/internal/suites/suite_kubernetes.go index ba99bf3f8..0641ef1d5 100644 --- a/internal/suites/suite_kubernetes.go +++ b/internal/suites/suite_kubernetes.go @@ -1,7 +1,6 @@ package suites import ( - "fmt" "os" "time" @@ -13,94 +12,87 @@ import ( var kubernetesSuiteName = "Kubernetes" func init() { - kind := Kind{} + dockerEnvironment := NewDockerEnvironment([]string{ + "internal/suites/docker-compose.yml", + "internal/suites/example/compose/k3d/docker-compose.yml", + }) + + k3d := K3D{} kubectl := Kubectl{} setup := func(suitePath string) error { - cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml build") - if err := cmd.Run(); err != nil { + if err := dockerEnvironment.Up(); err != nil { return err } - exists, err := kind.ClusterExists() + err := waitUntilK3DIsReady(dockerEnvironment) + if err != nil { + return err + } + exists, err := k3d.ClusterExists() if err != nil { return err } if exists { - log.Debug("Kubernetes cluster already exists") + log.Info("Kubernetes cluster already exists") } else { - err = kind.CreateCluster() - + err = k3d.CreateCluster() if err != nil { return err } } - log.Debug("Building authelia:dist image or use cache if already built...") + log.Info("Building authelia:dist image or use cache if already built...") if os.Getenv("CI") != t { if err := utils.Shell("authelia-scripts docker build").Run(); err != nil { return err } + + if err := utils.Shell("docker save authelia:dist -o internal/suites/example/kube/authelia-image-dev.tar").Run(); err != nil { + return err + } } - log.Debug("Loading images into Kubernetes container...") + log.Info("Loading images into Kubernetes container...") if err := loadDockerImages(); err != nil { return err } - log.Debug("Starting Kubernetes dashboard...") + log.Info("Waiting for cluster to be ready...") - if err := kubectl.StartDashboard(); err != nil { + if err := waitAllPodsAreReady(namespaceKube, 5*time.Minute); err != nil { return err } - log.Debug("Deploying thirdparties...") + log.Info("Waiting for dashboard to be ready...") - if err := kubectl.DeployThirdparties(); err != nil { + err = waitAllPodsAreReady(namespaceDashboard, 2*time.Minute) + + log.Info("Bearer token for UI user:") + + if err := kubectl.GetDashboardToken(); err != nil { return err } - log.Debug("Waiting for services to be ready...") + log.Info("Waiting for services to be ready...") - if err := waitAllPodsAreReady(5 * time.Minute); err != nil { + if err := waitAllPodsAreReady(namespaceAuthelia, 5*time.Minute); err != nil { return err } - log.Debug("Deploying Authelia...") - - if err = kubectl.DeployAuthelia(); err != nil { - return err - } - - log.Debug("Waiting for services to be ready...") - - if err := waitAllPodsAreReady(2 * time.Minute); err != nil { - return err - } - - log.Debug("Starting proxy...") - - err = kubectl.StartProxy() - return err } teardown := func(suitePath string) error { - err := kubectl.StopDashboard() - if err != nil { - log.Errorf("Unable to stop Kubernetes dashboard: %s", err) + if err := k3d.DeleteCluster(); err != nil { + return err } - err = kubectl.StopProxy() - if err != nil { - log.Errorf("Unable to stop Kind proxy: %s", err) - } - - return kind.DeleteCluster() + return dockerEnvironment.Down() } GlobalRegistry.Register(kubernetesSuiteName, Suite{ @@ -109,16 +101,20 @@ func init() { TestTimeout: 2 * time.Minute, TearDown: teardown, TearDownTimeout: 2 * time.Minute, - Description: "This suite has been created to test Authelia in a Kubernetes context and using nginx as the ingress controller.", + Description: "This suite has been created to test Authelia in a Kubernetes context and using Traefik as the ingress controller.", }) } func loadDockerImages() error { - kind := Kind{} - images := []string{"authelia:dist"} + k3d := K3D{} + images := []string{"/authelia/authelia-image-coverage.tar"} + + if os.Getenv("CI") != t { + images = []string{"/authelia/authelia-image-dev.tar"} + } for _, image := range images { - err := kind.LoadImage(image) + err := k3d.LoadImage(image) if err != nil { return err @@ -128,17 +124,16 @@ func loadDockerImages() error { return nil } -func waitAllPodsAreReady(timeout time.Duration) error { +func waitAllPodsAreReady(namespace string, timeout time.Duration) error { kubectl := Kubectl{} - // Wait in case the deployment has just been done and some services do not appear in kubectl logs. - time.Sleep(1 * time.Second) - fmt.Println("Check services are running") - if err := kubectl.WaitPodsReady(timeout); err != nil { + log.Infof("Checking services in %s namespace are running...", namespace) + + if err := kubectl.WaitPodsReady(namespace, timeout); err != nil { return err } - fmt.Println("All pods are ready") + log.Info("All pods are ready") return nil } diff --git a/internal/utils/hashing_test.go b/internal/utils/hashing_test.go index 5a86c83be..cf016820b 100644 --- a/internal/utils/hashing_test.go +++ b/internal/utils/hashing_test.go @@ -30,10 +30,9 @@ func TestShouldHashString(t *testing.T) { } func TestShouldHashPath(t *testing.T) { - dir, err := os.MkdirTemp("", "authelia-hashing") - assert.NoError(t, err) + dir := t.TempDir() - err = os.WriteFile(filepath.Join(dir, "myfile"), []byte("output\n"), 0600) + err := os.WriteFile(filepath.Join(dir, "myfile"), []byte("output\n"), 0600) assert.NoError(t, err) err = os.WriteFile(filepath.Join(dir, "anotherfile"), []byte("another\n"), 0600) diff --git a/web/package.json b/web/package.json index a4f3db8a6..f8bd0ff4d 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "authelia", - "version": "4.37.2", + "version": "4.37.4", "private": true, "pnpm": { "peerDependencyRules": { @@ -25,23 +25,23 @@ "@fortawesome/free-regular-svg-icons": "6.2.1", "@fortawesome/free-solid-svg-icons": "6.2.1", "@fortawesome/react-fontawesome": "0.2.0", - "@mui/icons-material": "5.10.16", - "@mui/material": "5.10.16", - "@mui/styles": "5.10.16", - "axios": "1.2.0", + "@mui/icons-material": "5.11.0", + "@mui/material": "5.11.0", + "@mui/styles": "5.11.0", + "axios": "1.2.1", "broadcast-channel": "4.18.1", "classnames": "2.3.2", - "i18next": "22.0.6", + "i18next": "22.4.5", "i18next-browser-languagedetector": "7.0.1", - "i18next-http-backend": "2.0.2", + "i18next-http-backend": "2.1.0", "qrcode.react": "3.1.0", - "query-string": "7.1.1", + "query-string": "7.1.3", "react": "18.2.0", "react-dom": "18.2.0", - "react-i18next": "12.0.0", + "react-i18next": "12.1.1", "react-loading": "2.0.3", - "react-otp-input": "2.4.0", - "react-router-dom": "6.4.3", + "react-router-dom": "6.5.0", + "react18-input-otp": "1.1.1", "zxcvbn": "4.4.2" }, "scripts": { @@ -148,18 +148,18 @@ "@limegrass/eslint-plugin-import-alias": "1.0.6", "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "13.4.0", - "@types/jest": "29.2.3", - "@types/node": "18.11.9", + "@types/jest": "29.2.4", + "@types/node": "18.11.16", "@types/qrcode.react": "1.0.2", - "@types/react": "18.0.25", + "@types/react": "18.0.26", "@types/react-dom": "18.0.9", "@types/zxcvbn": "4.4.1", - "@typescript-eslint/eslint-plugin": "5.45.0", - "@typescript-eslint/parser": "5.45.0", - "@vitejs/plugin-react": "2.2.0", - "esbuild": "0.15.16", + "@typescript-eslint/eslint-plugin": "5.46.1", + "@typescript-eslint/parser": "5.46.1", + "@vitejs/plugin-react": "3.0.0", + "esbuild": "0.16.7", "esbuild-jest": "0.5.0", - "eslint": "8.28.0", + "eslint": "8.30.0", "eslint-config-prettier": "8.5.0", "eslint-config-react-app": "7.0.1", "eslint-formatter-rdjson": "1.0.5", @@ -174,13 +174,13 @@ "jest-environment-jsdom": "29.3.1", "jest-transform-stub": "2.0.0", "jest-watch-typeahead": "2.2.1", - "prettier": "2.8.0", + "prettier": "2.8.1", "react-test-renderer": "18.2.0", - "typescript": "4.9.3", - "vite": "3.2.4", + "typescript": "4.9.4", + "vite": "4.0.1", "vite-plugin-eslint": "1.8.1", - "vite-plugin-istanbul": "3.0.2", - "vite-plugin-svgr": "2.2.2", - "vite-tsconfig-paths": "3.6.0" + "vite-plugin-istanbul": "3.0.4", + "vite-plugin-svgr": "2.4.0", + "vite-tsconfig-paths": "4.0.3" } } diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 4f98c710d..3a244f936 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -11,26 +11,26 @@ specifiers: '@fortawesome/free-solid-svg-icons': 6.2.1 '@fortawesome/react-fontawesome': 0.2.0 '@limegrass/eslint-plugin-import-alias': 1.0.6 - '@mui/icons-material': 5.10.16 - '@mui/material': 5.10.16 - '@mui/styles': 5.10.16 + '@mui/icons-material': 5.11.0 + '@mui/material': 5.11.0 + '@mui/styles': 5.11.0 '@testing-library/jest-dom': 5.16.5 '@testing-library/react': 13.4.0 - '@types/jest': 29.2.3 - '@types/node': 18.11.9 + '@types/jest': 29.2.4 + '@types/node': 18.11.16 '@types/qrcode.react': 1.0.2 - '@types/react': 18.0.25 + '@types/react': 18.0.26 '@types/react-dom': 18.0.9 '@types/zxcvbn': 4.4.1 - '@typescript-eslint/eslint-plugin': 5.45.0 - '@typescript-eslint/parser': 5.45.0 - '@vitejs/plugin-react': 2.2.0 - axios: 1.2.0 + '@typescript-eslint/eslint-plugin': 5.46.1 + '@typescript-eslint/parser': 5.46.1 + '@vitejs/plugin-react': 3.0.0 + axios: 1.2.1 broadcast-channel: 4.18.1 classnames: 2.3.2 - esbuild: 0.15.16 + esbuild: 0.16.7 esbuild-jest: 0.5.0 - eslint: 8.28.0 + eslint: 8.30.0 eslint-config-prettier: 8.5.0 eslint-config-react-app: 7.0.1 eslint-formatter-rdjson: 1.0.5 @@ -41,98 +41,98 @@ specifiers: eslint-plugin-react: 7.31.11 eslint-plugin-react-hooks: 4.6.0 husky: 8.0.2 - i18next: 22.0.6 + i18next: 22.4.5 i18next-browser-languagedetector: 7.0.1 - i18next-http-backend: 2.0.2 + i18next-http-backend: 2.1.0 jest: 29.3.1 jest-environment-jsdom: 29.3.1 jest-transform-stub: 2.0.0 jest-watch-typeahead: 2.2.1 - prettier: 2.8.0 + prettier: 2.8.1 qrcode.react: 3.1.0 - query-string: 7.1.1 + query-string: 7.1.3 react: 18.2.0 react-dom: 18.2.0 - react-i18next: 12.0.0 + react-i18next: 12.1.1 react-loading: 2.0.3 - react-otp-input: 2.4.0 - react-router-dom: 6.4.3 + react-router-dom: 6.5.0 react-test-renderer: 18.2.0 - typescript: 4.9.3 - vite: 3.2.4 + react18-input-otp: 1.1.1 + typescript: 4.9.4 + vite: 4.0.1 vite-plugin-eslint: 1.8.1 - vite-plugin-istanbul: 3.0.2 - vite-plugin-svgr: 2.2.2 - vite-tsconfig-paths: 3.6.0 + vite-plugin-istanbul: 3.0.4 + vite-plugin-svgr: 2.4.0 + vite-tsconfig-paths: 4.0.3 zxcvbn: 4.4.2 dependencies: '@emotion/cache': 11.10.5 - '@emotion/react': 11.10.5_fan5qbzahqtxlm5dzefqlqx5ia - '@emotion/styled': 11.10.5_otcjdfkheatawhug6fwk7ldzni + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu '@fortawesome/fontawesome-svg-core': 6.2.1 '@fortawesome/free-regular-svg-icons': 6.2.1 '@fortawesome/free-solid-svg-icons': 6.2.1 '@fortawesome/react-fontawesome': 0.2.0_z27bm67dtmuyyvss23ckjdrcuy - '@mui/icons-material': 5.10.16_ge2ne5gh5gcqikeclw577gsblu - '@mui/material': 5.10.16_thp4wrxo45nyllusrnt46mid4u - '@mui/styles': 5.10.16_fan5qbzahqtxlm5dzefqlqx5ia - axios: 1.2.0 + '@mui/icons-material': 5.11.0_2q3lgv2yds5td5xef72rojpyny + '@mui/material': 5.11.0_lskpmcsdi7ipu6qpuapyu56ihm + '@mui/styles': 5.11.0_kzbn2opkn2327fwg5yzwzya5o4 + axios: 1.2.1 broadcast-channel: 4.18.1 classnames: 2.3.2 - i18next: 22.0.6 + i18next: 22.4.5 i18next-browser-languagedetector: 7.0.1 - i18next-http-backend: 2.0.2 + i18next-http-backend: 2.1.0 qrcode.react: 3.1.0_react@18.2.0 - query-string: 7.1.1 + query-string: 7.1.3 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-i18next: 12.0.0_nger6pvrp5hnzeykouhwqmsdti + react-i18next: 12.1.1_ewanii43wbrufvukcu3uzq3hsy react-loading: 2.0.3_react@18.2.0 - react-otp-input: 2.4.0_biqbaboplfbrettd7655fr4n2y - react-router-dom: 6.4.3_biqbaboplfbrettd7655fr4n2y + react-router-dom: 6.5.0_biqbaboplfbrettd7655fr4n2y + react18-input-otp: 1.1.1_biqbaboplfbrettd7655fr4n2y zxcvbn: 4.4.2 devDependencies: '@commitlint/cli': 17.3.0 '@commitlint/config-conventional': 17.3.0 - '@limegrass/eslint-plugin-import-alias': 1.0.6_eslint@8.28.0 + '@limegrass/eslint-plugin-import-alias': 1.0.6_eslint@8.30.0 '@testing-library/jest-dom': 5.16.5 '@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y - '@types/jest': 29.2.3 - '@types/node': 18.11.9 + '@types/jest': 29.2.4 + '@types/node': 18.11.16 '@types/qrcode.react': 1.0.2 - '@types/react': 18.0.25 + '@types/react': 18.0.26 '@types/react-dom': 18.0.9 '@types/zxcvbn': 4.4.1 - '@typescript-eslint/eslint-plugin': 5.45.0_czs5uoqkd3podpy6vgtsxfc7au - '@typescript-eslint/parser': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a - '@vitejs/plugin-react': 2.2.0_vite@3.2.4 - esbuild: 0.15.16 - esbuild-jest: 0.5.0_esbuild@0.15.16 - eslint: 8.28.0 - eslint-config-prettier: 8.5.0_eslint@8.28.0 - eslint-config-react-app: 7.0.1_ffu622cxxp5swe5tqcog7svb5i + '@typescript-eslint/eslint-plugin': 5.46.1_mqzxmroayievgzgel6yrqgih5i + '@typescript-eslint/parser': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa + '@vitejs/plugin-react': 3.0.0_vite@4.0.1 + esbuild: 0.16.7 + esbuild-jest: 0.5.0_esbuild@0.16.7 + eslint: 8.30.0 + eslint-config-prettier: 8.5.0_eslint@8.30.0 + eslint-config-react-app: 7.0.1_5dzg3kvqggpfcaryo776p5cisq eslint-formatter-rdjson: 1.0.5 - eslint-import-resolver-typescript: 3.5.2_ktrec6dplf4now6nlbc6d67jee - eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq - eslint-plugin-jsx-a11y: 6.6.1_eslint@8.28.0 - eslint-plugin-prettier: 4.2.1_cwlo2dingkvfydnaculr42urve - eslint-plugin-react: 7.31.11_eslint@8.28.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.28.0 + eslint-import-resolver-typescript: 3.5.2_2lbwmhbr7bncddqbzzpg77o75m + eslint-plugin-import: 2.26.0_mv4znvkmpvglpuoorytwup6y2i + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.30.0 + eslint-plugin-prettier: 4.2.1_kl4pe43v5b43npmso5hoplpbyi + eslint-plugin-react: 7.31.11_eslint@8.30.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.30.0 husky: 8.0.2 - jest: 29.3.1_@types+node@18.11.9 + jest: 29.3.1_@types+node@18.11.16 jest-environment-jsdom: 29.3.1 jest-transform-stub: 2.0.0 jest-watch-typeahead: 2.2.1_jest@29.3.1 - prettier: 2.8.0 + prettier: 2.8.1 react-test-renderer: 18.2.0_react@18.2.0 - typescript: 4.9.3 - vite: 3.2.4_@types+node@18.11.9 - vite-plugin-eslint: 1.8.1_eslint@8.28.0+vite@3.2.4 - vite-plugin-istanbul: 3.0.2 - vite-plugin-svgr: 2.2.2_vite@3.2.4 - vite-tsconfig-paths: 3.6.0_vite@3.2.4 + typescript: 4.9.4 + vite: 4.0.1_@types+node@18.11.16 + vite-plugin-eslint: 1.8.1_eslint@8.30.0+vite@4.0.1 + vite-plugin-istanbul: 3.0.4 + vite-plugin-svgr: 2.4.0_vite@4.0.1 + vite-tsconfig-paths: 4.0.3_rftvpiefqgupx5rdsozqbqx3tq packages: @@ -154,13 +154,8 @@ packages: dependencies: '@babel/highlight': 7.18.6 - /@babel/compat-data/7.19.0: - resolution: {integrity: sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/compat-data/7.19.4: - resolution: {integrity: sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==} + /@babel/compat-data/7.20.5: + resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} engines: {node: '>=6.9.0'} dev: true @@ -170,14 +165,14 @@ packages: dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.18.12 - '@babel/helper-compilation-targets': 7.18.9_@babel+core@7.18.6 - '@babel/helper-module-transforms': 7.18.9 - '@babel/helpers': 7.18.9 - '@babel/parser': 7.18.11 + '@babel/generator': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.18.6 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helpers': 7.20.6 + '@babel/parser': 7.20.5 '@babel/template': 7.18.10 - '@babel/traverse': 7.18.11 - '@babel/types': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -187,20 +182,20 @@ packages: - supports-color dev: true - /@babel/core/7.19.6: - resolution: {integrity: sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==} + /@babel/core/7.20.5: + resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.19.6 - '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6 - '@babel/helper-module-transforms': 7.19.6 - '@babel/helpers': 7.19.4 - '@babel/parser': 7.19.6 + '@babel/generator': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helpers': 7.20.6 + '@babel/parser': 7.20.5 '@babel/template': 7.18.10 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -210,7 +205,7 @@ packages: - supports-color dev: true - /@babel/eslint-parser/7.18.2_e6dejpcwcc66ssvjscxl7tagl4: + /@babel/eslint-parser/7.18.2_krbl7gjo3afxleq6arh2klsyza: resolution: {integrity: sha512-oFQYkE8SuH14+uR51JVAmdqwKYXGRjEXx7s+WiagVjqQ+HPE+nnwyF2qlVG8evUsUHmPcA+6YXMEDbIhEyQc5A==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -221,26 +216,17 @@ packages: optional: true dependencies: '@babel/core': 7.18.6 - eslint: 8.28.0 + eslint: 8.30.0 eslint-scope: 5.1.1 eslint-visitor-keys: 2.1.0 semver: 6.3.0 dev: true - /@babel/generator/7.18.12: - resolution: {integrity: sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==} + /@babel/generator/7.20.5: + resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 - '@jridgewell/gen-mapping': 0.3.2 - jsesc: 2.5.2 - dev: true - - /@babel/generator/7.19.6: - resolution: {integrity: sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 dev: true @@ -249,7 +235,7 @@ packages: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-builder-binary-assignment-operator-visitor/7.18.6: @@ -257,11 +243,11 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true - /@babel/helper-compilation-targets/7.18.9_@babel+core@7.18.6: - resolution: {integrity: sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==} + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.18.6: + resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -269,30 +255,30 @@ packages: '@babel/core': optional: true dependencies: - '@babel/compat-data': 7.19.0 + '@babel/compat-data': 7.20.5 '@babel/core': 7.18.6 '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.2 - semver: 6.3.0 - dev: true - - /@babel/helper-compilation-targets/7.19.3_@babel+core@7.19.6: - resolution: {integrity: sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/compat-data': 7.19.4 - '@babel/core': 7.19.6 - '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 semver: 6.3.0 dev: true - /@babel/helper-create-class-features-plugin/7.18.6_@babel+core@7.19.6: + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + semver: 6.3.0 + dev: true + + /@babel/helper-create-class-features-plugin/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -301,7 +287,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 @@ -313,7 +299,7 @@ packages: - supports-color dev: true - /@babel/helper-create-regexp-features-plugin/7.18.6_@babel+core@7.19.6: + /@babel/helper-create-regexp-features-plugin/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==} engines: {node: '>=6.9.0'} peerDependencies: @@ -322,12 +308,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 regexpu-core: 5.1.0 dev: true - /@babel/helper-define-polyfill-provider/0.3.1_@babel+core@7.19.6: + /@babel/helper-define-polyfill-provider/0.3.1_@babel+core@7.20.5: resolution: {integrity: sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==} peerDependencies: '@babel/core': ^7.4.0-0 @@ -335,11 +321,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 - '@babel/traverse': 7.19.6 + '@babel/traverse': 7.20.5 debug: 4.3.4 lodash.debounce: 4.0.8 resolve: 1.22.1 @@ -357,7 +343,7 @@ packages: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-function-name/7.19.0: @@ -365,57 +351,41 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-member-expression-to-functions/7.18.6: resolution: {integrity: sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.0 + '@babel/types': 7.20.5 - /@babel/helper-module-transforms/7.18.9: - resolution: {integrity: sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==} + /@babel/helper-module-transforms/7.20.2: + resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.18.6 - '@babel/template': 7.18.10 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-transforms/7.19.6: - resolution: {integrity: sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.19.4 + '@babel/helper-simple-access': 7.20.2 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.18.10 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -424,19 +394,14 @@ packages: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true - /@babel/helper-plugin-utils/7.18.9: - resolution: {integrity: sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==} - engines: {node: '>=6.9.0'} - /@babel/helper-plugin-utils/7.19.0: resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-remap-async-to-generator/7.18.6_@babel+core@7.19.6: + /@babel/helper-remap-async-to-generator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-z5wbmV55TveUPZlCLZvxWHtrjuJd+8inFhk7DG0WW87/oJuGDcjDiu7HIvGcpf5464L6xKCg3vNkmlVVz9hwyQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -445,11 +410,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-wrap-function': 7.18.6 - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -461,53 +426,37 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-member-expression-to-functions': 7.18.6 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-simple-access/7.18.6: - resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} + /@babel/helper-simple-access/7.20.2: + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 - dev: true - - /@babel/helper-simple-access/7.19.4: - resolution: {integrity: sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-skip-transparent-expression-wrappers/7.18.6: resolution: {integrity: sha512-4KoLhwGS9vGethZpAhYnMejWkX64wsnHPDwvOsKWU6Fg4+AlK2Jz3TyjQLMEPvz+1zemi/WBdkYxCD0bAfIkiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 - dev: true - - /@babel/helper-string-parser/7.18.10: - resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} - engines: {node: '>=6.9.0'} + '@babel/types': 7.20.5 dev: true /@babel/helper-string-parser/7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-identifier/7.18.6: - resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} - engines: {node: '>=6.9.0'} - /@babel/helper-validator-identifier/7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} @@ -523,30 +472,19 @@ packages: dependencies: '@babel/helper-function-name': 7.19.0 '@babel/template': 7.18.10 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/helpers/7.18.9: - resolution: {integrity: sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==} + /@babel/helpers/7.20.6: + resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helpers/7.19.4: - resolution: {integrity: sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -555,35 +493,19 @@ packages: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser/7.18.11: - resolution: {integrity: sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==} + /@babel/parser/7.20.5: + resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true - /@babel/parser/7.19.0: - resolution: {integrity: sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.19.4 - dev: true - - /@babel/parser/7.19.6: - resolution: {integrity: sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.19.4 - dev: true - - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.19.6: + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -592,11 +514,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.6_@babel+core@7.19.6: + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Udgu8ZRgrBrttVz6A0EVL0SJ1z+RLbIeqsu632SA1hf0awEppD6TvdznoH+orIF8wtFFAV/Enmw9Y+9oV8TQcw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -605,13 +527,13 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-skip-transparent-expression-wrappers': 7.18.6 - '@babel/plugin-proposal-optional-chaining': 7.18.6_@babel+core@7.19.6 + '@babel/plugin-proposal-optional-chaining': 7.18.6_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-async-generator-functions/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-async-generator-functions/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w==} engines: {node: '>=6.9.0'} peerDependencies: @@ -620,16 +542,16 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-remap-async-to-generator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.6 + '@babel/helper-remap-async-to-generator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -638,14 +560,14 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -654,15 +576,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.19.6 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-decorators/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-decorators/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-gAdhsjaYmiZVxx5vTMiRfj31nB7LhwBJFMSLzeDxc7X4tKLixup0+k9ughn0RcpBrv9E3PBaXJW7jF5TCihAOg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -671,17 +593,17 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-replace-supers': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/plugin-syntax-decorators': 7.18.6_@babel+core@7.19.6 + '@babel/plugin-syntax-decorators': 7.18.6_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -690,12 +612,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-export-namespace-from/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-export-namespace-from/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-zr/QcUlUo7GPo6+X1wC98NJADqmy5QTFWWhqeQWiki4XHafJtLl/YMGkmRB2szDD2IYJCCdBTd4ElwhId9T7Xw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -704,12 +626,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.19.6 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -718,12 +640,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.6 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-logical-assignment-operators/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-logical-assignment-operators/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-zMo66azZth/0tVd7gmkxOkOjs2rpHyhpcFo565PUP37hSp6hSd9uUKIfTDFMz58BwqgQKhJ9YxtM5XddjXVn+Q==} engines: {node: '>=6.9.0'} peerDependencies: @@ -732,12 +654,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.19.6 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -746,12 +668,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.19.6 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} peerDependencies: @@ -760,12 +682,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.6 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-object-rest-spread/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-object-rest-spread/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-9yuM6wr4rIsKa1wlUAbZEazkCrgw2sMPEXCr4Rnwetu7cEW1NydkCWytLuYletbf8vFxdJxFhwEZqMpOx2eZyw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -774,15 +696,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/compat-data': 7.19.4 - '@babel/core': 7.19.6 - '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6 + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.19.6 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -791,12 +713,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.6 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-optional-chaining/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-optional-chaining/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-PatI6elL5eMzoypFAiYDpYQyMtXTn+iMhuxxQt5mAXD4fEmKorpSI3PHd+i3JXBJN3xyA6MvJv7at23HffFHwA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -805,13 +727,13 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-skip-transparent-expression-wrappers': 7.18.6 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.6 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 dev: true - /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -820,14 +742,14 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -836,16 +758,16 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.19.6 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.19.6: + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} engines: {node: '>=4'} peerDependencies: @@ -854,8 +776,8 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -871,7 +793,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.19.6: + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.5: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -879,7 +801,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -895,7 +817,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -903,7 +825,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -919,7 +841,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.19.6: + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.5: resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -927,11 +849,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.19.6: + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -940,11 +862,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-decorators/7.18.6_@babel+core@7.19.6: + /@babel/plugin-syntax-decorators/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-fqyLgjcxf/1yhyZ6A+yo1u9gJ7eleFQod2lkaUsF9DQ7sbbY3Ligym3L0+I2c0WmqNKDpoD9UTb1AKP3qRMOAQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -953,11 +875,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -965,11 +887,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -977,11 +899,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-flow/7.18.6_@babel+core@7.19.6: + /@babel/plugin-syntax-flow/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} engines: {node: '>=6.9.0'} peerDependencies: @@ -990,11 +912,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-import-assertions/7.18.6_@babel+core@7.19.6: + /@babel/plugin-syntax-import-assertions/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1003,7 +925,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1019,7 +941,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.19.6: + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.20.5: resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1027,7 +949,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1043,7 +965,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1051,7 +973,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1064,10 +986,10 @@ packages: '@babel/core': optional: true dependencies: - '@babel/helper-plugin-utils': 7.18.9 + '@babel/helper-plugin-utils': 7.19.0 dev: false - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.6: + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1076,8 +998,8 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.18.9 + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 dev: true /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.18.6: @@ -1092,7 +1014,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.19.6: + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.5: resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1100,7 +1022,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1116,7 +1038,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1124,7 +1046,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1140,7 +1062,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.19.6: + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.5: resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1148,7 +1070,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1164,7 +1086,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1172,7 +1094,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1188,7 +1110,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1196,7 +1118,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1212,7 +1134,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.19.6: + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.5: resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1220,11 +1142,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.19.6: + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1233,7 +1155,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true @@ -1250,7 +1172,7 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.19.6: + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1259,11 +1181,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.19.6: + /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1272,11 +1194,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1285,11 +1207,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1298,15 +1220,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-remap-async-to-generator': 7.18.6_@babel+core@7.19.6 + '@babel/helper-remap-async-to-generator': 7.18.6_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1315,11 +1237,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-block-scoping/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-block-scoping/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-pRqwb91C42vs1ahSAWJkxOxU1RHWDn16XAa6ggQ72wjLlWyYeAcLvTtE0aM8ph3KNydy9CQF2nLYcjq1WysgxQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1328,11 +1250,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-classes/7.18.8_@babel+core@7.19.6: + /@babel/plugin-transform-classes/7.18.8_@babel+core@7.20.5: resolution: {integrity: sha512-RySDoXdF6hgHSHuAW4aLGyVQdmvEX/iJtjVre52k0pxRq4hzqze+rAVP++NmNv596brBpYmaiKgTZby7ziBnVg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1341,7 +1263,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 @@ -1354,7 +1276,7 @@ packages: - supports-color dev: true - /@babel/plugin-transform-computed-properties/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-computed-properties/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-9repI4BhNrR0KenoR9vm3/cIc1tSBIo+u1WVjKCAynahj25O8zfbiE6JtAtHPGQSs4yZ+bA8mRasRP+qc+2R5A==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1363,11 +1285,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-destructuring/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-destructuring/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-tgy3u6lRp17ilY8r1kP4i2+HDUwxlVqq3RTc943eAWSzGgpU1qhiKpqZ5CMyHReIYPHdo3Kg8v8edKtDqSVEyQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1376,11 +1298,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1389,12 +1311,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-duplicate-keys/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-duplicate-keys/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-NJU26U/208+sxYszf82nmGYqVF9QN8py2HFTblPT9hbawi8+1C5a9JubODLTGFuT0qlkqVinmkwOD13s0sZktg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1403,11 +1325,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1416,12 +1338,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-flow-strip-types/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-flow-strip-types/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-wE0xtA7csz+hw4fKPwxmu5jnzAsXPIO57XnRwzXP3T19jWh1BODnPGoG9xKYwvAwusP7iUktHayRFbMPGtODaQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1430,12 +1352,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-flow': 7.18.6_@babel+core@7.19.6 + '@babel/plugin-syntax-flow': 7.18.6_@babel+core@7.20.5 dev: true - /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.19.6: + /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.5: resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1444,11 +1366,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-function-name/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-function-name/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-kJha/Gbs5RjzIu0CxZwf5e3aTTSlhZnHMT8zPWnJMjNpLOUgqevg+PN5oMH68nMCXnfiMo4Bhgxqj59KHTlAnA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1457,13 +1379,13 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-function-name': 7.19.0 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-literals/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-literals/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-x3HEw0cJZVDoENXOp20HlypIHfl0zMIhMVZEBVTfmqbObIpsMxMbmU5nOEO8R7LYT+z5RORKPlTI5Hj4OsO9/Q==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1472,11 +1394,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1485,11 +1407,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-modules-amd/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-modules-amd/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1498,8 +1420,8 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-module-transforms': 7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.19.0 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: @@ -1516,15 +1438,15 @@ packages: optional: true dependencies: '@babel/core': 7.18.6 - '@babel/helper-module-transforms': 7.18.9 - '@babel/helper-plugin-utils': 7.18.9 - '@babel/helper-simple-access': 7.18.6 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-simple-access': 7.20.2 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-commonjs/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-modules-commonjs/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1533,16 +1455,16 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-module-transforms': 7.18.9 - '@babel/helper-plugin-utils': 7.18.9 - '@babel/helper-simple-access': 7.18.6 + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-simple-access': 7.20.2 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-systemjs/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-modules-systemjs/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-UbPYpXxLjTw6w6yXX2BYNxF3p6QY225wcTkfQCy3OMnSlS/C3xGtwUjEzGkldb/sy6PWLiCQ3NbYfjWUTI3t4g==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1551,9 +1473,9 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-module-transforms': 7.19.6 + '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-validator-identifier': 7.19.1 babel-plugin-dynamic-import-node: 2.3.3 @@ -1561,7 +1483,7 @@ packages: - supports-color dev: true - /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1570,14 +1492,14 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-module-transforms': 7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.19.0 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-named-capturing-groups-regex/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-named-capturing-groups-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1586,12 +1508,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1600,11 +1522,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1613,14 +1535,14 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-replace-supers': 7.18.6 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-parameters/7.18.8_@babel+core@7.19.6: + /@babel/plugin-transform-parameters/7.18.8_@babel+core@7.20.5: resolution: {integrity: sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1629,11 +1551,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1642,11 +1564,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1655,11 +1577,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1668,11 +1590,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 dev: true - /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1681,11 +1603,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.18.9 + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.19.6: + /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.5: resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1694,11 +1616,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.6: + /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.5: resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1707,15 +1629,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.6 - '@babel/types': 7.19.4 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 dev: true - /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1724,12 +1646,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1738,12 +1660,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 regenerator-transform: 0.15.0 dev: true - /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1752,11 +1674,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-runtime/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-runtime/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-8uRHk9ZmRSnWqUgyae249EJZ94b0yAGLBIqzZzl+0iEdbno55Pmlt/32JZsHwXD9k/uZj18Aqqk35wBX4CBTXA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1765,18 +1687,18 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 - babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.19.6 - babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.19.6 - babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.19.6 + babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.20.5 + babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.20.5 + babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.20.5 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1785,11 +1707,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-spread/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-spread/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-ayT53rT/ENF8WWexIRg9AiV9h0aIteyWn5ptfZTZQrjk/+f3WdrJGCY4c9wcgl2+MKkKPhzbYp97FTsquZpDCw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1798,12 +1720,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-skip-transparent-expression-wrappers': 7.18.6 dev: true - /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1812,11 +1734,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-template-literals/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-template-literals/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-UuqlRrQmT2SWRvahW46cGSany0uTlcj8NYOS5sRGYi8FxPYPoLd5DDmMd32ZXEj2Jq+06uGVQKHxa/hJx2EzKw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1825,11 +1747,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-typeof-symbol/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-typeof-symbol/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-7m71iS/QhsPk85xSjFPovHPcH3H9qeyzsujhTc+vcdnsXavoWYJ74zx0lP5RhpC5+iDnVLO+PPMHzC11qels1g==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1838,11 +1760,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-typescript/7.18.8_@babel+core@7.19.6: + /@babel/plugin-transform-typescript/7.18.8_@babel+core@7.20.5: resolution: {integrity: sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1851,15 +1773,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.19.6 + '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-unicode-escapes/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-unicode-escapes/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1868,11 +1790,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.19.6: + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1881,12 +1803,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.18.6_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/preset-env/7.18.6_@babel+core@7.19.6: + /@babel/preset-env/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-WrthhuIIYKrEFAwttYzgRNQ5hULGmwTj+D6l7Zdfsv5M7IWV/OZbUfbeL++Qrzx1nVJwWROIFhCHRYQV4xbPNw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -1895,87 +1817,87 @@ packages: '@babel/core': optional: true dependencies: - '@babel/compat-data': 7.19.4 - '@babel/core': 7.19.6 - '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6 + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-async-generator-functions': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-export-namespace-from': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-logical-assignment-operators': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-object-rest-spread': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-optional-chaining': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.6 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.19.6 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.19.6 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-import-assertions': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.19.6 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.6 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.19.6 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.19.6 - '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-block-scoping': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-classes': 7.18.8_@babel+core@7.19.6 - '@babel/plugin-transform-computed-properties': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-destructuring': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-duplicate-keys': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.19.6 - '@babel/plugin-transform-function-name': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-literals': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-modules-amd': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-modules-commonjs': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-modules-systemjs': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-named-capturing-groups-regex': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.19.6 - '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-spread': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-template-literals': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-typeof-symbol': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-unicode-escapes': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.19.6 - '@babel/preset-modules': 0.1.5_@babel+core@7.19.6 - '@babel/types': 7.19.4 - babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.19.6 - babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.19.6 - babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.19.6 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-async-generator-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-export-namespace-from': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-logical-assignment-operators': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-object-rest-spread': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-chaining': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.5 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-import-assertions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoping': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-classes': 7.18.8_@babel+core@7.20.5 + '@babel/plugin-transform-computed-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-destructuring': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-duplicate-keys': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.5 + '@babel/plugin-transform-function-name': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-amd': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-commonjs': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-systemjs': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-named-capturing-groups-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.20.5 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-spread': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-template-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-typeof-symbol': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-escapes': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.5 + '@babel/preset-modules': 0.1.5_@babel+core@7.20.5 + '@babel/types': 7.20.5 + babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.20.5 + babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.20.5 + babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.20.5 core-js-compat: 3.23.4 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules/0.1.5_@babel+core@7.19.6: + /@babel/preset-modules/0.1.5_@babel+core@7.20.5: resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1983,15 +1905,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.19.6 - '@babel/types': 7.19.4 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 esutils: 2.0.3 dev: true - /@babel/preset-react/7.18.6_@babel+core@7.19.6: + /@babel/preset-react/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -2000,16 +1922,16 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.19.6 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.20.5 dev: true - /@babel/preset-typescript/7.18.6_@babel+core@7.19.6: + /@babel/preset-typescript/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==} engines: {node: '>=6.9.0'} peerDependencies: @@ -2018,10 +1940,10 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-typescript': 7.18.8_@babel+core@7.19.6 + '@babel/plugin-transform-typescript': 7.18.8_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -2031,106 +1953,64 @@ packages: engines: {node: '>=6.9.0'} dependencies: core-js-pure: 3.23.4 - regenerator-runtime: 0.13.10 + regenerator-runtime: 0.13.11 dev: true /@babel/runtime/7.18.9: resolution: {integrity: sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==} engines: {node: '>=6.9.0'} dependencies: - regenerator-runtime: 0.13.10 + regenerator-runtime: 0.13.11 dev: true - /@babel/runtime/7.19.0: - resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.9 - /@babel/runtime/7.19.4: resolution: {integrity: sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==} engines: {node: '>=6.9.0'} dependencies: - regenerator-runtime: 0.13.9 + regenerator-runtime: 0.13.11 dev: false - /@babel/runtime/7.20.1: - resolution: {integrity: sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==} + /@babel/runtime/7.20.6: + resolution: {integrity: sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==} engines: {node: '>=6.9.0'} dependencies: - regenerator-runtime: 0.13.10 + regenerator-runtime: 0.13.11 /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.19.0 - '@babel/types': 7.19.4 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 dev: true - /@babel/traverse/7.18.11: - resolution: {integrity: sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==} + /@babel/traverse/7.20.5: + resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.19.6 + '@babel/generator': 7.20.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.19.0 - '@babel/types': 7.19.4 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/traverse/7.19.6: - resolution: {integrity: sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.19.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.19.6 - '@babel/types': 7.19.4 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types/7.18.10: - resolution: {integrity: sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.18.10 - '@babel/helper-validator-identifier': 7.18.6 - to-fast-properties: 2.0.0 - dev: true - - /@babel/types/7.19.0: - resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==} + /@babel/types/7.20.5: + resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 - /@babel/types/7.19.4: - resolution: {integrity: sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -2233,13 +2113,13 @@ packages: '@types/node': 14.18.26 chalk: 4.1.2 cosmiconfig: 7.0.1 - cosmiconfig-typescript-loader: 4.0.0_cs4q7g5uavsvvdjjkl2t6wi57a + cosmiconfig-typescript-loader: 4.0.0_64g3pvarf3oduwh7nnbyl3yqm4 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.0_omfyfib2yqj7pu7wtuw6wjyhwa - typescript: 4.9.3 + ts-node: 10.9.0_hylbnkdpdgf7fwrtnxxops6eba + typescript: 4.9.4 transitivePeerDependencies: - '@swc/core' - '@swc/wasm' @@ -2319,10 +2199,6 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true - /@cush/relative/1.0.0: - resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} - dev: true - /@emotion/babel-plugin/11.10.5: resolution: {integrity: sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==} peerDependencies: @@ -2333,7 +2209,7 @@ packages: dependencies: '@babel/helper-module-imports': 7.18.6 '@babel/plugin-syntax-jsx': 7.18.6 - '@babel/runtime': 7.19.4 + '@babel/runtime': 7.20.6 '@emotion/hash': 0.9.0 '@emotion/memoize': 0.8.0 '@emotion/serialize': 1.1.1 @@ -2369,7 +2245,7 @@ packages: resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==} dev: false - /@emotion/react/11.10.5_fan5qbzahqtxlm5dzefqlqx5ia: + /@emotion/react/11.10.5_kzbn2opkn2327fwg5yzwzya5o4: resolution: {integrity: sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==} peerDependencies: '@babel/core': ^7.0.0 @@ -2388,7 +2264,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 '@emotion/utils': 1.2.0 '@emotion/weak-memoize': 0.3.0 - '@types/react': 18.0.25 + '@types/react': 18.0.26 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -2407,7 +2283,7 @@ packages: resolution: {integrity: sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==} dev: false - /@emotion/styled/11.10.5_otcjdfkheatawhug6fwk7ldzni: + /@emotion/styled/11.10.5_qvatmowesywn4ye42qoh247szu: resolution: {integrity: sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==} peerDependencies: '@babel/core': ^7.0.0 @@ -2423,11 +2299,11 @@ packages: '@babel/runtime': 7.19.4 '@emotion/babel-plugin': 11.10.5 '@emotion/is-prop-valid': 1.2.0 - '@emotion/react': 11.10.5_fan5qbzahqtxlm5dzefqlqx5ia + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 '@emotion/serialize': 1.1.1 '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 '@emotion/utils': 1.2.0 - '@types/react': 18.0.25 + '@types/react': 18.0.26 react: 18.2.0 dev: false @@ -2451,8 +2327,8 @@ packages: resolution: {integrity: sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==} dev: false - /@esbuild/android-arm/0.15.16: - resolution: {integrity: sha512-nyB6CH++2mSgx3GbnrJsZSxzne5K0HMyNIWafDHqYy7IwxFc4fd/CgHVZXr8Eh+Q3KbIAcAe3vGyqIPhGblvMQ==} + /@esbuild/android-arm/0.16.7: + resolution: {integrity: sha512-yhzDbiVcmq6T1/XEvdcJIVcXHdLjDJ5cQ0Dp9R9p9ERMBTeO1dR5tc8YYv8zwDeBw1xZm+Eo3MRo8cwclhBS0g==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -2460,8 +2336,89 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.15.16: - resolution: {integrity: sha512-SDLfP1uoB0HZ14CdVYgagllgrG7Mdxhkt4jDJOKl/MldKrkQ6vDJMZKl2+5XsEY/Lzz37fjgLQoJBGuAw/x8kQ==} + /@esbuild/android-arm64/0.16.7: + resolution: {integrity: sha512-tYFw0lBJSEvLoGzzYh1kXuzoX1iPkbOk3O29VqzQb0HbOy7t/yw1hGkvwoJhXHwzQUPsShyYcTgRf6bDBcfnTw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.7: + resolution: {integrity: sha512-3P2OuTxwAtM3k/yEWTNUJRjMPG1ce8rXs51GTtvEC5z1j8fC1plHeVVczdeHECU7aM2/Buc0MwZ6ciM/zysnWg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.7: + resolution: {integrity: sha512-VUb9GK23z8jkosHU9yJNUgQpsfJn+7ZyBm6adi2Ec5/U241eR1tAn82QicnUzaFDaffeixiHwikjmnec/YXEZg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.7: + resolution: {integrity: sha512-duterlv3tit3HI9vhzMWnSVaB1B6YsXpFq1Ntd6Fou82BB1l4tucYy3FI9dHv3tvtDuS0NiGf/k6XsdBqPZ01w==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.7: + resolution: {integrity: sha512-9kkycpBFes/vhi7B7o0cf+q2WdJi+EpVzpVTqtWFNiutARWDFFLcB93J8PR1cG228sucsl3B+7Ts27izE6qiaQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.7: + resolution: {integrity: sha512-5Ahf6jzWXJ4J2uh9dpy5DKOO+PeRUE/9DMys6VuYfwgQzd6n5+pVFm58L2Z2gRe611RX6SdydnNaiIKM3svY7g==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.7: + resolution: {integrity: sha512-QqJnyCfu5OF78Olt7JJSZ7OSv/B4Hf+ZJWp4kkq9xwMsgu7yWq3crIic8gGOpDYTqVKKMDAVDgRXy5Wd/nWZyQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.7: + resolution: {integrity: sha512-2wv0xYDskk2+MzIm/AEprDip39a23Chptc4mL7hsHg26P0gD8RUhzmDu0KCH2vMThUI1sChXXoK9uH0KYQKaDg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.7: + resolution: {integrity: sha512-APVYbEilKbD5ptmKdnIcXej2/+GdV65TfTjxR2Uk8t1EsOk49t6HapZW6DS/Bwlvh5hDwtLapdSumIVNGxgqLg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.16.7: + resolution: {integrity: sha512-5wPUAGclplQrAW7EFr3F84Y/d++7G0KykohaF4p54+iNWhUnMVU8Bh2sxiEOXUy4zKIdpHByMgJ5/Ko6QhtTUw==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -2469,14 +2426,113 @@ packages: dev: true optional: true - /@eslint/eslintrc/1.3.3: - resolution: {integrity: sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==} + /@esbuild/linux-mips64el/0.16.7: + resolution: {integrity: sha512-hxzlXtWF6yWfkE/SMTscNiVqLOAn7fOuIF3q/kiZaXxftz1DhZW/HpnTmTTWrzrS7zJWQxHHT4QSxyAj33COmA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.7: + resolution: {integrity: sha512-WM83Dac0LdXty5xPhlOuCD5Egfk1xLND/oRLYeB7Jb/tY4kzFSDgLlq91wYbHua/s03tQGA9iXvyjgymMw62Vw==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.7: + resolution: {integrity: sha512-3nkNnNg4Ax6MS/l8O8Ynq2lGEVJYyJ2EoY3PHjNJ4PuZ80EYLMrFTFZ4L/Hc16AxgtXKwmNP9TM0YKNiBzBiJQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.7: + resolution: {integrity: sha512-3SA/2VJuv0o1uD7zuqxEP+RrAyRxnkGddq0bwHQ98v1KNlzXD/JvxwTO3T6GM5RH6JUd29RTVQTOJfyzMkkppA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.7: + resolution: {integrity: sha512-xi/tbqCqvPIzU+zJVyrpz12xqciTAPMi2fXEWGnapZymoGhuL2GIWIRXg4O2v5BXaYA5TSaiKYE14L0QhUTuQg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.7: + resolution: {integrity: sha512-NUsYbq3B+JdNKn8SXkItFvdes9qTwEoS3aLALtiWciW/ystiCKM20Fgv9XQBOXfhUHyh5CLEeZDXzLOrwBXuCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.7: + resolution: {integrity: sha512-qjwzsgeve9I8Tbsko2FEkdSk2iiezuNGFgipQxY/736NePXDaDZRodIejYGWOlbYXugdxb0nif5yvypH6lKBmA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.7: + resolution: {integrity: sha512-mFWDz4RoBTzPphTCkM7Kc7Qpa0o/Z01acajR+Ai7LdfKgcP/C6jYOaKwv7nKzD0+MjOT20j7You9g4ozYy1dKQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.7: + resolution: {integrity: sha512-m39UmX19RvEIuC8sYZ0M+eQtdXw4IePDSZ78ZQmYyFaXY9krq4YzQCK2XWIJomNLtg4q+W5aXr8bW3AbqWNoVg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.7: + resolution: {integrity: sha512-1cbzSEZA1fANwmT6rjJ4G1qQXHxCxGIcNYFYR9ctI82/prT38lnwSRZ0i5p/MVXksw9eMlHlet6pGu2/qkXFCg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.7: + resolution: {integrity: sha512-QaQ8IH0JLacfGf5cf0HCCPnQuCTd/dAI257vXBgb/cccKGbH/6pVtI1gwhdAQ0Y48QSpTIFrh9etVyNdZY+zzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint/eslintrc/1.4.0: + resolution: {integrity: sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 espree: 9.4.0 - globals: 13.16.0 + globals: 13.19.0 ignore: 5.2.0 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -2527,8 +2583,8 @@ packages: react: 18.2.0 dev: false - /@humanwhocodes/config-array/0.11.6: - resolution: {integrity: sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==} + /@humanwhocodes/config-array/0.11.8: + resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 @@ -2568,7 +2624,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 jest-message-util: 29.3.1 jest-util: 29.3.1 @@ -2589,14 +2645,14 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.3.2 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.2.0 - jest-config: 29.3.1_@types+node@18.11.9 + jest-config: 29.3.1_@types+node@18.11.16 jest-haste-map: 29.3.1 jest-message-util: 29.3.1 jest-regex-util: 29.2.0 @@ -2623,7 +2679,7 @@ packages: dependencies: '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 jest-mock: 29.3.1 dev: true @@ -2650,7 +2706,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.11.9 + '@types/node': 18.11.16 jest-message-util: 29.3.1 jest-mock: 29.3.1 jest-util: 29.3.1 @@ -2683,7 +2739,7 @@ packages: '@jest/transform': 29.3.1 '@jest/types': 29.3.1 '@jridgewell/trace-mapping': 0.3.15 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -2745,7 +2801,7 @@ packages: resolution: {integrity: sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==} engines: {node: '>= 10.14.2'} dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@jest/types': 26.6.2 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -2768,7 +2824,7 @@ packages: resolution: {integrity: sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@jest/types': 29.3.1 '@jridgewell/trace-mapping': 0.3.15 babel-plugin-istanbul: 6.1.1 @@ -2793,7 +2849,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 '@types/yargs': 15.0.14 chalk: 4.1.2 dev: true @@ -2805,7 +2861,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -2855,12 +2911,12 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@limegrass/eslint-plugin-import-alias/1.0.6_eslint@8.28.0: + /@limegrass/eslint-plugin-import-alias/1.0.6_eslint@8.30.0: resolution: {integrity: sha512-BtPmdHbL4NmkVh2wMnOboyOCrdLOpBqwwtBIsB0/giTiALw/UTHD9TyH4vVnbDOuWPZQgE6kKloJ9G77FApt7w==} peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 dependencies: - eslint: 8.28.0 + eslint: 8.30.0 find-up: 5.0.0 fs-extra: 10.1.0 micromatch: 4.0.5 @@ -2868,8 +2924,8 @@ packages: tsconfig-paths: 3.14.1 dev: true - /@mui/base/5.0.0-alpha.108_2zx2umvpluuhvlq44va5bta2da: - resolution: {integrity: sha512-KjzRUts2i/ODlMfywhFTqTzQl+Cr9nlDSZxJcnYjrbOV/iRyQNBTDoiFJt+XEdRi0fZBHnk74AFbnP56ehybsA==} + /@mui/base/5.0.0-alpha.110_ib3m5ricvtkl2cll7qpr2f6lvq: + resolution: {integrity: sha512-q4TH9T3sTBknTXXTEf2zO8F3nbHg5iGgiaRx9XErTbXvHrmLrQXbQ4hmrLERocSTBFCFWkKyne/qZj0diWlPtA==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || 18 @@ -2879,12 +2935,12 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 '@emotion/is-prop-valid': 1.2.0 - '@mui/types': 7.2.2_@types+react@18.0.25 - '@mui/utils': 5.10.16_react@18.2.0 + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.0_react@18.2.0 '@popperjs/core': 2.11.6 - '@types/react': 18.0.25 + '@types/react': 18.0.26 clsx: 1.2.1 prop-types: 15.8.1 react: 18.2.0 @@ -2892,12 +2948,12 @@ packages: react-is: 18.2.0 dev: false - /@mui/core-downloads-tracker/5.10.16: - resolution: {integrity: sha512-eK9+olw2ZbXX+vGrtKnN01/vLP1aX0Lq0xok35bqWM1aB93Dcmky/xPNf8h31oJ/C+IzJBjZaZMEDzVZg4Qc0A==} + /@mui/core-downloads-tracker/5.11.0: + resolution: {integrity: sha512-Bmogung451ezVv2YI1RvweOIVsTj2RQ4Fk61+e/+8LFPLTFEwVGbL0YhNy1VB5tri8pzGNV228kxtWVTFooQkg==} dev: false - /@mui/icons-material/5.10.16_ge2ne5gh5gcqikeclw577gsblu: - resolution: {integrity: sha512-jjCc0IF6iyLiucQCu5igg3fOscSqbbvRCmyRxXgzOcLR56B0sg2L8o+ZfJ0dAg59+wvgtXaxvjze/mJg0B4iWA==} + /@mui/icons-material/5.11.0_2q3lgv2yds5td5xef72rojpyny: + resolution: {integrity: sha512-I2LaOKqO8a0xcLGtIozC9xoXjZAto5G5gh0FYUMAlbsIHNHIjn4Xrw9rvjY20vZonyiGrZNMAlAXYkY6JvhF6A==} engines: {node: '>=12.0.0'} peerDependencies: '@mui/material': ^5.0.0 @@ -2907,14 +2963,14 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.1 - '@mui/material': 5.10.16_thp4wrxo45nyllusrnt46mid4u - '@types/react': 18.0.25 + '@babel/runtime': 7.20.6 + '@mui/material': 5.11.0_lskpmcsdi7ipu6qpuapyu56ihm + '@types/react': 18.0.26 react: 18.2.0 dev: false - /@mui/material/5.10.16_thp4wrxo45nyllusrnt46mid4u: - resolution: {integrity: sha512-JSHcDQQ+k30NKkCM/0KX6jq4F5LOrbFKZpS+cEl7scZWOCJpUPH5ccAT5a7O8wzrgNZ8Y9PnwzNvWBrfShpJFw==} + /@mui/material/5.11.0_lskpmcsdi7ipu6qpuapyu56ihm: + resolution: {integrity: sha512-8Zl34lb89rLKTTi50Kakki675/LLHMKKnkp8Ee3rAZ2qmisQlRODsGh1MBjENKp0vwhQnNSvlsCfJteVTfotPQ==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -2930,15 +2986,15 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.1 - '@emotion/react': 11.10.5_fan5qbzahqtxlm5dzefqlqx5ia - '@emotion/styled': 11.10.5_otcjdfkheatawhug6fwk7ldzni - '@mui/base': 5.0.0-alpha.108_2zx2umvpluuhvlq44va5bta2da - '@mui/core-downloads-tracker': 5.10.16 - '@mui/system': 5.10.16_v64nlmo6pkqfmpmxge6otzlg54 - '@mui/types': 7.2.2_@types+react@18.0.25 - '@mui/utils': 5.10.16_react@18.2.0 - '@types/react': 18.0.25 + '@babel/runtime': 7.20.6 + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu + '@mui/base': 5.0.0-alpha.110_ib3m5ricvtkl2cll7qpr2f6lvq + '@mui/core-downloads-tracker': 5.11.0 + '@mui/system': 5.11.0_ogriz7mfahdh34qnfautfro5yu + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.0_react@18.2.0 + '@types/react': 18.0.26 '@types/react-transition-group': 4.4.5 clsx: 1.2.1 csstype: 3.1.1 @@ -2949,8 +3005,8 @@ packages: react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y dev: false - /@mui/private-theming/5.10.16_fan5qbzahqtxlm5dzefqlqx5ia: - resolution: {integrity: sha512-0MArkJaOHRCKqL/GWjngGZmyOeRz+uxffhx82bKcewr8swqV7xx7EFP02pk0L/gLdfcvYdqwH4YTVjG/+TaKrg==} + /@mui/private-theming/5.11.0_kzbn2opkn2327fwg5yzwzya5o4: + resolution: {integrity: sha512-UFQLb9x5Sj4pg2GhhCGw3Ls/y1Hw/tz9RsBrULvUF0Vgps1z19o7XTq2xqUvp7pN7fJTW7eVIT2gwVg2xlk8PQ==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || 18 @@ -2959,15 +3015,15 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.1 - '@mui/utils': 5.10.16_react@18.2.0 - '@types/react': 18.0.25 + '@babel/runtime': 7.20.6 + '@mui/utils': 5.11.0_react@18.2.0 + '@types/react': 18.0.26 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styled-engine/5.10.16_dovxhg2tvkkxkdnqyoum6wzcxm: - resolution: {integrity: sha512-ZMSjXvtiGwGDKqrSlXhpxK2voUaF2/lpC/pSTfFmZvKH9j9a9h1/iwo3ybgjFVYGgbfNeW4h0xEchiRohu9xsw==} + /@mui/styled-engine/5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm: + resolution: {integrity: sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -2979,17 +3035,17 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 '@emotion/cache': 11.10.5 - '@emotion/react': 11.10.5_fan5qbzahqtxlm5dzefqlqx5ia - '@emotion/styled': 11.10.5_otcjdfkheatawhug6fwk7ldzni + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu csstype: 3.1.1 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styles/5.10.16_fan5qbzahqtxlm5dzefqlqx5ia: - resolution: {integrity: sha512-GYxY9pAx/mIAF3l9QJhTfWyUdT18UyjXHRmfPFgDupphTyHumrVE4rgYoTFordmzMWr+1kaS0mAUvDfziGncGA==} + /@mui/styles/5.11.0_kzbn2opkn2327fwg5yzwzya5o4: + resolution: {integrity: sha512-Y4Qz/uoWz9NUC7AN+Ybzv8LF3RjlKs85yayLsdXJz0kZxqIJshOMZ4G1Hb5omNwVx9oCePmO9a+zemXZS76ATw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || 18 @@ -2998,12 +3054,12 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 '@emotion/hash': 0.9.0 - '@mui/private-theming': 5.10.16_fan5qbzahqtxlm5dzefqlqx5ia - '@mui/types': 7.2.2_@types+react@18.0.25 - '@mui/utils': 5.10.16_react@18.2.0 - '@types/react': 18.0.25 + '@mui/private-theming': 5.11.0_kzbn2opkn2327fwg5yzwzya5o4 + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.0_react@18.2.0 + '@types/react': 18.0.26 clsx: 1.2.1 csstype: 3.1.1 hoist-non-react-statics: 3.3.2 @@ -3019,8 +3075,8 @@ packages: react: 18.2.0 dev: false - /@mui/system/5.10.16_v64nlmo6pkqfmpmxge6otzlg54: - resolution: {integrity: sha512-OqI9B1jZ9zQ/dmoqseku4CzdEs9DbLiiMOaWxC3WeAJxM1UavlCgXz0encqm93LIlmSL7TjuHN1/rW8BJCnU8A==} + /@mui/system/5.11.0_ogriz7mfahdh34qnfautfro5yu: + resolution: {integrity: sha512-HFUT7Dlmyq6Wfuxsw8QBXZxXDYIQQaJ4YHaZd7s+nDMcjerLnILxjh2g3a6umtOUM+jEcRaFJAtvLZvlGfa5fw==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -3035,38 +3091,38 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.1 - '@emotion/react': 11.10.5_fan5qbzahqtxlm5dzefqlqx5ia - '@emotion/styled': 11.10.5_otcjdfkheatawhug6fwk7ldzni - '@mui/private-theming': 5.10.16_fan5qbzahqtxlm5dzefqlqx5ia - '@mui/styled-engine': 5.10.16_dovxhg2tvkkxkdnqyoum6wzcxm - '@mui/types': 7.2.2_@types+react@18.0.25 - '@mui/utils': 5.10.16_react@18.2.0 - '@types/react': 18.0.25 + '@babel/runtime': 7.20.6 + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu + '@mui/private-theming': 5.11.0_kzbn2opkn2327fwg5yzwzya5o4 + '@mui/styled-engine': 5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.0_react@18.2.0 + '@types/react': 18.0.26 clsx: 1.2.1 csstype: 3.1.1 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types/7.2.2_@types+react@18.0.25: - resolution: {integrity: sha512-siex8cZDtWeC916cXOoUOnEQQejuMYmHtc4hM6VkKVYaBICz3VIiqyiAomRboTQHt2jchxQ5Q5ATlbcDekTxDA==} + /@mui/types/7.2.3_@types+react@18.0.26: + resolution: {integrity: sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==} peerDependencies: '@types/react': '*' peerDependenciesMeta: '@types/react': optional: true dependencies: - '@types/react': 18.0.25 + '@types/react': 18.0.26 dev: false - /@mui/utils/5.10.16_react@18.2.0: - resolution: {integrity: sha512-3MB/SGsgiiu9Z55CFmAfiONUoR7AAue/H4F6w3mc2LnhFQCsoVvXhioDPcsiRpUMIQr34jDPzGXdCuqWooPCXQ==} + /@mui/utils/5.11.0_react@18.2.0: + resolution: {integrity: sha512-DP/YDaVVCVzJpZ5FFPLKNmaJkeaYRviTyIZkL/D5/FmPXQiA6ecd6z0/+VwoNQtp7aXAQWaRhvz4FM25yqFlHA==} engines: {node: '>=12.0.0'} peerDependencies: react: ^17.0.0 || ^18.0.0 || 18 dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 '@types/prop-types': 15.7.5 '@types/react-is': 17.0.3 prop-types: 15.8.1 @@ -3111,8 +3167,8 @@ packages: resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} dev: false - /@remix-run/router/1.0.3: - resolution: {integrity: sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q==} + /@remix-run/router/1.1.0: + resolution: {integrity: sha512-rGl+jH/7x1KBCQScz9p54p0dtPLNeKGb3e0wD2H5/oZj41bwQUnXdzbj2TbUAFhvD7cp9EyEQA4dEgpUFa1O7Q==} engines: {node: '>=14'} dev: false @@ -3124,8 +3180,8 @@ packages: picomatch: 2.3.1 dev: true - /@rollup/pluginutils/5.0.1: - resolution: {integrity: sha512-4HaCVEXXuObvcPUaUlLt4faHYHCeQOOWNj8NKFGaRSrw3ZLD0TWeAFZicV9vXjnE2nkNuaVTfTuwAnjR+6uc9A==} + /@rollup/pluginutils/5.0.2: + resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0 @@ -3158,18 +3214,8 @@ packages: '@sinonjs/commons': 1.8.3 dev: true - /@svgr/babel-plugin-add-jsx-attribute/6.3.1: - resolution: {integrity: sha512-jDBKArXYO1u0B1dmd2Nf8Oy6aTF5vLDfLoO9Oon/GLkqZ/NiggYWZA+a2HpUMH4ITwNqS3z43k8LWApB8S583w==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-add-jsx-attribute/6.3.1_@babel+core@7.19.6: - resolution: {integrity: sha512-jDBKArXYO1u0B1dmd2Nf8Oy6aTF5vLDfLoO9Oon/GLkqZ/NiggYWZA+a2HpUMH4ITwNqS3z43k8LWApB8S583w==} + /@svgr/babel-plugin-add-jsx-attribute/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3177,20 +3223,10 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-remove-jsx-attribute/6.3.1: - resolution: {integrity: sha512-dQzyJ4prwjcFd929T43Z8vSYiTlTu8eafV40Z2gO7zy/SV5GT+ogxRJRBIKWomPBOiaVXFg3jY4S5hyEN3IBjQ==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-remove-jsx-attribute/6.3.1_@babel+core@7.19.6: + /@svgr/babel-plugin-remove-jsx-attribute/6.3.1_@babel+core@7.20.5: resolution: {integrity: sha512-dQzyJ4prwjcFd929T43Z8vSYiTlTu8eafV40Z2gO7zy/SV5GT+ogxRJRBIKWomPBOiaVXFg3jY4S5hyEN3IBjQ==} engines: {node: '>=10'} peerDependencies: @@ -3199,20 +3235,10 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-remove-jsx-empty-expression/6.3.1: - resolution: {integrity: sha512-HBOUc1XwSU67fU26V5Sfb8MQsT0HvUyxru7d0oBJ4rA2s4HW3PhyAPC7fV/mdsSGpAvOdd8Wpvkjsr0fWPUO7A==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-remove-jsx-empty-expression/6.3.1_@babel+core@7.19.6: + /@svgr/babel-plugin-remove-jsx-empty-expression/6.3.1_@babel+core@7.20.5: resolution: {integrity: sha512-HBOUc1XwSU67fU26V5Sfb8MQsT0HvUyxru7d0oBJ4rA2s4HW3PhyAPC7fV/mdsSGpAvOdd8Wpvkjsr0fWPUO7A==} engines: {node: '>=10'} peerDependencies: @@ -3221,21 +3247,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-replace-jsx-attribute-value/6.3.1: - resolution: {integrity: sha512-C12e6aN4BXAolRrI601gPn5MDFCRHO7C4TM8Kks+rDtl8eEq+NN1sak0eAzJu363x3TmHXdZn7+Efd2nr9I5dA==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-replace-jsx-attribute-value/6.3.1_@babel+core@7.19.6: - resolution: {integrity: sha512-C12e6aN4BXAolRrI601gPn5MDFCRHO7C4TM8Kks+rDtl8eEq+NN1sak0eAzJu363x3TmHXdZn7+Efd2nr9I5dA==} + /@svgr/babel-plugin-replace-jsx-attribute-value/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3243,21 +3259,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-svg-dynamic-title/6.3.1: - resolution: {integrity: sha512-6NU55Mmh3M5u2CfCCt6TX29/pPneutrkJnnDCHbKZnjukZmmgUAZLtZ2g6ZoSPdarowaQmAiBRgAHqHmG0vuqA==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-svg-dynamic-title/6.3.1_@babel+core@7.19.6: - resolution: {integrity: sha512-6NU55Mmh3M5u2CfCCt6TX29/pPneutrkJnnDCHbKZnjukZmmgUAZLtZ2g6ZoSPdarowaQmAiBRgAHqHmG0vuqA==} + /@svgr/babel-plugin-svg-dynamic-title/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3265,21 +3271,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-svg-em-dimensions/6.3.1: - resolution: {integrity: sha512-HV1NGHYTTe1vCNKlBgq/gKuCSfaRlKcHIADn7P8w8U3Zvujdw1rmusutghJ1pZJV7pDt3Gt8ws+SVrqHnBO/Qw==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-svg-em-dimensions/6.3.1_@babel+core@7.19.6: - resolution: {integrity: sha512-HV1NGHYTTe1vCNKlBgq/gKuCSfaRlKcHIADn7P8w8U3Zvujdw1rmusutghJ1pZJV7pDt3Gt8ws+SVrqHnBO/Qw==} + /@svgr/babel-plugin-svg-em-dimensions/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3287,21 +3283,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-transform-react-native-svg/6.3.1: - resolution: {integrity: sha512-2wZhSHvTolFNeKDAN/ZmIeSz2O9JSw72XD+o2bNp2QAaWqa8KGpn5Yk5WHso6xqfSAiRzAE+GXlsrBO4UP9LLw==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-transform-react-native-svg/6.3.1_@babel+core@7.19.6: - resolution: {integrity: sha512-2wZhSHvTolFNeKDAN/ZmIeSz2O9JSw72XD+o2bNp2QAaWqa8KGpn5Yk5WHso6xqfSAiRzAE+GXlsrBO4UP9LLw==} + /@svgr/babel-plugin-transform-react-native-svg/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3309,21 +3295,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-plugin-transform-svg-component/6.3.1: - resolution: {integrity: sha512-cZ8Tr6ZAWNUFfDeCKn/pGi976iWSkS8ijmEYKosP+6ktdZ7lW9HVLHojyusPw3w0j8PI4VBeWAXAmi/2G7owxw==} - engines: {node: '>=12'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dev: true - - /@svgr/babel-plugin-transform-svg-component/6.3.1_@babel+core@7.19.6: - resolution: {integrity: sha512-cZ8Tr6ZAWNUFfDeCKn/pGi976iWSkS8ijmEYKosP+6ktdZ7lW9HVLHojyusPw3w0j8PI4VBeWAXAmi/2G7owxw==} + /@svgr/babel-plugin-transform-svg-component/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==} engines: {node: '>=12'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3331,11 +3307,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 dev: true - /@svgr/babel-preset/6.4.0: - resolution: {integrity: sha512-Ytuh7N282fv2Cy1JePf6HZ29/G5Hb8mQAjx4iykPjvfFl9NK6o5lZavmewgjOGT8kNPtwgvheuOQn4CifHRUhQ==} + /@svgr/babel-preset/6.5.1_@babel+core@7.20.5: + resolution: {integrity: sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3343,67 +3319,48 @@ packages: '@babel/core': optional: true dependencies: - '@svgr/babel-plugin-add-jsx-attribute': 6.3.1 - '@svgr/babel-plugin-remove-jsx-attribute': 6.3.1 - '@svgr/babel-plugin-remove-jsx-empty-expression': 6.3.1 - '@svgr/babel-plugin-replace-jsx-attribute-value': 6.3.1 - '@svgr/babel-plugin-svg-dynamic-title': 6.3.1 - '@svgr/babel-plugin-svg-em-dimensions': 6.3.1 - '@svgr/babel-plugin-transform-react-native-svg': 6.3.1 - '@svgr/babel-plugin-transform-svg-component': 6.3.1 + '@babel/core': 7.20.5 + '@svgr/babel-plugin-add-jsx-attribute': 6.5.1_@babel+core@7.20.5 + '@svgr/babel-plugin-remove-jsx-attribute': 6.3.1_@babel+core@7.20.5 + '@svgr/babel-plugin-remove-jsx-empty-expression': 6.3.1_@babel+core@7.20.5 + '@svgr/babel-plugin-replace-jsx-attribute-value': 6.5.1_@babel+core@7.20.5 + '@svgr/babel-plugin-svg-dynamic-title': 6.5.1_@babel+core@7.20.5 + '@svgr/babel-plugin-svg-em-dimensions': 6.5.1_@babel+core@7.20.5 + '@svgr/babel-plugin-transform-react-native-svg': 6.5.1_@babel+core@7.20.5 + '@svgr/babel-plugin-transform-svg-component': 6.5.1_@babel+core@7.20.5 dev: true - /@svgr/babel-preset/6.4.0_@babel+core@7.19.6: - resolution: {integrity: sha512-Ytuh7N282fv2Cy1JePf6HZ29/G5Hb8mQAjx4iykPjvfFl9NK6o5lZavmewgjOGT8kNPtwgvheuOQn4CifHRUhQ==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.19.6 - '@svgr/babel-plugin-add-jsx-attribute': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-remove-jsx-attribute': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-remove-jsx-empty-expression': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-replace-jsx-attribute-value': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-svg-dynamic-title': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-svg-em-dimensions': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-transform-react-native-svg': 6.3.1_@babel+core@7.19.6 - '@svgr/babel-plugin-transform-svg-component': 6.3.1_@babel+core@7.19.6 - dev: true - - /@svgr/core/6.4.0: - resolution: {integrity: sha512-wU9uyF6BUnwAqG7fDOowmDQzmbvovj1uq/iETfMK9xwQNaT+e7yN7SmDDcETXC72dnOrMcRuEWw0JEvpJha+yg==} + /@svgr/core/6.5.1: + resolution: {integrity: sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==} engines: {node: '>=10'} dependencies: - '@svgr/babel-preset': 6.4.0 - '@svgr/plugin-jsx': 6.4.0_@svgr+core@6.4.0 + '@babel/core': 7.20.5 + '@svgr/babel-preset': 6.5.1_@babel+core@7.20.5 + '@svgr/plugin-jsx': 6.5.1_@svgr+core@6.5.1 camelcase: 6.3.0 cosmiconfig: 7.0.1 transitivePeerDependencies: - - '@babel/core' - supports-color dev: true - /@svgr/hast-util-to-babel-ast/6.4.0: - resolution: {integrity: sha512-PjcU8jCneKXJnrREycsgfgQ/bzR1ogSKC5MBeUu2wmEoJIjzXX7X14DDktUjU9bkBy26yMDiVHn46Nl82P3WEg==} + /@svgr/hast-util-to-babel-ast/6.5.1: + resolution: {integrity: sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==} engines: {node: '>=10'} dependencies: - '@babel/types': 7.19.4 - entities: 4.3.1 + '@babel/types': 7.20.5 + entities: 4.4.0 dev: true - /@svgr/plugin-jsx/6.4.0_@svgr+core@6.4.0: - resolution: {integrity: sha512-gu6E7v8qRAtCxbymI1et3G7athogvKvzsJkSWiHVZsuVZbyx5O2b7+DIkKvAGh2RvEzgSvfGf8QD1BaHal2vBw==} + /@svgr/plugin-jsx/6.5.1_@svgr+core@6.5.1: + resolution: {integrity: sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==} engines: {node: '>=10'} peerDependencies: '@svgr/core': ^6.0.0 dependencies: - '@babel/core': 7.19.6 - '@svgr/babel-preset': 6.4.0_@babel+core@7.19.6 - '@svgr/core': 6.4.0 - '@svgr/hast-util-to-babel-ast': 6.4.0 + '@babel/core': 7.20.5 + '@svgr/babel-preset': 6.5.1_@babel+core@7.20.5 + '@svgr/core': 6.5.1 + '@svgr/hast-util-to-babel-ast': 6.5.1 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color @@ -3414,7 +3371,7 @@ packages: engines: {node: '>=12'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.6 '@types/aria-query': 4.2.2 aria-query: 5.0.0 chalk: 4.1.2 @@ -3480,8 +3437,8 @@ packages: /@types/babel__core/7.1.19: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} dependencies: - '@babel/parser': 7.19.6 - '@babel/types': 7.19.4 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.17.1 @@ -3490,20 +3447,20 @@ packages: /@types/babel__generator/7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@types/babel__template/7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.19.6 - '@babel/types': 7.19.4 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 dev: true /@types/babel__traverse/7.17.1: resolution: {integrity: sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==} dependencies: - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 dev: true /@types/eslint/8.4.5: @@ -3520,7 +3477,7 @@ packages: /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.11.16 dev: true /@types/istanbul-lib-coverage/2.0.4: @@ -3539,8 +3496,8 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: true - /@types/jest/29.2.3: - resolution: {integrity: sha512-6XwoEbmatfyoCjWRX7z0fKMmgYKe9+/HrviJ5k0X/tjJWHGAezZOfYaxqQKuzG/TvQyr+ktjm4jgbk0s4/oF2w==} + /@types/jest/29.2.4: + resolution: {integrity: sha512-PipFB04k2qTRPePduVLTRiPzQfvMeLwUN3Z21hsAKaB/W9IIzgB2pizCL466ftJlcyZqnHoC9ZHpxLGl3fS86A==} dependencies: expect: 29.3.1 pretty-format: 29.3.1 @@ -3549,7 +3506,7 @@ packages: /@types/jsdom/20.0.0: resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.11.16 '@types/tough-cookie': 4.0.2 parse5: 7.0.0 dev: true @@ -3570,8 +3527,8 @@ packages: resolution: {integrity: sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA==} dev: true - /@types/node/18.11.9: - resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} + /@types/node/18.11.16: + resolution: {integrity: sha512-6T7P5bDkRhqRxrQtwj7vru+bWTpelgtcETAZEUSdq0YISKz8WKdoBukQLYQQ6DFHvU9JRsbFq0JH5C51X2ZdnA==} dev: true /@types/normalize-package-data/2.4.1: @@ -3591,29 +3548,29 @@ packages: /@types/qrcode.react/1.0.2: resolution: {integrity: sha512-I9Oq5Cjlkgy3Tw7krCnCXLw2/zMhizkTere49OOcta23tkvH0xBTP0yInimTh0gstLRtb8Ki9NZVujE5UI6ffQ==} dependencies: - '@types/react': 18.0.25 + '@types/react': 18.0.26 dev: true /@types/react-dom/18.0.9: resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} dependencies: - '@types/react': 18.0.25 + '@types/react': 18.0.26 dev: true /@types/react-is/17.0.3: resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==} dependencies: - '@types/react': 18.0.25 + '@types/react': 18.0.26 dev: false /@types/react-transition-group/4.4.5: resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} dependencies: - '@types/react': 18.0.25 + '@types/react': 18.0.26 dev: false - /@types/react/18.0.25: - resolution: {integrity: sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==} + /@types/react/18.0.26: + resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 @@ -3633,7 +3590,7 @@ packages: /@types/testing-library__jest-dom/5.14.5: resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==} dependencies: - '@types/jest': 29.2.3 + '@types/jest': 29.2.4 dev: true /@types/tough-cookie/4.0.2: @@ -3660,8 +3617,8 @@ packages: resolution: {integrity: sha512-3NoqvZC2W5gAC5DZbTpCeJ251vGQmgcWIHQJGq2J240HY6ErQ9aWKkwfoKJlHLx+A83WPNTZ9+3cd2ILxbvr1w==} dev: true - /@typescript-eslint/eslint-plugin/5.45.0_czs5uoqkd3podpy6vgtsxfc7au: - resolution: {integrity: sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==} + /@typescript-eslint/eslint-plugin/5.46.1_mqzxmroayievgzgel6yrqgih5i: + resolution: {integrity: sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -3671,37 +3628,37 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a - '@typescript-eslint/scope-manager': 5.45.0 - '@typescript-eslint/type-utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a - '@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a + '@typescript-eslint/parser': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa + '@typescript-eslint/scope-manager': 5.46.1 + '@typescript-eslint/type-utils': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa + '@typescript-eslint/utils': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa debug: 4.3.4 - eslint: 8.28.0 + eslint: 8.30.0 ignore: 5.2.0 natural-compare-lite: 1.4.0 regexpp: 3.2.0 semver: 7.3.7 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils/5.30.6_hsf322ms6xhhd4b5ne6lb74y4a: + /@typescript-eslint/experimental-utils/5.30.6_lzzuuodtsqwxnvqeq4g4likcqa: resolution: {integrity: sha512-bqvT+0L8IjtW7MCrMgm9oVNxs4g7mESro1mm5c1/SNfTnHuFTf9OUX1WzVkTz75M9cp//UrTrSmGvK48NEKshQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.30.6_hsf322ms6xhhd4b5ne6lb74y4a - eslint: 8.28.0 + '@typescript-eslint/utils': 5.30.6_lzzuuodtsqwxnvqeq4g4likcqa + eslint: 8.30.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/5.45.0_hsf322ms6xhhd4b5ne6lb74y4a: - resolution: {integrity: sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==} + /@typescript-eslint/parser/5.46.1_lzzuuodtsqwxnvqeq4g4likcqa: + resolution: {integrity: sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3710,12 +3667,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.45.0 - '@typescript-eslint/types': 5.45.0 - '@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3 + '@typescript-eslint/scope-manager': 5.46.1 + '@typescript-eslint/types': 5.46.1 + '@typescript-eslint/typescript-estree': 5.46.1_typescript@4.9.4 debug: 4.3.4 - eslint: 8.28.0 - typescript: 4.9.3 + eslint: 8.30.0 + typescript: 4.9.4 transitivePeerDependencies: - supports-color dev: true @@ -3728,16 +3685,16 @@ packages: '@typescript-eslint/visitor-keys': 5.30.6 dev: true - /@typescript-eslint/scope-manager/5.45.0: - resolution: {integrity: sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==} + /@typescript-eslint/scope-manager/5.46.1: + resolution: {integrity: sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.45.0 - '@typescript-eslint/visitor-keys': 5.45.0 + '@typescript-eslint/types': 5.46.1 + '@typescript-eslint/visitor-keys': 5.46.1 dev: true - /@typescript-eslint/type-utils/5.45.0_hsf322ms6xhhd4b5ne6lb74y4a: - resolution: {integrity: sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==} + /@typescript-eslint/type-utils/5.46.1_lzzuuodtsqwxnvqeq4g4likcqa: + resolution: {integrity: sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -3746,12 +3703,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3 - '@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a + '@typescript-eslint/typescript-estree': 5.46.1_typescript@4.9.4 + '@typescript-eslint/utils': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa debug: 4.3.4 - eslint: 8.28.0 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 + eslint: 8.30.0 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 transitivePeerDependencies: - supports-color dev: true @@ -3761,12 +3718,12 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/types/5.45.0: - resolution: {integrity: sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==} + /@typescript-eslint/types/5.46.1: + resolution: {integrity: sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.30.6_typescript@4.9.3: + /@typescript-eslint/typescript-estree/5.30.6_typescript@4.9.4: resolution: {integrity: sha512-Z7TgPoeYUm06smfEfYF0RBkpF8csMyVnqQbLYiGgmUSTaSXTP57bt8f0UFXstbGxKIreTwQCujtaH0LY9w9B+A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -3781,14 +3738,14 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.7 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree/5.45.0_typescript@4.9.3: - resolution: {integrity: sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==} + /@typescript-eslint/typescript-estree/5.46.1_typescript@4.9.4: + resolution: {integrity: sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -3796,19 +3753,19 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.45.0 - '@typescript-eslint/visitor-keys': 5.45.0 + '@typescript-eslint/types': 5.46.1 + '@typescript-eslint/visitor-keys': 5.46.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.7 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.30.6_hsf322ms6xhhd4b5ne6lb74y4a: + /@typescript-eslint/utils/5.30.6_lzzuuodtsqwxnvqeq4g4likcqa: resolution: {integrity: sha512-xFBLc/esUbLOJLk9jKv0E9gD/OH966M40aY9jJ8GiqpSkP2xOV908cokJqqhVd85WoIvHVHYXxSFE4cCSDzVvA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -3817,29 +3774,29 @@ packages: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 5.30.6 '@typescript-eslint/types': 5.30.6 - '@typescript-eslint/typescript-estree': 5.30.6_typescript@4.9.3 - eslint: 8.28.0 + '@typescript-eslint/typescript-estree': 5.30.6_typescript@4.9.4 + eslint: 8.30.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.28.0 + eslint-utils: 3.0.0_eslint@8.30.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/utils/5.45.0_hsf322ms6xhhd4b5ne6lb74y4a: - resolution: {integrity: sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==} + /@typescript-eslint/utils/5.46.1_lzzuuodtsqwxnvqeq4g4likcqa: + resolution: {integrity: sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.12 - '@typescript-eslint/scope-manager': 5.45.0 - '@typescript-eslint/types': 5.45.0 - '@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3 - eslint: 8.28.0 + '@typescript-eslint/scope-manager': 5.46.1 + '@typescript-eslint/types': 5.46.1 + '@typescript-eslint/typescript-estree': 5.46.1_typescript@4.9.4 + eslint: 8.30.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.28.0 + eslint-utils: 3.0.0_eslint@8.30.0 semver: 7.3.7 transitivePeerDependencies: - supports-color @@ -3854,28 +3811,26 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /@typescript-eslint/visitor-keys/5.45.0: - resolution: {integrity: sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==} + /@typescript-eslint/visitor-keys/5.46.1: + resolution: {integrity: sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.45.0 + '@typescript-eslint/types': 5.46.1 eslint-visitor-keys: 3.3.0 dev: true - /@vitejs/plugin-react/2.2.0_vite@3.2.4: - resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==} + /@vitejs/plugin-react/3.0.0_vite@4.0.1: + resolution: {integrity: sha512-1mvyPc0xYW5G8CHQvJIJXLoMjl5Ct3q2g5Y2s6Ccfgwm45y48LBvsla7az+GkkAtYikWQ4Lxqcsq5RHLcZgtNQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^3.0.0 + vite: ^4.0.0 dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.19.6 - magic-string: 0.26.7 + '@babel/core': 7.20.5 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.5 + magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 3.2.4_@types+node@18.11.9 + vite: 4.0.1_@types+node@18.11.16 transitivePeerDependencies: - supports-color dev: true @@ -4033,7 +3988,7 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 '@babel/runtime-corejs3': 7.18.6 dev: true @@ -4151,8 +4106,8 @@ packages: engines: {node: '>=4'} dev: true - /axios/1.2.0: - resolution: {integrity: sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==} + /axios/1.2.1: + resolution: {integrity: sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==} dependencies: follow-redirects: 1.15.1 form-data: 4.0.0 @@ -4187,7 +4142,7 @@ packages: - supports-color dev: true - /babel-jest/29.3.1_@babel+core@7.19.6: + /babel-jest/29.3.1_@babel+core@7.20.5: resolution: {integrity: sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -4196,11 +4151,11 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@jest/transform': 29.3.1 '@types/babel__core': 7.1.19 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.2.0_@babel+core@7.19.6 + babel-preset-jest: 29.2.0_@babel+core@7.20.5 chalk: 4.1.2 graceful-fs: 4.2.10 slash: 3.0.0 @@ -4232,7 +4187,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@babel/template': 7.18.10 - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 '@types/babel__core': 7.1.19 '@types/babel__traverse': 7.17.1 dev: true @@ -4242,7 +4197,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/template': 7.18.10 - '@babel/types': 7.19.4 + '@babel/types': 7.20.5 '@types/babel__core': 7.1.19 '@types/babel__traverse': 7.17.1 dev: true @@ -4251,11 +4206,11 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 cosmiconfig: 7.0.1 resolve: 1.22.1 - /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.19.6: + /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.20.5: resolution: {integrity: sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -4263,15 +4218,15 @@ packages: '@babel/core': optional: true dependencies: - '@babel/compat-data': 7.19.4 - '@babel/core': 7.19.6 - '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.19.6 + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.20.5 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.19.6: + /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.20.5: resolution: {integrity: sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -4279,14 +4234,14 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.20.5 core-js-compat: 3.23.4 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.19.6: + /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.20.5: resolution: {integrity: sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -4294,8 +4249,8 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -4327,7 +4282,7 @@ packages: '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.18.6 dev: true - /babel-preset-current-node-syntax/1.0.1_@babel+core@7.19.6: + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.20.5: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 @@ -4335,19 +4290,19 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.6 - '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.19.6 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.19.6 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.19.6 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.6 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.6 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.19.6 + '@babel/core': 7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.5 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.5 dev: true /babel-preset-jest/26.6.2_@babel+core@7.18.6: @@ -4364,7 +4319,7 @@ packages: babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.6 dev: true - /babel-preset-jest/29.2.0_@babel+core@7.19.6: + /babel-preset-jest/29.2.0_@babel+core@7.20.5: resolution: {integrity: sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -4373,29 +4328,29 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 babel-plugin-jest-hoist: 29.2.0 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.6 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 dev: true /babel-preset-react-app/10.0.1: resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==} dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-decorators': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-optional-chaining': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-flow-strip-types': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-runtime': 7.18.6_@babel+core@7.19.6 - '@babel/preset-env': 7.18.6_@babel+core@7.19.6 - '@babel/preset-react': 7.18.6_@babel+core@7.19.6 - '@babel/preset-typescript': 7.18.6_@babel+core@7.19.6 - '@babel/runtime': 7.19.0 + '@babel/core': 7.20.5 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-decorators': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-chaining': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-flow-strip-types': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-runtime': 7.18.6_@babel+core@7.20.5 + '@babel/preset-env': 7.18.6_@babel+core@7.20.5 + '@babel/preset-react': 7.18.6_@babel+core@7.20.5 + '@babel/preset-typescript': 7.18.6_@babel+core@7.20.5 + '@babel/runtime': 7.20.6 babel-plugin-macros: 3.1.0 babel-plugin-transform-react-remove-prop-types: 0.4.24 transitivePeerDependencies: @@ -4463,17 +4418,6 @@ packages: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} dev: true - /browserslist/4.21.2: - resolution: {integrity: sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001366 - electron-to-chromium: 1.4.189 - node-releases: 2.0.6 - update-browserslist-db: 1.0.4_browserslist@4.21.2 - dev: true - /browserslist/4.21.4: resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -4540,10 +4484,6 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001366: - resolution: {integrity: sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA==} - dev: true - /caniuse-lite/1.0.30001425: resolution: {integrity: sha512-/pzFv0OmNG6W0ym80P3NtapU0QEiDS3VuYAZMGoLLqiC7f6FJFe1MjpQDREGApeenD9wloeytmVDj+JLXPC6qw==} dev: true @@ -4682,7 +4622,7 @@ packages: dev: true /concat-map/0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} /confusing-browser-globals/1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} @@ -4744,7 +4684,7 @@ packages: requiresBuild: true dev: true - /cosmiconfig-typescript-loader/4.0.0_cs4q7g5uavsvvdjjkl2t6wi57a: + /cosmiconfig-typescript-loader/4.0.0_64g3pvarf3oduwh7nnbyl3yqm4: resolution: {integrity: sha512-cVpucSc2Tf+VPwCCR7SZzmQTQkPbkk4O01yXsYqXBIbjE1bhwqSyAgYQkRK1un4i0OPziTleqFhdkmOc4RQ/9g==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -4755,8 +4695,8 @@ packages: dependencies: '@types/node': 14.18.26 cosmiconfig: 7.0.1 - ts-node: 10.9.0_omfyfib2yqj7pu7wtuw6wjyhwa - typescript: 4.9.3 + ts-node: 10.9.0_hylbnkdpdgf7fwrtnxxops6eba + typescript: 4.9.4 dev: true /cosmiconfig/7.0.1: @@ -4804,7 +4744,7 @@ packages: /css-vendor/2.0.8: resolution: {integrity: sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 is-in-browser: 1.1.3 dev: false @@ -4899,8 +4839,8 @@ packages: resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==} dev: true - /decode-uri-component/0.2.0: - resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} + /decode-uri-component/0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} engines: {node: '>=0.10'} /dedent/0.7.0: @@ -5002,7 +4942,7 @@ packages: /dom-helpers/5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 csstype: 3.1.1 dev: false @@ -5020,10 +4960,6 @@ packages: is-obj: 2.0.0 dev: true - /electron-to-chromium/1.4.189: - resolution: {integrity: sha512-dQ6Zn4ll2NofGtxPXaDfY2laIa6NyCQdqXYHdwH90GJQW0LpJJib0ZU/ERtbb0XkBEmUD2eJtagbOie3pdMiPg==} - dev: true - /electron-to-chromium/1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} dev: true @@ -5055,8 +4991,8 @@ packages: tapable: 2.2.1 dev: true - /entities/4.3.1: - resolution: {integrity: sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==} + /entities/4.4.0: + resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} dev: true @@ -5110,61 +5046,7 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-android-64/0.15.16: - resolution: {integrity: sha512-Vwkv/sT0zMSgPSVO3Jlt1pUbnZuOgtOQJkJkyyJFAlLe7BiT8e9ESzo0zQSx4c3wW4T6kGChmKDPMbWTgtliQA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /esbuild-android-arm64/0.15.16: - resolution: {integrity: sha512-lqfKuofMExL5niNV3gnhMUYacSXfsvzTa/58sDlBET/hCOG99Zmeh+lz6kvdgvGOsImeo6J9SW21rFCogNPLxg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /esbuild-darwin-64/0.15.16: - resolution: {integrity: sha512-wo2VWk/n/9V2TmqUZ/KpzRjCEcr00n7yahEdmtzlrfQ3lfMCf3Wa+0sqHAbjk3C6CKkR3WKK/whkMq5Gj4Da9g==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /esbuild-darwin-arm64/0.15.16: - resolution: {integrity: sha512-fMXaUr5ou0M4WnewBKsspMtX++C1yIa3nJ5R2LSbLCfJT3uFdcRoU/NZjoM4kOMKyOD9Sa/2vlgN8G07K3SJnw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /esbuild-freebsd-64/0.15.16: - resolution: {integrity: sha512-UzIc0xlRx5x9kRuMr+E3+hlSOxa/aRqfuMfiYBXu2jJ8Mzej4lGL7+o6F5hzhLqWfWm1GWHNakIdlqg1ayaTNQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-freebsd-arm64/0.15.16: - resolution: {integrity: sha512-8xyiYuGc0DLZphFQIiYaLHlfoP+hAN9RHbE+Ibh8EUcDNHAqbQgUrQg7pE7Bo00rXmQ5Ap6KFgcR0b4ALZls1g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-jest/0.5.0_esbuild@0.15.16: + /esbuild-jest/0.5.0_esbuild@0.16.7: resolution: {integrity: sha512-AMZZCdEpXfNVOIDvURlqYyHwC8qC1/BFjgsrOiSL1eyiIArVtHL8YAC83Shhn16cYYoAWEW17yZn0W/RJKJKHQ==} peerDependencies: esbuild: '>=0.8.50' @@ -5172,165 +5054,39 @@ packages: '@babel/core': 7.18.6 '@babel/plugin-transform-modules-commonjs': 7.18.6_@babel+core@7.18.6 babel-jest: 26.6.3_@babel+core@7.18.6 - esbuild: 0.15.16 + esbuild: 0.16.7 transitivePeerDependencies: - supports-color dev: true - /esbuild-linux-32/0.15.16: - resolution: {integrity: sha512-iGijUTV+0kIMyUVoynK0v+32Oi8yyp0xwMzX69GX+5+AniNy/C/AL1MjFTsozRp/3xQPl7jVux/PLe2ds10/2w==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-64/0.15.16: - resolution: {integrity: sha512-tuSOjXdLw7VzaUj89fIdAaQT7zFGbKBcz4YxbWrOiXkwscYgE7HtTxUavreBbnRkGxKwr9iT/gmeJWNm4djy/g==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-arm/0.15.16: - resolution: {integrity: sha512-XKcrxCEXDTOuoRj5l12tJnkvuxXBMKwEC5j0JISw3ziLf0j4zIwXbKbTmUrKFWbo6ZgvNpa7Y5dnbsjVvH39bQ==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-arm64/0.15.16: - resolution: {integrity: sha512-mPYksnfHnemNrvjrDhZyixL/AfbJN0Xn9S34ZOHYdh6/jJcNd8iTsv3JwJoEvTJqjMggjMhGUPJAdjnFBHoH8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-mips64le/0.15.16: - resolution: {integrity: sha512-kSJO2PXaxfm0pWY39+YX+QtpFqyyrcp0ZeI8QPTrcFVQoWEPiPVtOfTZeS3ZKedfH+Ga38c4DSzmKMQJocQv6A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-ppc64le/0.15.16: - resolution: {integrity: sha512-NimPikwkBY0yGABw6SlhKrtT35sU4O23xkhlrTT/O6lSxv3Pm5iSc6OYaqVAHWkLdVf31bF4UDVFO+D990WpAA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-riscv64/0.15.16: - resolution: {integrity: sha512-ty2YUHZlwFOwp7pR+J87M4CVrXJIf5ZZtU/umpxgVJBXvWjhziSLEQxvl30SYfUPq0nzeWKBGw5i/DieiHeKfw==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-s390x/0.15.16: - resolution: {integrity: sha512-VkZaGssvPDQtx4fvVdZ9czezmyWyzpQhEbSNsHZZN0BHvxRLOYAQ7sjay8nMQwYswP6O2KlZluRMNPYefFRs+w==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-netbsd-64/0.15.16: - resolution: {integrity: sha512-ElQ9rhdY51et6MJTWrCPbqOd/YuPowD7Cxx3ee8wlmXQQVW7UvQI6nSprJ9uVFQISqSF5e5EWpwWqXZsECLvXg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-openbsd-64/0.15.16: - resolution: {integrity: sha512-KgxMHyxMCT+NdLQE1zVJEsLSt2QQBAvJfmUGDmgEq8Fvjrf6vSKB00dVHUEDKcJwMID6CdgCpvYNt999tIYhqA==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-sunos-64/0.15.16: - resolution: {integrity: sha512-exSAx8Phj7QylXHlMfIyEfNrmqnLxFqLxdQF6MBHPdHAjT7fsKaX6XIJn+aQEFiOcE4X8e7VvdMCJ+WDZxjSRQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-32/0.15.16: - resolution: {integrity: sha512-zQgWpY5pUCSTOwqKQ6/vOCJfRssTvxFuEkpB4f2VUGPBpdddZfdj8hbZuFRdZRPIVHvN7juGcpgCA/XCF37mAQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-64/0.15.16: - resolution: {integrity: sha512-HjW1hHRLSncnM3MBCP7iquatHVJq9l0S2xxsHHj4yzf4nm9TU4Z7k4NkeMlD/dHQ4jPlQQhwcMvwbJiOefSuZw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-arm64/0.15.16: - resolution: {integrity: sha512-oCcUKrJaMn04Vxy9Ekd8x23O8LoU01+4NOkQ2iBToKgnGj5eo1vU9i27NQZ9qC8NFZgnQQZg5oZWAejmbsppNA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild/0.15.16: - resolution: {integrity: sha512-o6iS9zxdHrrojjlj6pNGC2NAg86ECZqIETswTM5KmJitq+R1YmahhWtMumeQp9lHqJaROGnsBi2RLawGnfo5ZQ==} + /esbuild/0.16.7: + resolution: {integrity: sha512-P6OBFYFSQOGzfApqCeYKqfKRRbCIRsdppTXFo4aAvtiW3o8TTyiIplBvHJI171saPAiy3WlawJHCveJVIOIx1A==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.15.16 - '@esbuild/linux-loong64': 0.15.16 - esbuild-android-64: 0.15.16 - esbuild-android-arm64: 0.15.16 - esbuild-darwin-64: 0.15.16 - esbuild-darwin-arm64: 0.15.16 - esbuild-freebsd-64: 0.15.16 - esbuild-freebsd-arm64: 0.15.16 - esbuild-linux-32: 0.15.16 - esbuild-linux-64: 0.15.16 - esbuild-linux-arm: 0.15.16 - esbuild-linux-arm64: 0.15.16 - esbuild-linux-mips64le: 0.15.16 - esbuild-linux-ppc64le: 0.15.16 - esbuild-linux-riscv64: 0.15.16 - esbuild-linux-s390x: 0.15.16 - esbuild-netbsd-64: 0.15.16 - esbuild-openbsd-64: 0.15.16 - esbuild-sunos-64: 0.15.16 - esbuild-windows-32: 0.15.16 - esbuild-windows-64: 0.15.16 - esbuild-windows-arm64: 0.15.16 + '@esbuild/android-arm': 0.16.7 + '@esbuild/android-arm64': 0.16.7 + '@esbuild/android-x64': 0.16.7 + '@esbuild/darwin-arm64': 0.16.7 + '@esbuild/darwin-x64': 0.16.7 + '@esbuild/freebsd-arm64': 0.16.7 + '@esbuild/freebsd-x64': 0.16.7 + '@esbuild/linux-arm': 0.16.7 + '@esbuild/linux-arm64': 0.16.7 + '@esbuild/linux-ia32': 0.16.7 + '@esbuild/linux-loong64': 0.16.7 + '@esbuild/linux-mips64el': 0.16.7 + '@esbuild/linux-ppc64': 0.16.7 + '@esbuild/linux-riscv64': 0.16.7 + '@esbuild/linux-s390x': 0.16.7 + '@esbuild/linux-x64': 0.16.7 + '@esbuild/netbsd-x64': 0.16.7 + '@esbuild/openbsd-x64': 0.16.7 + '@esbuild/sunos-x64': 0.16.7 + '@esbuild/win32-arm64': 0.16.7 + '@esbuild/win32-ia32': 0.16.7 + '@esbuild/win32-x64': 0.16.7 dev: true /escalade/3.1.1: @@ -5364,16 +5120,16 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-prettier/8.5.0_eslint@8.28.0: + /eslint-config-prettier/8.5.0_eslint@8.30.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.28.0 + eslint: 8.30.0 dev: true - /eslint-config-react-app/7.0.1_ffu622cxxp5swe5tqcog7svb5i: + /eslint-config-react-app/7.0.1_5dzg3kvqggpfcaryo776p5cisq: resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5384,21 +5140,21 @@ packages: optional: true dependencies: '@babel/core': 7.18.6 - '@babel/eslint-parser': 7.18.2_e6dejpcwcc66ssvjscxl7tagl4 + '@babel/eslint-parser': 7.18.2_krbl7gjo3afxleq6arh2klsyza '@rushstack/eslint-patch': 1.1.4 - '@typescript-eslint/eslint-plugin': 5.45.0_czs5uoqkd3podpy6vgtsxfc7au - '@typescript-eslint/parser': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a + '@typescript-eslint/eslint-plugin': 5.46.1_mqzxmroayievgzgel6yrqgih5i + '@typescript-eslint/parser': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa babel-preset-react-app: 10.0.1 confusing-browser-globals: 1.0.11 - eslint: 8.28.0 - eslint-plugin-flowtype: 8.0.3_eslint@8.28.0 - eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq - eslint-plugin-jest: 25.7.0_g4s445ihmht4kpk3znm26xsocm - eslint-plugin-jsx-a11y: 6.6.1_eslint@8.28.0 - eslint-plugin-react: 7.31.11_eslint@8.28.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.28.0 - eslint-plugin-testing-library: 5.5.1_hsf322ms6xhhd4b5ne6lb74y4a - typescript: 4.9.3 + eslint: 8.30.0 + eslint-plugin-flowtype: 8.0.3_eslint@8.30.0 + eslint-plugin-import: 2.26.0_mv4znvkmpvglpuoorytwup6y2i + eslint-plugin-jest: 25.7.0_sfwiddeckomdljtfndj2gztqni + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.30.0 + eslint-plugin-react: 7.31.11_eslint@8.30.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.30.0 + eslint-plugin-testing-library: 5.5.1_lzzuuodtsqwxnvqeq4g4likcqa + typescript: 4.9.4 transitivePeerDependencies: - '@babel/plugin-syntax-flow' - '@babel/plugin-transform-react-jsx' @@ -5421,7 +5177,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript/3.5.2_ktrec6dplf4now6nlbc6d67jee: + /eslint-import-resolver-typescript/3.5.2_2lbwmhbr7bncddqbzzpg77o75m: resolution: {integrity: sha512-zX4ebnnyXiykjhcBvKIf5TNvt8K7yX6bllTRZ14MiurKPjDpCAZujlszTdB8pcNXhZcOf+god4s9SjQa5GnytQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -5430,8 +5186,8 @@ packages: dependencies: debug: 4.3.4 enhanced-resolve: 5.10.0 - eslint: 8.28.0 - eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq + eslint: 8.30.0 + eslint-plugin-import: 2.26.0_mv4znvkmpvglpuoorytwup6y2i get-tsconfig: 4.2.0 globby: 13.1.2 is-core-module: 2.10.0 @@ -5441,7 +5197,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.3_qlteae5dad2nfnhgbnb4x6nyxy: + /eslint-module-utils/2.7.3_lh3cbrwbwxstv4lamhqnpgmjcm: resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} peerDependencies: @@ -5459,16 +5215,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a + '@typescript-eslint/parser': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa debug: 3.2.7 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 3.5.2_ktrec6dplf4now6nlbc6d67jee + eslint-import-resolver-typescript: 3.5.2_2lbwmhbr7bncddqbzzpg77o75m find-up: 2.1.0 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-flowtype/8.0.3_eslint@8.28.0: + /eslint-plugin-flowtype/8.0.3_eslint@8.30.0: resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -5481,12 +5237,12 @@ packages: '@babel/plugin-transform-react-jsx': optional: true dependencies: - eslint: 8.28.0 + eslint: 8.30.0 lodash: 4.17.21 string-natural-compare: 3.0.1 dev: true - /eslint-plugin-import/2.26.0_xmouedd5rhgbah4737x2hltudq: + /eslint-plugin-import/2.26.0_mv4znvkmpvglpuoorytwup6y2i: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -5496,14 +5252,14 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a + '@typescript-eslint/parser': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.28.0 + eslint: 8.30.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3_qlteae5dad2nfnhgbnb4x6nyxy + eslint-module-utils: 2.7.3_lh3cbrwbwxstv4lamhqnpgmjcm has: 1.0.3 is-core-module: 2.9.0 is-glob: 4.0.3 @@ -5517,7 +5273,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest/25.7.0_g4s445ihmht4kpk3znm26xsocm: + /eslint-plugin-jest/25.7.0_sfwiddeckomdljtfndj2gztqni: resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: @@ -5530,16 +5286,16 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.45.0_czs5uoqkd3podpy6vgtsxfc7au - '@typescript-eslint/experimental-utils': 5.30.6_hsf322ms6xhhd4b5ne6lb74y4a - eslint: 8.28.0 - jest: 29.3.1_@types+node@18.11.9 + '@typescript-eslint/eslint-plugin': 5.46.1_mqzxmroayievgzgel6yrqgih5i + '@typescript-eslint/experimental-utils': 5.30.6_lzzuuodtsqwxnvqeq4g4likcqa + eslint: 8.30.0 + jest: 29.3.1_@types+node@18.11.16 transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-jsx-a11y/6.6.1_eslint@8.28.0: + /eslint-plugin-jsx-a11y/6.6.1_eslint@8.30.0: resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} engines: {node: '>=4.0'} peerDependencies: @@ -5553,7 +5309,7 @@ packages: axobject-query: 2.2.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.28.0 + eslint: 8.30.0 has: 1.0.3 jsx-ast-utils: 3.3.2 language-tags: 1.0.5 @@ -5561,7 +5317,7 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-prettier/4.2.1_cwlo2dingkvfydnaculr42urve: + /eslint-plugin-prettier/4.2.1_kl4pe43v5b43npmso5hoplpbyi: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -5572,22 +5328,22 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.28.0 - eslint-config-prettier: 8.5.0_eslint@8.28.0 - prettier: 2.8.0 + eslint: 8.30.0 + eslint-config-prettier: 8.5.0_eslint@8.30.0 + prettier: 2.8.1 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-react-hooks/4.6.0_eslint@8.28.0: + /eslint-plugin-react-hooks/4.6.0_eslint@8.30.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.28.0 + eslint: 8.30.0 dev: true - /eslint-plugin-react/7.31.11_eslint@8.28.0: + /eslint-plugin-react/7.31.11_eslint@8.30.0: resolution: {integrity: sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==} engines: {node: '>=4'} peerDependencies: @@ -5597,7 +5353,7 @@ packages: array.prototype.flatmap: 1.3.1 array.prototype.tosorted: 1.1.1 doctrine: 2.1.0 - eslint: 8.28.0 + eslint: 8.30.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.2 minimatch: 3.1.2 @@ -5611,14 +5367,14 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-testing-library/5.5.1_hsf322ms6xhhd4b5ne6lb74y4a: + /eslint-plugin-testing-library/5.5.1_lzzuuodtsqwxnvqeq4g4likcqa: resolution: {integrity: sha512-plLEkkbAKBjPxsLj7x4jNapcHAg2ernkQlKKrN2I8NrQwPISZHyCUNvg5Hv3EDqOQReToQb5bnqXYbkijJPE/g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} peerDependencies: eslint: ^7.5.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a - eslint: 8.28.0 + '@typescript-eslint/utils': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa + eslint: 8.30.0 transitivePeerDependencies: - supports-color - typescript @@ -5640,13 +5396,13 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.28.0: + /eslint-utils/3.0.0_eslint@8.30.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.28.0 + eslint: 8.30.0 eslint-visitor-keys: 2.1.0 dev: true @@ -5660,13 +5416,13 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.28.0: - resolution: {integrity: sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==} + /eslint/8.30.0: + resolution: {integrity: sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.3.3 - '@humanwhocodes/config-array': 0.11.6 + '@eslint/eslintrc': 1.4.0 + '@humanwhocodes/config-array': 0.11.8 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 @@ -5676,7 +5432,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.28.0 + eslint-utils: 3.0.0_eslint@8.30.0 eslint-visitor-keys: 3.3.0 espree: 9.4.0 esquery: 1.4.0 @@ -5685,7 +5441,7 @@ packages: file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.16.0 + globals: 13.19.0 grapheme-splitter: 1.0.4 ignore: 5.2.0 import-fresh: 3.3.0 @@ -6106,10 +5862,6 @@ packages: is-glob: 4.0.3 dev: true - /glob-regex/0.3.2: - resolution: {integrity: sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==} - dev: true - /glob/7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: @@ -6132,8 +5884,8 @@ packages: engines: {node: '>=4'} dev: true - /globals/13.16.0: - resolution: {integrity: sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==} + /globals/13.19.0: + resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -6327,18 +6079,18 @@ packages: '@babel/runtime': 7.19.4 dev: false - /i18next-http-backend/2.0.2: - resolution: {integrity: sha512-TFiIqitZEc8+jyca31EW5ef5PjUYtUGGfL8c8FJwiiHguq5OQTqoR3mxpKqaCPiikg+cxSgXtNA2gZPCu0aryQ==} + /i18next-http-backend/2.1.0: + resolution: {integrity: sha512-rTVhhFrpnZJnNvCCdC6RjhFPk0S6mJ2VAix93vbDD19ixlrSJtoNqkk49wvR10PImBSsuGJf35gMQwn2mjer6A==} dependencies: cross-fetch: 3.1.5 transitivePeerDependencies: - encoding dev: false - /i18next/22.0.6: - resolution: {integrity: sha512-RlreNGoPIdDP4QG+qSA9PxZKGwlzmcozbI9ObI6+OyUa/Rp0EjZZA9ubyBjw887zVNZsC+7FI3sXX8oiTzAfig==} + /i18next/22.4.5: + resolution: {integrity: sha512-Kc+Ow0guRetUq+kv02tj0Yof9zveROPBAmJ8UxxNODLVBRSwsM4iD0Gw3BEieOmkWemF6clU3K1fbnCuTqiN2Q==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 dev: false /iconv-lite/0.6.3: @@ -6688,8 +6440,8 @@ packages: resolution: {integrity: sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.19.6 - '@babel/parser': 7.19.6 + '@babel/core': 7.20.5 + '@babel/parser': 7.20.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.0 @@ -6741,7 +6493,7 @@ packages: '@jest/expect': 29.3.1 '@jest/test-result': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -6760,7 +6512,7 @@ packages: - supports-color dev: true - /jest-cli/29.3.1_@types+node@18.11.9: + /jest-cli/29.3.1_@types+node@18.11.16: resolution: {integrity: sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -6777,7 +6529,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 29.3.1_@types+node@18.11.9 + jest-config: 29.3.1_@types+node@18.11.16 jest-util: 29.3.1 jest-validate: 29.3.1 prompts: 2.4.2 @@ -6788,7 +6540,7 @@ packages: - ts-node dev: true - /jest-config/29.3.1_@types+node@18.11.9: + /jest-config/29.3.1_@types+node@18.11.16: resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -6800,11 +6552,11 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.19.6 + '@babel/core': 7.20.5 '@jest/test-sequencer': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 - babel-jest: 29.3.1_@babel+core@7.19.6 + '@types/node': 18.11.16 + babel-jest: 29.3.1_@babel+core@7.20.5 chalk: 4.1.2 ci-info: 3.3.2 deepmerge: 4.2.2 @@ -6868,7 +6620,7 @@ packages: '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 '@types/jsdom': 20.0.0 - '@types/node': 18.11.9 + '@types/node': 18.11.16 jest-mock: 29.3.1 jest-util: 29.3.1 jsdom: 20.0.0 @@ -6885,7 +6637,7 @@ packages: '@jest/environment': 29.3.1 '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 jest-mock: 29.3.1 jest-util: 29.3.1 dev: true @@ -6901,7 +6653,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.9 + '@types/node': 18.11.16 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -6924,7 +6676,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.9 + '@types/node': 18.11.16 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -6975,7 +6727,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 jest-util: 29.3.1 dev: true @@ -7035,7 +6787,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -7066,7 +6818,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -7089,7 +6841,7 @@ packages: resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} engines: {node: '>= 10.14.2'} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.11.16 graceful-fs: 4.2.10 dev: true @@ -7097,18 +6849,18 @@ packages: resolution: {integrity: sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.19.6 - '@babel/generator': 7.19.6 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.19.6 - '@babel/traverse': 7.19.6 - '@babel/types': 7.19.4 + '@babel/core': 7.20.5 + '@babel/generator': 7.20.5 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.20.5 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 '@jest/expect-utils': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 '@types/babel__traverse': 7.17.1 '@types/prettier': 2.6.3 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.6 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 chalk: 4.1.2 expect: 29.3.1 graceful-fs: 4.2.10 @@ -7134,7 +6886,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 graceful-fs: 4.2.10 is-ci: 2.0.0 @@ -7146,7 +6898,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 chalk: 4.1.2 ci-info: 3.3.2 graceful-fs: 4.2.10 @@ -7173,7 +6925,7 @@ packages: dependencies: ansi-escapes: 6.0.0 chalk: 4.1.2 - jest: 29.3.1_@types+node@18.11.9 + jest: 29.3.1_@types+node@18.11.16 jest-regex-util: 29.2.0 jest-watcher: 29.3.1 slash: 5.0.0 @@ -7187,7 +6939,7 @@ packages: dependencies: '@jest/test-result': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.9 + '@types/node': 18.11.16 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -7199,7 +6951,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.11.16 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -7208,13 +6960,13 @@ packages: resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.11.16 jest-util: 29.3.1 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest/29.3.1_@types+node@18.11.9: + /jest/29.3.1_@types+node@18.11.16: resolution: {integrity: sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -7227,7 +6979,7 @@ packages: '@jest/core': 29.3.1 '@jest/types': 29.3.1 import-local: 3.1.0 - jest-cli: 29.3.1_@types+node@18.11.9 + jest-cli: 29.3.1_@types+node@18.11.16 transitivePeerDependencies: - '@types/node' - supports-color @@ -7353,7 +7105,7 @@ packages: /jss-plugin-camel-case/10.9.2: resolution: {integrity: sha512-wgBPlL3WS0WDJ1lPJcgjux/SHnDuu7opmgQKSraKs4z8dCCyYMx9IDPFKBXQ8Q5dVYij1FFV0WdxyhuOOAXuTg==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 hyphenate-style-name: 1.0.4 jss: 10.9.2 dev: false @@ -7361,21 +7113,21 @@ packages: /jss-plugin-default-unit/10.9.2: resolution: {integrity: sha512-pYg0QX3bBEFtTnmeSI3l7ad1vtHU42YEEpgW7pmIh+9pkWNWb5dwS/4onSfAaI0kq+dOZHzz4dWe+8vWnanoSg==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 jss: 10.9.2 dev: false /jss-plugin-global/10.9.2: resolution: {integrity: sha512-GcX0aE8Ef6AtlasVrafg1DItlL/tWHoC4cGir4r3gegbWwF5ZOBYhx04gurPvWHC8F873aEGqge7C17xpwmp2g==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 jss: 10.9.2 dev: false /jss-plugin-nested/10.9.2: resolution: {integrity: sha512-VgiOWIC6bvgDaAL97XCxGD0BxOKM0K0zeB/ECyNaVF6FqvdGB9KBBWRdy2STYAss4VVA7i5TbxFZN+WSX1kfQA==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 jss: 10.9.2 tiny-warning: 1.0.3 dev: false @@ -7383,14 +7135,14 @@ packages: /jss-plugin-props-sort/10.9.2: resolution: {integrity: sha512-AP1AyUTbi2szylgr+O0OB7gkIxEGzySLITZ2GpsaoX72YMCGI2jYAc+WUhPfvUnZYiauF4zTnN4V4TGuvFjJlw==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 jss: 10.9.2 dev: false /jss-plugin-rule-value-function/10.9.2: resolution: {integrity: sha512-vf5ms8zvLFMub6swbNxvzsurHfUZ5Shy5aJB2gIpY6WNA3uLinEcxYyraQXItRHi5ivXGqYciFDRM2ZoVoRZ4Q==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 jss: 10.9.2 tiny-warning: 1.0.3 dev: false @@ -7398,7 +7150,7 @@ packages: /jss-plugin-vendor-prefixer/10.9.2: resolution: {integrity: sha512-SxcEoH+Rttf9fEv6KkiPzLdXRmI6waOTcMkbbEFgdZLDYNIP9UKNHFy6thhbRKqv0XMQZdrEsbDyV464zE/dUA==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 css-vendor: 2.0.8 jss: 10.9.2 dev: false @@ -7406,7 +7158,7 @@ packages: /jss/10.9.2: resolution: {integrity: sha512-b8G6rWpYLR4teTUbGd4I4EsnWjg7MN0Q5bSsjKhVkJVjhQDy2KzkbD2AW3TuT0RYZVmZZHKIrXDn6kjU14qkUg==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 csstype: 3.1.1 is-in-browser: 1.1.3 tiny-warning: 1.0.3 @@ -7571,11 +7323,11 @@ packages: hasBin: true dev: true - /magic-string/0.26.7: - resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==} + /magic-string/0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} engines: {node: '>=12'} dependencies: - sourcemap-codec: 1.4.8 + '@jridgewell/sourcemap-codec': 1.4.14 dev: true /make-dir/3.1.0: @@ -8073,7 +7825,7 @@ packages: /parse5/7.0.0: resolution: {integrity: sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==} dependencies: - entities: 4.3.1 + entities: 4.4.0 dev: true /pascalcase/0.1.1: @@ -8138,8 +7890,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /postcss/8.4.18: - resolution: {integrity: sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==} + /postcss/8.4.20: + resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -8164,8 +7916,8 @@ packages: fast-diff: 1.2.0 dev: true - /prettier/2.8.0: - resolution: {integrity: sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==} + /prettier/2.8.1: + resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -8236,11 +7988,11 @@ packages: react: 18.2.0 dev: false - /query-string/7.1.1: - resolution: {integrity: sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==} + /query-string/7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} engines: {node: '>=6'} dependencies: - decode-uri-component: 0.2.0 + decode-uri-component: 0.2.2 filter-obj: 1.1.0 split-on-first: 1.1.0 strict-uri-encode: 2.0.0 @@ -8264,8 +8016,8 @@ packages: react: 18.2.0 scheduler: 0.23.0 - /react-i18next/12.0.0_nger6pvrp5hnzeykouhwqmsdti: - resolution: {integrity: sha512-/O7N6aIEAl1FaWZBNvhdIo9itvF/MO/nRKr9pYqRc9LhuC1u21SlfwpiYQqvaeNSEW3g3qUXLREOWMt+gxrWbg==} + /react-i18next/12.1.1_ewanii43wbrufvukcu3uzq3hsy: + resolution: {integrity: sha512-mFdieOI0LDy84q3JuZU6Aou1DoWW2fhapcTGeBS8+vWSJuViuoCLQAMYSb0QoHhXS8B0WKUOPpx4cffAP7r/aA==} peerDependencies: i18next: '>= 19.0.0' react: '>= 16.8.0 || 18' @@ -8277,9 +8029,9 @@ packages: react-native: optional: true dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.6 html-parse-stringify: 3.0.1 - i18next: 22.0.6 + i18next: 22.4.5 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 dev: false @@ -8306,41 +8058,31 @@ packages: react: 18.2.0 dev: false - /react-otp-input/2.4.0_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-AIgl7u4sS9BTNCxX1xlaS5fPWay/Zml8Ho5LszXZKXrH1C/TiFsTQGmtl13UecQYO3mSF3HUzG2rrDf0sjEFmg==} - peerDependencies: - react: ^16.2.0 || 18 - react-dom: ^16.2.0 || 18 - dependencies: - react: 18.2.0 - react-dom: 18.2.0_react@18.2.0 - dev: false - /react-refresh/0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} dev: true - /react-router-dom/6.4.3_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ==} + /react-router-dom/6.5.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-/XzRc5fq80gW1ctiIGilyKFZC/j4kfe75uivMsTChFbkvrK4ZrF3P3cGIc1f/SSkQ4JiJozPrf+AwUHHWVehVg==} engines: {node: '>=14'} peerDependencies: react: '>=16.8 || 18' react-dom: '>=16.8 || 18' dependencies: - '@remix-run/router': 1.0.3 + '@remix-run/router': 1.1.0 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-router: 6.4.3_react@18.2.0 + react-router: 6.5.0_react@18.2.0 dev: false - /react-router/6.4.3_react@18.2.0: - resolution: {integrity: sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA==} + /react-router/6.5.0_react@18.2.0: + resolution: {integrity: sha512-fqqUSU0NC0tSX0sZbyuxzuAzvGqbjiZItBQnyicWlOUmzhAU8YuLgRbaCL2hf3sJdtRy4LP/WBrWtARkMvdGPQ==} engines: {node: '>=14'} peerDependencies: react: '>=16.8 || 18' dependencies: - '@remix-run/router': 1.0.3 + '@remix-run/router': 1.1.0 react: 18.2.0 dev: false @@ -8371,7 +8113,7 @@ packages: react: '>=16.6.0 || 18' react-dom: '>=16.6.0 || 18' dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -8385,6 +8127,16 @@ packages: dependencies: loose-envify: 1.4.0 + /react18-input-otp/1.1.1_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-rbqYoLFB3Lp+rJvHv+Ro3E65gberxTBTKdZV8LU/wKo60w6j8lNBmwrtzhH30wS00MhxVkwjUlLYVtzK16ynjQ==} + peerDependencies: + react: 16.2.0 - 18 || 18 + react-dom: 16.2.0 - 18 || 18 + dependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /read-pkg-up/7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -8413,15 +8165,6 @@ packages: util-deprecate: 1.0.2 dev: true - /recrawl-sync/2.2.2: - resolution: {integrity: sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==} - dependencies: - '@cush/relative': 1.0.0 - glob-regex: 0.3.2 - slash: 3.0.0 - tslib: 1.14.1 - dev: true - /redent/3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -8441,16 +8184,13 @@ packages: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} dev: true - /regenerator-runtime/0.13.10: - resolution: {integrity: sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==} - - /regenerator-runtime/0.13.9: - resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} + /regenerator-runtime/0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} /regenerator-transform/0.15.0: resolution: {integrity: sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 dev: true /regex-not/1.0.2: @@ -8596,9 +8336,9 @@ packages: fsevents: 2.3.2 dev: true - /rollup/2.79.1: - resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} - engines: {node: '>=10.0.0'} + /rollup/3.7.4: + resolution: {integrity: sha512-jN9rx3k5pfg9H9al0r0y1EYKSeiRANZRYX32SuNXAnKzh6cVyf4LZVto1KAuDnbHT03E1CpsgqDKaqQ8FZtgxw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: fsevents: 2.3.2 @@ -8801,7 +8541,7 @@ packages: deprecated: See https://github.com/lydell/source-map-resolve#deprecated dependencies: atob: 2.1.2 - decode-uri-component: 0.2.0 + decode-uri-component: 0.2.2 resolve-url: 0.2.1 source-map-url: 0.4.1 urix: 0.1.0 @@ -8828,10 +8568,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /sourcemap-codec/1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - dev: true - /spdx-correct/3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} dependencies: @@ -9159,7 +8895,7 @@ packages: engines: {node: '>=8'} dev: true - /ts-node/10.9.0_omfyfib2yqj7pu7wtuw6wjyhwa: + /ts-node/10.9.0_hylbnkdpdgf7fwrtnxxops6eba: resolution: {integrity: sha512-bunW18GUyaCSYRev4DPf4SQpom3pWH29wKl0sDk5zE7ze19RImEVhCW7K4v3hHKkUyfWotU08ToE2RS+Y49aug==} hasBin: true peerDependencies: @@ -9185,11 +8921,24 @@ packages: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 4.9.3 + typescript: 4.9.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 dev: true + /tsconfck/2.0.1_typescript@4.9.4: + resolution: {integrity: sha512-/ipap2eecmVBmBlsQLBRbUmUNFwNJV/z2E+X0FPtHNjPwroMZQ7m39RMaCywlCulBheYXgMdUlWDd9rzxwMA0Q==} + engines: {node: ^14.13.1 || ^16 || >=18, pnpm: ^7.0.1} + hasBin: true + peerDependencies: + typescript: ^4.3.5 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 4.9.4 + dev: true + /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: @@ -9199,14 +8948,6 @@ packages: strip-bom: 3.0.0 dev: true - /tsconfig-paths/4.0.0: - resolution: {integrity: sha512-SLBg2GBKlR6bVtMgJJlud/o3waplKtL7skmLkExomIiaAtLGtVsoXIqP3SYdjbcH9lq/KVv7pMZeCBpLYOit6Q==} - dependencies: - json5: 2.2.1 - minimist: 1.2.6 - strip-bom: 3.0.0 - dev: true - /tslib/1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true @@ -9215,14 +8956,14 @@ packages: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: true - /tsutils/3.21.0_typescript@4.9.3: + /tsutils/3.21.0_typescript@4.9.4: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.9.3 + typescript: 4.9.4 dev: true /type-check/0.3.2: @@ -9280,8 +9021,8 @@ packages: is-typedarray: 1.0.0 dev: true - /typescript/4.9.3: - resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} + /typescript/4.9.4: + resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} hasBin: true dev: true @@ -9341,7 +9082,7 @@ packages: /unload/2.3.1: resolution: {integrity: sha512-MUZEiDqvAN9AIDRbbBnVYVvfcR6DrjCqeU2YQMmliFZl9uaBUjTkhuDQkBiyAy8ad5bx1TXVbqZ3gg7namsWjA==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 detect-node: 2.1.0 dev: false @@ -9364,17 +9105,6 @@ packages: picocolors: 1.0.0 dev: true - /update-browserslist-db/1.0.4_browserslist@4.21.2: - resolution: {integrity: sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.2 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -9415,7 +9145,7 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-plugin-eslint/1.8.1_eslint@8.28.0+vite@3.2.4: + /vite-plugin-eslint/1.8.1_eslint@8.30.0+vite@4.0.1: resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==} peerDependencies: eslint: '>=7' @@ -9423,13 +9153,13 @@ packages: dependencies: '@rollup/pluginutils': 4.2.1 '@types/eslint': 8.4.5 - eslint: 8.28.0 + eslint: 8.30.0 rollup: 2.78.0 - vite: 3.2.4_@types+node@18.11.9 + vite: 4.0.1_@types+node@18.11.16 dev: true - /vite-plugin-istanbul/3.0.2: - resolution: {integrity: sha512-eOKedaeciqJTLEAUo7mkMqXjjeAXGhHUYuiLLBUaBwj8AdO31uVOsZvKeVViRqHKyhi5YlarmGh8r7jJVlX0VQ==} + /vite-plugin-istanbul/3.0.4: + resolution: {integrity: sha512-DJy3cq6yOFbsM3gLQf/3zeuaJNJsfBv5dLFdZdv8sUV30xLtZI+66QeYfHUyP/5vBUYyLA+xNUCSG5uHY6w+5g==} dependencies: '@istanbuljs/load-nyc-config': 1.1.0 istanbul-lib-instrument: 5.2.0 @@ -9439,36 +9169,35 @@ packages: - supports-color dev: true - /vite-plugin-svgr/2.2.2_vite@3.2.4: - resolution: {integrity: sha512-u8Ac27uZmDHTVGawpAhvLMJMuzbGeZGhe61TGeHoRQLxVhmQfIYCefa0iLbjC0ui1zFo6XZnS8EkzPITCYp85g==} + /vite-plugin-svgr/2.4.0_vite@4.0.1: + resolution: {integrity: sha512-q+mJJol6ThvqkkJvvVFEndI4EaKIjSI0I3jNFgSoC9fXAz1M7kYTVUin8fhUsFojFDKZ9VHKtX6NXNaOLpbsHA==} peerDependencies: - vite: ^2.6.0 || 3 + vite: ^2.6.0 || 3 || 4 dependencies: - '@rollup/pluginutils': 5.0.1 - '@svgr/core': 6.4.0 - vite: 3.2.4_@types+node@18.11.9 + '@rollup/pluginutils': 5.0.2 + '@svgr/core': 6.5.1 + vite: 4.0.1_@types+node@18.11.16 transitivePeerDependencies: - - '@babel/core' - rollup - supports-color dev: true - /vite-tsconfig-paths/3.6.0_vite@3.2.4: - resolution: {integrity: sha512-UfsPYonxLqPD633X8cWcPFVuYzx/CMNHAjZTasYwX69sXpa4gNmQkR0XCjj82h7zhLGdTWagMjC1qfb9S+zv0A==} + /vite-tsconfig-paths/4.0.3_rftvpiefqgupx5rdsozqbqx3tq: + resolution: {integrity: sha512-gRO2Q/tOkV+9kMht5tz90+IaEKvW2zCnvwJV3tp2ruPNZOTM5rF+yXorJT4ggmAMYEaJ3nyXjx5P5jY5FwiZ+A==} peerDependencies: vite: '>2.0.0-0' dependencies: debug: 4.3.4 globrex: 0.1.2 - recrawl-sync: 2.2.2 - tsconfig-paths: 4.0.0 - vite: 3.2.4_@types+node@18.11.9 + tsconfck: 2.0.1_typescript@4.9.4 + vite: 4.0.1_@types+node@18.11.16 transitivePeerDependencies: - supports-color + - typescript dev: true - /vite/3.2.4_@types+node@18.11.9: - resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} + /vite/4.0.1_@types+node@18.11.16: + resolution: {integrity: sha512-kZQPzbDau35iWOhy3CpkrRC7It+HIHtulAzBhMqzGHKRf/4+vmh8rPDDdv98SWQrFWo6//3ozwsRmwQIPZsK9g==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -9492,17 +9221,17 @@ packages: terser: optional: true dependencies: - '@types/node': 18.11.9 - esbuild: 0.15.16 - postcss: 8.4.18 + '@types/node': 18.11.16 + esbuild: 0.16.7 + postcss: 8.4.20 resolve: 1.22.1 - rollup: 2.79.1 + rollup: 3.7.4 optionalDependencies: fsevents: 2.3.2 dev: true /void-elements/3.1.0: - resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} dev: false diff --git a/web/src/views/LoginPortal/SecondFactor/OTPDial.tsx b/web/src/views/LoginPortal/SecondFactor/OTPDial.tsx index 4694688c4..b05660a46 100644 --- a/web/src/views/LoginPortal/SecondFactor/OTPDial.tsx +++ b/web/src/views/LoginPortal/SecondFactor/OTPDial.tsx @@ -3,7 +3,7 @@ import React, { Fragment } from "react"; import { Theme } from "@mui/material"; import makeStyles from "@mui/styles/makeStyles"; import classnames from "classnames"; -import OtpInput from "react-otp-input"; +import OtpInput from "react18-input-otp"; import SuccessIcon from "@components/SuccessIcon"; import TimerIcon from "@components/TimerIcon"; @@ -57,7 +57,7 @@ const useStyles = makeStyles((theme: Theme) => ({ }, otpDigitInput: { boxSizing: "content-box", - padding: theme.spacing(), + padding: theme.spacing() + " !important", marginLeft: theme.spacing(0.5), marginRight: theme.spacing(0.5), fontSize: "1rem",