From da347acb35bb7fb1f4abb3887276781732264013 Mon Sep 17 00:00:00 2001 From: lskramarov Date: Thu, 13 Aug 2026 00:02:21 +0300 Subject: [PATCH 1/4] chore(e2e): run Playwright visual tests in Docker (#DS-5311) Backport of #1845 and #1886 from main. The screenshot baselines are compared with threshold: 0 and carry no {platform} suffix, so they belong to one OS and one browser build. Until now a developer could neither run nor regenerate them off CI, and CI itself was pinned only by whatever ubuntu-latest meant that week. Deliberate divergences from main, none of which have a counterpart there: - the base image is pinned to the v1.55.0-noble digest, matching this branch's Playwright rather than main's 1.62.1; - @playwright/test drops its caret. It already resolved to 1.55.0, so nothing installed changes, but tools/e2e/run.js needs an exact version to name an image tag, and a patch bump moves the bundled Chromium and invalidates every baseline; - packages/cdk joins the build-context allowlist. 73 files under packages/components import @koobiq/cdk/{a11y,keycodes,testing}; on main the CDK lives inside components/core and needs no entry; - the ignore rules land in .eslintignore, since this branch predates the flat config; - everything about the docs smoke suite is dropped - there is no e2e:docs script and no playwright.docs.config.ts here. No baseline is regenerated: all 182 pass unchanged inside the container. --- .eslintignore | 6 + .gitattributes | 11 + .github/workflows/e2e-approve-snapshots.yml | 24 ++- .github/workflows/e2e.yml | 44 +++- .prettierignore | 4 + AGENTS.md | 9 + docs/guides/06-testing.md | 60 ++++++ package.json | 4 +- packages/e2e/README.md | 21 ++ playwright.config.ts | 50 ++++- tools/e2e/Dockerfile | 134 +++++++++++++ tools/e2e/Dockerfile.dockerignore | 78 ++++++++ tools/e2e/assert-browsers.js | 73 +++++++ tools/e2e/docker-compose.update.yml | 27 +++ tools/e2e/docker-compose.yml | 54 +++++ tools/e2e/run.js | 211 ++++++++++++++++++++ yarn.lock | 4 +- 17 files changed, 799 insertions(+), 15 deletions(-) create mode 100644 .gitattributes create mode 100644 tools/e2e/Dockerfile create mode 100644 tools/e2e/Dockerfile.dockerignore create mode 100644 tools/e2e/assert-browsers.js create mode 100644 tools/e2e/docker-compose.update.yml create mode 100644 tools/e2e/docker-compose.yml create mode 100644 tools/e2e/run.js diff --git a/.eslintignore b/.eslintignore index a8785a4159..9e18c02c13 100644 --- a/.eslintignore +++ b/.eslintignore @@ -15,3 +15,9 @@ node_modules # ignore mocks **/mock.ts + +# ignore Playwright's output, for the same reason as dist: the HTML report embeds the minified trace +# viewer. Both directories are mounted out of the container by tools/e2e/docker-compose.yml and turn +# up as soon as anyone runs the suite locally — but, like dist, never on the fresh checkout CI lints. +/playwright-report/ +/test-results/ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..b0aa6ad401 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Deliberately narrow. `* text=auto` is tempting but would renormalize every tracked file in a +# single commit, so line endings are left alone except where they are load-bearing. + +# The Docker build inputs are consumed by a Linux shell. A contributor with core.autocrlf=true +# would otherwise commit CRLF into the Dockerfile's `RUN` continuations and the yarn shim it +# writes. +tools/e2e/** text eol=lf + +# Git already detects these as binary; declaring it means no future filter or `text=auto` change +# can start mangling the screenshot baselines, which are compared byte-for-byte at threshold: 0. +*.png binary diff --git a/.github/workflows/e2e-approve-snapshots.yml b/.github/workflows/e2e-approve-snapshots.yml index 1921d5e9ac..e132d1b7b2 100644 --- a/.github/workflows/e2e-approve-snapshots.yml +++ b/.github/workflows/e2e-approve-snapshots.yml @@ -17,7 +17,9 @@ jobs: approve_snapshots: if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/approve-snapshots') && contains(fromJSON('["OWNER", "MEMBER"]'), github.event.comment.author_association) }} runs-on: ubuntu-latest - timeout-minutes: 30 + # Same as e2e.yml: the container is rebuilt from scratch on every run, so the old 30-minute + # budget no longer covers a cold start. + timeout-minutes: 60 steps: - uses: xt0rted/pull-request-comment-branch@e8b8daa837e8ea7331c0003c9c316a64c6d8b0b1 # v3.0.0 id: comment-branch @@ -27,11 +29,23 @@ jobs: - uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1 with: message: 🔄 [Updating](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) snapshots. - - uses: ./.github/workflows/actions/setup-node - - run: yarn run e2e:setup + # Regenerated in the same container that e2e.yml compares against. Doing it on the bare + # runner instead would mean the baselines are written by one renderer and checked by another, + # and this workflow would happily commit screenshots that fail the very next run. + # + # docker compose creates a missing bind-mount source as root; packages/components already + # exists from the checkout, so only the report directories need creating up front. + - run: mkdir -p playwright-report test-results + # npm rather than yarn: no setup-node here, so the repository's Yarn 4 release is not on + # PATH. The container does its own install. e2e:docker:update-snapshots additionally mounts + # packages/components, which is how the rewritten PNGs reach the working tree for the commit + # step below. - id: update-snapshots - run: | - yarn run e2e:components --update-snapshots + run: npm run e2e:docker:update-snapshots + env: + # As in e2e.yml: the compose default is tuned for developer machines, the runner wants + # its own core count. + PLAYWRIGHT_WORKERS: 100% - uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0 id: commit-and-push with: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ebf77a6485..c315920d85 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -7,20 +7,52 @@ on: pull_request: permissions: - contents: write + contents: read pull-requests: write jobs: + # Runs in the container built from tools/e2e/, not on the runner directly. The screenshots are + # compared with threshold: 0 against baselines that carry no {platform} suffix, so the thing that + # produces them has to be pinned; a bare runner is only pinned by whatever `ubuntu-latest` happens + # to mean this week. The same image is what `yarn run e2e:docker` gives a developer locally, which + # is the point — a failure here is reproducible off CI. + # + # Regeneration must go through the same image: see .github/workflows/e2e-approve-snapshots.yml. tests: runs-on: ubuntu-latest - timeout-minutes: 30 + # 30 minutes was sized for a job that only downloaded browsers. GitHub-hosted runners keep no + # Docker layer cache between runs, so every run now also pulls the base image and rebuilds the + # Node, font and `yarn install` layers from scratch. + timeout-minutes: 60 + permissions: + contents: read # for actions/checkout to read the repository + pull-requests: write # for thollander/actions-comment-pull-request to comment on PRs steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: ./.github/workflows/actions/setup-node - - run: yarn run e2e:setup + # No setup-node and no browser install: node is already on the runner, tools/e2e/run.js only + # reads package.json, and the browsers come baked into the image. That removes the ~174 MB + # `playwright install` download this job used to nurse through a timeout — but it is not a + # net time saving and should not be read as one, since the image build replaces it. + # + # What is bought with that is reproducibility, not speed. If the wall clock ever does become + # the problem, the answer is a prebuilt image pulled from GHCR by tag — not + # `cache-to: type=gha`, which would push well over a gigabyte of layers into the same 10 GB + # Actions cache that every other job's yarn cache is competing for. + # + # docker compose creates a missing bind-mount source as root. Creating them up front keeps + # the workspace owned by the runner user, which matters on self-hosted runners where the + # next job has to clean it up. + - run: mkdir -p playwright-report test-results + # npm rather than yarn: without setup-node the repository's Yarn 4 release is never put on + # PATH, and the runner's own `yarn` is v1, which cannot read this manifest. Nothing is + # installed here either — the container does its own yarn install. - id: run-e2e-tests - run: | - yarn run e2e:components + run: npm run e2e:docker + env: + # Back to the runner's own setting. The compose file caps workers for developer machines, + # where a container sees far more cores than one dev server can be driven from; a 4-vCPU + # runner has the opposite problem and wants all of them. + PLAYWRIGHT_WORKERS: 100% - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ always() }} id: upload-report diff --git a/.prettierignore b/.prettierignore index 1076d9739e..b0e523adf1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -25,3 +25,7 @@ apps/docs/src/app/components/design-tokens-viewers/data/*.ts # ignore mocks **/mock.ts + +# ignore Playwright's output — see .eslintignore +/playwright-report/ +/test-results/ diff --git a/AGENTS.md b/AGENTS.md index 1680bc6953..3a8eb7355b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -82,8 +82,17 @@ npx jest # Run specific Jest tests (e.g., npx jest pac yarn run e2e:setup # Install Playwright browsers (run once) yarn run e2e:components # Run all E2E tests npx playwright test # Run specific E2E tests (e.g., npx playwright test packages/components/button/e2e.playwright-spec.ts) + +# Screenshots differ across operating systems — always use Docker for anything visual: +yarn run e2e:docker # Run E2E tests in Docker (matches CI) +yarn run e2e:docker:update-snapshots # Run E2E tests in Docker and update the baselines ``` +The committed baselines under `__screenshots__` are compared with `threshold: 0` and have no +platform suffix, so a native run outside Linux fails on font rasterization alone. `e2e:components` +is still useful for the assertion-based specs; use `e2e:docker` whenever screenshots are involved, +and never regenerate a baseline any other way. + ### Linting ```bash diff --git a/docs/guides/06-testing.md b/docs/guides/06-testing.md index aa059a9083..0bda76f8a7 100644 --- a/docs/guides/06-testing.md +++ b/docs/guides/06-testing.md @@ -41,3 +41,63 @@ yarn run e2e:setup ```bash yarn run e2e:components ``` + +### Visual regression tests and Docker + +The screenshot baselines committed under `__screenshots__` are compared with `threshold: 0` and carry +no platform suffix, so they are tied to one operating system and one browser build. Running the suite +natively on Windows or macOS compares your machine's font rasterization against Linux bytes and fails +regardless of whether anything actually changed. + +Run anything visual in Docker instead. The image is built from the Playwright release matching +`@playwright/test` in `package.json`, which is what CI runs too: + +```bash +yarn run e2e:docker +``` + +To accept intentional visual changes, regenerate the baselines the same way and commit the result: + +```bash +yarn run e2e:docker:update-snapshots +``` + +Arguments are passed through, replacing the container's command — for example, to run one component: + +```bash +yarn run e2e:docker yarn playwright test packages/components/button +``` + +The container always runs with `CI=true`, so that Playwright behaves the way it does on the runner. +Two consequences matter when debugging inside it: `test.only` is rejected outright rather than +honoured (`forbidOnly`), and a failing test is retried twice before being reported. Narrow a run with +a path and `-g` instead of `test.only`: + +```bash +yarn run e2e:docker yarn playwright test packages/components/select -g "single select" +``` + +Requires Docker with Compose v2. On Windows carrying Docker Engine inside WSL rather than Docker +Desktop, `docker.exe` is often missing from the Windows PATH altogether — the Linux binary cannot be +projected onto it — but the wrapper also falls back to WSL when a `docker.exe` is present yet broken +(no Compose v2 plugin, a stale install). Either way it forwards the run through `wsl.exe` and +translates the paths it passes, so the commands above work unchanged from PowerShell. It looks for +Docker inside WSL's default distribution; set `WSL_DISTRIBUTION` to a distribution name if Docker +lives elsewhere. That check only confirms the CLI and Compose v2 plugin are present, not that the +daemon itself is reachable — a stopped daemon, or a WSL user outside the `docker` group, still +surfaces later, when the actual `docker compose run` fails. + +### Worker count + +A container reports every core on the host, and Playwright sizes its worker pool from that. Since all +workers drive one shared Angular dev server, the useful ceiling comes from that server rather than +from the core count — on a 32-core machine `workers: '100%'` means 64 browsers, and the suite +collapses into timeouts that look like failures but are not. The compose file therefore caps workers +at 8. Override it when a machine wants something different: + +```bash +PLAYWRIGHT_WORKERS=16 yarn run e2e:docker +``` + +Baselines can also be regenerated without a local Docker install by commenting `/approve-snapshots` +on a pull request. diff --git a/package.json b/package.json index 580f89dfb2..d8a76351d7 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@messageformat/core": "^3.4.0", "@microsoft/api-extractor": "7.56.0", "@octokit/rest": "^18.9.1", - "@playwright/test": "^1.55.0", + "@playwright/test": "1.55.0", "@prettier/plugin-xml": "^3.4.2", "@rollup/plugin-commonjs": "^24.0.0", "@rollup/plugin-json": "^6.0.0", @@ -284,6 +284,8 @@ "dev:e2e": "ng serve dev-e2e", "e2e:setup": "playwright install chromium --with-deps && playwright install webkit --with-deps", "e2e:components": "playwright test", + "e2e:docker": "node tools/e2e/run.js", + "e2e:docker:update-snapshots": "node tools/e2e/run.js yarn run e2e:components --update-snapshots", "-----API-----": "--------------------------------------------------------------------------------------------", "approve-api": "ts-node --project tools/api-extractor/tsconfig.json tools/api-extractor/api-extractor.ts", "check-api": "yarn run approve-api onlyCheck", diff --git a/packages/e2e/README.md b/packages/e2e/README.md index baefd4ef1d..9cd102751c 100644 --- a/packages/e2e/README.md +++ b/packages/e2e/README.md @@ -25,3 +25,24 @@ yarn run e2e:components # Run a specific E2E test file yarn playwright test packages/components/button/e2e.playwright-spec.ts ``` + +## Screenshots + +The baselines under each component's `__screenshots__` directory are compared with `threshold: 0` and +have no platform suffix, so they belong to one operating system and one browser build. The commands +above only compare them meaningfully on Linux; anywhere else they fail on font rasterization alone. + +Run anything visual in Docker, which uses the Playwright image matching `@playwright/test` and is what +CI runs as well: + +```bash +# Run the suite in Docker +yarn run e2e:docker + +# Accept intentional visual changes and rewrite the baselines +yarn run e2e:docker:update-snapshots +``` + +Requires Docker with Compose v2 — see [Testing → Visual regression tests and Docker](../../docs/guides/06-testing.md#visual-regression-tests-and-docker) +for what the wrapper does on Windows when Docker only runs inside WSL. Without a local Docker +install, comment `/approve-snapshots` on a pull request to regenerate the baselines in CI. diff --git a/playwright.config.ts b/playwright.config.ts index d49b88feb0..ff74b930be 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -8,6 +8,49 @@ const viewport: ViewportSize = { const baseURL = process.env.BASE_URL || 'http://localhost:4200'; const webServerCommand = process.env.WEB_SERVER_COMMAND || 'yarn run dev:e2e --configuration=production'; +/** + * Every worker drives its own browser against one shared Angular dev server, so the useful ceiling + * comes from that server rather than from the core count. '100%' suits a 4-vCPU CI runner, but not + * Docker: a container reports every core on the host (Playwright reads `os.cpus()`, which no cgroup + * or cpuset limit affects), so on a 32-core machine it means 64 browsers and the suite collapses + * into timeouts. tools/e2e's compose file caps it via PLAYWRIGHT_WORKERS and CI sets it back. + * + * Playwright only accepts a string when it is a percentage, so anything else has to become a number. + * With the variable unset this behaves exactly as it did before. + * + * The value is validated rather than passed through, because Playwright's own guard only rejects + * `workers <= 0` — and `NaN <= 0` is false. A typo like `PLAYWRIGHT_WORKERS=amx` would therefore + * reach the dispatcher's `for (i = 0; i < workers; i++)` loop, spawn zero workers, run zero tests, + * write no report, and still exit 0: a green suite that tested nothing. + */ +const resolveWorkers = () => { + const override = process.env.PLAYWRIGHT_WORKERS?.trim(); + + if (!override) { + return isCI ? '100%' : undefined; + } + + if (override.endsWith('%')) { + const percentage = Number(override.slice(0, -1)); + + if (!Number.isFinite(percentage) || percentage <= 0) { + throw new Error(`PLAYWRIGHT_WORKERS must be a positive percentage, got ${JSON.stringify(override)}.`); + } + + return override; + } + + const workers = Number(override); + + if (!Number.isInteger(workers) || workers <= 0) { + throw new Error( + `PLAYWRIGHT_WORKERS must be a positive integer or a percentage, got ${JSON.stringify(override)}.` + ); + } + + return workers; +}; + /** @see https://playwright.dev/docs/test-configuration */ export default defineConfig({ testDir: __dirname, @@ -17,7 +60,7 @@ export default defineConfig({ fullyParallel: true, forbidOnly: isCI, retries: isCI ? 2 : 0, - workers: isCI ? '100%' : undefined, + workers: resolveWorkers(), reporter: [ ['list', { printSteps: true }], ['html', { open: 'never' }] @@ -32,6 +75,11 @@ export default defineConfig({ } ], expect: { + // These baselines are compared with threshold: 0, so they are tied to one exact browser + // build. @playwright/test is pinned to an exact version in package.json for that reason: + // even a patch release can bump the bundled Chromium — 1.55.0 shipped build 1187 and + // 1.55.1 shipped 1193 — and that invalidates every screenshot. Upgrade it on its own + // branch and refresh the baselines with /approve-snapshots in the same pull request. toHaveScreenshot: { pathTemplate: '{testFileDir}/__screenshots__/{arg}{ext}', threshold: 0, diff --git a/tools/e2e/Dockerfile b/tools/e2e/Dockerfile new file mode 100644 index 0000000000..4de1365cb1 --- /dev/null +++ b/tools/e2e/Dockerfile @@ -0,0 +1,134 @@ +# syntax=docker/dockerfile:1.7 +# +# Runs the Playwright component suite in the same browser, operating system and font stack as CI, +# so that `expect.toHaveScreenshot` produces identical pixels on any developer machine. +# +# Build it through `yarn run e2e:docker` (tools/e2e/run.js), which derives PLAYWRIGHT_VERSION from +# package.json so the image tag cannot drift from the installed @playwright/test. +ARG PLAYWRIGHT_VERSION + +# Digest-pinned deliberately. The suite compares with `threshold: 0`, which makes the base image +# part of the compiler: were Microsoft to re-push this tag over a newer apt snapshot, every +# committed screenshot would change with no commit to blame it on. +# +# Once a digest is present Docker resolves it and ignores the tag, so the tag is documentation and +# the browser-revision assertion below is what actually keeps the two honest. When bumping +# @playwright/test, bump this digest in the same pull request and regenerate the baselines there: +# +# docker buildx imagetools inspect mcr.microsoft.com/playwright:v-noble --format '{{.Manifest.Digest}}' +# +# noble is Ubuntu 24.04, matching the `ubuntu-latest` runner the current baselines came from. +FROM mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-noble@sha256:b27e719ecbfef153e13fd24e8341736733bf2658b229677eb21ff57ff5d7fb29 + +WORKDIR /app + +# CI=true selects the same Playwright behavior as the runner: retries: 2, forbidOnly, and +# reuseExistingServer: false. It would also mean workers: '100%', which is wrong in a container — +# see the PLAYWRIGHT_WORKERS note in tools/e2e/docker-compose.yml. +# +# forbidOnly is the one that surprises people: `test.only` is rejected here rather than honoured, so +# a run is narrowed with a path and `-g`. Parity is worth more than the convenience — the whole +# point of this image is that a local run and the runner cannot disagree — but it is documented in +# docs/guides/06-testing.md rather than left to be discovered. +# +# TZ is belt-and-braces rather than a fix: the base image currently resolves to Etc/UTC, matching +# the runner, even though it is built with `ARG TZ=America/Los_Angeles`. Since it is the build +# argument and not the image that says otherwise, that agreement is incidental — and +# playwright.config.ts pins neither `locale` nor `timezoneId`, so the datepicker, timepicker and +# timezone screenshots would silently follow the base image if it ever changed. Stating it costs +# nothing. LANG and LC_ALL are already C.UTF-8 in the base image. +# +# HUSKY=0 because `prepare: husky` runs during `yarn install` and there is no .git in the context. +ENV CI=true \ + TZ=UTC \ + HUSKY=0 \ + YARN_ENABLE_TELEMETRY=0 + +# Body text is bundled woff2 (@fontsource/inter, @fontsource/jetbrains-mono), so system fonts only +# matter for glyphs Inter lacks. The baselines were rendered on ubuntu-latest, which ships DejaVu; +# this base image does not, and falls through to IPAGothic instead. Matching the runner's fallback +# face is the whole premise of this image, so it is installed here rather than left to chance. +# +# Unlike on main, no source on this branch currently renders a glyph that exercises it: the macOS +# modifier symbols ⌘ (U+2318) and ⌥ (U+2325) reach the select and tree-select captions through the +# "select all" master checkbox (#DS-3969), which 19.x does not have. That makes this layer cheap +# insurance rather than a fix for a failure you can reproduce today — keep it anyway, because the +# first backport that does introduce such a glyph would otherwise fail with no visible cause, and +# because a container whose font set differs from the runner's is not the reproduction it claims +# to be. +# +# The two fc-match calls are the assertion, not a demonstration: they are what stops this layer +# from being "cleaned up" later on the reasonable-sounding grounds that the fonts are bundled. +# U+2318 and U+2325 are still the right probes — they are the codepoints known to fall through. +RUN apt-get update \ + && apt-get install -y --no-install-recommends fonts-dejavu-core \ + && rm -rf /var/lib/apt/lists/* \ + && fc-cache -f \ + && for codepoint in 2318 2325; do \ + fc-match ":charset=$codepoint" family | grep -q '^DejaVu Sans$' \ + || { echo "U+$codepoint falls back to '$(fc-match ":charset=$codepoint" family)', expected DejaVu Sans." >&2; exit 1; }; \ + done + +# The base image ships Node 22 from NodeSource. Every other CI job runs the .nvmrc version, so +# install that rather than accept a second Node major for this one job. Its own layer, ahead of the +# manifests, so that editing package.json does not reinstall Node. +# `n` keeps every version it fetches under /usr/local/n, which is 202 MB of no use once the binary +# is in place. Dropped in the same layer, so the bytes are never committed in the first place. +# +# `n` is version-pinned because an unpinned global install is a hole in an otherwise reproducible +# image: the base image is digest-pinned and Node comes from .nvmrc, but `npm install --global n` +# would resolve to whatever is latest on the day the layer is built. Nothing here reads it after +# the Node binary is in place, so bumping it is routine — it does not move the Node version. +COPY .nvmrc ./ +RUN set -eux; \ + node_version="$(tr -d '\r\n' < .nvmrc)"; \ + npm install --global n@10.2.0; \ + n "$node_version"; \ + npm remove --global n; \ + rm -rf /usr/local/n; \ + npm cache clean --force; \ + test "v$node_version" = "$(node --version)"; \ + node --version + +COPY .yarnrc.yml package.json yarn.lock ./ +COPY .yarn/releases/ .yarn/releases/ + +# The base image has Yarn 1 classic on PATH from its own `npm install -g yarn`. It cannot read a +# Berry lockfile, and playwright.config.ts's webServer command (`yarn run dev:e2e ...`) shells out +# to whatever `yarn` resolves to at test time — so replacing it is required, not a convenience. +# +# A shell script rather than a symlink: the executable bit on the committed .cjs is not guaranteed +# to survive a COPY from a Windows build context. The path is read out of .yarnrc.yml, so this +# cannot drift from `yarnPath`. +RUN set -eux; \ + yarn_path="$(sed -n 's/^yarnPath: *//p' .yarnrc.yml | tr -d '\r')"; \ + test -f "/app/$yarn_path"; \ + printf '#!/bin/sh\nexec node "/app/%s" "$@"\n' "$yarn_path" > /usr/local/bin/yarn; \ + chmod +x /usr/local/bin/yarn; \ + test "4" = "$(yarn --version | cut -d . -f 1)"; \ + yarn --version + +# package.json's postinstall compiles these into node_modules/@koobiq/builders. +COPY tools/builders/ tools/builders/ +COPY tools/e2e/assert-browsers.js tools/e2e/ + +# The cache is cleaned in the same layer rather than a later one: node_modules is already +# materialised by then (nodeLinker: node-modules), and Yarn's global cache is another 640 MB that +# would otherwise be committed and then paid for again on every image export and pull. +RUN yarn install --immutable && yarn cache clean --all + +# Fails the build if the image's browsers are not the ones this @playwright/test expects, which is +# otherwise silent and surfaces much later as an unexplained diff in every screenshot. +RUN node tools/e2e/assert-browsers.js + +COPY . . + +# tools/e2e/Dockerfile.dockerignore is an allowlist, and the failure mode of not reading it at all — +# a builder that is not BuildKit, a rename that leaves the two names out of step — is that the whole +# working tree lands in the image and everything still works, only slower and off a context nobody +# reviewed. CHANGELOG.md is the sentinel because no e2e run will ever have a reason to want it, so +# unlike a directory that might be allowlisted later this cannot quietly become a no-op. +RUN test ! -e CHANGELOG.md \ + || { echo 'tools/e2e/Dockerfile.dockerignore was not applied: the whole working tree is in the image.' >&2; exit 1; } + +CMD ["yarn", "run", "e2e:components"] diff --git a/tools/e2e/Dockerfile.dockerignore b/tools/e2e/Dockerfile.dockerignore new file mode 100644 index 0000000000..cd82fa6220 --- /dev/null +++ b/tools/e2e/Dockerfile.dockerignore @@ -0,0 +1,78 @@ +# Build context for tools/e2e/Dockerfile, whose context is the repository root. +# +# Named after the Dockerfile rather than being a plain `.dockerignore` at the context root so that it +# can live next to the thing it belongs to. BuildKit looks for `.dockerignore` first and +# only falls back to `/.dockerignore`; Compose v2 always builds through BuildKit, so this is +# the file that is read. A plain `.dockerignore` dropped into tools/e2e/ would be read by nothing. +# +# An allowlist: everything is excluded, then the paths the image actually needs are added back. That +# is narrower than a denylist but it fails silently — a missing entry surfaces deep inside +# `ng serve` or `yarn install`, pointing nowhere near the cause. Two things keep it honest: the +# assertion in the Dockerfile that fires if this file is not applied at all, and the fact that the +# list below is short enough to check against the imports it exists for. +# +# Verify with: +# docker build --progress=plain --no-cache -f tools/e2e/Dockerfile \ +# --build-arg PLAYWRIGHT_VERSION= . 2>&1 | grep "transferring context" +# Expect roughly 28 MB. Substantially more means one of the patterns below stopped matching. + +** + +# Yarn 4 and the manifests. .yarn/releases holds the committed Yarn binary that .yarnrc.yml points +# at; without it the image has only the base image's Yarn 1, which cannot read a Berry lockfile. +!.nvmrc +!.yarnrc.yml +!package.json +!yarn.lock +!.yarn/releases/ +!.yarn/releases/** + +# Workspace and TypeScript configuration: the dev server builds `dev-e2e` out of angular.json, and +# playwright.config.ts compiles the specs against tsconfig.playwright-spec.json. +!angular.json +!tsconfig.json +!tsconfig.playwright-spec.json +!playwright.config.ts + +# The library under test, the harness application that renders it, and the Luxon adapter — the e2e +# pages of datepicker, timepicker, filter-bar and notification-center import +# `@koobiq/angular-luxon-adapter/adapter`, so the suite does not start without it. +# +# The specs themselves import only `@playwright/test` and `packages/e2e/utils`, and the e2e pages +# import only `@koobiq/components/*` and that one adapter. +!packages/components/ +!packages/components/** +!packages/e2e/ +!packages/e2e/** +!packages/angular-luxon-adapter/ +!packages/angular-luxon-adapter/** + +# Pulled in transitively rather than by the e2e pages: 73 files under packages/components import +# `@koobiq/cdk/a11y`, `@koobiq/cdk/keycodes` or `@koobiq/cdk/testing`, which tsconfig.json maps to +# packages/cdk/*/index.ts. Leaving it out does not fail the build — `ng serve dev-e2e` starts, fails +# to resolve them, and the run dies at the 10-minute webServer timeout with nothing pointing here. +# It is 62 KB. No equivalent entry exists on main, where the CDK was folded into +# packages/components/core, so do not drop this line while reconciling the two branches. +!packages/cdk/ +!packages/cdk/** + +# The one file the harness borrows from the dev applications: packages/e2e/module.ts puts +# DevThemeToggle in the root component's imports. Listed as a single file rather than the directory +# because the rest of packages/components-dev is ~2 MB of dev apps this image has no use for. +# Without it `ng serve dev-e2e` fails with NG1010 on packages/e2e/module.ts:9 and the run dies at the +# 10-minute webServer timeout. +!packages/components-dev/ +!packages/components-dev/theme-toggle.ts + +# package.json's postinstall compiles tools/builders into node_modules/@koobiq/builders, which the +# `dev-e2e` build then needs; tools/e2e carries assert-browsers.js, which runs during the build. +!tools/builders/ +!tools/builders/** +!tools/e2e/ +!tools/e2e/** + +# Last match wins, so these come after the rules above and take back anything that slipped through +# them — a stray package-level node_modules, build output, or a log. +**/node_modules +**/dist +**/*.log diff --git a/tools/e2e/assert-browsers.js b/tools/e2e/assert-browsers.js new file mode 100644 index 0000000000..92b8d0dcf9 --- /dev/null +++ b/tools/e2e/assert-browsers.js @@ -0,0 +1,73 @@ +/** + * Asserts that the browsers baked into the Playwright base image are the ones the installed + * playwright-core expects. Run at image build time by tools/e2e/Dockerfile. + * + * The image ships its browsers under /ms-playwright, so `playwright install` never runs in the + * container. That only holds while the image tag matches @playwright/test exactly — which is not + * something the Dockerfile can guarantee on its own. `FROM` carries both a tag derived from + * package.json and a digest, and a digest wins: bumping @playwright/test without bumping the digest + * in the same commit changes the tag, resolves the same old image, and leaves the browsers behind. + * + * When the two disagree, nothing fails loudly: `playwright`'s postinstall quietly downloads a + * second browser set, the tests run against a different build than CI, and the result is an + * unexplained diff in every screenshot — the baselines are compared with `threshold: 0`, so a + * different browser build invalidates all of them at once. + * + * This check turns all of that into one build failure with an actionable message. + */ + +const { existsSync, readFileSync } = require('node:fs'); +const { dirname, join } = require('node:path'); + +// playwright-core does not list browsers.json in its "exports" map, so requiring it by subpath +// throws ERR_PACKAGE_PATH_NOT_EXPORTED. package.json is exported; resolve that and read the file +// next to it, which stays correct wherever the package is installed. +const { browsers } = JSON.parse( + readFileSync(join(dirname(require.resolve('playwright-core/package.json')), 'browsers.json'), 'utf8') +); + +// Everything `playwright install` would fetch, rather than a hand-maintained list. Chromium is the +// obvious one, but it is not the only browser this suite uses: the scrollbar and sidepanel specs +// select WebKit with `test.use({ browserName: 'webkit' })`, which overrides the project's browser +// per file and is easy to miss when reading playwright.config.ts alone. Deriving the list means a +// spec that reaches for Firefox tomorrow is covered without anyone remembering to edit this file. +// +// The excluded entries are the ones the image legitimately lacks: tip-of-tree and beta channels, +// `android`, and `winldd` (Windows-only). +const required = browsers.filter((browser) => browser.installByDefault); +const missing = []; + +if (required.length === 0) { + console.error('No installByDefault browsers in playwright-core/browsers.json — the check cannot be trusted.'); + process.exit(1); +} + +for (const { name, revision } of required) { + // playwright-core stores revisions per browser name; on disk the directories use underscores. + const directory = `/ms-playwright/${name.replace(/-/g, '_')}-${revision}`; + + if (existsSync(directory)) { + console.log(`ok ${directory}`); + } else { + missing.push(directory); + } +} + +if (missing.length > 0) { + console.error( + [ + 'The base image does not ship the browsers this @playwright/test expects.', + `Missing: ${missing.join(', ')}`, + '', + 'The pinned digest in tools/e2e/Dockerfile is stale relative to the @playwright/test', + 'version in package.json. Refresh it with:', + '', + ' docker buildx imagetools inspect mcr.microsoft.com/playwright:v-noble \\', + " --format '{{.Manifest.Digest}}'", + '', + 'and regenerate the screenshot baselines in the same pull request.' + ].join('\n') + ); + + process.exit(1); +} diff --git a/tools/e2e/docker-compose.update.yml b/tools/e2e/docker-compose.update.yml new file mode 100644 index 0000000000..b5c7d52f4e --- /dev/null +++ b/tools/e2e/docker-compose.update.yml @@ -0,0 +1,27 @@ +# Overlay applied only by `yarn run e2e:docker:update-snapshots` — see tools/e2e/run.js, which +# adds this file when it sees --update-snapshots in the arguments. +# +# Every one of the __screenshots__ directories lives under packages/components, so a single mount +# is enough for Playwright's --update-snapshots to write the new baselines back to the working +# tree. +# +# Kept out of the base file on purpose. Two reasons, in order of weight: a plain test run has no +# business being able to write into the working tree at all, and the mount puts the component +# library on the Angular build's hot path, which costs about 5 seconds per run across the host +# filesystem boundary (measured: 27s against 32s for the same spec). Updating snapshots is rare and +# can afford both; a plain run should pay for neither. +# +# This is an overlay, not a second configuration: `--file base --file this` merges the two, so +# everything the base file sets and this one does not — `platform` above all, which is what ties the +# baselines to x86-64 — carries over unchanged. Confirm with +# `docker compose --file tools/e2e/docker-compose.yml --file tools/e2e/docker-compose.update.yml config`, +# which prints what the run actually uses. +services: + e2e: + # The report mounts are repeated from the base file on purpose. Compose has merged sequences + # by mount target in some versions and replaced them wholesale in others; spelling all three + # out is correct either way, and a repeated identical target is a no-op when they are merged. + volumes: + - ../../packages/components:/app/packages/components + - ../../playwright-report:/app/playwright-report + - ../../test-results:/app/test-results diff --git a/tools/e2e/docker-compose.yml b/tools/e2e/docker-compose.yml new file mode 100644 index 0000000000..d5468e6a50 --- /dev/null +++ b/tools/e2e/docker-compose.yml @@ -0,0 +1,54 @@ +# Runs the Playwright component suite in the image built from tools/e2e/Dockerfile. +# +# Invoke it through `yarn run e2e:docker` (tools/e2e/run.js), which supplies PLAYWRIGHT_VERSION +# from package.json and checks it is an exact version. Running `docker compose` against this file +# directly leaves that build argument empty, so the tag half of the image reference becomes +# `v-noble`; the pinned digest still resolves the correct image, but the tag no longer records +# which @playwright/test the browsers belong to, and nothing then verifies the two agree. + +# Named explicitly because Compose otherwise derives the project name from this file's directory, +# which is just `e2e` — shared with every other repository that puts its compose file in tools/e2e, +# and enough for two projects to start reusing each other's containers and networks. +name: koobiq-e2e + +services: + e2e: + # The committed baselines are x86-64. Pinning the platform stops an arm64 machine from quietly + # producing renders that differ from CI in a way no diff explains; on Apple Silicon that means + # emulation, which is slow but correct. Override only if you know why. + platform: ${E2E_PLATFORM:-linux/amd64} + build: + context: ../.. + dockerfile: tools/e2e/Dockerfile + args: + - PLAYWRIGHT_VERSION + # Reaps the Chromium processes that would otherwise pile up under PID 1. + init: true + # Recommended upstream for Chromium. Note that the usual justification — Docker's 64 MB + # /dev/shm — does not apply here: Playwright passes --disable-dev-shm-usage unconditionally, so + # Chromium uses /tmp regardless. Kept because upstream still recommends it and it costs nothing. + ipc: host + environment: + # A container resolves `localhost` to both 127.0.0.1 and ::1, and Node >= 17 does not reorder + # them. If the Angular dev server binds v4 only and Playwright's readiness probe tries ::1 + # first, the run dies after the 10-minute webServer timeout with nothing useful in the log. + # Both variables are read by playwright.config.ts. + BASE_URL: http://127.0.0.1:4200 + WEB_SERVER_COMMAND: yarn run dev:e2e --configuration=production --host 127.0.0.1 + # A container reports every core on the host — Playwright reads os.cpus(), which no cgroup or + # cpuset limit affects — so playwright.config.ts's '100%' would mean 64 browsers against one + # dev server on a 32-core machine, and every test times out. Measured on such a machine: 64 + # workers gave 255 failures and 802 timeouts, 8 workers gave zero of either. CI overrides this + # back to '100%', which on a 4-vCPU runner is 4. + # + # 8 rather than a higher guess because it is the value that was actually measured clean; the + # ceiling is the single dev server, not the core count, so raising it buys little. + PLAYWRIGHT_WORKERS: ${PLAYWRIGHT_WORKERS:-8} + # Outputs only — the source tree comes from the image, deliberately, so a plain run cannot write + # anywhere near the working tree. Mounting the sources as well costs about 5 seconds per run + # (measured: 27s against 32s for the same spec), because `ng serve dev-e2e` compiles the whole + # component library and those ~3200 files then cross the host filesystem boundary. Writing + # updated baselines back is docker-compose.update.yml's job instead. + volumes: + - ../../playwright-report:/app/playwright-report + - ../../test-results:/app/test-results diff --git a/tools/e2e/run.js b/tools/e2e/run.js new file mode 100644 index 0000000000..9f468e1ca3 --- /dev/null +++ b/tools/e2e/run.js @@ -0,0 +1,211 @@ +/** + * Runs the Playwright component suite inside Docker, so that screenshots are produced by the same + * browser, operating system and font stack as CI. + * + * Screenshots are compared with `threshold: 0` and the baselines carry no `{platform}` suffix, so a + * native run on Windows or macOS compares its own rasterization against Linux bytes and fails on + * font rendering alone. This wrapper is the supported way to run — and the only supported way to + * update — the committed baselines. + * + * The image tag comes from package.json rather than being hardcoded: the browsers baked into the + * image have to match the installed @playwright/test exactly, and a tag that has drifted from the + * manifest is indistinguishable from a genuine visual regression. + * + * node tools/e2e/run.js # run the suite (the image's CMD) + * node tools/e2e/run.js # replace the image's CMD + * + * Anything after the script name replaces the container's command rather than being appended to + * it — that is how `docker compose run` behaves — which is why the update-snapshots script passes + * the whole command and not just the flag. + */ + +const { spawnSync } = require('node:child_process'); +const { existsSync } = require('node:fs'); +const { basename, join } = require('node:path'); +const { devDependencies } = require('../../package.json'); + +const TIME_LABEL = 'Runtime'; +const COMPOSE_FILE = join(__dirname, 'docker-compose.yml'); +const COMPOSE_UPDATE_FILE = join(__dirname, 'docker-compose.update.yml'); + +const fail = (message) => { + console.error(message); + process.exit(1); +}; + +// Read straight from the manifest rather than from node_modules: CI runs this without an install +// step, so the packages are not on disk. +const version = devDependencies['@playwright/test']; + +// The tag has to be exact. A range would either not resolve to a tag at all or, worse, resolve to +// an image whose browsers differ from the ones the lockfile installs. +if (!/^\d+\.\d+\.\d+$/.test(version)) { + fail( + `Expected devDependencies["@playwright/test"] in package.json to be an exact version, got ${JSON.stringify(version)}.` + ); +} + +// How `docker` is reached. Normally the CLI is on PATH and this is all there is to it; the win32 +// branch below can replace it with a hop through WSL. +let docker = { command: 'docker', prefix: [] }; +let isForwardedToWsl = false; + +// `wsl.exe -e` alone always targets whichever distribution is current default, and there is no way +// to detect the right one automatically when Docker lives in a different one. +const wslDistro = process.env.WSL_DISTRIBUTION; +const wslArgs = (exe) => [...(wslDistro ? ['-d', wslDistro] : []), '-e', exe]; + +// encoding rather than stdio: 'ignore' so a failure can be explained with the command's own stderr +// instead of a guess. Neither probe prints anything unless something goes wrong: spawnSync only +// pipes, it does not inherit. +const probeCompose = (runner) => + spawnSync(runner.command, [...runner.prefix, 'compose', 'version'], { encoding: 'utf8' }); + +const describeFailure = (result) => + result.error ? result.error.message : (result.stderr || '').trim() || `exited with status ${result.status}`; + +// Both prerequisites are checked up front, because neither fails in a way that explains itself. +// A missing `docker` surfaces as a bare ENOENT from spawn; a Docker CLI without the v2 compose +// plugin — a machine carrying only the legacy `docker-compose` binary — spawns fine and exits +// non-zero, which is indistinguishable from a genuine test failure further down. +let compose = probeCompose(docker); + +// On Windows, retry through WSL whenever the direct probe did not cleanly succeed — not only on +// ENOENT. `docker.exe` can also be present but broken (a stale Docker Desktop install, a CLI +// without the compose v2 plugin), and that deserves the same chance to fall through to a working +// WSL-hosted Engine as a missing binary does. +// +// There is no docker.exe for Win32 to find in the WSL-only case — /usr/bin/docker is a Linux ELF +// binary, and while WSL projects Windows executables into the distribution, nothing does the +// reverse — so wsl.exe is the only bridge. A `docker.cmd` shim on PATH would not help either: Node +// does not resolve .bat/.cmd from a non-shell spawn, so the probe above would still ENOENT. Neither +// would a native Windows CLI talking to the WSL daemon over TCP — it resolves the compose file's +// relative volumes into Windows paths and hands them to a Linux daemon, which cannot bind-mount +// `C:\...`. Translating at the wsl.exe boundary (see toDockerPath below) keeps every path +// Linux-side, where compose expects them. +if ((compose.error || compose.status !== 0) && process.platform === 'win32') { + const viaWsl = { command: 'wsl.exe', prefix: wslArgs('docker') }; + const probe = probeCompose(viaWsl); + + if (!probe.error && probe.status === 0) { + docker = viaWsl; + compose = probe; + isForwardedToWsl = true; + } else { + fail( + 'Could not run `docker compose version`:\n' + + ` docker: ${describeFailure(compose)}\n` + + ` wsl.exe ${wslArgs('docker').join(' ')}: ${describeFailure(probe)}` + + (wslDistro + ? '' + : '\nIf Docker lives in a non-default WSL distribution, set WSL_DISTRIBUTION to its name.') + ); + } +} + +// Not folded into the block above: on Windows a missing `docker` already got a chance via WSL, so +// by this point it either forwarded successfully or exited with the combined diagnosis. Off +// Windows there is nothing to fall back to, so a plain ENOENT is reported directly. +if (process.platform !== 'win32' && compose.error?.code === 'ENOENT') { + fail('Could not find `docker` on PATH.'); +} + +if (compose.error || compose.status !== 0) { + fail( + '`docker compose` is unavailable. These scripts need Compose v2, which ships as a Docker\n' + + 'CLI plugin; the standalone `docker-compose` v1 binary cannot read this configuration.' + ); +} + +if (isForwardedToWsl) { + console.info( + `Forwarding through wsl.exe to a Docker Engine inside WSL${wslDistro ? ` (distribution: ${wslDistro})` : ''}.` + ); +} + +// In forwarded mode every path on the command line is read by a Linux process, so the Win32 paths +// join() produced have to be translated. wslpath rather than a string replacement, because the mount +// root is configurable — automount.root in wsl.conf — and need not be /mnt. COMPOSE_FILE and +// COMPOSE_UPDATE_FILE are both direct children of __dirname (see above), so translating that +// directory once and joining the statically-known filename covers both without a second wsl.exe +// round trip. +let translatedDir; + +const toDockerPath = (path) => { + if (!isForwardedToWsl) return path; + + if (translatedDir === undefined) { + const translated = spawnSync('wsl.exe', [...wslArgs('wslpath'), '-u', __dirname], { encoding: 'utf8' }); + + if (translated.error || translated.status !== 0) { + fail(`Could not translate ${__dirname} into a WSL path: ${describeFailure(translated)}`); + } + + translatedDir = translated.stdout.trim(); + } + + return `${translatedDir}/${basename(path)}`; +}; + +const args = process.argv.slice(2); + +// Writing baselines back to the working tree needs the source mounted; a plain run does not, and +// the mount is slow enough to matter. See tools/e2e/docker-compose.update.yml. +const isUpdatingSnapshots = args.some( + (arg) => arg === '-u' || arg === '--update-snapshots' || arg.startsWith('--update-snapshots=') +); + +console.info(`Playwright version: ${version}`); + +if (isUpdatingSnapshots) { + console.info('Mounting packages/components so updated baselines land in the working tree.'); +} + +const env = { ...process.env, PLAYWRIGHT_VERSION: version }; + +// docker-compose.yml reads all three, and in forwarded mode it is parsed by a process on the other +// side of the WSL boundary, which does not inherit the Win32 environment. WSLENV is what carries a +// variable across; /u marks it as travelling in that direction only. Names of variables that are +// not set are ignored, and an entry repeated from an existing WSLENV is harmless. +if (isForwardedToWsl) { + const forwarded = ['PLAYWRIGHT_VERSION', 'E2E_PLATFORM', 'PLAYWRIGHT_WORKERS']; + + env.WSLENV = [env.WSLENV, ...forwarded.map((name) => `${name}/u`)].filter(Boolean).join(':'); +} + +console.time(TIME_LABEL); + +const result = spawnSync( + docker.command, + [ + ...docker.prefix, + 'compose', + '--file', + toDockerPath(COMPOSE_FILE), + ...(isUpdatingSnapshots ? ['--file', toDockerPath(COMPOSE_UPDATE_FILE)] : []), + 'run', + '--rm', + '--build', + 'e2e', + ...args + ], + { + stdio: 'inherit', + env + } +); + +console.timeEnd(TIME_LABEL); + +if (result.error) { + fail(`Failed to run \`${docker.command}\`: ${result.error.message}`); +} + +// Only when there is something to open: the run can also fail before any test executes — a build +// error, or an image that cannot be pulled — and pointing at a report that was never written sends +// whoever is debugging in the wrong direction. +if (result.status !== 0 && existsSync(join(__dirname, '../../playwright-report/index.html'))) { + console.info('To view the test report, run: `npx playwright show-report`'); +} + +process.exit(result.status ?? 1); diff --git a/yarn.lock b/yarn.lock index 48e452abda..131d9457c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6749,7 +6749,7 @@ __metadata: languageName: node linkType: hard -"@playwright/test@npm:^1.55.0": +"@playwright/test@npm:1.55.0": version: 1.55.0 resolution: "@playwright/test@npm:1.55.0" dependencies: @@ -17316,7 +17316,7 @@ __metadata: "@messageformat/core": "npm:^3.4.0" "@microsoft/api-extractor": "npm:7.56.0" "@octokit/rest": "npm:^18.9.1" - "@playwright/test": "npm:^1.55.0" + "@playwright/test": "npm:1.55.0" "@prettier/plugin-xml": "npm:^3.4.2" "@rollup/plugin-commonjs": "npm:^24.0.0" "@rollup/plugin-json": "npm:^6.0.0" From 2a769bb6d597bf5afef27bfe0bdf244f63008d49 Mon Sep 17 00:00:00 2001 From: lskramarov Date: Thu, 13 Aug 2026 09:49:59 +0300 Subject: [PATCH 2/4] test(icon,code-block): remove two races from the visual specs Both captured the page before it had finished assembling itself, and both were exposed by running the suite in Docker, where a developer machine drives more workers against one dev server than a 4-vCPU runner does. code-block reaches highlight.js through a dynamic import and rewrites each block's innerHTML as it resolves, stamping data-language on the element it has finished. A screenshot taken before that lands catches the page part highlighted, which changes the element's height rather than a few pixels and so reports as "Expected an image 1556px by 3540px, received 1556px by 3232px" - a layout regression, to read it. It is also marked slow(): with fifteen blocks to highlight and two captures of a ~3500px-tall element it is the heaviest test in the suite, and under contention it was overrunning the 15s default and failing on the budget with no screenshot to show why. icon fetches every glyph from /assets/SVGIcons; an unresolved host occupies no space, so the whole page reflows as they arrive and the diff is a horizontal text shift rather than a wrong-looking icon. The open dropdown made it worse by adding an overlay animation on top, and is dropped here as it was on main in #1848 - 02-light.png is regenerated for that. Neither wait is used on E2eIconStateAndStyle: it registers no icon resolver, renders its icons as font classes, and would never satisfy the assertion. --- .../code-block/e2e.playwright-spec.ts | 32 ++++++++++++++++++ .../icon/__screenshots__/02-light.png | Bin 98176 -> 92551 bytes .../components/icon/e2e.playwright-spec.ts | 25 ++++++++++++-- packages/components/icon/e2e.ts | 18 +++++----- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/packages/components/code-block/e2e.playwright-spec.ts b/packages/components/code-block/e2e.playwright-spec.ts index a9d1875f51..e7432dce69 100644 --- a/packages/components/code-block/e2e.playwright-spec.ts +++ b/packages/components/code-block/e2e.playwright-spec.ts @@ -4,9 +4,41 @@ import { e2eEnableDarkTheme } from 'packages/e2e/utils'; test.describe('KbqCodeBlockModule', () => { test.describe('E2eCodeBlockStates', () => { const getComponent = (page: Page) => page.getByTestId('e2eCodeBlockStates'); + const codeBlock = 'code.kbq-code-block__code'; + + /** + * Highlighting lands after the initial render: KbqCodeBlockHighlight reaches highlight.js through + * a dynamic import, then rewrites each block's innerHTML and stamps `data-language` on the element + * as it finishes. Nothing the component renders blocks on that, so a screenshot taken straight + * after navigation can catch the page part-highlighted — some blocks already carrying their + * line-number table, others still plain text. + * + * Left to toHaveScreenshot's own retries this does not fail informatively. The half-applied state + * changes the element's height rather than a few pixels, so it surfaces as `Expected an image + * 1556px by 3540px, received 1556px by 3232px` — which reads like a layout regression, not a race. + * It also only appears under load: eight workers against one dev server reproduced it here, four + * did not. + * + * The first assertion is the guard. Without it the second passes trivially against a page that has + * not rendered any code blocks yet. + */ + const waitForHighlighting = async (page: Page) => { + await expect(page.locator(codeBlock).first()).toBeAttached(); + await expect(page.locator(`${codeBlock}:not([data-language])`)).toHaveCount(0); + }; test('states', async ({ page }) => { + /** + * This is the heaviest page in the suite: fifteen code blocks, each highlighted and rebuilt + * into a line-numbered table, then captured twice at roughly 1556x3540. The 15s default in + * playwright.config.ts is sized for pages a fraction of that, and once several workers share + * one dev server this test lands between 9s and 17s — so it does not fail on a wrong render + * but on the budget, with no screenshot taken at all to explain why. Tripling it via slow() + * costs nothing when the test passes and leaves the assertions untouched. + */ + test.slow(); await page.goto('/E2eCodeBlockStates'); + await waitForHighlighting(page); await expect(getComponent(page)).toHaveScreenshot('01-light.png'); await e2eEnableDarkTheme(page); await expect(getComponent(page)).toHaveScreenshot('01-dark.png'); diff --git a/packages/components/icon/__screenshots__/02-light.png b/packages/components/icon/__screenshots__/02-light.png index d9cb8a353d8b9c1dd7ec634885120f7d506fe472..4ccab43a5e4723244b7435d69675d60bc26d0dca 100644 GIT binary patch delta 57928 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 z z-zncyd{U4;_bJ-{Wl0Dbg|lUk@0?$nC!E&oqWU16>`C1e3S9JHD>Ynzy}H+EORjY+ ze6i;4Mt6+09G<3^Zu;dV!g*%zb-}i;m9+M%X3}qrSCl`Fe4bt|lik{4u>Z8Dd1F^P z_Rb#|-dw#oWq0UBcYBHkYC>)j!wxQACa+ldYFV{@o?n3wmk7#~;syik(x#`y;L3)Yqm)+JUW%mqT{Z5EL zks0}7Pc70gmCHmUQzZL|jzdc%k;hPsQ7(kR=Dfk~I4l&c;AXT)6Tlizy0r*;8l9T% z3n9hOiQrP`uyEIljDIUw+DUGg%}b}Hk+T$V_ku;x$*qpP!oAmpy<+p-JcSPP!u#o4 z+^TC_JF}~8R!Zt$4a|bc2diyn``-fquNN%d{M851YqCahKLVPrj#x4dsnR}MTw#su z>8Qr#@d$eR*fPm$6qC!$N-HFivk39VFqJ!Q4yMnk8hukq(M(_TCv?)(WH?&#b-}yj zt~&3sgrQ@rm<0syzoZlNY0jQ`X4;irYv<6V@_r0uBBVZ1jt|ZUFVk9=;;W$mDzNSK z931pU(+Q5`Vo;-<2Lkv$GRp2IW4cH(%D&;IaGr)FI68{YyE*7}kL#rrz&LBu5@iJW z_1NvWWj9KQ@PPUg!{#H|n&}2o=*2OGNJzyKx2}B`lM)3=OoieZR$oiq$}e}wi6dH1 zCFB9SkrN6LQ8g={_d=!alPd-Q$|(8BS3F?;&{Xt}N_u!-quFt9Q7@b-fq#vgLAhmdJuC|2V4zSLi~741Ts1SEBo7WntF+bVquo z>@W{wSTewN?N%;rfvNHqEAdXd(x;cN(&=bBMZ%uQTEO$PeBFVnD}V?fjho)&+Vf=T zdv~ueTV;LZm!?cB>%5WYR>IGm)f=L#>TTcd6Mr5Xo#Pg+TW7Y8ZxdaI>lrA=`atCN zuFyLdexz|RUXC@madDq11S>NQ37^=pLCKtNP%N+e1@Bmr92u9Gr}}Xui+fH&zaTg` zlj|$vhEs8`Jfp`GNHPUjo!kk-&}me=FQ%yIq;7#uIx6l!H$t;?Rvu-s3d1yn`=6f` z*%ITZc79lPTCd{T)z3w5eH^NwuBW=RB?2N28|J4T)a!O+dN=-AJ+t+@o3h%!8_MA# zVDKWB+y0$T(4eX$>?g2Mr~jO%vA|r6)-3T?Zh!R@tnCHvz9${PewACGzFW+rW6WM6 zUAN(Ihp$4uKkWfCewfP3D-qF(Q*1I0_H60B=wA(UZ?)Rr^0Q%i_%z>H^dM%2DlcQQ z`-$Tw`0Q12!U0QP!Hytf0OWItFSunq#XTL?+OnG1R^%g4vG`0nh@()k5QhSYS@5Wc zQ$R(&k6>D-#{;-)Jh(3_+l-qqGcJ&&Th^7(uh%f8xw|i)kLPqrL~ich*djw08xSv$ z^j5KyTn$%!a^r{x3@po#*tiVL*?4y_W0Rg_9 zfytyGhrwWTVGg69x%j9i%m=x_JCMPXLN?T=QbVi7j^c`7AZk4p$~vC4M~m%0R@ouO ztd|wB)*s)f?Y!BRuc516GNat|MSEhJtGI-xi2W{Ve0xooPIp=*O&5jxcj_C?3MoEq zHUqPXVqiDNxlpYM@Q)ch=p>n6s;|e~J6g=JR_4O5eo#0!1F1MYY zpP078=0QTun_y9EfsC=?JElvSInyG+YGAP%p2N`aHl^xV-1}g!9qr=Fg`9(Hjp2Uk zEbEDL`jtq!5j|ho(#8mS9W$JkpbV|JH!K>{1qgy9O!H7U|A8b_s*CTw1se}T@at^5 zw@L{Qpz846q7xw=Md{!O_t4af>(fAy?~a>+?`~STDkIKB&5i=s5B5V~hnB#_%Y(l8 z2Isn<(=>LQ1=P%&9inqd)-X$*t0zs!JvU|(D+xUcq%DeDrsq^XR3&`uGo@&%zxR27 zu?^Bl4%(n%b!YuMe?Dc$+>c9_SHZXf*y>a0MJp>CVyJPX?-j1yVfzh}gIfmP%Z_tB zV>Lkede%`dZTT*i#)URJ6;GMneIG^rkcWGyR^^xLjwjcJnv`-^R;w#U9#Ly>C|*g} zR++87E2@NF@2wf^)@Bqwaz-p@G?ENRbc=5HZ>+zNFooabQ@E*nr?${D>rcddj!seR zmp&tYlY}k9)~iM8b=@D+l~|+Q($Tdj`8|Bt3m5bt|BV&UOju3U8f!_oAGZ^1gdvX~ zUqkWkbi)TRg0}^gig)^A?-}690^K=32?cW@Y!$^I&!ZDBtak*zshQ zqYfoMdcKXvt)VtH&0?LXW-7p*w{}3pXH1wa4=$(lP&wuNv__rGG2VA^p#BNSeds2wEPd{aWVJ|TT#(UQ*fB=6lrjHOuZmrm1< zJByH_;~VW`(bZeow+W|7z~a01H1mmt;bNw`Kee_^a(s&cYVK0ihVfAgmWUYkT5O$^ zkSxJQI4@sN@BGv}7G%7)MSXBKvyYci3$sU;Ma^|JQ`>~orbKScXnVdayl%KbL%px2#EG>1p-k z+LPaOP0b5Y8|#CWw5`|VU=V>ETpA60homy)Qg<~5vX^?FK3ewBpB z{=8f)+G9j&Cej9|CV6jtLZwL^)?{%Sp`*CEs8hBZSxck~5$iWmAo=t#PpJEb&wB{3Ah%=mnX2Kwew-hYxxU|THxN|>|QuCTwG=y5e4gMtwGx1 zXV>_{E(#s}k#?*UtmpOlU&jcxC!43$(0zsT7BjvA6x#t3J^Ak@KyGf#lHpNlzoV$` zWOdq#mW2;g%%Ase9MtXkvR=3 zf=j=}3e;|04|AC`J<(~Ij(*^iTwKve)ZX!p-PHUKbU2fu{P^RJk z+gexOVllvHWHISg`k#9J+iGAH?T}j^@WL$biKVmN`O~Ip7VGDYeD!|7EYftO!n*y| z8v7{dskX7eCU1zbvHirk2ufb_I*xMNn-=khVFIUci_GrmT9$T5*S5zB5Ae}!Rw=j} zYU}@}(zsQI{Y)o)AGwWo{ivXbeNW%sVsdBBu@eJFTq`zOqveEZ=e;4i$qtnt0E53_ zvfdzIAQ4)Yr-pftD&1mdA~x}hVv+1ud*=<0^2zStidx^k^@0wT)5`VB(Q5HwpM}oX zz9E}RCnd|IJPMoK%crpL2Tgux$TZcIVR!F;dyss#jIywY5E)7L3BjU)wZ`fF{( zSt+SUI>*cL!3$avx}8AwloU}+oO%mQgJ~N8Lva)`%75*nP3wE?Nvs`-wBQd658twBnm<&y}u!Ozllp zy52qC=8UuB%r0Es*y)>v%?rS0V=$_ZWGv5!6yM{E121rqi{95&{^qi7aQz2NQSyAHtK$%@RGcQ9II~Dr`qrTthQ)aQ8 z*b{lIYdB-!!vgEbPmJSCYW@;guRb;={uioja}a`_Cl)N*)|1>9 zx!zMAnmn??W>D4F)KC!KAILpwbdJ>Az%g~ex!c(5ULHFmDwJjNuEaO3nEOM-&x1Ic zSno*+B|Lo`feUMoULCIXWsSC0^^ZdBM#~2RKOw zpy?nh-to+&(bJ~z@NHR8D0)mrrR1Vy9~*sJODwgSY}T&k?G|$NSBPSg+OL}yKxOQE z*r6{OOQmUJL}c8iDr-k=usZx~l<-=ptfYogtL7-)bdrlaa_7V&RnqXtD6?qMb#`$y z?>+1JFBWMz=g9j!GOh*C!QDW!IOUE5l%kynw}uPyS99Sj6Tj~uaS9H>X2&VUdp6nRwwgf-WG_mwRJb=#v7EP%Hl{O%nUrmwYIpmwjYky zAkRQ+xfN22wcge-L|}Kb(bjRqx^kWI1QE2G&x|_2cmZ*X^kVjp@8R6r%-9>wUcHiX zenk#=Tw^~1nH=%97s*Cid~JX`ssT5Jjb^74^?j*)W;vul(yde{s%*JCwxlL3f)@HI zE@#5yfq`DHj(6?(Rj)u{a))Mr;roQsprtvf9XV#(`kLI{s`!=WJNprie+4qTtzY4$L3?#pynrYZdXxFx5Lyti3?gI!W!q1EOlRv7-UpL5$O~}x`C76d~w3i~y zx7OBSd?mwn0Q$$%;^5j}hSXMob>P~2Z2r6Ut#eQ8^;Yl+SnQX>ek(LP#&Rp!*o4V# z?dJ*UX|EX5CoOD|kyFSol)(rGA|$ir9{g0DfF}2V`I%zY!bQ=7chsECr`63^*lD## z1}{Z__;>ofyngvy-0=ceYM9=;Ui<06b(eg`Z-qf<7LoVZEUptL?j79!$ygLZ88n|X(KY0MKr#*C5d72`Fv%Of67R|`|#4>FCb;srbtX&kJFm4bZP z2e>jKB%Qd#>!Iqwj6bU{yS^jV4K>|$eN!GcEoV(w45Picrx(!v$SG&WoR#I0FgA`z zG@ysFPA3?<$3SM5Yk~DZM`%>;Op@oJS?v2-BS$cNeA7z*y!u0H8gD0Mx^J<2iYp5m zYC2^|H9Wi|D|@#70X2mugUaQ5p2ZmDHUQ_}LDwUae-rk|nv(mj*mM^ehM4Z13Y|Ks z$%0s&h(TD^fqIuOmvbpIe*_*@>&f|w|ILx;@hndNI|idGV^Yv6TCj1smrP@7ef1fLiV?1+f3Rj=6v2 zSPhX--tzL#y_bPgQ?R@1=gE~CfxvpVF)Yyxstgi45qbhT;i%|nYHG63A;z3WX641` z{B%CK0W>>x!NuD>>inki!9o6 zbU2kcvyjMxir%O2R}R&dH%ueDHa{X`r5&%DenFv>i%_d(J1(31pMvD82d>j^H~GHP zrA_A#2&q;)FpglQGiZ;CeH&7kS8V|NgYuNJ)l4Pa60#h;JZs4_06oKPPxptt5!V;9 z<*Zf3bCjB|OAZ=E$3sOhnp84zu8^_F>3bBiI`f~pVYRT1deDp#&cWN!~ zUU*U61;~tro(^=Dxo;A&zF~)v5l^-RcGosPR~s0YmpG~qqm&u9Ilc4-a^m0QlrvZOOhea>N&Ba^J;psZ zI(v_-8p|pszGdtXy!vQUtpb<0myTzbkIy~0H{82U8>)2lyj%%*a((}$kCB9XZv5x_ zSUik(xZ9k#JZ~p!jQeeWdQlq-Lq zJVg`u@a9{g)K{VN1K%OjO?z5q8WJWQ)y-6Vvf`d&ptTtyC|d>f-$&M!uwh@RZWGYr z@S&$V*M$6<0;te0a(t7hYpmx}W=)xUWcYO5w^A<^$2J}!7Pfx$&fE?D9`FlSVy>eG zxBw5~8pDCDKuiDcRq$}bvVq1OG<3b(c1t3w>Y8;lEcqwd0fLd-0F_bs=rT#Fp||HN%c zuS9!K*DFkonJr!Vi;LsO;>T0n+ka38*6_LQ4P#1p5`Te=s%XKaVmkV@@5br<`N4am zs;k2CPVG+|PX6>uhg~Q;YXGklAp1c*rgX4FE2}u+l{Ccbj(hM`)hXm z^47wd`rpq>wRo0}{osbVzrN@${CEyQQ}cO282BSs!MUkdAnDxT9Vl8_v>&2M}eQIpKos) z*M+p{iyoZfQfIG5cdMx39A#0ph%Y$rBc;NMyy4#kq&ly;dQj!PYp(0eP@Q+|eMq8B z1bI8gUP4Wg7x}8gy$5>f`0z^Zuet{P`8^i5>q_o`h_N=U#PZXu4mN6qiI&$)MrvDx zd@NI_L_;kJN`=D?<|xWrw=yrHy0YUy<9BBjy*#(|fnZYEPXDTMro@UnN~z0RVg^xd z(93aX*v+wisy5F>qN52sp1kyOKB`~A15o>v_mfKIjWvT+jOI87?`2A6n<)_}lrr$GE#C&Oavb}px zI6Q#Z0Zq-a6(7d;?xo7Y(N<;2&#|a@sgZy!o4~||a{IZfYcd6M)j-4oV<4};%*Vf8 zmiSW|De7|r>iRJIF_={0XN|fI8fCR9%wN^?s=ODl+aSQx5<-U`*~>ez!Rr#~%(9VFCSq1OSyR{34EwR$d*PSX&Z*h=73 z&3KHe_xhhZ3FsQ<0JF;ba3bQI;hSJ{_1!2F0`IP>zPm+L2L1(mx*9bM-)j1J9&eTU zH4oUZ$hbB;ZLNXyY&3YYi}wWjcm(8zi0}Rcb#+$A<;LJ+_-4g<*f-Ds4F0Bp;hUj= z264uLYY+uC7a8<@$)mO*${A4kq@u}%l&;!WtR59cg+f|mnH}P0wHH~=2E`kR*ODxG z>*DlLI!-oipVM$7nIKdive=NCGH~NIs8B$9XI9k!ynWA9IE>yT(cEl$ZhKH|lQBUY z-UM8)i8yfSDjD8a-ljg&GH7oS;}?U+I>HQWTmR-^})hKw-FhF`|M zn^dREreV~_k)~F-Z092&rJ2jiHZl22u+n1#Zl)n1Mt(J6Jk`hn$xVZqC-Ys zs>>TUJEQ2Jl6|ER%mGVq5!#f37~kb>=jG;io(^S7Ydt(${s+1xn5kQlsC;W$BNfTn zUtc(Pl{0nXlXTU%;fh&d$W!q{V!IihF%kQaK&X8u9 z5+UHJNkZI;31C{eMN;WXVN}uZ#`Da3It+r5AtfhQ^@*VIYq`ap`3?W0LKVt9Ds<$! zQXX(?m4-~~fdN8Ef}_F2fA1B*Fwx_^!aML@0lc*e1miyjY`gSyabP59WRy zl6rl6n&-k^*2n=hjU8^Cp^Lw^o~}=flj=uRW-M#KzUi>A*Evi^ULLP#DwGVtl6BU!Bd=AtlC>8~}6B*r+uCHec8 z9wXK@at8xLKN{(N^FoFDAo|rkx$yX`C+Eq@k^=q?>lr%r>VQr-MVO;j+1Hi}^{eyM zd{2&Ercu116Yi0bHslAVlt2E99e4oaih^q!57p=L6%$o&Rqe7$?$4JU&!?zgA|>5? z3#jKCCSj^>YC`?TLhu5I zo40M`fA!n^bJ0i4Ib^kubbOa@tW~FBOXE6UhSgbd!}kd>W6*3R7I4`6KeCsQM zn9$)kIQnxk<@vWj>k0wWoyxR|MuPw-;&}<9KFN)&??r3~-F@q{YN*7M)IWWu#p66- zV0%wwBJ`nuR=~gb*17X?X=6$R5E>r-48Xe%HeZ4_MA}I?^y-O}6R*j*dZ47cMqMY| z=Ao6sauv3b)IyED>+1vc7x|ocmjUnzg%jufuPYkZw~`Sn*AVJ#L1On}bd5JmMXf|1qc28q`a zt$1|+qJQU0twZ!klg|&o^>7=1AInt^vHf~jdOO-Xz5U@xtT|n=IXz2GbS1*p4yi0x z{)&?Kd9lK;p6(2n!&-e(>k!HV%)l2%EKgUE=ohaxCRbOfk*1tD3n!^osns8BW3L_|7 zWliYqbBYTNxi!9}g_&WDFOYU}&HZ#?Y;MDq3PYOJga!1st*RYEm)2xnFVFE_FWS~HM&AXJ@4GvmYd_aq;`=fm^2C^)`k3VSPYl^}YkP>b zEw|7@;N^3B-V3J>Z+aAv#v(qX;)jQP`wn7(4mOqjFz#}N?5z6#`!$c7#KIT-sFf|7=93IPm zLWBc!DI+mMxKaMAg%n>Ngc7xO4KR&&+3JIp+E0>_z_+LIXCpx<(^r=N2}uV2BQfMJ z#%dZrbsn7Q*5|M|ypyJ;4&iSRAc3!Yw%l(VaCbJA^C$iS*Lc`YR?dHihob*Qg;AJS zCEe3uCrsoN+E_jZhd_Xq(=b_+{+;X>8QNIE3OsWE7a&=D6yG53&pIJcdUbfk&UC&@MTP!-c=M>QM5a>HYPj@+ASuog*le`|hs*0~o?Odj1{)dU{Q;ic z3PhqlF2oOie=S`Mt|AKHOt&vPvZkekI;C%jfeL)-3###XmU)kF$$I?XFD3Tho=BE? z*cpMP?JMiq)d{CR=52hz2^DX5&NRp5#2cccQO#3%M9j^$);HD?Z#}h1|MY6>K#Y2{ z7((&bH}(XN4J&%okhM|AmC8pm&KrNtl18oeF?Kl2cLwd`%f4l(C4HZkS+OshY7`vkFzNTbX|YogMR=cC1auwsgYZ z;FrzQgRe2sGrHKnJ`diZ#Qr=cktCkEY+v^{zrxY;#_3|~wWBV@i;3N*{AMpf{M{FH z&fLutH#?SPwawEmMHkiB0hTlckd&=#WifQ4lb@tUf#_Jj!CXHrNTy^HFAfJg*5Ci- z^Ovrf2#=uB7qIVM1is|784aztJWaysjWKaWBc=_ASI!tme<5vu^1&RD5MhEDHqoUB zMJ^U=bL$VA*zqccx^zmkfK%)OjDKFA96tEtD>y|*t4easY$Xs)9xPq#|NP3`t-j*K z>atdC6;f*w{y|;c|=da*xIQQThb(^ftJ>^@x`|A}xAaJ@f&j3QlO zj}od3N0W06|KQBaRl>cg`CYF|MC8`p5#viPh%jH@h{ex6-`Xc7Tp5-hn;4BH${huN zE5;Hvu1?tqbH#tWc=6)8bj)(+B>9uBLC+OF}cOn*W0Ko z?{0;BzSAjBs+XXAn{ajf-irb@zrDXXlq?fH#oU$m>_)7vcKqzMC@IBPM&yA5(51S4e$2?euC zmb1*0-N6Kdc1P5_(-1K6gL3s9Nw~+{61Q{GJ_F2TRi(bhF>S_7ll1H$vA-)%nCxNl zn^Rs@RZvHk%Bl)=B(vU!fA|>Ur&4*+tdqA_cG(Z(Xq+{v3Z&{I^nm2;jqQ0M!KjqD zzO_w82#Y*UL*4vn4IZC1WhA9;y?L@UfOA^&TYgLz`%W873VHl18(W_$P#U!lQEqCQ z2Xl3%;pNBq{ctoTuSR}%iHk3}GSYOiFGUYe;JCyDeezt*^v^Hd#KeD;jxp%|7c@P4 zYBE*t<1RbU^ucHo7o;0CRQibsg1aRS&k0pFo5q5q&0d!Oq2uRfZiS{;dusfw`g!kd ztc|<%F~@(FyUIlc!~MN+E>pI#Zi%Vw$QBlsalkcW7K8)dQ~~Dy5SErbj&exM2?-ikW7%Blynf7u*N`9W1a& zPB)(3?tiLHtzBXFI=-L4*#gX!+Q)#=t*S&yez`=kOc;Z%wVgs$CrN|im>~ax;8n7m zt5n>vtOL^DG`5!;)2&>2k~CpuGX+-8GFRB0aevNTPZQHpnrr4qaI^y$bhqcCW~=w2 zsx2CkgNq~B(Kk=7o(hKJ3S7E-;M==$LI$*Vg+aOd>2;z%xAHa)G!T!aloZkH z6a)Z2mY)tE{=X-${6E;AM_T_sQ)2!n)&Hwe``;4<{$CSq{{K+@52C-K5f{=9iWX{1 zlH~ba(&)T6>IVECRDmlY80)ZtE#T$cNLLo3rkNqjF!73{oBA_8<3>c7$&R*CLG(jZ z(ai8#0}_=0jdupAuIS@ufOZ{{!hhJzI8usbq?)u5_r64dwrKoSu$dBul<}Jkn>AV2 z-xkYnN#L&43)v{fb2?NS^3*XqKt2I3Lzo@;zcjv3v2(QWNa5T755~o6SdlHZqs)=h z#YfEnL~G&!5H9#$I~FR^2X%voY7op18sS9vQyZzt&KRYx0j_}gc721!k?C3k7S{Cz zFOEQI^6g#%j`5*yHJ?vA3^&WuaMtC0kTG~)@Cj!Nez++I=0J2dX#58*MOD2G_k5<% zW1v?rNB-~#c>~8^eu#)KL0t~$CfxP$*Op0p$!G%3uTT+>y?R>6t{9^so5gmKg6h-*Pji&9)^Q{s!u zoEJLOq}bZdsp%eIXO0(!Fd_afnfV?3sOYM5i%LoSv4vQ zTwOC6HWU+V{0gIHne&bfPoYV5kvLJ%pQ6P$h-DP|W$x;qG41q;M4-oL!Jt^&u7Pte z#`EMwX0~B|6Qb(w8jX-*W~&wy(5ZJ+mdm*9Vk8#qEPM#N=wQDf`2KtYwq}aLI9X`Y zAcf&Xf@9ispPPS9T9j_|`nTHSVNu)2(mh@l77)EFN9eavTVw74Oi! ztloSsG#CDr<{w=2V}oOv0GBN01+1Ffl*~IBe;XLpn?s7}JI`Iur24j{^2st=!0air zI`o-MEc?msOiW>$lCPGeqsl`qjV@j^Wx{Ak$N-ApVJ8`jB3Y=iG8-#p{dj<&fFz@~ zQc}Efjzvli%`iW(Vi;MP$i@3cy!h5wS$mwpe)T1C5`qQ9l?0ZX3Yoc@aG;576t6lJ;f4^yF^ z{RHd=_=qjt2*t00=w~X+hDJTR$YzJ;D@6r|P~(wIR9=-~V4THg^;ZLM(NK76x?|7Z z?Nl0A{e0nn2}Jfmi>JbjKI^}oGS!hGPlc2@41IFRw2~gO_JUs(N&SON&|)eBFx5~L zm@o*c0sehiHmO1`71p%oT~iju7_YGWb6_pn(&Lrv<7Nw3)|u1BlJ@J%x>^0el8Gvol8R{u zhlV%SR@wW))TUa^#e%v=6fV#PweH9lxW@~HawCI4I@s!)OpEVDvBoM)SHj-4!c*p6 zH>pXACAC#%pY}H{bdz)|yfd5eeH4oxG;!Icyb|!b`xLCC9d?y8D9 z;rH}mO^L_Pj8o971<`Iq6PwJK<9)46tiAbD!!e%V&bA;-fA)vy*=jud%2~mAs3sL% z&ERG>5vX*ofOqhUR4GY@j^5~fi`UioOmMKEHaAbs{!0PF@l&^G#>PrIYKQKwL5fvl zjN%r%c*y*Hue^JMf)5}u?CmWY5KNyn)p{RgFJ6NzVY6t(dnDZ=53)H_mHL$BxxuhT)p3TA2zRCdx~>W#zm60 zaVc6$@9B$IS#0k0l1vP|6~pls><#LP;ByY@Zo~95O?!-v0hd12mPT^rQOrC8@YnGP zp9+ZNswy8=zQos6)U|O$Sxq@c?iIhA_*pNENaVR~?-ra!r)AeDiZ$fTSasdzmfg(3 z=Q3JpU4eLLy{q@De|MAHs6YFL5<*%mo_v0-C02rvHd(KF!#ed)Cb$8^TD`m5D$fX!uiBB}hfs#-B^5rpD&ty==A z?QT~oeqv!yH=v#Un;9zNEfQ$L{Ky$}wR6^z0+ur{CiG( zW&Hp=)Vl+seK7j`52xD8g>34Yp$Acy2BvKe_l2D?YIL+wSczmghGzwc<;TkIq>gK8 zU~_J-xP#4vx`w+gclMfWTDL?syTQUK405)BO*W|p&SD{%1F@&wE$m*NG}_-x*XZcP z7hE+BmO^5=CdLTK@1wD_^<@>DtOt;4%<$;cAa6x;rag3=Hn*;A%hc)~Xo#?)^e*Zb zW@^V+%S=a~Z?@A}jGFphwN!OW1b1mpztNl@HtPB`hM3x^$2j(qr9$3x%SfQ=lSm;t z(5M9iFmlbXaC-S-1Totb{feenlxvRbVz$Slu7|Tn; z%M1MeGwsp7lR6B1{@u0UFVBYCvEX^2rhs^p>}PB>J2{Y7b08dhE-SWIFBdgP07fF) z?{_#ayf>F}Y^whU;(zi>u?wIuGSCg9Dh;=!QT2CGEs`u!P%fzPVwlN+uE?is^01Zv z=4n-7nRAw$qBh&U$tupdn2)Ba8z!_C?|wCSZajV}|5|9d4X*<$X$!e61Y^QBc-f`S zrdguOMXSK0m_epU=cwwov^SOA^s52e-t@h%V-OWH`Xwg&|H0W?M@1EO|Kg|^h=_oK zk^%}!cf&}FlytXr$I!!3kuK?Gq)WPo6a=KZ8IXn{h8kdi8SePLzwf&1x7PjV-ue5i zIp?hBIeR~Q?@#D4e`58-jf%BjY-b8D3S z8dcVBx1}l-3m|=OTfKvhUuL@us-%qL`|MirZuC#=-TfmiL|?wMBKX@(#p`@hwNJAT zO=+H;!ZaY`lkvlp!vJl_F_tDetH@}z5735RB`bN z@b?0Y8x7zKU+;LIj$EY3p`;@1kTY@om+4~8s!m3SFLjWYFt-)8{5qXTE3deOH%V-z zy6)PRLm@nBrSq0OS&F=+6ao4aU_UPkrRPkPR0C6GEg$O8CnYH5@+QaG*##FG(}i~3 z!vJ1j#0vW1x7i5Of5O>uMIxs|NsQkPZvV%389Pj<%na)4*Rd`f2Cm=}yJhlAc~N~w zCGVv_%B73Tm_uc9APQbAN8U$uTU%wtkUL=R$tvuJ6QR_+EUYq_=Bo+E^;n%{;7byV zF7>0jWx_26JYK4fsn3|h37x$o4=%XS;k6If?z_~Ev&phFJ2tU!H%PXPB)lO5P(v{D z)o+qadLRz_-#p4or`W2V2KmogUQ$L|lzce z46*X6c*MK^KfQu-ww>AhaaYMUl))hlkLB2eHFQ2D>vX6GPB0<6y!Sqij8w#TX>g3b zo}-%V;rygp(w~xs^GLwX$&@8pNb?D!`e=?J4w;`pzn59N3M+XB5VJpiCMP%(IvKV} zXXvJt%X-2w$%SFFBj`ISAIVnUBx9DUP&hsAp47kDF4ntphBxb@C(8hiVtUTiqkAZ_ z&=J<1Zqfbk9^-Rq1YRQWIn}3hrsv)ZDGIIUol$YGaYO9|ApmP@!$gSKr-6+xS@n<1 z{A7L=@NHqwb@<5mlH<`aj=qrX&C&;YZ9u}I%MFt(OE`^l=;O#g2w-~0cTO-vz36$QL&`f4*`w{K9`*EgROO6&?0Lq~fRfL%Zr zb|@+-dPeTgCGipe)6EXi*{OAIl9k1X{_)>AQTk*ibu`0M6yz6Gy=kO?$w z&p6({$k$yU^KWG4w)T1MMyk7nej~~k{WjcR6&u-Cp386{nT1LcvB2F=t=K+-h5o$Ce+NuwJj-&#U zX|;S^PnhS|`SLw*_&Z)(!g3aHHzA*3jI9UZ?=H)saB=4!>ID!_Sy`1>kZ(Um8!oZL$2Lp-DUS7qhn0--F`qe&BN;uNM9JvPrUE^Dx60oX0w2xL zSMM(#oIi^vViy)(HQh?p5U$obb;_b%Hi7v6=zY`WPUf~zPKP@0<+yI*{Vgb$ym4e6 z9Io@AmRG{Mn&s&(V0KTL8)&vIN)tuf#-u{LgSEP2$T=I0xz~OKC%lc>DkWp1A<7QQ zq&~n_6`lsE+D&}w@3KWyeKAxskVwclIXo%bZ&LCRF-U$c-ib2HO)APU-I~*w%$b<~ z@t_T(|3;tAuc3cjBdqp(&O;*rzsU_L!4#o_)3#{Y3|MP%CyDf}1Ps1wY}AUgZ0Zly zzbbsjh~Ru`oKqYl^g6&WJ<+Jfs{L^7zU(X9gt>ynNEU87^CFO~X{XwJmyOoB$DMY9 zAzfH?NLblBWBW_zw-XlRjW=6MS5clSo3D4y$&sc{jygm{8Y6>0Gk)8^HI(aDp+IS5 zUVc&ky_4Nx6S>5ca)7GZW7gF8_^p;UjK}0a^Zaj?dSXV7sPC)yLW31VYu@04fwVfC zN%8%_T|UIw$vT94#{Ig5$J{;hFD^XdM5MY?`rVB7UWs!9i~D0oQO0);fc?*Hf7LnS zQ}9``Ts5{Nrj~=ax`SXRTiF!WF$l3ORYlagSagw7r2@MJAjE`nEMAn!AZIX(rPtaq zrD05OxS4JpNP_CWd@kB;zd$&gOL-=r2CbL}-b>i8p!EFg((T&p5t`wvN@=JHMLnXl z49v0WezS>!0+mPfL?z1C&uFKvZK(}=vBSEbyZx!gvIc$vC1 zv|I|9=YIfvt`Skr3IAndxk(961aN7Afw?TKSTM{Gt$ne7n?lVH-__Q z!VkHgGt^MsnWmd5%;R`sZKSf+^;u2%jOyy!43w!mgm2bmS0v|sq1q6!q}{abDt+3a zO9M&~lC)%Y`Lya!6kVS4%n*5m!JsnN8+9-BEo+u)1nWvFsjOQu2LlcN`zO-GYOy>( zQx4WxvgE_y6b2+B_k1zSGy&KjfK^mVNM zW8%=Z2AD0}dEtxCzg*>jDQ;Q`{0*?)Yf9Q+ov79&ZI*fwbhC&GA&d4`rI=yYGI*iP8ZWm6G&j zg;aewa*Aox|msr#{j&cG1Le#$Z)9GgsCyht0{z$U$V^Uf3Feb@{T$t*I(yy|= zV8b0Jt@fl5nuRrd4w;pwX{%ok(4J0GhUsZJ9>)WeRnMbfg>5FWCU(n3R8gO9De1cQ zvU{9QLf1H4dC8UO#yg9GahP`|Og#?{GF1l89KgobK=y~Zxkt_#3IIl4`2>@ngzIU8 z&+|4A{*b=%Kbcz^USHN5{oHnb#UogaUws%K{6m&@Y|d}MO}TDaIFJJ#Tm*KPEDKeK zPz2;-Gh7(DLDYO}^Cwo7-SDY+Vyzp`Qd4yo#RcC337zqKXiGc&0mq9IEXgooLG1=d zPJBji59;j1KzBHA2{1OX1&*6I#gS`9!!JF*CId|q?-&|GNA?oP`1wl?c zmkbO}{`epXIia8JZ+^AhS5?W^)tH*0_O<-$Cgcp7D98b^0;;c9-&x16LGalbrx0!o za&_xv4f^!X+lg4`8}UQQuD_22tHfe{_1Rh zx-1b^t(%XvK#ZyG`vs?aBIlMvQv1)qyB=TvRXutdQ?C)5$^&`ZFBlLcf_X9MyN*gr zU!n%i$4&}+e+%{~wCVZ1^x0jFx>G;+VteT=qP2!M!Lp9QmCW(!lpe)X+sn7mCvDm5 z>U&+pUi5ly3`3uylZ6CnPzs45BQ-?jjbqt{tPlD3f!?1Oozj6%)O5tWIdr}}`n^6QT{!o<-lPOtR5 zR<@ReWo*!Y4IJlv(`~C&-Y4&w#%&Z3{4(=zkkU$-`r+NUv>di(=_hPD zudOCj`)MXam{(o9EbjgSxY2t3x0`BW-em$Q+08E=L_ZB~t~=M8BkgVenOY&9>%fXLiZ^t1qHoG?C(6N(qQU5bIFl-PM#9WF-iKMwHq;q38XUN$#OF^?P&CYoX636 zv%GqnUaQr1Z$z+Pd^(+b-Psl2Rue|aU8msNoM%F7hReO~W9L)<1N!IBhJ-Wn@;Byy z1!At;0wKZv6n?$Jb-%e^Vz7wd`wbR?i<^f}>g#Xjt52$JcT;#&vHvJjOZ1bNSMz8M zowtvnR&nlAuR6g!p>mAI;oiS$%XM`!hDqkiGy|hxiY$ogr|B~A%niQU`lU9FhRj&5 zp-0Dsc_{sV^pD-E$iGv9+&@+Alz{9>mQ#>;?2kYvgP~ak#boD`ka6+h)|?6|jRK|N zk4)C3alAY2lyAqFpx;M0rk&E*qiv6D)$iNiNQuajJ;zmZ)ZA2i1Q!~Gjjw7C`970z z_I&#OIN$Cj3(*ShE=xlK2{8}B5flce?v7p43m;fpU#2%JELWrxI`5g9c>^ywnLcmr zcN3qlg{{}ICMnE6^(MT)MZ&SWiF`V-Okht=&FygJ>u&^?BxU}c-%ck7IklLQ>~m!M zCt&?5D$7D&Vx-}>gjX$x*j^{5StmCbOe&AQC-3;C#lO^w<#oNt%9GyshlCgZ)VH2; z@BC~qKa+FF&@YaH{|JX41ZYcQ?x*ZQN(E`(GwO5?TJD*$o3NnkOT(W&_E zb<#PsuR^aTa7?!D8Re?Bi7Px<)$wk@ha=2EnoQb=(JSuQ1B*LU>)eBN^O)kxw-ipb z5dCA^GRMmak3beXMfa>!?l(h&^XhnG->M3`GRV>hxOrz()D;&0H+e?Z>T11Y{uLF# z6seS%-yY*d;SM0~cdcDsjPfdW{h89)(VPCASzOO%l26x{Nwq$whLZhHbX`D5yUIv( z;$Kph-0b@97YxOrifbPv&OvubCmQlG9<~2pYHW$=AOTMh)v!(3$nvq(nr^c>V%w{y z3i)92&2+AD2g!89<$Bnfzb6VR=7c%&r437fm7VhH+aM0a=23yf^1d7}&qid+tMW0D z%lOBKpX!;z+URwbo%*kg-&PzvIX9VQzGJqg`ce_MzXZ5A3t|r++%NTZSsc(;{C7mf zgm)f$M!>-T);~qdI`fUq^}s~$=-1L}vIr=&;kqy)A7u&6FZ68V^V?VO)lgGd1OjjG zj&L!Z6oLnc6L)?2{hI==#gi+;I6^>+N4NXjNPEB+PwR2{nQh$@vd?LBElB%9pNS^ zivQ^q%ql(I-hEMb)n1+fw3c0RL1tdV?Qh!pDYU0vAwb@zHVw9}M4S^&*ES%G%!?YQ z7{i9L8vd}?0)L3v$2+lf5}N#eO%CnYGam2C0nJ=vxt}+a+Iwa{Y@|RK?h17_?{@RP zisNL*8qCVaZ6IcVZnTOmDQyP>3+NT(~X_9Z!a z1j@ViMV86A_V2{b?*2~s4q`vu@P1i?VCr(^IQGljg#38sq}Du?jX6^~cGcTyEh#tc z>(kBJ16`LKKT44otN1|#r>zwB(NHacF~xu~7H$O)X-vq=r3xD7MJgLd=8gW=Wkms+ zvY|M;A^o;}x({W*TUL#90sB+8v{REs4Lr_&Wjka8+)@ znM)mri1O4V2abD#VDc=k++2e{gy(yHAD9$1w2GVo7bJSVugB)dvUip(!ia46EH72M zWyNK^1Q9dJI=5#FNQ6CPmU7JCU;`0ofl^D(^ptJyG%>&~x7&rfV^~oR|b?0{AR zvL9=n_FsfN0r;Fu3Bfrqllgu0WUKsbP4BlC{mnA5=fhbN-?J2buBOY;>W1?wTV^!)g-5d7;I^bnlQ@lu^A!dcL zr4^{%Uu~OzJYB#4{Ix|QSr#YNm0b6w=7e~xrp>9e zpR51k{&=0t+8HOgJbdUTi(Miy6i^;vDiGVKfO^rv)UK_A9%COUAE;MO;A2#|UE3X; z%WcO5;*G?;%+Qr{8;V%XF z)vmy=GQYF%Si62oR74LMRqkG*537@l|`L!lkZyTvoB+x?ugg=!zd5`PM z0wo6;y}bnf`aaRH2$N}jYpY3!Z!R5#gjHxSKWugrfp5w>o$TF2?0q`nJk6HI_Ystr z#fJRg`ynZk+@dGi-(@UV*+eO()SiezVY%&cfU)*?$bCC9^<0k6Mwl%;lgk}p>T7M% zhKvVa@gPPB&KrvfH$yuN0S_S|=!Idi@VH<8Sss`ex(v7-b_DEj_D1T6y-#YivX_q4nVD zqS(;u#qO_Obr;2Dt1Eo&Nn7ErITt-K_nHow#Ks&?COB5=X@UCWDA+(L!YL6K!0mIW zs#GEh18G#dk_6cwQuEmTz!podd~cSM)5XYqwnUu?l+}8fjz2{&mQD4|puE1<_5YUE zs#%WT&-bGLCb}azgTLk;OwO+CK_lDF&}27s9DWznrvbL;u**l+Ewq(nz!c7Zh7=W^ z>{SWM4UqXA10FbalDhMcj&7;tJGqlfGf@Rz>gQvR0Uhprcg&r)0XfXU4`ikT-qg7I zOQ9uULpJpgy}E>QIbGH3$%xoo`($U^(~$Bwrx($6?);NgV|a-i;K ztgJKCmIz)wN4*k{gF-hWbhQ%e+2#~7j%l~ZW5~w{pj*qO^`N3Eiur+KB+oC_z+m3kA%3SY!z~ZG*ysh?5JQS#9}ywM4c; z$zrahB1qjIRiQVZzq4qW2bJFzqpwC0&(?9;m%S7IKccHhNGID+0 z`oNy^X`P^A9&Y7StpYId)6=M@_{}LGj}R7qjo6F|T&s1J5r2ht(~!DODUqdAiLq=d zyaoU0OMQ7mU8va&f5$M~`r8(xim z#lc5m&GE(OutEQh`J#pQtc8Jal`bp6GMu&@&vB@ZgU3h05krM&cEEIV#OJr;;3`gR zZ2468Wn7J@i64%^#B;{k@ZDJQ0CC%h;45~7o)fs(nShbvGl54GM=A=s@3(mk%>mVW zlDRfe1+>+Y23=O{6Xa3E3|sS!97H14(2&=C`tnoPU)3*UAiegzXl+>RZVGEyhTggH z)FuO|#31;#MvWY3G;=mkx}+AhPb%ESG@c`FmOK4I-?qfz*A{=TB^Zb>+K#Do(w~Ie z_C0D)>v5#WAB4q}3RqKNH@AY5~+~Lr&J)T>5DTv*hqgDNO^z-^-(tZ;Y%5>@{G675^;GJQrs;;fQoSpeu z5Ny?u3UTzOuhUa7v~RcORedex;48pAmu`|#f1MBz0DTK`@)f90jT53W28bN4N%V96 z;T?2Y+m9xQ{=+~5`@JV+^8VQ<|2r#Dsodef4ec82eGbN4`{?8{7%3yL{r_amI$wz9 z8w7s6*c_H0XjnQ9Go7O%+Nsh{*HuoAQ#QmIWOSvMs0QWUJdm6FT^PakX*xm8PSfG_MH>*u2D0DY6be9#;sNAyC> zj?;Yx@>h@CQu(IA4xsG2YJwY`F*}OO+X7~v|Lk4FGaf(rEdzv-UJ8L-CY2-4fbSZS zXh@>oNpV>hiU3T>-?<-loD3@kzcXr{F zOIf55poF`PuuTC@A?8ZZ!#aU>3B==QSN+R^JM!>6)Utao-O{&a$$pjSc!uT*BlF3_bu55|fK-qNA{>D7@%(;7lrA|&id$=M8 zB->U7uv=xscrN;$byl z53nsn6@HiC-6A!1ydPgwv@UpapxdVA>{Xd0m~Z%auo6YRegx(2z;QWw(E|@3=Gyi^{X|k+=9>D4oN;_ zyO(HxhmP1k5Q=N|b@yL%k=!0v*|OnP{N5dyOEnufF+dDZuzpUz^S>4NJ9+=NT0iCg zi!T5FC0zKQGWP$E%JY9#`~N@wt3Gkdz<-Uj~VfP*bA<~?kh8#K_Tf(9QI}v!b zat!f`d2Vvqnx*_KiIh5zY#z6E9-_r)V^~QaiY*#-mk;L+tnqnuzDX>>aV>(nXKW>u za3%#Y#+i4nTVVIE2=Hwp*Fv9odol6-F2G@n-0qzZb>w*Um2)t7RS_n4(c=+~#R=;Z z>!`hzHpH6-vMv3y;EOiwgfRoJjkL(V2#V)E4DbK1kosj|NOO8};jGc#2j?JJhFcuH zIEC%gX{cF3ZA!%lhTJ(}O!9DEcP?D|`s?kMCZmh-y%gM?AM?#5Yt4)oQPB(X$#pq< zRn?@I@*bRhmUTz$J{zyzC9RX-z$t|5-%+t}1}MLH4TX;L9cmX(;>7&5;_Q4khz`#m z5*<4<>XH?T##skA3dadr?Dpe3U%Z&#A+rZq^J+UH@c2gh6t<_d zkdeQhmu+II&Gv*32 z4xn)B&qm#_O3v&yEzZgVpZd;iWO}B0eu0`GyBRZHS@uTOQkMCx51?i)x$MCqPOUc| zRqod_KYb__2$7Y#we!I#fo~L6pjbSIn~t3wZ&OfwDWbv?`4&;Loz&L49TaLDtv+78 zlOKlnE`2PGRR(S_o9(y2Z;JK_I)MGrFXydQjLGS7OSUCzUb6F`q3yhO~Euv!U?pfL<_(7OsB9h}& zDR_COS^ML3emNKTmS=!jswR^c7#tn;u=|cU-ssA9&>NBJ=7@-R8J0qdH@FYo@nz!F zo2NEnx5;xsRF`Y?qumLKI#ZKe_#MOR$NHBRj7Gs6huUwnW{y8>%OKxOg719J{gIrT z^5>(7D|7Y-V67x%eQAdC5z`e9@YG)bV=Vx4>1ZM&KfcHlD?4Km> zys)vJ=g@dJSXPuUe$y0T^Z@U(v>Qe9I4~FS3{N+Y{D^e+HtyPQKPibm{kY>1OGn$T zU+(AB+dUVCvu%2X6N?{v*0n}2jTiCuDDvKau9acWeTlbU9&vqmv3J2BML(Z<=W`(G z0}qNfkAm?{@77Tskpi=L{~iFQ@#XQDY=F0aP#jUqU3|O_`l{D~d)*K5*m4edx@tcg zt%OXEK#-o_7kJ^kP!0C|Ab_`|FJu9 zU_9~|w?83&fxWirj+4CO{13)&MEjqRTNwrD2XkX<3dp6&aD2Y)mpIpy&yQVJmwD|4 z{WHBU4daV%1lLlNt(0DS7T{(X_?lFlaVlu9>NUqWdEy5`e2Z)ZdO{Ft75y*xZWt8lD4OcZp_DPQ?_R`fN0g**!Ms} z#>M?xcrKbazm*Q2yR!K>X3;D47a?7)6wNpXs{3~@Nbv|Eb*Sde94AB#%4Cdg_NMjl zQB_RDTU%)PLWcLIA-FCh(|zyIm{LTXA99vB_;YmhZ$-N<8TC_BT`bT}J!<1&)V>J9 zw&R~hV@{CQL5da@7D+891u+d2V*tcHJpi-+ykEN|XK>Li);fXUvdWS#RNo;Fs%HC6F&a*%ngjnkIkz=4j9-N^VBjzw?KIh`qwl z)KBVEB`cozq%aR0Uvp#Q?ce3!uJWEL~aU$!@}#a&Qj@P{rZk+{yWpcp4rbaxS%E zW_u)deIg`sAxn1IoN))Mws>X@8*alYM~!= zw<@WVasFAGg(g_TtBv7=$-y2qL0Rj66803cSGy+o9iBF==hgrekacieh!%Hv3TNb7 zA8O)+)L!pXn0TjQ=PH~XOn-nf4^b#u-`#h&hyD!qXPs|~_PE=8gnz=3I~0P8(ovUG z5#m$@k!8)(Dp$Ak9H-U+>EobsHOuvPLc6lPE>ol zYswv@aF~y#wl>Ma(dnLChnZ5^#pi6n`^7(DwY8_3t8?pw$=lFp&k~*44O^Iq9?ejE#RGnka;mRFuH?)}4cU#Y>sh=-5#2jT@A)5s^+~yIg)6dAs zOQ#Sc(*Sy|mvzz5h~QoF7n~Vhnzo@YWFQ*2>H7p8`Gt$n5(2J2E4;`?Ea4(t94+#P z(eU;}lZscc#~~$cv&UTt^1W-Z&Vh;c5;txqo+6S+f%)v3gYq3{e4&ByOLoSZYITY? z)02}?u8C=$L5}VRTU%sHxuR9|=ZsO>ewTyjMSC=9F&|TjjsvpDiS~ej2lyq&#U4A>dS#oFF+>t`edVP zNy#QI`}zSY2mJc2)a28QVr&T`YjxL2>+6c>yFt|mJAFmEXU|qR$f-ELrzWx&$B{ov ztOSx05|}cZ-+7EsUVOv9U!T!GECxXR!!W;2cPXqdepT|`y&Yf(T{>00EEP&mFw``Z ziU2$9%p~uJmMc`-p_@)9$~QLd-@E8Ni#|I+W%Ih991jeXlNlweWW&Y8<^yzLY-bO@ zn|z%4Tv}OlvHbg$h}rYW4&AzzU}HLtLMs=cjPKt&E*h7z;9_Y8?hC32#bjV&?zSWa z#a0`{+@aa6R}z>i)oBylO%#lXQ0(vTZvd_^CnFM$?_0g!YUQfon2Ejw`M@}xKpB1V z`@Gx(>R(xeZ0z*OoP}EyPc^j^#KfC}Jc+~hrfQDrXX}oA1VZ_RnC2W52UB|lp3E4BV>cc(_ zYYKKO7qj4qcR_PAa8b-m8*mh4?UdsbUHU3+FPPZY@5*}!dLDk1JM0ztT+YOzcM-J| zt~E2j`shSMV`4`!D$1w+X}P%fA+0;9**K7pabV0PM$2E z-M^9};#Zm#S!R1sDnZAqt>5jzlgno}k|rMJ<6Xop7oC$plEz%B`?7B`q!IHMD=zh= z!`tfJj~lNA0qpU@FCwZ2&8dds%_HygMe)lUD-|!&FeOj#t6})^!L=k)>lowdACfL( z0Cm&0+^!80b4_{4a?I#UE_(VhPTeHPgx;jVb%p=mp%5Jl$%={6y<1#HS8UL zC6VZoFBRazwnr@ab`MQ;f2wl?6$5j?cAX&kL?@+=PBIa+ta87fhNx^cO9Itri3DT{ zV`xRWA@fgZ8_K(i8z|aGxFVaIuXLzDS04Km0F7|Za14^l`az58b^66nJ<_d$U+5)? zcvqo>c$0~L;HLN9yp3c}xpVvF4$$s^wkkXVD13YWtZ<5*E3I96Qi=f$_9I!)v%U>M zo`i)EVhH*siL1Ft>wtZWB43rdpFI;!i_I zBvm4Fy2*n>(=eX{0@~8sFHSq?fPhwThztX_Luk?$2~o#z;il&hWH2WfSD@`duK>hA z8AtnSu4*(EGXe!L`+K-+sE1>wQx?!_T#)%Ykfa(4;+$m_X3n(u4C^9{Q1u+fzIJO-PLb2z& z@iD3lo7q!BC!3twd?HSKau~#}vn}_sB5z^(E60T+Ofpr2fbmrOsewWp(0H*g82rd7 zX7~gv=H}4duNt{kG=+eGkeqMWE)N5}h;UHmzIjey_5>8)Kqu^b?JFzm%}d;6;HvvW z>uvFi5i!BSzL1gggR9KxBxm?(*b&9dS^Q;1yXs(iyVA0ZRHf&TAHkigIhT!S+dpLl zwNi~aIn^a4EIWqBKW>2mRbTfeSRDT2kQ&D;4(Un9NbSLD`WyoNnAUCh`PN{XYj5aE zlm>uBb@U7^rwr!pwtKPzea+6PwO{qxe|ad$AdnW!Hl}QU3E%S$E^^<3F5e_wtleyf zpKPP;sl98;Y<2tkk|Xap>#L2(!TEZes-13-Ys?_@Pe}op3SI!m0M0FH{B*S7TtDxz zn`}Z{Nye8^a8pn1$7zD*7N^|fV-J=2>-g61?oxj5bQ_mD@{|q;kofHe&|-R@ zfG0#wLJrym#eQC;)=*4Cj!<)Xgmraw6~lh#e>p|x$V+OczfK!gosZ@sDUW9JuGX%4 z#_=MjZOSfeXv*wns~u+;iI*uz4o2^4IWXdqkA|%cU@Zn*H&!Xj!GGSutl9Ec9PRJ* zC@((<>MSxQIXxa1EElw;6?bCQsj%!))JO7}UBg@b3F11MtTy{acAuSjRas`#BDAs$4QQ&9L6n!lhYi=XDiXpZ8$Sfs07ZPf{b|- z<_ermpBz-(ppn~ZGRr9$*abJcQk#{vEt3G{bM*ADI~dIMG2uhv8*svs`a~YD^)SuN z)@10VRH`&U%P#{DrfKsRhFlFJRiP5eGnG;ch^|$edgOI1IqQ>!qw|x@)6olZa?=XD zo2!kE194dI0A0&X)>UuJ>&t@8z1!7x09vtv%{2EQgtqZ~<$mv&P)OFFEzZ0_z)zUy zsVY?XX22O(^g=%OMAt(ntw)SfPzVNnGDX#IF(7>hu@tGT#+TnCeg3CcV9pno%Nj%F z^7pTq2xOyQOZsow*yyE|x{*=qO$Qy{AL@XGGFR6sK3&U-k*#=6%C8H6AMyq7Wx42% zZCqmF$$;~Hn|)Ty5O6$4kqvJ?ckq6gB;{{>(Sz zVksQfuSD5Fbq~`9nf?1s5@RDi)m}LKA-@{wd4mkvQ5{G7_ypg^0w^UVD z3JL1W5Vpz-;_B96OFBm|A#ub5;#}@N5Hsoh$J^G|Ev4FCZje5e5y-w}SJ^(Uq{CdI zQqQNGPw&C>wK46`^9dF&7-^cviaOkpqg7OpL&63SuG4xp!|K$Oj~w?}E`g5Sd?7e* z!EP=Ts$}K^8P|fbL@hgyD{gWQq`2LCYUP=xQTy_Wte2<=gNw7P-Wy?sd4FB%(baQp z5(9hTL#qlr>o|m5D$Yn!a3{J7rjH%PoL{G>Ob&HnTD^7y5KiSBUU2RfbI)g2pZc>w zF~E!4NP(=$;+<5^meYGgdrgK1SBgt{1~|uJYMsc<=V{T3QCVfCV?05l2lPlzgLTCC zkFg2Z$Zq-b5f#9$vk^v1WRb(TGq5mVf1cI)Flco^*IHydSv^hz%OVQ*1rJE^?9y1J*-A?5k7g^>3Ic*b<{ zq2gImi30Bzh9u5`A|Gg!?4}t_O#nSTF#Qu_A zOamdmf}JqJivG-Lu&-}tEQEP9OrvmQ%;G&;GS^{JvUPngeLi@;sR`y*Br5-yR|d|; z9J{@bu2|$1HP~M$Bq){G|EUx2ps0)Dx(hSLGK$_#5s!MA^#b&XiW| zt)}H>x7Lb8t99_pUdc~7(r{GW&z@}^o1u3jiSX84qEEgL*u<{fqIbXab}AP%DogU9 z*~BdrECsw`X^k4abMD=^n|4x$J&n)^Q_yZ1+zY7RSII1ICZIAqecB)?<4s)evmO+Y zY;On7EV_U9E;R#QkoMV~4J2}_6cqQmJ6|!WY;d@B z`uKP&ZdV_0Sel>ISj1(|(Tk*QQSVa6)9s%_{7$mVjXAhh8Ekdffb5Yf4WGrOqOEL~TI`xcnu7Tf~Tz*Gqlc^=1M3>)+WXK@t) z?&A4XW6j*sV}Y6suQ$ysoGCSHfN`$$dkcG~onFhl(XeF$*b}vesXdKbh$V|b8nyI_ zJSt%5m{zz%^#LwDtRLg~uJuMgX>OvH@a_K;pr&9HX8ZAni93?0Ts22)IZ8u5>bZaK zp=6#t7YJdMy|gep`8H-8i03peK=u80t0mv~b+usoaf1hP_b%$7I%c~x=rt?r>)~4} zwRpQ_O`Pr5{kKK7W-uY!0|Ns!st%fl4ue1$0p|YW&~_h#C{lP}n%-$!Wzb!l)+bdD z#ho~Z{5{7+krO*z0BwGSQx-gj!B0+J_6#{ADA5+9Q0d#66PKxrITE?FGaDieo9r9L zM8g_WJfCc90$n9#oROb$IdiDkf9`~U?_6WbjfZ$rZFkIWos2<8e@V-$LX{Rqh^yMoD}gb7rkM?|f2WSx zXygJjt7u5i0$5?oz|MNu&FLv{FG6P8aLz_ZxwM+14P&hDdvC0FDIytCr1>@;Cz`NL zLxwt7a2632CaFxyEFW0Ks*V_F*ZUu-?pz*!LdJ4(WC$`n7!XAqS^F1Y~+mfmH9PZxx!@yi&#?*FlND9~+g6$43%&o)< zLRtfLH;&|KT}bORIO9me1_xggIljHQg2tvxnADk1&DWkPU2dUvp8<4N$!*g>)oUT4 z!(3u=6p})odZD*;sgPuCqxO`@#NScuX3K=Qmf9PMS$1Y}w`$?y7pbOLj=XSL-)|^0 zZ2N?vNay7RA6Z+<0vp8|);qiDj>~uPFFE~Bv^*Ofk|y_%`T88pk2^jF&M)pe#A|*1 z-PyJJd9$6nv}8=^&~fb31M6a%<^X+EA4Oa+>Kor`RM-J(B4kU%0!Apc zc3cfZD{GzTS6S57zUCTjudKWn&mV}Cl2m*#d%53sNmg&t-q?B-!2TBJW$*^q%V}|` zDvu$cEGN6lg}UynqMg}w<6LFW<3$s_d%nx$9&{sHf{L1>_OxFjX!%`_3Xa?#@wbKCL>9IOp=u?8o^_UjkaLtzw^ae^S@ugR47TA^izP9=ecmbMW+v96 zkhJ%aijByb#MwxD&mD7(5zzT*E-~ocU=r7M(l<#c&V3c@hZx-9-BN*y>y&|1?Y)1_8NIgr&3dh_QHAc(|f`bU zKpnbR)4>XO#dkTMp24IBQ-< zUrvk5Z0+rN*h>KsONz)uI*9je$lHYe8U+gNa`bg)_rNK3ue59#*Gc1PdLec_iu2SE zME&aLcOJ@|@a{ zzY4QKJI)H&Lq2^q2Q}t(njmeUiY%GanomWmcnX)O42%PXL+%b9b;W>lCqSa$WBVEt zE){cVjpG+IGk@92_2mHnia1P1TLE`N)h#y6-?b!p-EDlGM;2EBz|siqh(r~)vV;&k zCEGm1ad~Vuu@p>P-?{G=bic_~XA*z)Gyzm_&qI2hSIyF&B zp*Z?;slCxHuBZ;6VgE9J&llbm-`d%{EYP_8T@pg1=4I>CU2oLRk_c{Ka&qF}^S~Wm zieskz+bpln^AvrxO;%r)CIJmsz;Bibs82?1?yo=u!yqW;dSd;y?Tgg@V8LB=Jro^) z&9pe3Ec*EJIgfXThUz3rGSg{4@P9G&)^Sa}@!$Ux6_xrZ(xsxHASE#xm68^akQ9;b z95C1c5s;SdZt3ol66pqE3>aM_2BUW$zW4q8J%0SjA3Hm{&bh94JYTQ(@Xk=z%u7+x zem7!>WS8apE5h^a-(|=8V6jOA>Q}i@6Mk8YMmm0$wG-PHR z3x|Zm^1lhUGGR4pKU@^NdRmnPh;v_8R#@;U(EDfPFO6?hh6Ze3UA8U$OH5=znU5IV za2gIWas9@i+djQg6~co0(j}*~B{XAc>CsCo4p?)Kh}nMNJ+GFIlp(Nk$z}I%&xx)| zX*@0)BjeldZoTb=-elAkxf*K4{`(RsFS+8h<{U2PB$(U{vYR4^-(SH#s3D@54*7Fu zG&$&3+R0ky%Z_w{J8Of6`If(S0$oHVYwcd?wktF1*1({Nmg{jw-Yo@#D}5Gmn@l(D zfW;ejA{lY!wAN!k=~QcNz!BcwxwlW;C2-@CNYPDNS#Z{K5en<|Wi+Q-;R?R`REdqF za7(bWZw!5!$9i^NqrNuEFsP{t-D+M*b8erW1;g44v4)7Wmf7aonuI%Wjx1cM*p?OP ztSlbkU@(v0_}^NAb>C*T6BU3s+0cp_N0DB*qa;;utuFn#XXQXaY3&ZJ=tU}(S@ThE zgA$9^1*>8HmTXTQIPoD%)lgI20m&3_mDp;(aY-h2x|cQdO1mnAp{z&B0P!|-26cdg zUqP>~de(ml0L{qdx}02nBi0bQ(4M0Wui%!Pa+1!w(;#L7(ea`lnqt)wzAfAGoZwM9S3 zCJ9GV#_|0~AEzCd+-amM{T0f}AMi5Su19213(ym=Y&Zok)zZhHQ{Y#6oa>saa$7bVypHo>Xe z2?16hYw+BeeIou9TS^wdU=McWWN+9X{a7gjO6=yef5cESF`VTi7 z;R~cIUPoLKJ`lG@lU2C^fpp2f*w9Q_C)yO%(D0H5eSG`=B?|@F8jKN`h zP&i7TZz$Ohjs7x&mN9no5M@oR^5lZtN9a_9z<82W4zOE|EzmmbOpyrN;dXL$);LR3uwc%>6M%>b~tl=AEX~4O|Enn&jR8YsGiNuwg9B7RT?ne5YTVIebKKTUV17ubs};4`*}m)NEU{ecuz%XU>aEX z&&yb9Xs^HUQ_Vk~23}_<8+##}9EAn7+gMtDT-sa}iQ1|d^SoPOTXygzrN+0fo|Oq1MJ6Db`1H;%w|qwiP)QEABI=;*XjxbGS99y`rUrsTON{^g0z!qILfG_I*u?PN`C*z?JB*eILz zceWBd_#h>9GTL>RCx+~-Rk1687G17ionu^VPMV3Shwb)7z@8aAxA%Z(-g5#NUW#7V zvC2zIvm_@t>j9egEAw(i1?(3%eD5G%?`Pa2n)f&gJ}R8Pah&+I%jm}BUmVq?*?1@m z85QSb_1y8nc8$ZOJZ%77xFgkn3$<5cWGqV74I*!nlE?i6nq%Zwwx>`f`Aq1BF+CnV zeSP!lLyp?c*1frLj-;ti4_qn%j~=PwGy8%PlHidEe*-vE6EOFSEbi#;&ir!YI?Y=y zK`-fIA)61;?34zfkmIUY=+T7J2Gl(iK?pm}@VGD$S~1;yt@-i0wb_1w*{< zl9C#Ulb&Ak`SA`LL51t>YX|x~e504S=nV+BrontcPRJt0o5hQo02;M`TnXBt}5 zTFGoLC%~u&WeeZF1b9<7ggXKU+&6?g)cZi#N9NM9kiY$Kr^8NvuiJVF;-<$LT04N* z`lE%j-xxsNSlpYn)ju48d!2QbL90R12Zw^e3=r+OM&R|U!)5YtMQQ*lvV&PW@7=_K z)}hnwZN-uVZozj#vrr1&t!W9!5U@5|21st`MEsM{cqnITDo~6QNKhdnef@f?TkJlu zWzBfoXvfmsIb_$v!073)I6v7p+pGU-RTQJ-5H0hF7RtES(?{96U?M@6d87Drt=i}P zi;$oYZYLuhX5`ln7x*@{GXqEkL9Ekv%AsK2H^%va*gIbd?St6Gp`)}Wl?Br=;6!z; z#i2Qrz%J_jgxoVrg>mF3ulmy@F^LTiDc$|~S^ts17di6Phz>22oCX0RF^})AWcOH7 z-Y=CK-h;f+`UavrZ36!u!eQ0)SPl-kg*1<+%QE!NBjg(vdD8iaJ%9Wb1rVali)Ru|NN^Ka+wgMu^nk8-bk96hwut zJq9nb{OsX>-U3dp??fk`*VPL@@OEW&Z9E0ow2InxRu{p&=-0CfOLq?N>v12@$~-N| zjeF@){uG)w1$q#TlSfTkfHyWMb+@UVa!+#esh)oFFo|Fl?^#rqgy`t)y;INB)>1Ro z-lMsu$a&QakYJ7Yx<)wyY?uVWdBdCbCgOtb zrvAuVuX<)k`~Y?8vvGhTIDe3Xc0Z zaW5UCk}iRK94>5gZOPr_Hu*15v-yF!g}bkwFC22mBG#)x4O+qzE(HI8bx!w^1bh1E@EaD5nd}h1)OqBP;l>^ zHr2&*d$>0nJdu;@d)o|!I6wBdCoeaU8^_GbYGkcQUE24^@82b7yRc9W4Rq{`n&usNQzTW|d4j8>qmGy0FbQ<2Ajrl0IOe?B+ zCv-T-7FN#NO}6!|YTyEpV+DEf=O!_1F^P~WlJK4*+);K6yZ+(*4vUgr8nMQbmAFTb zVwjEZcptyz>hZanNBUk855@RMzFj~jm{;i(6v=4n2gk0pWtybemMDXdkLWmZ!aONK zK!)gVUx|YG19x;CWa>X|LXPn)je2o|UH$r(BzY5+ITs!p7VbbyQ?6#tM|KUi&^u;S zkm);deT#>uRY9{|UA-!JEXCKx(?S z``70Q_}37mnPnSQ*WmYg){Q08!8;aAKCb`2{;)s1At|JmZg80oK?UI>^!XpT(3`a> z$8qGlKgAQ4p}sa*w?_`>+w`tK>RNvzEOeM z-tI`>5I`L5{GHgkeY3rbH$aXx(rxvEeCUEn#AX$|hB?6T5e7Cp&+h4uE8$h}Sx;)^ zb8?;ZQv7ypmG4&G_;;5dT*uEPAi4@dZtI<3u(Cs+v096|d<5e4UOe~xqzgt=AEa!5 zfV`O+sgvXv*fq_v&5?gzX!?;2Sp|b?kpbnr;0apOaV@+0%vqka)gq=_;Z!319rsv2 zsd1Vl;3kAVdGgzShu~R2L!eHU(IYGqM_k|j#%lN4;a$k|HCqWOgM{}<=lA~30JrD} z2WBTU^?|6eRz*l_i;)!eAmXTWr^gy?kHEn2NkQAuD#RYUlb_8~^G8QwN>c z#HN(;V%VzRWzgl$P7%2vAp-t`6X3GG8nyJlIzNeC8{>V=DlTX{BXSs`4%-U9)7XKKp|L)k7O9UnP4KyEBea0 zovtzf75lkjuf0Q7LZ{NlKi6N#nQ)g5x_TtUE86H@2BIh%p&)Z=*OcJ}uaP?1oN;6m z5xdIB3njaKzD6{poN#)feuy$?!Nd{x!)_B2ww#{fLmBxq_wU2-Cw)CuP!L0=Ssg~# z?4ohxz)&(^-2VD(EhoG6L^O2*TukwYw_SGU^;!`4hBIDpe?q>Lx_M z?^=~-UPzKuQ+(z|Afn`}Xvl==E1wkdbjj#5FKm?xK$p=kfQ0AzE=e&)H`zBqW%0 zo+!d{Yif=In1Iu@%jd^SB=h|1mkq#}bG=!h; z8TNqVnk=OGihD}(^ZSRmE?Q>}C9ceSr$=DaT>Y-6ww`lpVWX!+L&##Lw_ws6%tB!uKurihP4AFkk>8#re2t=oA(ycNa#vaXf2B?rxVU0*X17z2GY`PNIGf7_Gik&FoY`4Q?tm!B@VowjA!4x@QP~@ z!_*Q4puZTezt+1b7pTqt&PcW8v@j_SXp}|8-CF4R31jl1Vh$4oyJnRrI2^X zndsLrm|3@#Ri^up^(CEk%>lQt+|+k(3mf^LJ`w&%P)2oq_^+>>_35g6{aH*8($gq zX=of&zWvV>ydte!OgE4`v<5AyG4VTESN^vh6PG69B#>YfPo`CzRl2ayhVU}BV8GPD zW$31?<0fzg^RR_{%1O;n&!4z<*!>DP?#?=hj^1qG$(xuOV1T+RR&@7^K7tH)@oS-N zM3bq{ouMM%pdvqN-@kYa`OK8R55@>v8XLaaFqnfA(T^_MY+%3~c~Yx8c^r)CxJpPf zJlVREwB!0D{@^ViJlLfg?9%A{=u*V}~mQB$+?jcoZG`My8aa|P7bGL&gj(f$MQCTd7WBy4^pV!IP;CkGHS4!ikOo*69Z z3?F1Xh79{zBqgEB0RF6iW*55=KlFOagErd_Mc^pENjkyDsVOHrI0?Eu%DCthaF42@ zDGtoo&+b)(mCyFCrJCk}Vu%rdkZg14>U3&^T&W~4y)0hPzy01Na!zlfGu8$L1(b7C zajgUNP+l_ded0m?Od_e-T3df=ql2!-hQwk-a>%oTnVZZYS&Mv)%K&i-F@<#i;D$IZ@Z&lBhqTRq$aXe!``& z#sK2OPq8FHd0|ie_sK53E)W61$UZg{nE+^mduaF0(^+BoPb=OOq#olPhw+$#57o$PKvbl+Z&y|SrTAJ78pdu(iMOmNF?EtDtg zh{QNYX~8F4S1beSa(vlsd>lNL`aMqvW=c6ctVReqN?YyH=0O<(I2Q`Hv;|!1YsC~# znj4zDM@i!oJJpw-|zl$0guxz3)QpkQ*aAC=>i9kEoPR6i_hDmI`b?BF2Hvx zs)pe{0P!}px8>uRnsT!WrAs03_FAC1K48gphMHD8y11Gv(u=mw2$>KyXHi^PSx-kt zc`fvD#lD1dVylC&Sj6~=zEJ(?wv?u;ZQmBz9!?)SnS5#oe9+T7y9jpj@@#t7NSJ4) z7t{O8;#X4A)?YHpdz*y&2Zu-VO-2*o!3(gnvAMgp=B^DTP1LG{ z7_IDk8E>$kzWY0c@{~1n9*hlTqGN0TmnSq?DpM&9;M?)j0>d7>pl5W;^y%*Ik_P+y zU~??~u#`}a4&0vK7%ORdkdx*)JcLYBT3#PB#WKXLF0)!`VGYKDDY^Rsp&tQ@qH}Ci zxM#Vm-RQqW^=e_$Mj6tQU}lt?Hu#WBI26K&{yn*Vt4Xt~ z&FtPXn%v?Rd(2JVz2g}LT zEQ#F!{In+H9@xSozyX|Y#>Xv8HFG%aqzf-or6w1LcX4Sc6j%EwX16 zJQwt7=v?RkvK4)aw~%yXdVvrG@`msP47Bc%r@3#$+@4}*Q;LinG!(s<;`zd-LkICD zp@HR?K8z*sP7zcLt$lXB91$fum}^F<$BMkkymTjoMkpIFhldCLew3HD{N5$>Wy(!s zW8XPCdd6HnerEOGeCMXDnCWS5Tv7vxPf)KyW4soiB-NsN*|Fogr!g9B%&N{tgB#9Z zCUgtF3lh1Ovb@i zvOg)|6ja`L<6j_wD0(0|ZLZv7{~vQg?vr9}*Nfm_19(|0s|A(fYKu!L$86NoDLjSn zE)ZP07K-JO2dh(u7a>P+iH1Hye_}*p!*Hxno->-fA?-AI&mOMJePl$7E1Q&g8Ymnu zPB;vK#;asaa3bs`!Y~NS*Zf7YxS`2c!6A3SiK&#Y@8!-!G?3s&@m8DvRi`e}V5SY) zvn9bD`WO`0tVMEB#6`!%X$=d3M+|U<5WhU{3Z)ib2E&hA3%L{4!-vRl!oPpnb3sZY z>izpft-comUWZww;cMCFx|rCSmx_N&R=A3V+mFf6^HvK#>)xo@FD@6*-&4)r*1e3> zt23FYyG!-OFcOO_jN`g`l44;*BkgWL1E#fQ_c#L%2QRcR4d`RA6_BGh2&8MEgzDX~ zGIg@%f7Tmi`rUS4Lbc##2*~h+kTTJsUF*38xYx_eD`IL64=fK3?hhs_&7VxvUR|}| zald(^7->}?w(nGof4=(PT7eSbyu`MM^Tq*%@czVc^N?cdu->*(mTkiu2RR|HdnXr! z-Jwq@zf_Qx%;bjy4ZgCRIzo1iX=keg6jV?yowAGf?i(4QTe2kDLi1tzujDy*J~i3z zw6NdT>6r&cE1COXB|;zP-FRel4A^q;RAI@j8)LG+KcK;psW!0lvUaRASW-~#@kfDB zIUc%JY&CUXN57)3&UvwsUBGVUwD;F@)n<=}-bwOfDTP2xw1FAx{b2dp-MO9@(V=k} zytUgWO#0rJm33Dfv7ZmZE*;dSf}YtgB@2PY*T1~B2XtJUNj7mzr#se+lH1Z6_6vtx zE~>Q((K zt=dRXP;Ak{mshC9AmG+G(xJS=&C|^r0Gt$%0%`LN*Vm3l|MncD3f>s&-qo8AB zp_pMM=Q5?#GwbvzC-5ic*=12u`{}r$HX7p?0el7NlLuEEOqw#0F%izPiSqi_TYq&WdN!osv`XGLF+P5M zgjX}Q;?hLySZ$p4hDVMJtux4BNFlxLRr!WgkZGBjm(lcUT8s$9xm*`nIKX5$H8nzL zzulp4K0&tV%m4hC1a_@9+Pg!{L9B~4|ZWn#C}fL+wQf| zln$ggX#L#%@t(^jt<}wt$AL)*(-VVEeBt~;y#6BRcEfG|p_zK&{uH2h`f_*ssNmUB zFGU*ZkoHA)+?ngGS0LERrFV*b1Cu^(skVv*oN}?mXvs zX7o);1%Nwx{n^bx8uT+r=-1}cs-Te##yZe8)K*~yB&i@p8{ShO?kDY!SA(rboI35 zw|p82{p)loAIe9HZ2}b@ zN++35dMI0uB>_@>nPu{IPP3!|b~S|dMPlAmYyyFj?AxfdZQc3+@M-upmq72;_;4@h?olK*#l2_+?+0NT=b8Ubbv$ik!UT{E9q<09p8tFQ8li=W%P zL5Z&&!4Rho>^=haRE;~cmCr@ibU@aB)Ij)a7DGwSudlSqW9er}n9bkTXP7}I#FROo ze?Az34wFaiRts!S?lah9PEH86qKIIndJJ@*$Ln=wx(1kv#NPOd?Y9M@(ZUFO>zJx4 zZ9^PT7@Im*_xY3zdPjo%R5q0Uux;E-28ZKez8PnRIrj|aY{JqA+pRPe5Nv*vV?nQ- zI>lo8lu#`j3nz&1?glp;6YuM#fRuz$BEqmW#gGuoGD}(mrb#V5LNW%4y0^7X?meVG z7rAyXj#XWW1>`o{SAr=q$^$daj{7Ya$v=U{RDHfRpNNbvI`%)^t+$qHYe&W8P8WL! za6L-IHf4UJl7=NCF8oltc_NoIg-D05hkwb;U!>y3es%Fgq>0a`!-aYaiVw9mvvv*8 zlpOKm5ezB1&y|GAT=pwc;i(3ZTW&Ot~clVhw~* zF7w=f?gjSRK(85hQQP!Z81A!#c$(}2ixm4uC&$D0N&3D0XNaL8uv!%MhHkHJ?wHJ5 z1YC&1m>;osCaPl3x9spRj?y1j2@wg#?>8AAa<7ayRAD2k{NQsTI7+$sv(NB@h^}yk zPfWb_@6+C_(uyR^>E_MJ=mH0tH`GtrBMk{nIXo? zv@j;Y99_B2KMy1ofBER24aOgO8!bEG;zueCTjKegR7?@1fq?5uqxxAT0KSY*cjGIp zl?Mre!``!vMmbWj_|)32M8zV`x<7P0p52XLHsd0fPfcpP4BGw!)eWDkHV-lCbaX#E zb`eoGm;1gpEZt{@%1^s~tKIk2BbExlf+cvk3wr#y$WRLZXLD?H0}_xqVM%nq&+$TPko!yH3z5$;Ti9~MX=MLJ8WJ}oCP+`G#-AE&I!3n()ytD(NnCd5%}N@ zCDckv3M$gM0%^ofwpvogJxoDmx05DtwjySXaddHD5r~Y9`1I)|Pc%`oxKnCrIP9#u zt4=VGDc+ogK9hnP_^-p63kwQJi1)~V9mZ!7f58fLlHrFJu1*Tn zZVKVUbjEpO%uZmP3gktHciU?_ar?&y)-HD7ah!=iJ3al5TeppLzIrEb!+~B}ngeqs zIkmHxLJA5EzDhRuxE22X=R_ltvN&J>D=B_?;x*fH z{+yi^#mx))V~~f>%}(a)syq^Q>`uBr!fFLgd%>k7R>@T@-VUsXOy#LCSRQvYo3Ktc zHBPM0m}V(qsfFz3v&wDmAwNnj&vr~b&l`UZ*e*pA_OMFHIFmh^Sk6usf`7&g?y&x~ zc+=u(5k9Swwu3sjm-&U-OT*pbZH5$u8NJ^bX-Y+Z-9RIJIlgg80F>H2V-j*)@tJn( z;2l+*FVAAl!4?M7@^)8oc)u|H^V9z_=hVMP+HJSD=<$=wGd|BS{bf3G&{aRO^Zj!Z zz}bZ)t(~$qf6SAC~kp`8o(S#W$WFZqP zi`R@v6OI2U4o0oE$m@qIL(_^g$8>Dg(4!B`%NS^vxE?vX9X^AsC!4=bt&IBFGS|gf zm8qNYaYc`vjkBOGQU8O+^WZSz92a2WmhD4ut18aVe-?Z0i2VDY!_EtA{8+c@6&)OG z1zcU6x4?V;qx%HHU?50od*ZZtSXxGYer(O-o_evcn8j2)^V4L!zV^-I>#TKZt$%NO z)u`#&EZq#&jFCxXbugiFo{v~dIS#mtp;1vn#K#(zUM&aPwOnTGrfOq=-X7K#e#}a& zLb+Cvj;yhZ4r93sx~Kbag`Ynv?MgyNdu4mub90)jJLRi7*C2u&3dM&#sI@t<7P6TB zlz7UNwk}hzHVn$&SG#c+VWuLE9tfd=tr94s7 z@9or*Q=E^#80-fgm8MM7A1+j^@b&~GjRiG|u55Qbvrw0dQO&U&W!Y6#*Ro6cXTJIq zp6Nfw^X$vjc2~gPgk?hkrbgUYYydqjgmzTdZ8ks&>Lc1_J&L+|_sRa9 zf<=NesK(Obtlj#5X};%w|3(d(D(oIiVjhCCv8;20l(E$AvLDI)=s0~OWsWFP1lyPM zSXbWnoIoe~5^nekyNGp*@X6+{GbWcpwUr(8bg7$j8EpEE97JDS{KhAV;nCr-Aq-xG<#Q^aLcwVfz8z%+mcQHI-T=Ei zuRrmV#51{l-8@qfuj9`E`ueWxOY$b5Dhj72e-^hT9ugdC+cf+Cx-r&uv!<3}dz!yK z`sc3RsX9&?%;sOTDa4wpxfXva0`os(Rt}xhgLOKM3O0+s^Dd>$=T4@Zsa;IBx=Rpz znG4ej0eAhxZ|n38NKyR`vD++kJ-Dh_cyU$%^RKuxwEp=y$-&y0OIL z(=^b3_uT6REHQ?^-q9hwlm^IqVs~O<9f~hJCUVA$5MJ<^ zY#x?r-PH-}FB!#2;zrDzI=z4>XdI)c##_4j->kdK_H?X<*IbC+G&+wF<%xha(1yN*>d ztx^?HFL35XmZAHp5UucNHaR}k-DJLTs#MDpG*c^35u1D`>7iqF3Cx_8numBDjMJdo zCzO*#os7>=yxl&yYpGPHK8&<>7hQQJeg&40#@5m}T5bM3cBRpwF30+YZwz{3_t!L~ z%D_4Tr<<8jXy%5hmsxwEHIX}LxCB;cf++!Qjpy!1p)h>yxfR!tEe97KlpSw;c0CJ#X1vND!0=}RKx0xNOB2G%L^MXn_X3O8p8FsPpQdN zRGhCf)g+zo9pjh^v<|j0;p}C%$g#V+@X`?QJlKvmIBNZDVKf@yn*@#rww#L!=lthh z(eKv$mKnpislZx7FJvFc@L4ZW&euL>*J5+OgJ1`jFxNE@a@bAPumwwwcu!OF;0BV$ z4Mq-7sYCgF(^U%Z>wf z&0;IZQyy5TcJmU0u+mofl+E;)3JRSlyIF8?6;{6S@r$E!YQNE)9wFQFC#ip?qIOe4 z{L>#w7b*mM1}L984?W5i6x-{DhQR>@{{_ zckVYcA!jTp%?40t<(gWOB;kpD4-d2Eh>%YzNm7@4einH_gFu zQJsB4BYf*@lX;+Wp$sAzoz{Yve`?WeKb$qf9TW17=e)YMC#>H1cO5=5N!H+P!T;KB zO2cIS*LL%~o~TOgjWX8<5F)xOSTj1h1%#TFTEWOK#-2HgWT_5|sFicnL)QQ9 znq%K*!J;u~By){w=d)}SaUC&LdYu%%mywV*4-&iXy zgS`Y2+To$8p5PQo3G_=aM^@rgu{x0@W_lOi3(^ZHw@bXB>#R*MAD!FO>mUx1D>Hf* zx-;%Pa{r8`jhlSOh|ThIAX$o1VxcFRVw27v9&if|rI8Bq^!WZm?xCc7aNl#brCFci zfM>Vm3jBykNSV=3X<=!(rq3wO($%+jtXvQ6B3iE=?8C7@bjl|QpgocN_3F5fR~+LH z1|8JX->kM5`HYRNgS`r(32H(W_=zZ4=NxVyX4#&ZBlGu;jt9%nfNa(DzGy1b&2BQ* zUF4jUi^yXv$=-tqdKvks>}PcjmG-%O?6N4HOxO=#E3|t+_!T6qvw?_j;AWmU{x2xK z2d!Zgizh_|7i}GRKm7VQb>MvZ?*DI+I$XInR=N@gvS{~)N3x8q=7_|Kx0}~mvt*Dw z+kSDtJa^~(;NT#gxbC0~vJtq*aUePj`|bKn87Xv7(_Mg_dT+ey)kZ#o#a*bQO05{y^JCV0LCMOh(&_N`JIVEA0NZ14|C@tPF*GRT{m`H6 zb^+b{_PZC)3qE$Y1Xn4c1EvExO^dehMVXmEkoNBn#(0z|Ej%gu3w4X%YHZ%2#ex!h zvjqk0tCV2*kgaa^#w-i1i{1Qj)RRrpd&hb0H5pJ*;kWo~-WiFFFV2fPxktYY$e%LR zz)B99<_=i4KU z9G2D4w4yAS?=6xpOANDIMdEB!ew`#g(&72?5(ioy*C~#u0rva8%V?gV!Hi#WI_YQ=#YohCA8!9Q**wm2y>B6+9 zr=nH4>-JfJjsg1F!;$y!1#dUup59)IL;vvU{G`e6we&9MZtw`#ule70MeILQ}ouIDG05t6I5Uh_<9VqtZu>?+L7RGHgZ( z#V(@;iAjH1^-EG+S)Lnwd4e0hA?ch$78HfD75h2+;#Z^@X13Wk z(mG3UZt{Pp5&WAlBQ+msA79{{C$@wkVcHB z-MngN9k0lkbIxmmfi)_1xUgVKF#=3c8y>!NFw9R=#%JYAWdLMu``gXSTA+Dy`0Aoq z8iTLGz?P=h8EoV%o`?5rjUYjiRFK-kA``aQ^_&9xMY_%B)GbN#af(s{w^w&zg=PKw z7jxKCS!RE-nL5OCkxncWbyc>9q~ItWo|+ouS0hO{^rRUP8{uHy`POY>9Wo%^S3CiO z%Q!#5{da}|b~>DWU`rc^+rO>54j7o}ZL189^92x`Lz^qeE*A>K!-7vJEfI5JMdJH= zCIp!DH?1$j!|VX=Wy0 zI>Q~XbZy9)4Kbcr42jp!x-Vx%5ms$&jNcln+b1Ii=2|w1qs|Ylc>l7_Lp}P-Zd@`q zTS#M%C;H-;hN~OMXz<(P8O7Uqc3(gKIBXZS7+i(M{#YGK7JjV={ST_1dH@bRW}+XF zj$dT%i61v@1hXAn+fknK^3J(q<1Tm&nDoD9>Tg`p^tzX$gkNWZamP5S2kz~?UZ`SJ z-5QWxGMv$~oDfdR6Lul}7Hyb{Sl&J$Fky{VNlH2Bk1il12|Rir_gZ=T%5`g%iE|Vc zVBV&Fm>ObbTU#vj3Ic7NA8D=uE@z_D4NU`hO_=l>fhM##M*n%iq$R)jJmWf)8bbf` z+IBfVax~~KTS6_Bu)l+zL;1)y?`XFGM4UjdNiU2<}@6{%)j|U)l2w{(?bS&`=X;p{YoG(bK zpHYQ9lm3%H!mp%I>4=@G(#x^144Wg+vdq5fe9c4D2_ekP{P9?_W}Zh>Z~+grod2F8 zApM$>df*|>c`=VWKSco}oy{}x zWrnUy{7~K;b?xGN`Z9xh9#FvPxSiU46CvYHLw!VWhbxaeS;WS=9=C>o$pF(-mUa^1;`59XIPT>B)c9FI)YHYp?9nID4 zuG!@K#Mu#pv1NRiz5ea7;}&K{Z70Vt&uGl^;ASk7?hf3#`p@4)lU(43f{0I&``{GERF zT}zlmEIefVn^1}VW|(c+1AIWBVk+M5D+CfF#Uk^lsgg11K@(xr!!m8OFbw)(d`qLT7Dl=cI!W&fs(Ihr5nNE2CAKG@V2uil)gKS~2C+|X$vx$c(l<77Mv z46Oz0U19;QfP>b)fw>;ex%#=OY8hm!A18w7re-+%jx&eX>lWl-2W%pYf>&d*zj&?* z?f?{qA_*Hr#C$oY{7JC#&H(2femCfH-DfoMnOoQzNYf)7p?`#+O{IxRyI9V)*WUZbWAE$h!xKE~ zA9>w@q(=~wET=*13^mis=iqfhFIFLiAr-aw@8Ok9;%6IcJN$~sVjW@ol+m;VMx+65w_2bOM~8von|vP6LBE#QZ;&xP8F$?gZgx1EXUvbCe1 z=GeJ9x<55|?qKq+{`7J%-0v$@G|+(CwiXvxM`a$A-s8(?OdtMj^GDBv`&R@DYwjvH zIWH?+v|itIxgW_W{~gTx(AnE#ok6T=XhRx-T{ z*O@B|@9WC4@)}+*`6a4}$8k}3Jni0C$lA)vA(6P#w(c~sXCc$X&kce$IxqMqC|B(_eYFDu zOaywMUlBx2mn!u*qvhwQI-YVG)+^u8ef(b?Zv8LQlE1rQJ#BFwwRk^ON1^IKcqxl( z%_K1I+k8{y)((lFu=O8^M^sF>!3i$Xv%a+1dY&pR zkN!}b*Z3HC0gjgLtOCj_BZ+ytt~R=@BY9Nn1cc|KM>&Z33izm-Av3dNLve@faH)8j z!@k;AP0izcm_+jVOw|nouX<+~|0YPz8Lq9auB=Jqs)@qEA#p7Y2LU9Yn_>D6FlDe~ z`>}?Wro4g=W`Uvik`$M#tf>(|zH-}~_=Vq}vP^pXzhJ?{a-R^BVbi0C*jOIZi)b86 zh&y~bJy%JpA~W+y0yAB|_L$#%XZ#?gHehe3^~_Tkg*cFEeIQAwc3yXKeojU|OSi`! z#g)G*Jcwt=qzThTOJ$7Dz(2@7kXM3)`qr!#N9wCR<=VC?G~<5+@jgTU zR*{ptM-WV`bXlekre@a2OI&v{E>U+k|>HLT0i{;~4{y)WiS6ma(*KHI* zrHV9>W(Da20s_)hKza$i3P>-Zw*aFeB3+~tdhbXlv?xdmz1I)~>4q9Qfjj=cTVC$d zefaJ?<(JD=g!nS5!%Bl3I>k9jnk#g8#=Xnud@$q&|TKQn~nyEFWYfh z_9D{dNt~vaKP3@$jPiGkoNZ)E_XOlwo%=kevrNk=!z@K-^^eQ*gSXsoO zBc?Tayfj0sG|JTycAnyQa*f;-JbO8OBSvL8^T&83AQL! zX+<3J=J=Davq)Bf3ye281$h$taGRNs2Lz-pDQ~0qTuoy|HX+ewwyd}$cEa<3BX11Ic5AbfbfSk?JCw=(rj@^ zetqMH?D-lINe(7>!zn{C39%ZF?^gEv-e3H!i{@F=3?Ay5&r>@;xP8G*Ffdk<;(SKX z)Yf`1;A^a{{ddGL^3q=Wbbl^*aD{JRaIj+BKzq})+FlcDQ^l@(*sgFy6Pq`3HSur& zO{n+n03JUEZ3WgDlSL-_d3jCiPTpsnE|n-|sU)PPrX-}_zqRJ!Vs|z+z0hztO~ocs zUsY38HPqMYdt*L@OTvD(xJ-6ei~VV(I~;?Bec_%Mz3Rh=QGSDGlI9f>3WqoPulq-u zsFD9Pdb}M&6A?j9Wqm>+g<+%-#v1eYR$_bG>$9JJRi5Idi;JBV$v@hZ`Y-$JgH&<*%54VKS~Gl&xygi zXJVd25bbSQ!9|31nth3*J z0S@em^5f!nYG*E2KU@4HBmKz)SvbjrpKq(B^3f|d6h!iRV%1g3n@5Ud?tQO%2AiML za;Lv6RLWBET1WNjmCM;k`zIk16*3qQMh1tQ`-Y?J*(A~>7fN@|2!E2hxivXC?MO&Y z!*q;JOL9zKU#hKROA`|4Q4hGE-5##r0-Z~7gKaaVOYzAEF8fjKQthYp-tz0W|B(3( zJ$%NqICt{3M02^wA8o0UBY}rufBRC`rFQ5eiYI_ zZ|+mg%*@Po6ywSA>L`;}=Opj!QJG;&Okj55PBr=6NF(pXBi0u`H|!$@e~|Reuh|cn z)|9V6BCm0Q+VeqKFw7X%dNj~`1_5r20dAemUgPGuRjQ|NkVPUp0<%7Qr$-R;ep4lvFKOYTeG!Cw=g;emrM0@ zSDi2e#i$y5-%-K9?-it{JMPb+Qb9=culo$`vEQ`T5K;+BD1+xASH{|dYJk2Vg&=)N zW~qy=>ooG&gJO{8xm%!AbmQ^jUTxdUX((cSgY?P%j(TJyxi`#6!u@bE=z8mLH}ohE zPzzOwKsup62-I(zhBqRu&gSFd#)v|qnra+g^&s~QEj|1Dc0u&|)-*aUXv?C+KSNGhT>dH`Nd}ckL z5$sObfdep~2kJMSY}Bq*uku}Eez7I$=Oa02e+yf#-^bnK_v>F~`Kp{6J z>jmz>RPyWyo_1x7F3)+Hb)}3Mx3-CahmNPdbW&1MT3n26DDVJIvn*xVP}{u_h^grf z@Xt9Aw4NKgTi5J)09!5~IXy)L8V<qOowm@f;9T)?@oYqN;8zM=< zJ2`u>&Mk07*y({E>^w*Os$k1#RU27}ufjd===Z~fwrfQQU z984(!`F92+eHW8Rc_}E!J5k&~$ioK}m6R z$?Szh!7lf3Vmh#i*^fF@OY?{C{pNfVRhoKe6! zF#hY;vDE`T3UxFhZ_JJ*;@$ax`o+N4`&6$HHRxBJljV)cy6}?Fs9(umQ z1cr@$Soh=N+t6v`3N(N6cd1kbTw^C6x~3o^BKYShgy5abq>jkQP*;d&m_%kIsT3hZ z*18HRkiI8#e*-E!wlepOH1aUWNE)lZ%9kdr+n1E63^o>CMNahy+%Cwv{3VHwCS7KW;b)7_;n zZ%i*R0{0%t|w|ezvesX`QbM zT-cpVUji&)t<3&gc=N3%7}SE6_o^CS7p0RleB)k=CBx-Kz+ovTxa5g#*}ef@BHo9} z%Yl4wcS0vYfx>>-7BnvFr}ZAX1Nou+uWo=mqYQW_?Q$$S^Hj)TqSb^c@G=-!o_2e$ z$HuMf?mUQr-^}o@`-(<^2)XalVr7OcK?S%YF*7pafBC_Zu3XV(coKMZ$sH$|94y7p z4>TM>PU*3H7Z!hZWX}TwvRu})k;dbMHkA4K#fmOH7;4qd^0YXK;Z*9d;yX}hs_16j z{+%)L)bXNM5=I^GcSzU8|11Ld1A^j(%CKDX`F&qybo(44Ha6Di5W`y%XukIfum}yS zyzRkZ(LS?%+Imq85+E#j^Vdrz&Q;9TS>|_^y#23x5(N;BI8FmVH-qJY)t!;vo}QA8 zTXLJ2>uN*5eB;$CRxl~gZPFX1T%NuBNr=G(-y!?8VDc-Og4e)Sk|7?(WCJ$U3^+)> z%p9_gnPuj*;|exB{*eGXYru3Qtl1hvU%c6f^b)`Q-KrGZT|bXMcN^&HqIAw-HvL^? zBJQ18RsH%Kjr$oNYP7~KmJ!OKd4>*e)NGlYYi2z1i#tN?AAZFl^tjD3v}&-&MFGwJ zb=y*zZc25HX$O84>G*g=b6V`)J)EuzkDNuI=`+{qt1DI656Tz&fwT_VoS#SvmNc$Q zvx))^wg-IlCHlk!;piaH`wH? znk+-SgbLJGjM(P@^>18PxlmmC_J*Cw(u1R&Rj?JtyLWbY<=8vta@Wv>j=gj~(9x0U zQ4Ppc%l4bk*-H-2d0eS*s(NVG5%WCCYDR(P#BRTE>fh5A^f{WaKSvxtS&B0-hV6g) zlncL^r~CklOm970yC4lVT@_JNDT1FYb5A}FyETvo_8)p2G(?`Cca@UP-Otjf*t;(z zL^pcnGZ<=SeX7m2(FzA1o^TI%ux!pxOhb`aJdNlRZqA>7j|Zr|(;~BCaJz3H@E5H~=7}7#+&G*Mq|MywgIb(|xu1AztR^Sj z5z3RA0$y-YW=I}U5yMaEMV&EfDoTo~ss-HD_MRIH@2` z{DEV)1GHSw{D$6OwW;T}wWH(fibJr5V#eW;Ec}H7a0m8O`GthicS*|3V))ed8Hl^8Nm+F~ z$6A9Ao}0lWF(c6_9%i4@w@7cOG-PP?6EhZ4WR%2TcqQ)4hDF{^E`6iNunv*o-O; zs^3~iTSOddn^VI<>zuf`$_jMPctj+1a|SgpvC_<(SLnG{fvzTXEZ7(@QO-sL8KeEL zTVJ}&l&jdlaH$xJW+_14DzC~eapTZiaLSGY_a#D!EsYXu19Np?3q9*thF~+4`?`=2 zv_LlspNx-`%`tG&_?j+8AQ-r}f(2N)Y53vVbZxqgW@r9_YVcO};^O9TeN{DEovrz3 zWBfywjd>hhBhrOKgiq{o{G#)pq+K)fg|8%emHkO;-1O<5CxSnZ1R3<2@qb1$#_9_dJ?lNK14j zj8&P80)KD^Qh22k?6~|9{(-v>{Z24&<~taURRk)1mpjo8?{`N=m+9P=hkF&G(lW<* zX-PRR2hV*3=@Q^x-cDt2Fmp#--hT2E9m+9ypJSj9EtYrOI^mCKOzT+Rx(o)BnwUvqB z@rYy#Tk#fNkmD_OblIO^0mBr0H6h-+SOxP*q+z69Lp{9(=UB#-u{lylMY+V0QztioJ zB5e;V+=LoYE5m8hXo|zA27jCu08+nSO;6OajRgyy8k?&M4wSd-=jOMQ3Br^&b)qm)2q2n#cZ-bkXHUfdMvzG5{cjU3A zHI;9N!&KyU6JG7|@BCuSPg1}QVBm8Du?3g!!Z?4%k8+CAzToAp-s9*OmUb%oUf^DE zICs?&0ZcPxeAQkj_r;}2l=!;$Qt~-%y3x$rsyeF1t#CFUwv4_?$+8Lqc0`<~Im;}B zg?$VT;4LA0P$wteKx6N|v|}_5hG|v!km{fqZO=z+uXX=ZB7L*6QsF{bPL67k#F-`^ z5ky$#KYwVDj6#8esNT#1X>)4yJR4~LP*f;kdpsp(#ybss_g%f@B?RupO%pYrZg6*g z0z|xri!xCYPIGnE7+pW{-x#;{Iu%I8zkjYQ$ zMrLbcZ5@etv9vQxV?4N1gO6As%j!j87lc*_H8tcjLUzskY}=b&^wFD6froR%mHH#q zAtigCoB-W~6+T=V42y(Ip3>8mBjLBug#sqAoW)y~ovM<+?*|>*zjEVnO;jp`KfQ~K z7UB-*>q`bsJm-7RhY#ET{tdD0RL|OUAqxe8=%|GHc9PCXm}E0vyv99SN%-=a0H&Cr@g1J%@uksiSi&nAnu8};{bZGUZYaV*st!I91P<5!w=k7 zTH_%|)p_d$mcUe-9_zsl8hNE*({fCS7h;c#ceSVD3|9kMBEB7hMACW9YQ5!B0?(O% zc9Cf9BqE)=H4WuHm^JPox-YR_I%pmEeEyPUnGB>IIAi3oU(Ca58w|x~gyd9I6%~Pl zeHK>%9>K${me3`CRFY(*gPFGRi-3u9>C4lm6b3PC{LUrfD0wd(j1Npt$E4K+qW%@7 z+v<3z)N9cjbTK6*CbY1x#GFWhW5?dJv+H&5;| zG$Um(Xj>|VX6_?EXmySB8kX<$W7zMKN$0GY=O|#oh#+}Ca|V5$_M33TNdlXsNSoIvVk&M^w;SL(6iM73 zo0!Ny3&JCm3OSx|aVhrSVq#p|B&+;>N9NVb4iGQc=bD55qn?K-p;f696;>oe;6V{; z`^JRKBQc~g#z;Y-AfQP^-Q**p2R@$v=&^JX%2sUoghD#dW~Sz5324DEes4smN{cmj zq`(e6J2&Ha5EqM3@V>UUw}&&D(lzyFxf{3AhWIMNgIRw^U{>hw9I7EgZ+Hn;gp2vbe-0@xiBf>bjK^q_d6i4YGY}dJ03m zXCi{2gn)%egNOI<=e3OY4=;QB{Pf$QeJR2$OMuW&)p_$;COaMdE*~f7gx^ck-TXOK zqna%K+-z?F%&Smk6&UVqo<5cdau;#|dL#WHv%X-+z;BJmO0k!lHk~+Od#*=c;{vZa zoF_j0OyV8LVvs||2GQBm9Be1PRQP8C0>!O)Z{EG|&|tHV7$Y=4Sro;t*VfdF;j%-3 zx&(SFn3Gf5$CuLwv!O`eXhz7hYaYVaA@A=Fe=T201q%&2EbPW}k5t5Bc#R#VIM0%d zj7+H7I$yg4>BcL*=cXMP7zh%Y7blwyG72GAepI`ON^!2J`CGUZzy8+CYh~m3?#+j} zflf5C_7(SaqkIvN4J~?sGF+Zt38Ms7>EMW7iPYG|Z_VdzU`+TgkGMa2TZcg~bx6qsh8pXBmy$>xaFdFedh?z=Za5L>BhFg4+y zO}XTvdA`$gD^_N7(?+Zv;osyvAHd(zV*@N{TIKJ(u6Rw*wM!39(u?RW?|6qZOq z1??8g3V#{1*SL5&*|k9+8?W{B3NkYrGBbx{E`!g(4Y~PSK3+ZXv-b0Q!ZS{5hS%-0 zAE-h8Fp+{g*wJm05xQ0=;N>4QdhPgpCr1f&q}4+tn`AMvuH zBup#IR>dus26_g@0U(9Oj3PI-(cjlP&Z!|XL>fBDTHq>b%$3i|MDOLZ zv6?Eoy2#%H{g4pWI%b$Xs-k@8=1DaQ$ zlEC+o*q$Oiu%1X4ba%lo-96j~>Z1D#rYi<_7|uU0q@4VAwbml2747~y__)j%KVh-9 zPqp)DVWtc7ugvAjLFfCDF^`wq(3&9H@{+~KjrC@ z5-B|>eg(C+?96U9)MR|f_dCV4I+MEtX8)tZu>)yn6~p9Sc12s!b4N{ia8U#dz##j< zENxw=QDITQVki51fPm5@+Oo5s=JYh*`ir)BAf)wCO-|LdqKe?}y? z(SGMRrqE%13e|X`j#2Efn;TuxT^V~no(zNr!5QrSR378WI6lT=0{-ggl;$0MR1b!t z8IZn>^f;>Wxy(IU3oH2Rx&gkrJ;}w{-#_(W1*_`@HD2!C?vC$oPQCj!_2tW2Lmd99 zWmDZiIZGNZd5OQdr!S*#PmK9w&bEybMZdAQhl>+$hKgE>EB~o;zP1dUS#HlgZyl(I zby+LlUJ}a1m);XPRC=>UB-u!DKchlTCuHa|zy`^r9vU95tFh&xR=$0EbVkBbh74kx z0KZAKRuZ4bX)U~}qk~^@!2Iobw6nL}nkNP1n`#4_{ff z&^6fm;v&lV)0ZuZ+mx$0!dBZRS5QFoK1-VwObLUJ^Ky%Ha^fj^WJ=K3DG+d7UtRXI zSAOT^^VTKoNWTlMsBza@YUj2NG7NgUwPHYffW37)a5kdVO`i8L(KG znEEuxV;Ujt`tp)BX9I1gj;=uN#?aR#h&~cyOr~<*=h4KIK>A~15gEw`Uj%b4!&k`D z<;6U?<6DumywP(?o_|L)fU+m9z3Q3YLDbNmHXye@qPCI8@Y93}GG3f&9QhG{4P`EI z$g*1H-A14#on7kk85MCFf|fJpIos24Sy;hxisjJmh{PW|yuyOf}%Jq0@9 zx!-N)$4f$zpEo2-4u)f!Y$sC|R66lIfBSQLI4u}0r#0cL{VM!`VYR&vPKYCKQ4*_i zc|W%%qa`ajO-xz6JFY5q4QkY>@S4}S{s$^e5o7jQ<@Ras$Mwzj4!Uw+wQn()-TjO< zuBkL?sN7Re&o%$KFuQJ`(CcVY47~@_ukPW2+;hy==A`y;HOJ=64Px3-1L51#Opszr zi`S?}pC_w@oZo;1cidKATlUm=W+vjHF+5JaY+B$00CWyzWK(XHTl@Vi&D2edmTYoB zgzm@b#1i0~jUSzVi7~9r=B$a0MpOpRfhwx{K%e=Rw~ZI4W(-)aOZ#iq z=^5oafWKgg?<8l5_Mm+_EA#jM;*t%9@0+&oP=+Wf$j}W<;dL<7&&{191a7j-hzWv3 zUsyIPK^)x+ceHR^d++AW%jqpKsimQknr|ZFnv$SJ+~k2!Ur;gKo!}CU5feWl(#COi zkdlsTFFTv-of`f1a`bnc3vfnwMeVbUK#BlFj^*N_@D!Bwd@)E(E-%qch(~fUdg1x$ z=nOnJ#DoQ1bzA5%n9SNQp5h06QbSZ)t;fe|e+j-9$91`0dO3}|;0{S6+>R%Q#gSwL z2o_hKdzRG&ARFyPk+Y6!WJVyJ(t2gI=I*7v?*S7#CdJ)ZfBcPC6^}3AC1s1lV!7e8xnvS-1i6dNa+s!9&PPXn;c_cmy9~3&eM&U~!#GpC< zyd~!HfbXKmb|rzbZaa!qB}BiS8mQaZ*{z|JO89oi|A9wUh^VwQl1B`${pH1%y3K8z zb*H{tS;gG+Xo+QT6qcQ@WiHk0*RQHne8kN7V4iE%&-yi5p^BcImQt=j?!@~!EmR?F zYTcpDE|LLXBKOE~!v2gSXVh7Hd2{%=F4aT3howG*58zot2L>$9{+>Y~KqNiJ4L8-g z9A7ArY!J<77TZ|k`E00S@EIEf;u(|3-$G5JUhDiprT}`T+jy0QL}#=(yWRJMb3%Wb z)I3aVyyg$fKzuPaA_J3(dcSyY%Nz0{jh!NhItfXIcM(5yaFq912!@;HD2FgBZ-b>6w6_zUzIANOB}*;#07mugoQ8!#}@bs@x? z>V+gyzb2=<@C!s6e6c?h{4*Jyze$#cX_C01V}h*?KR+!!yo(QjyqE9q)j;1o2@fCAHc;V$039g048s{Ay^a4g&ALCPTyXKD&6TBExA! zd_rq)2TXUO-MHlZh5h5@Mg-A&d-cn&+D~F}Q%AFeU)RwRMW?C~MYrd_%fU25E=*Yh zF+P$U_^}gxm;!@uw5^@v&WXlNVvO2+I;Ces@YVRdB=HHGTq>dEoQlWy_dny)^;Dah znO&(%+Iw#mSfjTA-lU}Ivjf5w^?&vbmuD2 z#JCDUX<|ZS%F7|bE)ZK8P+mYxT-Ek6S^pa%p4a!$fO(i{a@1k}dM8`ZU5(_%3}#+b zmFSX!EBB&kMhTK}^0+|h3`_|=VFkae!6Idg2(=IX{>WG&%n>LK9324Dp=jS9`xlx_ z74?nIO{{z^cbPrhKZPT1(qJjYS=405+Llz+;i^x%=)Y7u=(;B=<;s;FlICi490dEd z6+2@{cU|cr&*a>Dt?8{*X>LPf+1`yPm~V|fg}gUh2T5?F1Kvw1BLvK&-eo-8|XN1ocIyl`WkDyYai}>D}79;^Y!)2G6H4%^ROjt@%_9(#k9D zeC8dXUM+Hz>0ztRyz-tTi>j5ErF1QqeVz7&HgP0X4O?g{{0p z;{t+1qM|T+Yc2~7DnlI`m@ZgbWOQ=>{WHU@*BsMwrC85uCyy}Z*U!0!G(RNGhvzXm z7Zdr{SZ+p@Y2($RpSwT5IvNcMC?GN{yY4wUvGLqILix>5qfoRpL?d})K~?rt)}EwZ z^$LP?#vkNlp)+<4mf-lEvq!8p6u+{25vFD9gU3TZXk>?pRi=hFLF2F#=qu{Fz|jH* zx@@wS-cFMK)fT@JOsSHj+%#4LxBDe-L%WWhR#tG!GC){RJlaOtRhNJJgCsnU? zC-!D(d?zW{p3@{hiU-5njfH=+%nZ|YTJ*N7R=NWjivTtR=G(6y#naPTzq3}~DRJHr zVM$q&{+ozV=V{unJVaCvl(x}UBocty9Q0Jc5JGQOjQ47n(~?Lpg&y%hujziZ+H8AaM?#b zddEUoW*QC(+e@=<;xH|e5w9-$%yn7kSw&R#zs&hh;+)-m&bFMo+G+B{LcRZ34kr)w zbznxjU^USps*>AuH*jbCn9 { test.describe('E2eIconSvg', () => { const getComponent = (page: Page) => page.getByTestId('e2eIconSvg'); - test('svg icons - dropdown open', async ({ page }) => { + /** + * Every icon on this page arrives over HTTP: E2eIconSvg registers a resolver mapping each name + * onto /assets/SVGIcons/.svg, and KbqIcon injects the response into its host element once + * it lands. Until then the host is empty and occupies no space, so the text around it sits where + * it will not stay — a capture taken too early differs as a whole-page horizontal shift rather + * than as one wrong-looking icon, which is misleading enough to be worth ruling out here. + * + * Safe to require of every icon because every icon on this page resolves to inline SVG; none + * falls back to the font-class path, so this cannot hang on one that was never going to load. + * That is a property of E2eIconSvg's resolver provider, not of KbqIcon — the sibling page above + * has no such provider and renders its icons as font classes, so the same wait there would never + * be satisfied. + * + * The first assertion is the guard: without it the second passes trivially against a page that + * has not rendered yet. + */ + const waitForIcons = async (page: Page) => { + await expect(page.locator('.kbq-icon').first()).toBeAttached(); + await expect(page.locator('.kbq-icon:not(:has(svg))')).toHaveCount(0); + }; + + test('svg icons', async ({ page }) => { await page.goto('/E2eIconSvg'); - await page.getByTestId('e2eIconSvgDropdownTrigger').click(); + await waitForIcons(page); await expect(getComponent(page)).toHaveScreenshot('02-light.png'); }); }); diff --git a/packages/components/icon/e2e.ts b/packages/components/icon/e2e.ts index 4d2558ffe8..a6c79173ff 100644 --- a/packages/components/icon/e2e.ts +++ b/packages/components/icon/e2e.ts @@ -353,21 +353,19 @@ export class E2eIconStateAndStyle {

- - - - -
`, + // The dropdown item above is rendered inline rather than inside an open kbq-dropdown, so it never + // receives the panel's styles through the overlay. Pulling them in here is what keeps it looking + // like a dropdown item — which is the point of the capture, since the icon inside it is what is + // being checked. + styleUrls: ['../dropdown/dropdown-tokens.scss', '../dropdown/dropdown.scss'], styles: ` :host { height: 570px; From a7386936bf18d4ebc98111e78bf8a336815dc2b3 Mon Sep 17 00:00:00 2001 From: lskramarov Date: Thu, 13 Aug 2026 11:58:48 +0300 Subject: [PATCH 3/4] chore(e2e): create the report directories in the wrapper docker compose creates a missing bind-mount source itself, but the daemon does it - so against a rootful daemon playwright-report/ and test-results/ land in the working tree owned by root, and the developer's next run cannot write into them. It does not heal itself either: the ownership survives until someone with sudo removes the directories, and the error it eventually produces comes from inside the container, pointing nowhere near the cause. Both CI workflows already carried a `mkdir -p` for exactly this, but tools/e2e/run.js did not, so a plain local run stayed exposed. Creating them in the wrapper covers every supported entry point, and the workflow steps go away rather than duplicating it. --- .github/workflows/e2e-approve-snapshots.yml | 6 ++---- .github/workflows/e2e.yml | 7 +++---- tools/e2e/run.js | 20 ++++++++++++++++++-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.github/workflows/e2e-approve-snapshots.yml b/.github/workflows/e2e-approve-snapshots.yml index e132d1b7b2..8bc3ff85ed 100644 --- a/.github/workflows/e2e-approve-snapshots.yml +++ b/.github/workflows/e2e-approve-snapshots.yml @@ -33,13 +33,11 @@ jobs: # runner instead would mean the baselines are written by one renderer and checked by another, # and this workflow would happily commit screenshots that fail the very next run. # - # docker compose creates a missing bind-mount source as root; packages/components already - # exists from the checkout, so only the report directories need creating up front. - - run: mkdir -p playwright-report test-results # npm rather than yarn: no setup-node here, so the repository's Yarn 4 release is not on # PATH. The container does its own install. e2e:docker:update-snapshots additionally mounts # packages/components, which is how the rewritten PNGs reach the working tree for the commit - # step below. + # step below — and which already exists from the checkout, unlike the report directories that + # tools/e2e/run.js creates. - id: update-snapshots run: npm run e2e:docker:update-snapshots env: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c315920d85..be68156275 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -39,13 +39,12 @@ jobs: # `cache-to: type=gha`, which would push well over a gigabyte of layers into the same 10 GB # Actions cache that every other job's yarn cache is competing for. # - # docker compose creates a missing bind-mount source as root. Creating them up front keeps - # the workspace owned by the runner user, which matters on self-hosted runners where the - # next job has to clean it up. - - run: mkdir -p playwright-report test-results # npm rather than yarn: without setup-node the repository's Yarn 4 release is never put on # PATH, and the runner's own `yarn` is v1, which cannot read this manifest. Nothing is # installed here either — the container does its own yarn install. + # + # The bind-mount targets are created by tools/e2e/run.js rather than by a step here, so that a + # local run gets the same treatment; see the comment there. - id: run-e2e-tests run: npm run e2e:docker env: diff --git a/tools/e2e/run.js b/tools/e2e/run.js index 9f468e1ca3..3b37cdfc92 100644 --- a/tools/e2e/run.js +++ b/tools/e2e/run.js @@ -20,14 +20,18 @@ */ const { spawnSync } = require('node:child_process'); -const { existsSync } = require('node:fs'); +const { existsSync, mkdirSync } = require('node:fs'); const { basename, join } = require('node:path'); const { devDependencies } = require('../../package.json'); const TIME_LABEL = 'Runtime'; +const REPOSITORY_ROOT = join(__dirname, '../..'); const COMPOSE_FILE = join(__dirname, 'docker-compose.yml'); const COMPOSE_UPDATE_FILE = join(__dirname, 'docker-compose.update.yml'); +// The two directories docker-compose.yml bind-mounts out of the container for their reports. +const OUTPUT_DIRECTORIES = ['playwright-report', 'test-results']; + const fail = (message) => { console.error(message); process.exit(1); @@ -173,6 +177,18 @@ if (isForwardedToWsl) { env.WSLENV = [env.WSLENV, ...forwarded.map((name) => `${name}/u`)].filter(Boolean).join(':'); } +// Compose creates a missing bind-mount source itself, but the daemon does it — so against a rootful +// daemon these land in the working tree owned by root, and the developer's next run cannot write into +// them. It is not self-healing either: the ownership survives until someone with sudo removes the +// directories, and the failure it eventually produces is a permission error from inside the container, +// pointing nowhere near the cause. Creating them here, as whoever invoked the script, is the whole fix. +// +// This belongs in the wrapper rather than in the CI workflows that used to carry it: every supported +// entry point goes through this file, so covering it here covers a plain local run too. +for (const directory of OUTPUT_DIRECTORIES) { + mkdirSync(join(REPOSITORY_ROOT, directory), { recursive: true }); +} + console.time(TIME_LABEL); const result = spawnSync( @@ -204,7 +220,7 @@ if (result.error) { // Only when there is something to open: the run can also fail before any test executes — a build // error, or an image that cannot be pulled — and pointing at a report that was never written sends // whoever is debugging in the wrong direction. -if (result.status !== 0 && existsSync(join(__dirname, '../../playwright-report/index.html'))) { +if (result.status !== 0 && existsSync(join(REPOSITORY_ROOT, 'playwright-report/index.html'))) { console.info('To view the test report, run: `npx playwright show-report`'); } From dbbc81b15cf4eb4553e8bfcc48187988fa31dfa7 Mon Sep 17 00:00:00 2001 From: lskramarov Date: Thu, 13 Aug 2026 13:30:14 +0300 Subject: [PATCH 4/4] test(icon): drop the dropdown item from the svg icons page It could not be rendered truthfully. A kbq-dropdown-item only exists inside an overlay, so the previous version opened the dropdown and captured whatever of the panel happened to overlap the component's bounding box - clipped at the edge, and timed against the open animation, which is what made the test flaky in the first place. Rendering the item inline instead traded that for importing the dropdown's own stylesheets into this page to fake the appearance, which is no more honest. The appearance of an item with an icon is already covered by the dropdown suite, in a real panel. What is lost here is the icon resolved as inline SVG rather than as a font class, which is a thin enough distinction not to be worth either fake. --- .../icon/__screenshots__/02-light.png | Bin 92551 -> 89220 bytes packages/components/icon/e2e.ts | 14 -------------- 2 files changed, 14 deletions(-) diff --git a/packages/components/icon/__screenshots__/02-light.png b/packages/components/icon/__screenshots__/02-light.png index 4ccab43a5e4723244b7435d69675d60bc26d0dca..7e54ce95889ae329c3217f7f5e920323c76d3544 100644 GIT binary patch delta 54582 zcmbrlbyQWs`!9^5q5>)nQUU_fNJ>lR0qF+m2I*$2fHX+w0jWcGx4@yBL#K3uG#u(~ z{QiFHz4u-BuDjm#&L3y?nLYE&>^)D-vp-J&;;~=dJihj#zDLLpu@ zTj-_*%=@39pnL{?N`gI{Ud$EliXh*BJwBWLSBuw+fK0^JQ?RKL{rE~ooD35MWjNJ( zB#kG80e92xc*3&k5qNX=*^xO4%Gbef47l6u&S6gydBK0)!vA{ne1Sqqwt(?*nTKFc zE(!Lza)(5T%=cynt0Mr|vIkRjce1k2&nF^_XL$8l=RMe#+z{i`)F`sRP7j}lj4rp0 zhhn>PprCxbGFK&=*YZM({0VmYx;G-?l$7cCA%(e^d7UwW|1}EAFYijO2wNuH4Dfj> zqeBZHA}720!ur;*!TzPh)q|N4Pe*=wyAlkWt?TWaYMhcjf~W z6zkq){uwXMZ>}!3io%N1YpWRlR{lwgCL2J#=Jyv7F3=0SpY1n{aWHeBYh=p_{%Tpj zF$MNX<;tTWAmH)8>9~@Hg2f(^MNHW~82q1;c*@uD+N{=K}}Y03y&#hc#^ zsUbm=Zv4e9B{@Jy1r@YZH`*0^oAOlb3_=V!KjoiZH2!&`uW#r2q6^8x`)^|>EYtYw z)7Lu>O$lQg%ah{JVq*KId0_MP#vAzAX6uQ}i=4mt-gd`Bn-{tN$-)p{F(I zXJP49^HHDt9HvCoR*!URC_|{1%)fg_Uy%HIb4B-fCT6U#t-gqjvcdKA%)yGDlb*j@ zLp⪻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