TypeScript can catch disagreements between files before a build ships. It cannot tell whether an HTTP request contains an unwanted user_id, whether a signed-in person owns a database row, or whether a production email link reaches the right app. This guide takes one small web app through those boundaries: a private reading queue with a browser, API, Auth service and database. The complete, reviewed source is embedded below so you can inspect the actual implementation and adapt it to an app you are authorized to build.

The big change

  • What changed: One npm workspace shares Zod request and response schemas between a Vite browser and Express API, while Supabase Auth, SQL grants and row-level security control access to stored items.
  • Why it matters: The reference gives an AI coding agent a concrete contract to modify and gives the owner observable tests for inputs, ownership, version conflicts and release behavior.
  • What to watch: Local build and five pure tests passed. Real Supabase sign-in, database permissions, browser behavior and Render deployment remain to be tested in the reader's own accounts.

Before you start

You need authority over the app's purpose, repository, users, data, development and production Supabase projects, email sender and hosting release. Use permitted synthetic identities and reading items for testing. Have Node 24 and npm 11 for this exact package tree, Python 3.10 or later to reconstruct the embedded source, and a Git and Render account if you intend to release. Check the current Supabase and Render plans, limits and spending controls before provisioning anything. The guide does not assume a fixed bill or that your account permits a particular feature.

The example is deliberately specific. An enrolled user can save an HTTP(S) link and title, see their own items, switch an item's read status and delete it. The list displays the newest 100 items and has no pagination. There is no sharing, upload, payment, background job or audit log. Write down any different behavior your real app needs before asking an AI agent to change this code. The goal is an exact, owner-verified app, or a recorded hold where a required check fails.

1. Define the contract, then inspect the source

The embedded reference/ directory has npm workspaces for packages/contracts, apps/api and apps/web, plus database/001_reading_items.sql, a lockfile, tests and a blank acceptance-record.md. packages/contracts/src/index.ts defines CreateItem, ChangeStatus, Item and ItemList with Zod. The schemas infer TypeScript types for both sides and validate data at runtime. The create schema admits a trimmed title and HTTP(S) URL; its strict object shape rejects an extra user_id. The status request requires status and a positive expectedVersion. The API checks these shapes again when requests arrive. Zod's documentation describes parsing and inferred types; TypeScript strict mode only checks the code it can see at compile time.

Inspect the API route and SQL together. Each protected request needs a bearer token. The API creates a caller-scoped Supabase client and asks auth.getUser(token) to confirm the user; a browser getSession() supplies a token but is not the server's authorization decision. The table grants authenticated access and uses row-level security policies comparing user_id with auth.uid() for select, insert, update and delete. That database boundary enforces owner isolation for these operations. Supabase's server Auth and RLS guidance explain the two checks.

The API's status change calls set_reading_status with an expected version. Its SQL update matches the caller, item ID and version in one statement, increments the version and returns the complete row. The API validates that returned row, including the private user_id, then projects only the public fields into a strict Item response. An empty result becomes a generic conflict. This version rule covers the reference API/RPC path. An authenticated owner with direct table write access could update their own row outside that protocol; RLS still bars other owners' rows, but it does not make the version rule universal. The browser's sign-out helper reports success only when Supabase returns no error. Returned errors and rejected calls warn that the session may remain active.

For a different app, settle its actors, enrollment, records, permissions, retention, states and endpoints first. Give a coding agent the exact source revision and ask for a diff against that contract. Require it to explain every change to a field, endpoint, policy, Auth flow or build command. Review the diff and repeat the affected checks yourself. A generated type or successful compile does not establish data access behavior.

2. Reconstruct the local reference

The Python block below contains the entire reviewed source, including the lockfile and SQL. Copy every line inside that block to a new UTF-8 file named restore_reviewed_source.py. Give it one absolute path to a new, nonexistent directory under an existing local directory you control. The command reconstructs files only; it does not install packages, run the app, run SQL, contact a provider or deploy. The script checks its embedded ZIP and all 22 file hashes before creating the output directory. It refuses an existing target. If a write fails partway through, inspect the partial directory; the script never deletes or overwrites it.

On macOS or Linux, replace the example path with your own new path:

Terminal
python3 restore_reviewed_source.py /absolute/path/to/new-reference

On Windows, use an absolute path under an existing directory you control:

PowerShell
py -3 restore_reviewed_source.py "C:\absolute\path\to\new-reference"

Expected result: 22 verified files in the new directory's reference/ subfolder and printed archive SHA-256 084799240a574810c1902c83a4cac3f6e3b1baa52ef56e173e6a3bb6ff386180. Keep the script and its output local. Review the dependency list, lockfile, SQL, code and .env.example before any further action. If the hash check fails, recopy the entire block from the article. Never edit the base64 to make it pass.

3. Set up the development project, build and test the boundaries

Record the approved development Supabase project reference, region, budget, schema, grants, RLS state and migration history. Inspect whether reading_items or set_reading_status already exists. If the SQL conflicts with existing objects or a migration, stop for an owner-reviewed migration plan. Apply the reviewed database/001_reading_items.sql once through your controlled migration route to the confirmed development project, then read back the actual table, constraints, grants, policies and function. The file creates owner-indexed rows, authenticated grants, owner policies and an invoker status function. A successful SQL submission without those readbacks is incomplete.

Configure email sign-in and the exact local redirect origin in Supabase Auth. Enroll two permitted test users under the project's actual policy. The browser requests an email link with shouldCreateUser: false; confirm the setting and actual behavior in your project. An API response to that request does not show that mail arrived or that the callback authenticated the right account. Put the confirmed development URL and publishable key into a local .env based on .env.example; .env is Git-ignored. The VITE_ values are built into the browser and therefore public. This route uses no service-role key. Keep secrets and personal records out of source, browser variables and public evidence.

From the reconstructed reference/ folder, in an owned Node 24 environment, run:

Terminal
node --version
npm ci
npm run build
npm run typecheck
npm test

The reviewed packet used Node 24.19.0 and npm 11.17.0 on Windows. npm ci, build, typecheck and five pure tests passed with fake syntax-only public configuration; this did not connect to Supabase. The tests cover two request contract cases, two status-response cases using synthetic complete RPC rows, and sign-out success/error/rejection handling. An earlier fake-configuration HTTP smoke saw /health and static / return 200 and an anonymous /v1/items return 401; it was not rerun after the focused repairs. None of those checks proves an authenticated read, RLS enforcement, a real sign-out or a working production app. If your local build fails, save the exact error, Node/npm versions and lockfile hash before changing a dependency or code path.

If you need more detail on one boundary, the earlier guides to adding sign-in and protected data to a React app and setting up a managed database address those narrower tasks. This reference uses a Vite TypeScript browser and combines both with an API contract.

Start the API and Vite development server from reference/ in separate terminals:

Terminal
npm run dev:api
Terminal
npm run dev:web

Open the localhost URL Vite reports. Its proxy sends /v1 requests to Express; the built Express service later serves both API and browser from one origin. Sign in with the first approved identity and record the actual redirect, user, create response, list, reload persistence, status change/version increment and delete. Confirm a successful sign-out clears the session, then cause or observe a failed sign-out and confirm the UI does not say “Signed out” while the session is uncertain.

Use the second approved identity and direct API requests to check the denial boundary: anonymous list GET must return 401; the second user's list must exclude the first user's item, and PATCH or DELETE with the first user's item ID must neither reveal nor alter it. Submit an invalid URL, extra user_id, invalid status and stale version. Send two status changes with the same version through the Express API and confirm one increment and one conflict in the actual database. Confirm a successful PATCH response omits user_id. Test with 101 synthetic items if complete history matters: this UI returns only the newest 100, so pagination is a required change for a longer queue. Fill the supplied acceptance-record.md with observations and evidence; its original blank cells are not results.

4. Prepare production before Render's first deploy

Treat production as a separate approved Supabase project. Inspect its migration history and apply/read back the reviewed production schema only with the owner's authority. Confirm enrollment, email sender, exact public redirect origin, backup capability and recovery procedure under the actual plan. Keep development and production project references apart. Do not use a reset command or substitute development data to clear a failed check.

Freeze the reviewed Git commit SHA and branch. Before choosing Create Web Service in Render, set the root to reference/ if your repository nests it, choose Node 24, build npm ci && npm run build, start npm start, and set health path /health. Confirm region, plan, audience, access, production SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, VITE_SUPABASE_URL, VITE_SUPABASE_PUBLISHABLE_KEY and PORT if needed. Check every value against the approved production project. Render starts the first build/deploy when the service is created; turning later auto-deploys off does not postpone that initial action. Render's deployment guide documents deploy history and deploying a specific commit. A changed VITE_ value needs a new browser build.

The separate guide to deploying an existing web app on Render covers a broader existing-app inventory. Here the release settings apply to the exact reading-queue source below.

Save the actual deploy ID, live commit, effective build/start/health settings, project reference and URL. Check HTTPS, email delivery/callback, permitted CRUD, anonymous and cross-user denial, stale-version conflict, persistence after reload and relevant logs. /health only shows that Express answered; it does not query Auth or the database. Hold acceptance until the real identity and data checks pass. Record the current plan, email, compute, database and backup costs from the accounts you use; the sample has no observed charge.

If a release fails, identify the exact build, health, Auth, RLS or data step and keep its logs and readbacks. A code rollback to a specific commit requires comparing that code with the current service variables, environment groups, Supabase schema and Auth settings before deploying it. Code rollback does not undo a migration or restore deleted data. A database restore is a separate, plan-dependent operation requiring its own authority and verification. Repeat permitted and denied user journeys after any approved recovery.

Complete reviewed source

The following is the full public source delivery. Python 3.10 or later and its standard library are required only to reconstruct the files. Copy the block byte for byte; use a new directory controlled by you. The embedded archive SHA-256 and all 22 file hashes are checked before writing. Source reconstruction does not mean the application has been installed or tested in your account.

Python
#!/usr/bin/env python3
"""Reconstruct the reviewed 22-file TypeScript reference into one NEW local folder.

Python 3.10+ standard library only. This does not install dependencies, execute
application code or SQL, contact a service, or publish or deploy anything.
"""
import base64
import hashlib
import io
from pathlib import Path, PurePosixPath
import stat
import sys
import zipfile

ARCHIVE_SHA256 = "084799240a574810c1902c83a4cac3f6e3b1baa52ef56e173e6a3bb6ff386180"
ARCHIVE_B64 = (
    'UEsDBBQAAAAIAAAAV13hZMEzXwAAANwAAAAWAAAAcmVmZXJlbmNlLy5lbnYuZXhhbXBsZQsODXB0'
    'cgx2jQ8N8rHNKCkpKLbS14/0Dw2KDwjy93J1DtErLi1ITEosTtVLzucKhqkOCHXy8Qz2cHTycY33'
    'do20RdaBLskV5hniGh9MkkWoWkiyLcA/KMTW2MDAgAsAUEsDBBQAAAAIAAAAV10N9klSKQAAAC4A'
    'AAAUAAAAcmVmZXJlbmNlLy5naXRpZ25vcmXLy09Jjc/NTynNSS3W50rJLC7R59JLzSsDE3paXIpg'
    'OrUiMbcgJ5ULAFBLAwQUAAAACAAAAFddfXFiSWQFAAAKCwAAHgAAAHJlZmVyZW5jZS9hY2NlcHRh'
    'bmNlLXJlY29yZC5tZJVWy24jNxC86ysayCGAIS3lhRMg8UmxnawBw+tY8tmmZloSLQ45S3KkVeBD'
    'PiJfmC9JNTmSvbASIBdDniH7UV1VPd/RpEqdtqPAuuZAuqq4TdpVTIErH2r6+8+/aG61W1PnkrFy'
    'wuMXJY4pUujcYHDPCw4sdyrfNCap6acJaVfTra9ZubZRra7Weskj66s1rXRc/UyPj4+Dz1vHYaTb'
    'NvgN14Qf1Hah9ZHz9dos+sCRFsE3JEUatxx96biTAvu3Jdglb9j6tmEUN+1aPdcIg8jPXKXXs8rp'
    'hlXgpfEuJ2nMMuiE/0YrE5MPO6pWXK1LzAIOTX+/keKsqfLJISU9t6wqb7vGRYUALkV1fzNVrcch'
    'w1EtOlfJ2VzzXEvAk5NbnwSxkxNSOfxd8HVXjv2PiiO3GiWz3ZHu0soH8we/6UP9V8YJLhC74K3N'
    'QOV6d2ho66nlgOElxJLZUhc5xJyQv2oUVPNGobgaldUmSInIvDQuFqju2QmB5sCiWqnDTEEFNe+M'
    'rVVMOiS1Ym3Tqm9HtSCWYrc5oISS57zwgekCjxKfnBzr4lcTohTUWr+j60tlzYZpT7q2m6Mneri/'
    'OXZ18EIXAvMLXX1t0QRK9HN0upGJoozY2YSX/eB5Y+pMbAm84VAbtP2CGKPRiL75i2c3vsKVyrJ2'
    '9ATWU2WehpSb7wsLohCXgsBZ9CNlyH+tcU6AD1xyOU+zaQ9cnsZCGyv392lEUZwKV8k7uzunXsKB'
    '0e+3rUt1D66MHVm4QTCKZulGRggKOUVp+tYLoXwDGlXkeJspcC61sOsaLvQC7Emuv7zLcLWPL9e+'
    'B3V6DHM2a9xaoXCbp4wh+JA5JGdV5BgzuxMdiHNg2ftE0w4uFeOisxkrgQYXcj++S7Q14DjAQIsl'
    'rsDc38njAa0TxE6HtAjycC0Api7IGDgEH8DR50IQKRt4YP4U9S7SFJmEN10aHmIgHKTQM0oCin3i'
    'xk7eFCvFi/e9TJx3u8Z3kZ5+u5qR2pwqk7iJTzh7Nj4dCvrygGqd9JH7D8CPJlRltUTaaGvqfGEI'
    'yMGwIZJbr2vB4OP4NJcmdKEJJgTFRxwStP32SPBb3oIZo9PxOAejOZy/1ugpQ3yKcHHn0oqFL4iA'
    'ZGaxN0qR0wt9llRy3+VQsPQIze+4Pidvha1iuVwqBs7OIf+caSGJAGiZk8xmheMwHDJNa7lYl4b5'
    'FEoiK8hgae/gGfIvnQlHIb92BSU4xBDeBjnSk9Dw0dTQq+nfwq5SF/MUxntJbgPq/Lch/FIAP6ee'
    'txN6eLi+pLvJ7OKTury6uZpdFY1NyizRTNOl3MA5LRmbECiejX9SZ+OzIzlmcOiITTDayNDQdF9g'
    'L9+YwWbavzUOlMg4vfHEXIuYXAtRcJ6iCObQPYaCaYa31RyjLCzAsrDNb53M/Ry9p4Ctlwssbcux'
    'j+OzIV6hn2wiQZzAYX/j1XG+9a77aTa7m8oi3C/HZy+63L2xjd77ZbvsF2a2AmEB1Oq3XCs4twEB'
    '5rzSGwO03+e78UsFzbpavaq1iFiyAlD5PoHE0RnqT37NjuAf65xr7cD4fjeK8YmxqTxZa7BH47t8'
    'g5koIEvnVTZZ7MPeXbJpiSi9w4/iGuIrpPcTxDM2bfoACOOrC9qyeXzTwgmFWEvsESyhfts+iSBE'
    'WRqX5jGZ1CXRWIC8eG/T/XfdkPAZg60lcpbvQSHP6yD6VSm/4we6htgdvpdknyKDxksnXwXZkdFU'
    'C6bhOH+7RrOSYUqMax8Gg7vSWMSIcQDMMnkOWZw6VKt+tY8+/vDj4cumfJXUBmKXhbowoSlGwPlu'
    'QD7YDeggcEhlGSkDS9rvxQxnXHF9+DD4B1BLAwQUAAAACAAAAFdd2KMtIDUBAABiAgAAHwAAAHJl'
    'ZmVyZW5jZS9hcHBzL2FwaS9wYWNrYWdlLmpzb251UdFOwzAMfN9XRH1e03VjAyEh8QAfkiXeyFiT'
    'KHbLYNq/4yR0KxJIlVqfz+fz9TwTonKqg+pRVM/73hpoVLDVPOEDRLTepVYrF3JR0BDtoCgNUOwh'
    'Q/QZskDnTX+EQkMdbSBk+MwlA9veHk1iEWpRB8Ev73Z2Lw/IO+aFlJT0G+j3/4iirp1/7SyNEwaG'
    'xHXeAPfADfXOHuFJyiY9XDNqu+AjsdCJiw9F+k1g1A1C5BMlmxy3A1JZnIipKjxS1GMdAYN3CDI1'
    'JlPcjnT1YCzSqHzAiimXnIeBAM6A0xYmofxEzgdSVDrHNck6EbAPaqsQmvGjPmTWUrbtw40Hp8D+'
    'cmctVzf8y+fM7+RG3k/NDC9/+0k/AJtfagu5ubop7XRo9rBh2fU1PTyVVcuVbNd52ewy+wZQSwME'
    'FAAAAAgAAABXXeea/4cSBgAAqBIAACAAAAByZWZlcmVuY2UvYXBwcy9hcGkvc3JjL3NlcnZlci50'
    'c81YbU8bORD+zq8YpKq7q9s4cC39sIjrAaVXdKhFUE469drg7DqJrxvvYntDgOa/3/hlN5sXuOur'
    'TiCU2ON5eeaZsQc+LgupgU1LyZSK4Q70TcngjF1VTOm4/qbKQijmv75mU/2yEqnmhYAZDGQxhsBr'
    'CHY3uFN5B6lkVLPDnDOhG7lfVVXSPlWsW3/o/L1w6tCeOtZsHMPhiIohO9dUV+ibWzN/T7hqaRxW'
    'PGPdtBBa0lQvKLttpG6LrL2Bvhb5hDXboshYUlI9agspa/isTGsAGnHSdXsd6XeIDWIDnUDPmJjA'
    'HtwSpSVP9Zv+3yzV4d0GwPnF6f7B/vlR7+LsJEGBSuZhFLc3Ti8OTo7PX+0fnBz1fj/6M/FaxDCM'
    'yJiLcNuKn745e2u20oLJlBFRjftMogQXupEjYzoNn+3sPNmJSMYGtMp1+GRrawsVzCJSUqnYGp9K'
    'WaSYRoIhkPbOw06uPbUkNfe7LW1WjEMNdrQsETvPphDXcYFkXNF+zsJg2imLayZZ1unfBH6zwkCC'
    '7mQ7iCHsSXYVm+TGIJClEez94pJNFNNhcEjTEescGqYUOcpj2jtKF5KhLnsADcJsVa93B5NciPAO'
    'cj7mOoFg+9nHfoDy/sDQmOiOGM2RRm1nWm54DcXHBLSsmDFmDW5QdSNSGNRlldI8x5SihmRejKgg'
    'aYoxApM9B9qY6nSEsHU/HDAqmYTw3Ye/1PufokddwqYsNXoIOpahyoBWelRIfkuNoSCC588hMFgC'
    '8AGEm1ZXVKNmWR4+3UI+edeZlIXE4M/5UAAXKHZVccxIYGORTFdSgKjyHANrHNTFRybQQav83fb7'
    'TWOu24V9RP3aB9tRaVGyDFLXMBAENmHyxhrA8E2C8DtgWoCCYnLCU9bBPDL4yG5ghKwgjb2sj8ba'
    '/SdcITQ8SFYLLoDBKkEsSiYV9pxzJAGClsCA5qYd4nZxxgaI1OitibDZyJjGmvfix+JC5n4LZrFV'
    'PMyLPs2NapcWZT7utzOTwKVP5qM7C9/sEtuPPT6z2XKR3kFGNY1dWlBgD+g15QYBYpw3pLxAsEKr'
    'osmyk/70CTbNaUN1+e1S7hfQs35s0iWPswQaO4RnMNvdmG20amay3eXY1hVWjauDcLF0mmhTPW0i'
    'nJeIk9x1/EWRyLswRwn3sf/Nj+opQYBMLw8DZEmGDbbnPIhserBd5KZpBzyLNdc5i7FVxw6aeGLI'
    'UIjY8SvrUR1XZeY/1goKaYttLhOYy5WqlAljraFDRGw3CbexM9fZcd4SC/tSWna2nqykxdyICipB'
    'J5Tnpk+289KuQtv0M0ShvkOJogN2aq8Cb9Okad4L3AGiqtQ07G/jStMFvXJv0TVBZERZqB9CCS7K'
    'yjBi/t5YQOOK9IvsZg6FFb8HiaeYuxUkxITmSHUTxH35+GxWcuz7Ep8SQAhxDrniN3XV41hlRoWr'
    'ODT51UwmCj3Aa/driAmi0KDoZLFb3MvK78LIh3xoHf+5aXn3UdPcXi1udhOe+Yfg96NpZp+SFb5x'
    '8Wm3yFB0k44VNtRoDa1bT+eHid2gae+DL+V5au19HtNlmYYBPsx6NdkbLN3tW1pO88yzvOzhOwy5'
    'jOz0xE1gXgWk3vzDkxrlnb4FKc/85hb9Alo7aP9Lw62nAwx8ZZZY4XfLajNVuO/eg2bVJ7DhZYYl'
    'rtkSMf8HjFzi14/vmjUyvhWyK9MGERhPqciu+OaJy/PuGbXaZvClPHlhjT/MEwtRiwnPSc7EUK8+'
    'wJ+u72z/etU2vQ0V4NMjbPNm7eTUnpnuN/4aO+qgqITvqO2ZqR6WzGluRg87aYduqiZjhkWYcSno'
    'GN/JASFd/L1m/S7OeHjlRC1Fq8R1SbgySkZFBpt7exD8dvQ2gMePYXn91dH+i2AdjA6FVaBw/SXP'
    '2Wc53OUiY1My0uM8iDy0jfuIVQJHBrAYeg9Mcm5WTRb+r7IUsvLTmzrHWcYEZYdVNLCmQnAichQN'
    'A28P35oYmGE4rhMTyHLD2VlTi0uHbY4b6uQYPBNhM8JDsEXsT1CPIi3/fcHokSyu3e5uy9e8GIaX'
    'J1Yflq6Z+x7d1Xpnl97oP1BLAwQUAAAACAAAAFdd7y8GeAoCAAByBAAALgAAAHJlZmVyZW5jZS9h'
    'cHBzL2FwaS9zcmMvc3RhdHVzLXJlc3BvbnNlLnRlc3QudHOdUttq20AQffdXzNtaYF0sS3as4EIJ'
    'gb41mDw1mLDSjojS1aW7qzTG+N87K6mWjdtQCoK9zDmjs+dMUTa1MsC1RlpyVZfAqlpg0t/42qgi'
    'M+x2UvRAg/oCZs9j9QDacNPqbZNtUTd1pRGOA9zz+5qrhor3qok5yWhPLVspLav+CRs4TAAKkQAT'
    'kYhSXK3ccBnFbjTH3E0xj13MhFjEGOc36xWbEbolsc8dZbnmGKw4d+MsitxIrFOipJEbr5AvqIA3'
    'c9FRTGEkEuH+nZeNRDaDVkk6vxjT6MT3sb/3srr0qdiLp7pCTg3gDZUu6iqB0DbL6NageOaGEGEQ'
    'Lt154IaLxyBIuu+bbd+Iv2LmPWZyJEOspVP28Pnx7gv89goabl6AZxk2RgMHEkXaDML24Q4UmcYr'
    'AVgWVKwruYemTWWRQV6gFJr+PXVg86nztbf71Hdzndj0aQxj59wSp58FD3+0XE5P8fXEGYRB8AEq'
    'rcXeG8wi7DlSIDb3Hfpr+oqZ8b7jXl8yHU/TXE0d6zHAExt9pkexwgbBeh1210VqN6PV3UlJuwwi'
    '2G7oeS2aDWPEoKjgQscMci41EuXofBiRQvsSDSWXea1KFN1k24h0l1FDcFRvqG0QOWU0ZnER04Wu'
    'P0R0AM/zxpzO5pGlNJ9w3DmngOJgcf3Wf+mJ70bxBIxq8b8anlGiYD2Y9wtQSwMEFAAAAAgAAABX'
    'Xbdb4u20AQAAXQMAACkAAAByZWZlcmVuY2UvYXBwcy9hcGkvc3JjL3N0YXR1cy1yZXNwb25zZS50'
    'c31STYvbMBC9+1dMTrEhOO7XoQ6GhaULPZSG7N5KCYo8jsU6khlJ2U1S//eO5STNB/Qmad689+Zp'
    '1KY15OAA3x1uJuB2LYYjCAtzv2qUDLcOKjIbGD+svSpxKo12JKSz41mkTgz7M2pvSi5E0ym81AiL'
    '+SMQOk/awvO3l59PfBOl0uulYmo7AaVl4/sHcAxvSW2FQzBvGsnWqgVpGr/RacSq1sGilQvzBkWw'
    'meK7Q13GB/AWaanKHPapZ49xAl0yu2qx3LNPBZHYxcMLAyJ8D/bD4M9OOG8XaFtuQygigD88mA3P'
    'OXzMshmsTLnLr6K5QX3Ovp5QB0AiQznXqB+vuwN/yT79B/zPXuW1dMroY2Nv/+gy3orGYw5ev2qO'
    'LMlvpziw5BADDRkc00itqHAu6ETBYQCoCuIRhaqXEq1Njl937Xly63n8WAu9RnYhtkI1YtXgeJhg'
    '4AyUpXAibVCvXQ2jooAPSTAH9xKc4b3ED2UtBzO5FAFDIIN0Cf02zZirIrT1Wb07j3+xI8uwXBNI'
    '07QNP/mksCkt9xRwtvor+z3qGe7c8R6c3IUdbEOIl0RJr91FfwFQSwMEFAAAAAgAAABXXY/gRPnF'
    'AAAAOQEAACAAAAByZWZlcmVuY2UvYXBwcy9hcGkvdHNjb25maWcuanNvblWOTUsDMRCG7/0VS46L'
    'WNmjN1EPglTx4yQe1smLDU0zYWYCW0r/u0lXLT3O+/HMu190nSPe5hAhT9kCJ3XX3b7K1bBRvmH1'
    'dvevw9UwuIvObdmXiKat2GOFyU7qC5RjaZBzf6apSaBGMymoncTvidagDfxD8pjgb4igekpgGsnm'
    'VWN8Fs4Q273tMv4zM1mY7S5Ie6pCbQ+XP8EHPS7UTciP4eu2PTxv2y/woy7ycJ9VPTTLhUSxeByt'
    'yl32/bK/NK2Jw+IHUEsDBBQAAAAIAAAAV11SWXrJtwAAAAMBAAAdAAAAcmVmZXJlbmNlL2FwcHMv'
    'd2ViL2luZGV4Lmh0bWwtT0GOwjAMvPMK4zMluzcOSY48YLX7AJNY1FKahMYF8XvSdi+2ZzSe0dhj'
    'LEHflWHUKfmDXRckyneHnNHbkSl6O7EShJHmxurw7/c6XPCfzTSxw6fwq5ZZEULJyrmrXhJ1dJGf'
    'EnjYwAkkiwqloQVK7L7PX91FRRP7n54j+Q6PhRe2Ziet2eIP9lbiu+eRZJDokGrtj2bF3rYwS1VY'
    'SzicSlwSI7Q5ODR9bqKztlW/K/ux25m98gdQSwMEFAAAAAgAAABXXZDuw4L5AAAAuQEAAB8AAABy'
    'ZWZlcmVuY2UvYXBwcy93ZWIvcGFja2FnZS5qc29uhZDBbsMgDIbvfQqLQ08NadKtqnbaYXsQAl5L'
    '1wDCkHWq8u4zpJsm7bAT8PHxY/u2AhBOjSieQDwfszXYfuAgNoVPGMl6V646uZXbhYZoJ5XKgxQz'
    'VpQ+Qw0YvckXXDTS0YZEjG8ghmwvphiJNDQBePHuzR7lmbyDpnH+dbQJ1muYbEJY9M0SrE+o3/99'
    'W22ktIhX5uUEFHWrcjo1SiduhWShksti3eBU7PKjgLkWbTCgM+i0xXvl95nwlylyBv0aBl9SDmpQ'
    'hO33pjlXo5ddd2DnJ3Z6+ZtcmqPWeVNn1+/lXj7WNuhawIPsd7KrpJbI6CB3rMC8mldfUEsDBBQA'
    'AAAIAAAAV12cu9iM3wAAANcBAAArAAAAcmVmZXJlbmNlL2FwcHMvd2ViL3NyYy9hdXRoLWFjdGlv'
    'bnMudGVzdC50c6WPMW7DMAxFd5+Cm2QgTvYY7da5Q04gyFQtRBZbkoIRGL57ZThA0o7tIFAi33+g'
    '4vRJrOBEsJbANIHJNOB575xEOXo1fRN3UFF+YNv7MV3Aj+ivOFziR34vCuudPZ5c0bFzXiNlqYFm'
    'C1ojleuoglK8RxGIAoybCwegnG4QiMGBpxwiT7WJzMRdYMQKSklqDnX7W/ZgW3h5haWB+2+O+FVc'
    'sm52UX/tZZ8TdtmlZ8glJVjb9gDKBdv+Pyqc4W27WhNcTDiYdjcHl+Qv6gV0ZJqfxRl1Jr6atq/q'
    'h3mt5xtQSwMEFAAAAAgAAABXXQGiWa+WAAAA2wAAACYAAAByZWZlcmVuY2UvYXBwcy93ZWIvc3Jj'
    'L2F1dGgtYWN0aW9ucy50cz2NUQrCMBBE/3uK+WxBPEA1vYKCJ4hxa4NxI5sNtZTeXY3VrxmYxzx6'
    'PqIobJrYoc/s1EeGG8jd6HLyVz5krSsgfWuLuoHpcJR494n2M0gkSovMN44jY+k2VdP+93OMgSx3'
    'mN8fKlNJwEVOCqGUg8LAjtbrT1E3u8IIaRZeoW3RwBhwDuEDLHBW3bAernBvQ6KyVkv1AlBLAwQU'
    'AAAACAAAAFdd8cf1JTAIAAArFgAAHgAAAHJlZmVyZW5jZS9hcHBzL3dlYi9zcmMvbWFpbi50c7VY'
    '23LjyA1911fAzlaRrMiUZ2pfotvE9mgzznoyrpG8qa1Uym6RLalXFMllN+XRelWVj8gX5ksCoJsU'
    'ZXsUO5v4weIFDaAPgAM01SrPCgMPEBVSGHmRKJka2MKsyFbg/VGXuZgKLTvVxclP2uu1VLXqgldd'
    'Grlqw+7/ldKmDWaTS74Fofl3Qg9q1fNSxbITZakpRGT2tEYLGS1lPFbz9FO58ybsiNIsTlBaZSkt'
    'aOFqbaAsEhiAXR2upBGhTNfhD5eT0e345vrs/Gw8ur35fNVz4ku5+Y/i1zfnV5fjD2fnV6Pb70c/'
    'om8z8I/I0K+/whFqCMAsiuweUnkPo6LICt/7qLRW6RzycpqoCMYOMUCrMzUvC0Fue0HlBu0F/Wji'
    '7qOBNvlXCxVZZlAozqJyhQLhz6UsNmOZyMhkRf/D5OPVKJH0Zuh7vxN5TurZVVp4wEcUZd0kT7+h'
    'SlNZkD60dtcC6C/eDK8LtUbfAD2MaREaL2W/g2/6Oah4cLySWou5PEZViRwcayNMqY+H/U4+JBVa'
    'cqRYVGMsZXySlQbfL94OKbagUtT2dtifZcWKpZJsrlIUSMRUJsPRSqgE+irNMQnotaQHx5xY9U0h'
    'fy5VIWO0alf1p6UxWTocyzQGMnuiUkhUuux33Jt+hwzij3Pwa86iK7BQcSzTSmnlJG+Dt4BXtV5U'
    'g4rqzSDsJwrTvt7PRJlENvdj6MExrMSXRKZzsxgcv3l7+syWrGJ7/WEyufbHAWBCN1Vh5lTA8OXX'
    'YRFr+RgJqx8j8WNWFkA+axuYMmHl/ITiWiYN1O6qJHVp8OI8dfJecFRpSJAwDi+/IU5p6GCXGhps'
    'yC7TFztRx/iJEqKcV2rBLGA1ibR1PcqziIr7tNealalNLC02/lokpeyCNgXWU4BM56AIjfxiLpAK'
    'iXwHwGI92LZaQm/SCGodFFWpjZ8Ls6jUtFGJWWQxrvP+NJp4bZhm8eZdF8p0mWb3adCFa6RPpWXf'
    'PRnCA0a804HJQsIUGULLAjR6wm6WeY5kpEGAyZYy7SGJSDi7vkTjJ2tZqBm9VLhPLK/PV2OQKeZQ'
    'hM+IalC7LPRC5SFasKA+QCyMaIMkBkIuH4C4F8riFPK/uTRja91HOgIgArPSRLa0OnTePcNojkjq'
    'hPdYhWNPqXO8kLXNmTTRgtFrMwbgsGvz9QJ5Dr3vostn6FdWqF+Ys7twdy5FgSB989D0JhQR7lvf'
    'Mk7buzaEYegT+PAOVXgunifU9rwueIKAjVhj5yeNrQDBQFvbALbW/t5yuujCn8ef/hLaOKvZht8G'
    '1TJatK0Bq/YaWhaGwWAAb0+/DRAEUxYppGWS7JDJxSbJRFwnSY1QrYY83IXjqH6eLZ8G4Tnb357+'
    'Affhcf+PFiKdy7iH2mcou/BwA3efbS7DDGlcxuB/8/BIzTa4Y/tuA87lXgvLoi6IWOk8wcJiOujW'
    'U8bf/h5wfIlXwkKiSCQvFiqJC+k2hTkLvsWC1kI2s7wXuLyo2u99kwpsr3bl73uJsslWSVOTOSAu'
    'KmmSCxeIBY0haDRExu7Zp/s8wC+5SbjXhaRJx0uzLJdYaJBmqAVLRRZepUAUWE4kdDtNRLr0mg4S'
    'rvKAhzoXNKBYuUe+3MG//vFPLAD2yQUI/LV7gMRAFYG5fNc0aLL5PDlk0fYhsmlFnwOgkVQejSIe'
    '5dVHUSwxee19193znbXv1Ik4Hq1RF3UPQsz3IqzBJZKkZVY/gMHQhRwXFZv6+lGlNArEUvBdZ/2m'
    'wynTcRioeNuxviIVeNdnk4sPXruhD8C+7R7YVmNHfIG0+SXHziPjHyzCbrHDu10r37rcoj8u2Eu2'
    'IWbyWhRa+m4bQahLJq1nmPQmrWzVLOA1tNrtkxK/froF5DPsdJauqaFRl7PcrRA9kUYSK4sN4Pb4'
    'RViNC7jHCyYGRwGUBdtWczMVi6+y9cuSyIo+SiLvPTZvI11iOJHXJQYjeq/SOLsPeZwvVr5Tizgq'
    'zUF55wUV2/aaCfWSxKGMeT+6Gk1GtI09qB0m8Buhdt5+DWrMhRAbFM7MPvFI23JA29VR28EW9Cyl'
    'OklcxMu3raejivWeEbRhlG4mquejJ93oSY15NVTNrp5TQpNwddR8Js3rvmWFX5b13Ahof95uDLFO'
    'DxpuB3XTcbppJAi4LR2YGb/DObsxN/JBB0fGZ/JQl9OVMnUiyjVnsc1Fvgnzgn/fy5koE+M3oOEz'
    '0eHh9ZKODA1PeAl5YofOxtj29YGNpt7L9K/KLD6Z3LdFwnrakOV8OKcZSi+yMontF4IbHDG7mHyJ'
    'xlxi0c8yxnEtMpOsC66yksxORyFOXgiPHYtsgu5yHUly3DjUYQ8Qa1QnptQk+cMBTqR4Hk1ogzyk'
    'WlC0NAanKM3cejkDmaCNKaW2XbSho48VpdlA7B0dKSHIkQO4njMJ7YfYHgtewTUWescwclcQ+x9E'
    'fLtgPx70PKix2qlweOEVeUObZ/jwBu1gfHCGMDCVO6M9C0V1HliJDXKBShISok8va/kCNB6le3UU'
    '/t9nvD0BDxofohpsYDOTB6jua2qCV9Q1YZsszmiv0oHyexp2k/oR+7yjJMvk3gj7FeUdG+fEbRz1'
    'bXPj1sLEvZtUXsygNJN8GtP50Np3tPX/GRj+u9RALZKi+6gBMjz03cId7n7r1EGq9hohxaa1K6cs'
    'pePfmBqgHVB8/5bzrw31OdSl5+6w//sBvOHqcx8iQvvlCCNy5Bb1dt8XGi/rtwePKxSh2jaCNFEr'
    'mdVM8ADrTMUOr5DBcW8YOoqsfo4o975MAoKl3WFazAW1JwKnDaeu3P8NUEsDBBQAAAAIAAAAV10B'
    'iNnh0QAAAEEBAAAgAAAAcmVmZXJlbmNlL2FwcHMvd2ViL3RzY29uZmlnLmpzb25Fj8FOwzAMhu99'
    'isrHalpRj9zY4DAJKAJ2Qj10jjespUmUOKjTtHcnWaf16O///ck+F2UJaAfHmnzrhK0J8FieE06B'
    '9P5AkmZ4+WoemgYWJQxWRU0Te6dRZvZJweqYFTldRaOSExaTKohnzCrxkdKKsVuDv4RHUhujaCT1'
    'hEghzA0ae5TppF5/eOvIy+n75OjeuZmP7F55t86yeVtuxR/4Y6EaNZMR6FKieXfl80vP7Rt0SXbJ'
    'RmCDOiq6doLHuqrqaikhF7Nqidbs+ZBJV1yKf1BLAwQUAAAACAAAAFddzhwQ12wBAACIAgAAIQAA'
    'AHJlZmVyZW5jZS9hcHBzL3dlYi92aXRlLmNvbmZpZy50c32SXWvCMBSG7/srzq7SQtc6dldxoK4w'
    'N0HxY+CV1PbUZsRE0rQ6tP99p9UJDl0gkI83z/vmJHyzVdrAARJMucS+kilfuyBUlISyhApSrTbA'
    'Sm6QtS3+q065wPlkOFPjyGQXlVQJBoUWpLRiJXMDKMtXrqFzfcCWuAOa2czzfM9jLpzA3gZN5BHA'
    'cdoW7hsvyhUVwlzls+0DbMgLKgc6L3CwAC525HUOb9cS9xzBBfY5mIVLRmQAnoL9QBteszadj7u9'
    '7jRcUiQ4HuHGznjeGw6mb93eMFx+hAtSEaVuNyEel7EoEsxtthjNJ8vxZPQe9mfM+e/cH4u7DKe5'
    'L4DJtNpBXclQa6VtNkUDGiMBW62+MDaP+RZjnvIYGiMoI1FgDitMlUZYFVwkXK5PBamoazSFlmf6'
    'uWrNOEddog7o2Ym8/64HzC+fWAAsM2Yb+L5QcSQylZvgudVq0XsyP6MkJruvoU9T1fiqbVUU4QdQ'
    'SwMEFAAAAAgAAABXXaV1hG60AgAAFQgAACgAAAByZWZlcmVuY2UvZGF0YWJhc2UvMDAxX3JlYWRp'
    'bmdfaXRlbXMuc3FsrVXbbtswDH3PV/AhQOzOTZtiD8OCbNgv7ANmqDJja7UlT6Jz2cO+fZRkO21u'
    'K4LlITYi8vDokDy5v4dvbVvvwWiJQAaoQjBbjfZeGr1WtsECCtxgbdoGNUFrzU+UNIfvuFG4Bdwp'
    'R0qX0KjSClJGO+A0R/OJtCiIQcVzjdB2z7WSc/6p4OhcETYOkgmAKqDr+Ku1qhF2Dy+454Jr0dUE'
    'JercCl2YJvcxSZpxQufQ5kOWNgS6q2uwuEaLfAkHoqNq7qNcooqUb8Z4NTITKZwUBXoQUsSkCHd0'
    'gJAVyhdIatQlVQkxnySEpSk8I20RNSyA2cDi6TEysfVVCD4/pH4KqU+PH+OLz/1zB7MfFVHrvn5+'
    'eJgFTEeCOncEO+gx67QXcDbU6YOVhmQ4ymbhkQawDWvAHeEAwhLtKeBiQBoiv0C8WuxdkQtiqRrk'
    'Qk1Lv08BtNn2XWmL9ydM0uUwHUoXuIM3Y5GH+ct7Cr5/54Yn6ecge821QCcZW9TEt70yeKjDmTVb'
    'qP1wg0PZWUX75cTixrwgCOZ8oTKsrWm4iUZnYdZ4LZT0DJYTXgHeEcfjJinjuzFFfkZtsmEML8Hy'
    '9h3B9Rq1hoP3o0gR/jI7Y3sGJ4hhe/yyDuLBiocoxsat8UuWppcqxwtdrdyHnKm8VVQN43Zb+ajj'
    '1fJ9yK0X/w8k/9FkT7IPub07Q+l1p6W33KGUQ8rHKQnekLSDVWbQ5rhrGYxX5cgY/Nkr40l5Caiz'
    '7OQMaNZnLzKphS47USK4X4f1YUC/PX4A/RoIK6u8FSzpCmYzEA6m09ErzsOC/4TsyGc1UstGO1uN'
    'bx9gkb22nlXvL4yxrfj/AIKIQYNgutd0jaV92KHOGcl8wKjWOedlnCifb+XdcjKdHpvKO9oWOza2'
    'J3Ql+k7MGawGd6x8HLdbUU9t5y9QSwMEFAAAAAgAAABXXVRfXfXKSgAAc2YBABsAAAByZWZlcmVu'
    'Y2UvcGFja2FnZS1sb2NrLmpzb27svVd341yyHnzvXzFrLg+tRk5ePl4HBEkkgkgMIL/l+RYyQCJn'
    'wPb8dpOUWk2pFSi1pOl+fa4IYG/UJqqeXTtV+F//5W9/+3tixu7f/9vf/u7VUVRWpn24qfrMLe0i'
    'zKqbwjWdMPFv8tqt3eOd5xZuYrt//6+nN6PUPnhh5K7dogzT5EgEOT8v3LwOC7c8PqiK2j0/y46E'
    'Tf/87H8d749P7q9+5T+c327T4lAeGzhT///unl60Cfzbfd3jUzPLTk/uHvzPeyqO20zczE2cI/Hw'
    '4o+eC3/8ndPfJL6B3+DvFP7PPQU38cPk8ZtJ6pw/7X/8O4z+7b/D2P1r/+Xi5ds/ZWbhU0z5D78O'
    'Hfdcet9Uc8/yv0PHPwP+/eIznvuGOzp2mlSFaVflzy+fKpV1Zlpm6QLfL27255rwNwgiH9Z1u+wo'
    '5XMp9g15WDakzuk5+g3/RvzMqRd5/R9nZgMPqIPf8Af/8rbKd97C+LEZ7LJCVXa3zcPIN+glnreu'
    '9QLPT6W/Ac/fxb+rmXNR0oTV+R3yKM5nuHYi+//HqVNHxzb+wy2tOowcwAy7myyzcfSSmRcMO/YX'
    '8thl7j/gKNk0atwzRoKqysr/BgCF64dlVfTfkizel9/Swn+CPnDz4/rmluq3yh9+UA6TyvWLsOpP'
    'pMvAxCD4xph2tjxymrnYrKvFMrT05djdQwuGtkw22CTUpoV2SkeCeWkGgTJzAXLvbxSQt4OFC84Q'
    'rj2siIR09wFHWvs0yYOKjNV///cfrdpZ/Uj3nJnxlJK50IrnR1Fou0l5ZrvEL3+QTLPqyDwzelw/'
    'faTljuz4uZ1XVBFEvkm4iVOkoXNjFvFnifdHCycB/7i7WsQHw0hDZb1mVTvht6zsmmnTyistS8LJ'
    'ONNzlAaR/KCOxpKaVyyLc1szQ7rEpRhIhvoUXWpI3kWMgfF5Hhu4N0vhee6/KOITO75EwLfs+Doh'
    'f14vvmzjoaDf0JuxrSe6Lk/mG2+8441RDXc7BtlFFiKXgD/X4dKaitKIR3eyXW5iToc3875kbHU3'
    'oWdaGU1WK0wOcxT1PVzZLqCGbVmMfk3UX9Wbv1TY3aeLunsg6O4NYpYRkjgOR4Q+rHrG7hFBNVAF'
    'tebVlCas+fzQjdyycTGBS/qtt1h29jozdim1D5wxGC3FxVG+QzWdL52j6tbJRQHhsxJ6WWl3fykh'
    'O2bRhsmndujLJo5ivry9Ws4JKuYHWS0Ks+ME299LkNa0Vuh7qsiLwjqTiC4biWUX9iu90BzeSCoC'
    'WQeFQnegt0bRwPdifi3uO2lBCVCF7Xt9fWh/k+58y5GvEXT32WLuLoX8lq5c53hZ85utghD5wDrO'
    'WFRaTJ2qSohz4ZwtZWIVHzKvN7cLFZmMigXe4huv5UZJndussWnMlm07eVqkMrplk1lAYebQ/hZd'
    '+UsE7BWua5WfOzY/aOMo5gf313fmEQ+Ol7rGp/3IwTVFTKbrNo+wVTsW0qivmi0a0zI/FdJCjHJf'
    '4Xky7PAyWq8Lb4ctkz3hR/yuidI+ssbAVFCkzdT4XTrzHUu+SNjdp4u6eyDot3RogjSEpXBolBI8'
    'DHCLQwgIKcLeiFCfyBEhD7fSDpCAfs0TyJQbF4y29A9BTaU5SzRKno9MoDed6YY0JyPTF6MD1hWx'
    '/1t06K8RchQmdfeJC6p7+kcB319fv16OJkkN51if5m5cjjqzx1udtn1qMpkQIqXNxd10LEu7GLEP'
    'i0wYN7IBg5XuWT0pekUR8ItJ31BreLveiVtAz1JW4Mn2t1hMnZnxVcL9tB580cKlgN/Qg7MNSjOg'
    'goQVaRNOSklrCc0waDZwgyMBy13hFnXhazYnwJulCa1ViOFziOwS28vGQoum+0O42xXiBu758Was'
    'UPAeX/m/iaL+OiGHJgJ/qoxPDdyL+HRztYSZrXUcTkmu5F16NAn8lejPGK9ZlEtuFkhSESarQtpl'
    'E0MwxAW5RIx1uNwBo7bi3HU33WxJt9WH5WwxSrRYb2W42pnz1cvrpzM3/loCjtI08T+5H9+1cS/m'
    'u/urJW3V7cEhkzILUG1k7o/LJzCXMG5vAktDTVskq4aNDE8tFrBzmz9wUaoVTjSu1KgM+i27XMwa'
    '7+AJWJUp8/Vhi06qUvFelvR3tvy1hB2HWYmjbvSp0v7eyL24vz+4Wt67dX+wJv2BwCBq3YYLi5rb'
    'eyomDQlvsDVVi0pTTKXDYeo6a7f1RmBYHQIzyFBukvlTzQjauZZtZn1WskdMCGQJqnvh5Q2we878'
    'tQT+mUcWFy3ci/ptxxYMbUSjSeVQq1UtOGQmik4b4NI8RqSVFOaSEgc7pFrqhpJ7vYo0kwjXsGDn'
    '7IDDNt2LaOoZlePpDVTNctIYNh0SuIvf5dji64RchKXdfLKY79q4F/Td/dWiZl2Dcfcor1YraDxS'
    'o8ma3ACa1lgDj8iAXpXlCLAYo0GjXVRiG1aratgcIcKBRkI051eRZGQ251qbbEbSByGgl2lbv9yl'
    'v7PlryXsEqHA7lNFfW7hXtDnu6vFjHBQ6y63O6WrgI0cjPtyUHe9pVMtFonDKoFmE6n0p0xgcRu1'
    '5baqqnnjzmfsXaMEe84Te2HPh27TSPF0ZbZC4Wypycuz7luG/LWE3H1yb+4uevJbtkXQ7rhwgmar'
    'WE/VDWrwmziskGpQi9VyJ40WiAIaa7LTZHE7w0DD44nOlSlwBFm7ZtF2fO2pVDBR15rAYdvAV9bH'
    'vgxwv8eRxVcIN3Grz97lvGziKOLL26ulXOr0Utsr7mTsI5njc6nqpdtxakGQeIBmrElFdYhpPLdj'
    'UuYgmJQqRk2EAI04wHXJxNvtviT6WNAAeJGUuTvi9hWW/C57nLcc+RpBd58t5u5SyG/pyFGeDMx6'
    'FEugz9MTUwyDkPHx0PO9FTxHAmyKIMVCHS+gLSqZazYZin6Im8YjVlyXFZnqTMkgy+dpJFBaNNIP'
    'vDbJ+t/jwOJLBJxmbvLZXflBG0cxP7i/WtL0HM4Ffs4R0WJfTGJGnTROJ3n0im9IUVrs5KZoaZUM'
    'SQBIqjk186JA7iWBlHe6NLZIgN4YLgJgDabDYI8MTLrbiKn6m3TmO5Z8kbC7Txd190DQb+nQahXW'
    'Sl/ZgdYzaNGuxMDtBEcVm0m9w4NNlIZI6OeKulgJjA4BDTUNZWS1lA0Np5FZKqWol9CitRGc3OTb'
    'QB4CMp/+Hh3664QcHJGbJv2n9+oH7dwJ/MGzq8W+OQTbSZwt9/OGjXSbhop2r63iIEIPZGpoiM1b'
    'Vb6Jp3N/BTgzl+OiaRR1RxWwsRfCmiqsgXG7MdYMpF8t3HYz95kl8Tv17ju2fLLwyzpJy0/s3/f0'
    'j8K+v75+7axI+mEpV1LSwCt4Rvqdi/IpnsfrcrQV+4xE4GmV510BBrPEjw0VKYa2r9woRlg+IZbo'
    'ugm1VeQhpeyP5XDpNKZH/B6HkWdmfLJw2zBB4E/t0xctHAV8cXe1iBU+CKaHKVUr48jVxoU6FbJV'
    'QkjjJLR2g8UO240Sb5FutE3XPkBhg7Ufo0ynKLJKRli13UpoLJlMFcxIAJrw3lhV+83v0o/PDPkS'
    'IX/iadWPBu5F/KbTqm0sWN4yalaE7iTUeDxCFW2qo+kYzzpfRwiJlhf7UTAuADszdMgcK6LRLZKJ'
    'VY9UZqPswZRy/L5zc4LycRtTSNGtt/TvcVr1dQLuPrkPdxc9+C0qGnOtrCuQZCMNxRwokhVPYJhw'
    'qF0XtLg5wObgZjmjosbOGgJp6Qxza1Lyxit/I1JWsGl2+z3RG6RbeQBZ8eTC7XEK+z1U9GcK94fj'
    'z4VQLyV37zZ08TnJ4e4vv0r40ivlSfL3DlQ/ar6roUdONj99wQM3m+sIp519kxXp3rUr4Ozv8izu'
    'IQy79NW5Fvg/NXAE/vn35o7k66jX3SkpKO0G6kqo4txFb+9X1WrsBGmhmWSK7qNm3x5QSiOAHUxB'
    '4QidqCYhCLwvx8DS3Kq7bqQWimqtBYCySUfidwvywaj1Bjx7dXLyonsIyLqILvngh1VQW9/sNAbK'
    'LE3KtCiBCz5cA9kijSInbRPACs/t3Vw6c7imFT4jJ+ioRi58ka4W06vtHcX2XNHNbaOvC9Kc275I'
    '+byAbLWmKCpPH1uaCRMzbFNk4dJU6iiZZSWndNmK82eR7icrlMRQiWtTjZ2OA08TJhtGhzcqEfH7'
    '8jiTkaP2D3Yu+Qd87ATUN/Bv//t//+1//Dt85CJ84ab2Tng8O3Z9BjbOA9mTz69GRTchJs6OKaxl'
    'INbdwifSVI2bDCT6EhWALNGn0pJFANmRNxHumAxOxICKenOCLDVO6pYcsEA9dmVtA1uRQOkIphl3'
    '8P9oP5SPw8UVzgsfBotHXgxPPb4aFDG8qVW8AMeovNx2vZIt5pVhSpqlTVYWS27VNawi4tLRdZFc'
    'BrjIMQlD7teMUJFWs3X1MbYJm8NhYdkkFoumY+qO3NF/sjfDh2Oi+zJEdE/hoXsDGjCtSkpOQvDj'
    'l0nUxpL60RBm4JzVAXbUY22RYhpXZHJUoKYNoyNo0EPqEK5hSYHifufugNCbcl4dqfZmn9DGYMMM'
    'TP+5jg8fh4XXreQ/DAwPzeWfeHo1HHwkAqmsn+VBPYIQTBAP1qENRVaN2xUWrKSVIqBrZ0xPmjrX'
    'SAdB5jiHEWQRkDFRVJ3lZKN1bACjZOCJpAn0XTRkK/UPNpv/ODz8MHL3k/o0uQu8z8bFE01e4OOJ'
    '0qtxkvAusq59niISVq3KTOkmOY2WhrTK3DC1RV4BmDzbAjXQ+NZyZEbGyF53NcQA6XqsiD7quYtl'
    'vE2bKQU16MQ3GmPRqn+s/f0noOTYaY9i+TKE3Db3FDpuS65GRrgc741uNMZUvfF5kooEL84DtF0G'
    '5MK0NGi74/kFEiw6dNBZcLr21vlBbuZ1tMhYFMagzHJwgKfjHTB3vfUB2qKFEnyc7YFlP3zXPz/6'
    '6d2/Dojiuoy+EkWn9p6B0anoahzVCxg35GStEUWu1hmLrKmUZuEpy5rVZm8LnOxOZG41YwJ0Od7E'
    'Clxxy1m6XkCIubVaLwZNLhfoaWy3AV3jZZryey9XPw1HZzb/JWF0axH8ZbrovrmfQHRfcjWGqGRz'
    'sB1nxI2MwKQRT+XbjEtEvvA6QDmugWQwC5uCIGUfJCojWkV2NR4L6XQ7V7xgGTMaoHbTtZPgtbLn'
    '1pjex0rgtB9mnvz/kC66NUL9MhDdN/cTiO5LrgYR6wegHc7285avy7k+H4j5bjs1WaeT6ZVg8CO1'
    'xgTGChRB4KYV2Sgjfq/Ry6UQuKFQOsOw3PqrkFuFLWJAUxPZZdLYoT/MIvb/IRB1X6mHume0UPdG'
    'HTTjfBwsdHwydhV6u6MMaoYT3UiQrZkT+wle1Rl9nBabyHjE1N4sXk7Q2Bi5pERgFRPSMuKlGoB3'
    '7XrMg6Ia8kSZAMVH2fX8Pwaer5sLdc/NhLq3zoMAu1kDRIOt2QGI03AADVHbw86UnAyl2Ad8DYmZ'
    '3Aisstf61kf60pYXJEmt2IZ2ycELhTlXZ8R6vh87dcpuQoSry436Sfj5K86CrrUr+zAEPWVg9mzZ'
    '1TiS+oHBuKIByni0I5Y6KyrAngRBSJPhTo2hQc6YxXqO7kF7C6yD8a4Jo9qh4e1MJUI04vAdbRzr'
    'gZEtOeNBGlFUPCXaP97Q7ONwcmk1FJeN/dkwedzeBUoeF10NkpHib0N9RHNYGvf4HMV28663zNKs'
    'BXOPSKRVp0sSmYySQYkZszeibrWmgt4J7JAR1z3vg2OgAceVoUymUM3mi5ZRMv8PtmL6aHh0XwqO'
    '7jlodG8FBjfbObC6ULcJJFh8OOIyh+BGBRAdNp3t8TVMJmGxw10mgeemVzfxtJMiC1AoXPc6rPKI'
    'TKGLFqF4J4iZGdnE69EiUP9Y85hfh0UW1Uf6dRVG5bNYOLbxC1C4aOEo/4u7mzPl12UO7ymLrTAh'
    'IIP9qFGO9ZUqIuA92GsdR/d1nKb4cuHR+3I+BtFVlemNYin2xB5L3UAkI4rZjkEbYjt11m01H96H'
    'cc62bzMOeYGV9yFpzboKbsPRPsXGx1GBr2bkY/qnIIG3Vzd3NK84gN94itEHOixOdI9OXKni8Qyo'
    'xonlhAOANaYmGtN85Q0eQ22YJBQLeFJiKcYSGs+GPmilMTrg7WpLDeYaJDaT9dJLHnSb59D/fMDf'
    'qjzO2245Qx4B9uYY0fA5OPAVWL9noFcn9qkvlp8ppctGTjGjLm6vlxeaepFbKSaQpCK9wkXOzUsH'
    'mQ0VO2jKaipobg9J4hZMRwrPmWtXyTVFD3ijihDCt48D4MacSaNh4eMFNQRgvdJnsk7/afLKgtRN'
    'wud9lNFv2C8I6o76SSfdXt2cKV5h40QnFEelzbp36UzsIUjeyEUhszk5WeNkv3E5tHbgaEF5Q4Ka'
    'MrmzMHY+p2IoW/lUMs95eznaTTzaLncuOAWS3GnghzZO71A+WVpW/pEH1Wdi+7KRE98ubq/HtmD0'
    'I4QQFTrjyj6tTJVm0qYBhJ6awnDhhZu5Vi9H8GqfTmmb5t1oMuOLcgbMtigx6SEqlomIB5f5aJgw'
    'BpkKsHxcXbZ/GrYL14yqMHY/U1wXbRyldXF3vbCygeGnm30+wYAun+5Ut8iqUU4Vpb892MXBZwTf'
    'Azfwap4zqLdduWMgo5iZiVRUk4z4dYA70oIq0B0zhXE42jUrZjT2flFYTymIR9rgXyLSskoL0/9U'
    'if5o4uT/c39zvTwxaXEQK1hKe0KoHaBUDAKAyXHrTLqdxKw5VliCoEWmGSJqJjUX9b1Mb1cYb3vs'
    'hi8r0yzpfEuyB4vGUx7htYk/hra/OBE4vmC5hX8Xyf8f4Fle/1pJPkgu8Emi/NHG2Zfr/u56Yc46'
    'nlwZ0pqBVyzBH9yQJ71a3eU5fJSN4Or1gpQUnoG1+do8KtNO1MEkn+KHMKSmbZaTHuUvFAn3wwra'
    'kh7YLAB1PvuwzvljOvxURoxnZ2UvV340zL1c+aGOfbnug877fDqJt2Ht/rXMdYsX0lCcto0qN3Jj'
    '94iWOy+Gk+vDdcQktzKvIPij/OdF6X3R/7mim9za+Fup099kZlG6xbMLx+PSFH97F/mJ/mnb4Mfd'
    'zS3dK/YK5jOX2foDSdUHGF5gqo84DduUDYqPSXbeiGIKDSKLLnqLJlfwJJzKSEtFOevDVAVU3lwT'
    'MgEP1S5Zt6icjAkplSj/nU4FzmtJSOw0SU6eA8cX/+2FBC7/9verJfSD4lPSQY4DJkK+Vzp3tI+S'
    'ubu6uaX3ulREvNZkD5pPSLKeqLnAHCoa7Yc5tN3SIr7wvZIHGyBe+r0ibkoDYhIBNBR9EqxDd1/U'
    'EGtrh/nGIrVomG0FLWdXlll/mlTewfYf2XieYvvDBD1v5Pod6SPX765uzuSuCMQibtf1mtAbyrMU'
    'vgJQFD6kDDHi+VbE0kiBxI17FIgLhI6fCvkkRoQ1sF2FSntIRZGC+8jzYInt9AFi9H1puFEHPvQZ'
    '/EimP1QtT3aH799/rNK4N8eJSRXaN3Za3O6KYT/lDbp967L27fbZm8X6ZItPCxr6hvyioH9u7EL0'
    'P5XdnJt8HQyO4m3IxSyUZ2grczYxOo77ehdtKdvTSzdxW9aiB5IhV4C0misOsN3BxLwRVnw0mEbo'
    'Ei4uNy61rROB9RmqsrgJbIvt5/fAn+WZl8+VFGZyHMxfxtDxW5039u2T5G7cokiL5yeG4Ht2JX4i'
    'fxT0xd3Nmezroi3IpdkfSE5IDHA2VNZuQaTrnLXtjd9S5BIAE1fIApmCxEMsD7V//E293UqboCtz'
    'gtUcSef2bO45yrRIxqkD1gQE5P6HbZU+kOiT3HuYgeuN7DsRPkUxOv7c3FK6wrxPGsqGKquJk3r8'
    'btyhKzZAd9TONxKWoUpXm5R2GI3tJUe78uyAE9LOBw6UtVl78sg6oPkuZkcRBgdaMm9XIQfPE2H5'
    '8cPRySXRDm+++2/+/Z/kN+q6Rc1FT3mK4/jp2AV6L8fzE07z8uaWyhU2TDtuNd5pVGAf9FVQdHEG'
    'JSy+aJ1MojzmqFHafhnMN5CB0D3nOxQfcRa+pheZquaTAk6BXM1wyd4hPcDTcLEexEG32g/G5yPd'
    '8dz5GPFepl3SP+3LXNyez8GI1/kYiGkRC9ZByAeVDYbQ7LDjsD5ZLSVaouopbBhqLCGE0ztosJZG'
    'mLmOjoqgk9arcK0mcMqoswUwF5md0+gSmM203NJj9YP5eKdfnz1ffC//TnRPS+bjz+254RVbtkXJ'
    'hIdJE60oaoggH6eWNj1G4mGnZJ3fgis1MTmXgRatBUJYl5HWIdk1WMF7RUh1S9mWanPtN6bl8RpN'
    'KPpuXe949TeadD6a2Tw9MsHv2bD4mf6Z9xdzjzPh12VAxmaMctCCm1c1kcSVGc0Itx9zEKr2Mq3H'
    'dscFujdNtb4AEwXYOqlbTqvVqNa1RnIpfLkBOGVZHSekuTqPMGRBrAzp02TwcKT/oCXZOS0qcJGw'
    '9bVkkLfpU98ns+cb++6f/+jxzbm1Kyx4lqJ42IyJDACnVBdCDlRx1Q5TwvmBnUp8TpKZCDO1tdvL'
    '5bzaLud54PN+iA9uNjNHFMvt8ADEFhJzUDtWDBVD6ozqE4It05lpB+7NA9R/aqpI/BsMvmFQ/klA'
    'V3jyfiggHnnzPlNyLSz8tB3MgpJaHTC1TYZ7iImKq3zQ9vQJCTG7YCR8bi99o45Hztjzy/FaWoxo'
    'v5EZxvJrow/tAz4XgmxcDp3kWgJZ9p/gz/srsHhvDqsPQkb3pbjonkFFdz0m9B3V7fgkp7NFtGBt'
    'qgQ30FovD9VWl13KnuULmc/jBcSWpB4f9uJuO6tAiGDRdat0tM4n8qSmHWu5IUojnK08kkI0/8O9'
    'ev9ERFyT6OxDQfE469lzRddCY4MtOLQHBDCLeF7HLLhrltPDihBmXZ87Ei373oiPgghsONUQZczZ'
    'pZ0zYoD9tMox3EZnSHsgIG2MjiVNhQ2HH1ntVv291MW7M2R9FDq6r8VG9xwy3qAyVhI76bBymQ2L'
    'FtmEimtxRESB/MYTfH/qjFyfq4AczwiAiZEhT9fEujuwRjVCJp3CtyRjxw09BvdIuV57VmCMJHSZ'
    'tb+TyviXoeK1VGofionLvGpPPb56WuF5S6RTBqrUiD2wFabdoVeSquBBBZ4qlGHJ/WaoAhhgS1Ar'
    'K3FEgdrYlsHENlKjByx3G0WQbrQkii88eHCS6QCqH+7h/St4eGfA+A9Dw9foiIeJ2J4uuBYTaoC6'
    'KxTokX6yT7z9vle2YSDtMUCe8FFcjcZDDREyP/JCXZtsMEKNV5geLnDE7RRtISjiarBtiF+Y0MJw'
    'CmEk5dx+9ZuNHf9SVLycy+sTcPEjsddzRddio55y9oEKySClB0MJt1poQTIRh3IywIje8e46wmfo'
    '3Ei7UZ42kIhge86ebvA1JzY7fpT1TUR4u6mCSswKm28bPofY+lNSfP2x6Hgl+dcnwOMiE9izZdcC'
    'REPFhpaSKYpsMNXNLXDeY7iMxBtpw9N+KfUDgk8Ys7cdLLF8gDoMMRiFLSKktqflvbAFRSUeZnur'
    'bNPB6DfgJOG3n5MT7I9FyJftaT1MHfZ0wbXAmMhah1lI6QCoTrhm38XoTG1GNMEUhxXPaiYXtjyZ'
    'htyS5iGPVjbBDBXAho4ODGmFdMTp63XbSSpS7XcwMFlbiRqG9O+1r/UvRcXL6cU+ARc/co09V3Qt'
    'NloP3OfTibwvFC0R263W98JESyFIlKxGmhWrUY4OudgzgTwZD010sIKF6onNvFMZu11mzsQ0dG63'
    'XNcBKKRMITIr6ZV8Re/MOvbHouOlfGSfgI3vycmeLrgWF/yhFWxkTvRBX20cwG33fbeYeHJctkxM'
    'sRtJWAK1Czgr1NwtrHbnbmm3ylF43c/jMtb3TWoQA4Ea+M7cMtVAF+C0ZtuPT1P2x6Ki+0p90T2t'
    'K96wezHdOh5sL3yi8JmNkHSMI4xmyBqhZDIMLIRwObqG5iKZ0rNw8JeqpcgiMXCcYSkVWRgwysi5'
    'PDFcHil5D/QYgyU44Lfa8PwXoeGKjGcfCohH6c+eKbkWFqMsjbYzVJqBqKlkMjZbHrjCTKh+pU50'
    'I+8xNtQnYlZGEbbvkQgZ+ZQ6DzIPoZYjV6lcLzDmMlvMI1Dl9wdVwdeJG/1mZyPvTZf1QcjovhQX'
    '3TOoeIOqILf8EpxyEoA4OQTu5PUMoInMBra6VFm2a9sVWmwqtysSneFkxc4YWFzODW/JaHgzyRI9'
    '3EJw4C4siA0XQFuPlsCs/61Uxb8KEdfkVPtQUDxOsPZc0bXQoJUlOWKibVJvY6imRgefNVJpD6+H'
    'zWD3cRvA/kJX173OeQdtwsrL9SHdzPdMLKu6KY+UNFcxYgx6kZZROj0i2CQ5DL/Z/ta7k3F9FDq6'
    'r8VG9xwy3qAyeoMoRyo4iRJwUlHVdNiV9N4wNGDUV2OJoCM/MvPelZROLQcBEoJIcHb4fk6P+CFy'
    'uMqLDBJyYyKamCnUGfXI1LSD/zupjH8ZKl5L3PWhmLjM4vXU42vx4MyFCWvOd9AE5RQ1weEaSsh4'
    'PDkI2rSVSvrAOIfWQXk3b0cdslz1yzLfgttwzFRTnMPlYfDZAxLWO6SZbTR9NCUBB/qt8PDOtF6/'
    'iobXM319KB4epv16uuBaTLB9BK17XC43bjkf4nw0VcCZRVjoInQwGIHpxqZhfWY728KNnGxRbWez'
    '1FP2SYXDPRWoPbFemrsMx3hG2Ne0qplrm//Nxo53ZhL6GFR0X4mJ7mlEvEFHgGMV4Q40x0XiXM+g'
    'XGs8RF8FbMaWkzoYA3t/1hKYX/e51Qn51NRBpgXWs+N6FU44PxJWg8polSRpAD+mxSkyXUoM+lvp'
    'iM9Gg2nbbla95PDxdrPaO5qnWC63V2cPj2scuO3Gx5lKbD3fidf5FtrwoSHaiApZBy1n5+EI3gC4'
    'mY7wLeHXgMa0Wk0H7HQIsDEqRuWg18u5v9vW+SxPMYuP9wsx8X/N5zc++djeuyb8A3nsfZW4flqF'
    'ZpWeXXH+8Yxb6yvy+tvJb+51Yb3ulgp/Q98hsOfdUc/0rtgp9A6QaM+LzmQrKLVt1fTVxWyxkHOt'
    'guaz2g2mCccNY3KH25rPd9oKWo7NkC9XIePQI7/HlDmxhXgDgSYL8aDFXWXsf9Hz3uqre5lBF6rr'
    '1KnT4zck1Vmst65yxxoPpOq4Vu2fi9CT6+dl0SPj6X/AD0JInV3+06S5icLKvXP5Jx4SSJMbL0zC'
    'MriVyz9OPH5A4Nbz6x/4t2M3flBQmO3NSTr3SHzwVaevuQnLiw96Kwwv0tG9nDDsO+NOM1o7jSLX'
    'rsLGvfwzj1KKPax4Ti323ZX0CtjfSfJpT1/oHcPSmeIJ6qffmzONK4KELjxi2Q/LDteRXhNkS6bX'
    'BIXhBWkX8EjekzSDORXZ6goyVunUNTBykXI9syIVcmAPC0Ov9ks9xL1BxmdgNnbsrTW9Sju9rj2u'
    'ySNom1F0cwpRd2NmWdTfBG6UucVLkdHezthn2ji5Uj9dco6Tdo2xbQaZViSAYTM56MPeNgWnm9bJ'
    'AgOM5lDOBLiUxjMvxzuw6AN1DcAWILYzF4ZsKYu5SpH1cE+KFAW0updO66VsxbX0ixrmCJ0LPXBy'
    'T32gQ77Hfjh/9V2VE1jfMTigV4s3rV/wSzoRep9ET2TvhXi6OcsNvWJzuC8pilhReJaiYgfQ42zM'
    '5AFNTetOMNXNRPUJmMI4NBhnQYPwu1M4trFYt9usQrdGhks7jI53arI6zhOlZaRlpu7uf3FIf74j'
    '3I7fD7Sq71Y3xw8rwqS886u+FfQvSfGX0zFG+8AsrGtQcTfUOeHx3TKsbrHw3Fzv7W5rT9C/jZvw'
    '+Ol5DniFN5s74sCdwembbTFdBOrQQnOlVtB0hknDWownK9xBgi5qTGW6nc99HJa6Sl0oWofqW73e'
    'Cvp45Scqz6Icv4CrabVoiEn6EVr2Nx0cH81lnonn845J4SXhC5GeZxlnildkwdsTK8WYgnszN+Wy'
    'Pix22mrqTUOYtucEAzRt3NrcGpQpwpWhKZR1413d76Nd0WGluzQXYx9a4aMUwdrMRDDVs+0RYf6l'
    'ZZkeQvfZkIDEewbkM8mz/E4XN2cqV2zGHkLMSMTaIzAwwsCaXUZRhR9Efr5FExVyF7x6XPIY03G/'
    'w5yNn4i5leTxshhPjyuxBREVkiCqcF9tpHApwynY4NMWaD9mroNfzcmbMvQTs6qfjWNxmve9l6c/'
    'iP/g7v2js+/uNWZZBF6vCKSOdKOYQCtjhopTeCl163UblAnje3S/9KkDqeAiu9tHhljIcxd1BFXk'
    'kXEXYu3eLXfpzBA202ixGe+VnWQFH9FDThEGrtk/+L5Qeoq7D5dO13L3TPHI0vPvzZnGFXaPbNtu'
    'klZtDmvPbMR1BcMzdt6Ouq3uDLTWxmBR45NguaaROl5hwc6GyTVykNGy8rdFXyyjeVY3Pk+xYbiP'
    'Knq/sOz8F2OKxj+WYsibpwv4+4JjlXWWpUVV3hx1UFp8YGCs42c6H7pJdCJ4lnLmXLs95BMJhyu4'
    '00/CVEh9mmazgs2Yas3HQpApB6BImcGxEI8PcAgogUQpPQ1Pk15qDwytAXLEIP2YAaOp3qxSdUqX'
    'JV+0X7cAc9zqFEzqLqPDcyM1/A5W3tM9c/T+7jxOX6GFxtUeHsuyTCIpsuk5jHJJyTfKbqqubbM4'
    'rORsui1qawzWRZssILBXERw9/ulxv4KgZBflm+0uBrEQSD0iTNF4CINx9Qbv9ac2SF9h+VX8Po7o'
    'bnFKW16lHxr/+5LwieMXt9fG/Rb5BZBMhLGq2UYLSvN1sJtSocrFLE7m9Jof+xSTx6vtPlb5wA/3'
    '1AqTZk2RH1ZzbGZVfT/satmVK3BwXM1FV1vCrkb0566LHuxFvbL49dPs+5oX/tXV0vMSdt0bLyzK'
    '6vkgfe+Q7neip3BUd5c3Z0pX+H1KbUzNA22VjjYrU1uMGq2eLnOWpHh/lwVrfXFwZr5r4aUOTFG5'
    'mPALokJJhnZbnTNsnCEj15uQougVWLPFIatQo/R90ZNP01DHvZ2dfpzWvqd6Ys7362v1twomFKeF'
    'aIwLNcuvIXcWxY0wJnbTdVdTCF9IfSiV7FFBH6eP0mbQ/A7fsHnde6q/W1sI1ASsbyRerCwWRtwl'
    '8kEbF1+4gXaEvON6R0Knrn7sGeeP+zit8jP5E5N/enithnGRRPN8b7VDiwU7hxHYX/kGiKuLvncH'
    'EBWd/ayYjeZLLZWNuJD9mTjx0THjlPsNOU2WOOXmzpaNtUxoQ2W9XRSMuUE+iNvoddx+MRjZQ5Xz'
    'BibfxyC7v74503qdpTsP42Cxq+Buv2wsoVHg3WY+5ZmOxvejgI6lgY/6rEc7+7hyPc5Ck46kNj3I'
    'Wvro4GF2y6xns8FhZgFs6MxssZrruF22X8rS1NqfZgfHxVtcvqA14fcw9pL2LXsvn5x16BWTEW5j'
    'j9MFvggjN6/03hHhWc5ZOjBPJw6c5UWicvNeGMZ79CBnwKGHpY20wCm0k72DSAJ6sio38IQjpl6/'
    'jo6vM2UM7dqP3+n9rCGttOowcp7dBIDJdwnnTPQslPPVzS2hK6Qhruc66TQ8P+pScUMd4ryzNLFI'
    'NlPDE4QCmO2CQIjDnB+DLogh6mI7y+VxWi8lGThgJT9BpYYJV0zTkBYloQECt/xrwTUDs+STsjpO'
    'R/SzYcC1gY+Oc5fHcvvOzFPZPW8/4lzs+1rqhcjH37l+GQjpsQQf1EucIg2dOyf2K2teTbV7teaj'
    'ED1XVH2d5uNQHtfUfZ3qpbP/VfWupBiaCHxVxR8+xK/XvfAofb3yNTh57HD2et3v7kev13yd94+c'
    'Fa6o+jrNx0bN19S9jurjpIIv1b80k3yp3kMDutdrXoGqS+ur7/WuGStsM3NvgiqOXpiJIu8YLu7p'
    'noeM+7vz3POK7bhFqNfZDpXdmm0LnIxY3u1j4FDyO0lInRUr68wOmOnJsrML92A1eeE7qy4SZCkL'
    '96a4W+9podgUbAngQk/KUt3vqfeugyrTf5Y55Hum6UeCJ64cf27OFK6I0MgfF+0dEZvt2kRA0Izg'
    'cTKdouGiSaF8uuzmhcIDKYjNiQH3U8JjWkjAp2psiegsFmBaJw7+egaI092m9saew0SSrfhft5v+'
    'WtTvd03Enwj3fdUkPGfyHur01Kz9Tp6g/JqzoN3GOTTMDN4g5hROD2Jab/bkuhVGQ1Ue9NBIxwmj'
    'C7knLkf2WhGCWshdaju3tiiMjXYBCP7iifIPK7pbe6AHWyGPIn4fKzzaK3n6jPYJy6In7JbAx6Tu'
    'TpBu7Y6gn8senIncbs9Az1s+PTKKypynm73cbHiq+IGeut1MemASdddJTyWP8qMcl75mFBznMNE9'
    '9x6Zah1nDWXwdLtPmWo9qBC7he8eF9i39qfPV3vFBvBVi640sb+z+xFPz7j4zrjTwuIBX45r/u44'
    'djlOcf/HyOcsxcCHlmIPQ4T/LOcirat7lsIP3/4ePPxssPKo5HGQ+Z/ePZbVpfuMbdzPNmoXhY1Z'
    '9L9iJ/Obnup6Tlg8G6Aae4fqPBE8Zd87/tycKbyuNCve2lY7q7blEhxrbK4IhzIQVltnPtKPa2Vn'
    'LZH+vh9NtQzZ0Kv9fDoTpiMQPphJz1XtfiMnbSFux2FLxxKYoYe5QCfGeyOBv7baeleemSw8SsWs'
    '7FtVgJyShv4Dfc8R2iWhjzo9e6TFnjv6eftk5JLwCRIXt+fDnysmJzoppjtf2y1GJlYs2nzZRbud'
    'q+yXAGonMajJawKcu47G7cCMrClP4yfgETo7NTuI86FIybkXM2TZwYi1xav1omvITP3Fk4gXBqFf'
    'HWpe1dUva+Qn1Ns79NTTAP8ddFVatGbhuC/sP71HYX2neoLo9+sb8LrQ2latsaCXjSuN05eMTOsu'
    'HkxgjKymtTVLtbmF7hY0vuikNbdoYV+2Wy6l2t60okEaZBobqI6m5pC42B+ARYVLS8rcpl9oivJ9'
    'fvJxhzBniidWnn6vPXzROmDT2zsc5GQzn4t0iNucJoo8MXQbS0AgKUiquGql1Fy6M8KYcVQQjDOy'
    '4ZemFDpetNdU3N1uGPFgLsVRf1gLnALTX3f44pVuc5z7Pu+pgrxjofud6ImZd5c3Z0pX+Kp06cQz'
    'Rt6c8Ex6mZh+vFEya1a1AaARxCaWpDznWB3HGKRpxuCWK/zZaAxt4x2ColAl7bEERw4gDMHGIhXa'
    'IQo8T20/aWP0UwP+/oM8Tz/PIy50yth0l7Ebgq7MTfjYUPrjDiUeUL5IWHx7yn3lgQRhcIuOI3KD'
    '6lgs5tvuENTxMu0AidcWtuxPim5TShWc0QWMbLgMlwotWhCzsT7LmKwYpWsZnBEoGq58jYQTQfJY'
    '+Lp8xZ9uHfzYuPnjztkeUD5y/sH9tedtlKfvdTM9IkTj13w26nQhmuKR1wZTnZgvKtFkxrwZc+W+'
    'gBMTGof0WFBSMJb3+4FkhclKM4uYUdjcDNc+Fnt7iyIZ9QuNx588MX67McXP53a3ayToGneDR7bs'
    '361hnvgXj2w2LhfSZnlT9rGVRuXT68JjhbT9sWvxoNXjZDr4IftLAn+IDf0l2z7uuP+e6l3veJP5'
    'ULnUvfE+NY4jNCU0vMi7Xt4SK5hhXKu0CfQQbnGzDdnUF6tUZy1/v50CLDCKqHKGSJuZsrAp3k5l'
    'BpUnnsh53SzOfnUT7JG51dMwfwLH4Ocdpt4h+jnT33eotfRstXj6OZv4XmM0sBK1AAcOq1lKh0u6'
    'Wm6VnYAELdUuum405sdyuE8illKSQigZW9+XUNv3E7wRMnNb+ckwOa68NT33EFnGNc+kkK7UPtwO'
    '4+t600Nd8txY/3bRXNA95Zf7cXce568QFGRPFk4rwIKZBrGFlD4qx6IpjduaQclym4QYt2rhSVMy'
    '5HzPLuciFYxcCzJwra9lzkWDJbiaMxucDNM42K9ScZVHivpHC+pWpz+3ckHfI6MjyVvxHC/Oa5cr'
    'nMiW8MryrPF0hsBt6GYGX0rRckONnMmWwVspACqg2dJoVcuSmG8GIEGaAlrM9E4Ne2U0HODYKFOJ'
    'BkKAyNf4XKwrqIJ+cYvii737rkvO+PZR6OWsjFeMROjM0hzaGFm6E6covZrVOrhZhMpALvxZNSrI'
    'ZeAvNnFU7NV9BanETqNGwzKyXZjEqA4VdaNo+dJ0l/kkFdW4UshsHqu/un10O5H550/bQ2ESuMcP'
    'KO9L0Ye729V59DrtuaTeuQ700v72P3+a61RpePxHVeiFt3vr/4Tet0V0uSb+nfaHHqSzf3qD6D1n'
    'qj/IHkH44+YGvO58FXKCtbozApvbuwRBkfxaGnVpCkA7Z+0NssTbJFD4az3cayJCTie5LKRsHZnU'
    'AiB3PKZNSHXZLdRKBNh0OK7Y8lWuaR+xt3EKwnHVEvhBzIDnvL+Qd/D1O9kzX7/fnL3Artjj4EUj'
    'a/hhnzCUsaRX1npsHxevOjhVTN6oNngzGoqRpmWjIF/Np1kKpu3O7PC211pFFqyNNey3Zaa2dbks'
    'vXUBhl6A1r/Yt0vTO04yrdrzbnvYsbOcvRz+9t//hrxrKnnsn7/rbuyFtvq4Mfg70RMi7i6vHYcP'
    'QMOaBgpsIxPZDL3ENEtVNrYuzzW5LFZJPnbqYcllQ6buBro8iFKwg8XRNBmHukQNrJ7yM1fKDLEz'
    'UWfr7ng1d9vn8MDrzAtmHWF2OhX9tn9+Dkm9Rw99p3pizvfrmzOtK4IRiTyAg0SXdvoy5Qh2v4Bm'
    'nm7N0xU4sqplaO9LVd+oUQAEu/6wIMUsljyi3rbKBtFG5mGHa0ALkbvI0Lnx1gi3K0X+KINr6Col'
    'VJ4Wb3FYus869L1nu/oH2RNX729u0Os2roMmS3n8kBaBICXu/jhtcHQfT2po5OJ1VxIDi4y3dIxZ'
    'fT4pfWGxabtBwgc83IW0r2roUkBAIR4v5TbfrVpkE/UcQqvvsiWKQj+okqNSsMsXrNLfs112SfnI'
    'pcvbm1uSVzifHFaTIt3XQgl2B5/14NrZdCbSs2OtU6pudRgTVIibzG6u+TahSKS3c6llWnrKxG6m'
    'xy5r1TNaT7htrM3H85UVz2X+VVPdS94p84cuXC9N0C494W73jJB3HKTBX3yQlpmF/SPTxVuMgR9I'
    '9Cfz3UeoeVz/sWHuddW7qyo/Mrp9pfaPDFd+UrumFQbeW97C0dN7b3wjrsvo6le6NzbRXd/AZbzC'
    'uGzsq1/pfn7hdWX8ImA+SfM8bOexHnpQeLVW8qeZtjQj0UnLDB1bZL6pbDiU/SmmH+cNUaZDdUZZ'
    'sxxu6X4bRNDKWcrWNuRcihymEqWrjZ7m6g7i1QkoLDIfkSIs8z8+ZONP2uvqbLq3bHlzjL5/ufa6'
    'EntXJO79COg9ytf7bNnVwNPt0BxI100WSzGhLKQiRt1xCZItM2rbieoWTbJWReJCq+fgmF5z43m/'
    '61IvMMXjXTXElbYDhmWfgkCVomOo3rDAZP87Ae+d2Vn/MNx1X4G67lnMdW9A3A5bKXQ3FPtos1j0'
    'bI+HOGYLw9D4AjZBlngrNeXI32RbyiFyLaAXRZfTGT4POt7fBZvpcfKvecKStbVuX8/5cTGKSUP9'
    '6Gik/4m3p/H2elrZjwDcw2yyzxVdDTlVlYBlCASquRdaZjvSwk3N7KjSqXjAUA9EMhGxhiEPB6cN'
    'O3eQo4nfTDpipC1H6l7EZ/ZsiUpZWafjhONTQEb0StP83wZy780m+6dg7unp9Gdh74nWHmPwiSpX'
    'Y3FBzNZjFw91GJUiCdcAVBsvOzZQA3fHlkQVqtQKgVfVjMAWg4KpRLdRtHw+ZsQu0lTtgBRbaM/w'
    'ynzoiM0gB/WK1+Yfnsz23Vh8X26gPw6J9+unT0fhbUvPIvC2+Gr07eEGCKu4R7lo0UU23qSisfXH'
    '+SIEFz481wMfHQi29rKpX4KYMoLLerzuQ4rHt1yO1el61lHT5XG95jLTYL7uDVZNxI+b7p03Oi7e'
    '9c+Pfnr3P4H6FqDeLdy/Aqmnpl6C6qn8aqz2oYxpslRvVd+wGBzs97sVxmz12Y4VjTnIzeilUVEx'
    'JyTQaNhgWMpUEk8tPHsdbOfSbDIn/DWRjpU0AaaxJLE+LDeV+mlYPbP5P6H6Tqh2X6RRu5f0afdG'
    'bWoWI6Em5rG9AIUUnWVzNMhmvdUuWApAaGBcYOIGTuB9L098RJruDHOypSeOG6cLfTSeLDzJF5s+'
    'EuZ7VMeqXqPtqqY/al75n7r0wwH6JZq0e1GPdm/Voto23FqH9NCCVeGJeT54MwyLjoJpp0oxQWRh'
    '4i1rYZiVkCTi4SyZuIk5QF4+n1cGyi9ZRD5UgmrI7tJsIbMtxnS0U9pPwuh/6tD3QfSJTffPAunj'
    'ph7D9HH51UCFxJGkeHN9ts6yYMgcyzsE0eaAt+NiKVvjQYeXuGNBoLKQd75Gsem6pDdDu+jrYLXd'
    'WssMRvYjVCsS26v3O7SmB6Np6d9oJ/J9SWr+LAh2XwXA7kX4dW8FnxxNeWbSAUYEznI9Q62iJ4dZ'
    'wjRsFvoIG6E+k9fNtuXqXBCnDDRKqIU/ScJZk3NsLDXQ7pBPhGKSi6LeH5YTY+QGNf3b7BD95aD3'
    's7fEx5lIP6J9RNijJ9eaSgO8UVnt9IBxS6Wftr1o4AF72BqdRCXWHkfHozBaCwkDaPgYzDiMRdeI'
    'BWZra05Mxnu0OgRjOsssdRV5+Aw3ImrO1dAXxhaMXSc0zxEdig8NHXpB98TcH3fXBhDtB6TTTBYG'
    'bRwYy0OzTScmWykxW9olsQ0bvtpNp7mLs8epuMfVXU1tF3GTTA/SIEYOzW5RgAQzzVa1nT5Ngrw+'
    'UEatfrSX5u9kI/dUCI+Pc7X9ifpZrI+eXeuCqycHBELXmNnP5kGGeIeVNq0tfFPtx57iMMoWmick'
    'QMZ1Us/rcBuU9NgfrzdlOtDsSNpI1nra2I6dWSGlEW0LwxGlIl+aDuEK94IyTJwTc4ugvkp8p9Aq'
    'jvVsL8Tek8/sjuhJVrdXN7eErlj3rrCpUPMLeDNxY8amM7iZjb0MiNEpHWyEZLXQ9RYMu5IADobl'
    '4IqPo9O4FQ4LZxaMSXNTQSUHM0ujmHcpENLsGkk/ygcEv5ad3yPVPJ0v6z1pnX6Q/c7T880Ncl3y'
    'prnlD84BDNB9naqUx4jGBrV6cCXk+1EiywVPSQJU6ns04UmTh90UyuNGnYYuup5AflTqMAYmEDYv'
    'N+W2Ymo/1Csdoz8gr98ZeCfPjTPM/iLp0uLyhRAjb7chP8dyjctzOJErbMbxWTTU1nK+YxEBNoHF'
    'mqEjdxrshxxLO5/rTWZF9Vujsedlk65NTsiBEusMHgcMQ8GrgdCojpYrLtFloDKqGbLRlhH9LnPN'
    'xExOhjnPdQTkG/x21XJL88iR24ubWzKvs6UWHR9mEXbBiGpCWf1WzjqLzYsl7LEyJmoVJgCkhWTp'
    'gSyWeN6xmxkedFIvhNNtRXuj2brf1hMq0MxJbmC1MtsK6O61EPs/wPhjxvwgpM13YN4q8gtAXqfr'
    'zfDvP0XB+Z9vj9J6L6dzkNbbu2/2vnxjh/wHdBeDAL79Qb4RtxfoXTwC7IEvzgu4uUzp+XGz7x9k'
    'T/C5v7l2zr2QlLEmCX6ocnvLIbOARdau5XToYQdxEAwVVoTxByl35dIMsmpMjcUUcIhUQIalkS99'
    '009gaxMtdOMQgOqKlRBI2/5qJrWnE2n+RRTpna/ycWmUHX+fxwLyDi+Mh7SPgHj44OaW7BVG3zgR'
    'ziNUgKfGlF1anssxnlfsJ15YNXN64YOryEDa2WqlLzsKFg1t5voSt1r7ej4dtU1AWyG6yfesT9lD'
    'Xy7X8DSz3PbPdVp9GN7puRS5b58BXdA9CevH3TlF7hVzIHq5WTUISYSjZD5BqWk4SWWvwkrbQ+B1'
    '6QzIoSpUgaWskNhrs9g0lmXZ9M0emsauuF77jVta+apqVLUxdXiZLesDvfvVBJY/0mfcLXj/Mo6K'
    'dxEXn+6x71lTnAieJW+fkntdtZiIFqbg8yNYxVaaOj7Y9lTklqqsmIaz6pLdbhqpy90WlGYrujaP'
    'q3poOlr0je8MgMn3ixDfUdIgY04DcWSCkQA7nWfIqH3BXeoKkbeFmWXnP3nNSHgRC+250DBvn1B+'
    'J3rk5vfLc0CYKyaXTNi7cjdbAsKuX2AxOFCKZ7SozowFXO/9AZpkEdjm+yiYTFl2rEBsUq7W0zmY'
    '4UiQspBn7xGP6xMjpBZbGU028nyUq18XxCo7bbdV6c2RK0coP8NV8l0K6iHpM28vH9yQ16mpXLNr'
    '3lFwaqHEaG7RjDgyJ6nPY8x4IoXQXnTBoscKXRUGUljPS4bYr0kjC4U9q83naYQsRhoWBuzWLpT5'
    'MknxjHbG7w929LVK4xT68Zw4rfzQXcEfZE9iub+5dk+ws10OLpOgsjCJisJ8UsbTFsMjFyHweLk7'
    'TA1gP7UArVvMetdf1BHhLsqIMRRqNtkDc7sGDVKc9pLtKnBSZSZXTKbrN/h1veyI+VS4zMc+g8S7'
    'WHamesex8/XZY5C4AsO2UJOkCvObXCgnEwymBFFyWjYGnIZPNijXqInWhhwlVGEgNAMrl/ak4qZI'
    'B2Vj0V3Jy75UycM6nicCfBBqog9slv6sYKcfN0naH3/tIAqTg1tU18A9LavnPRnJb9g35B1gvyV6'
    'ktvt1c0todfFtl1Zmy3jT4s2kej1Yb9KtuZIjKTxwGZcG/IVMJkSHsgiCF0b8JyjVvbygIv+pnOQ'
    'QVuNsgVSA8zIiJBpIs0llHNNQvc/aon8rAa67vjnjisX6+X/+nJ7Vei4UehVL7b0vdK5jbtPuYMG'
    'cBTJvYSvbvVLNwKen6X82BH4x6N9mrsAvfda+olAaGVaF8dJWmxmt2EqbuOZwb+0m3DsqNecKz2I'
    '1/3cKQT59j51T/bUre5vzucO5BWhKpOkA3u2X6/sLV5RWrKxaW1TtUtqBk1ImSoqkAwqpUkclNpA'
    'vL+r4vkhqKmNJw3qHrJn3Z7jZfy42E9Wi/UGOxD0uv/FpcdloNlHUWVPX3Hh3X/nyv+OlQn0e0Z1'
    'yMtno4FD+DumF/lJ2eblze3rV8BB6XCBKDxuTLOrYKEiboluB1t2xuMW1Cf2uloGQhyhmpOILVqJ'
    'JexmNHhQdiORNEabkDtUSwrRuLWtAkgfY+aS8avnNpLG+uQGuWEisy7dKzNtXRUxsTxqvhs7MJPE'
    'jS7UwNuDf+D/gk2KR9H5Py7q5iXhIygub6+NuRm4BzieqZlS8+gUGo/FQq/S0XiFuEiHdvWRlhW2'
    'BTKKPCJD0X3dzKQ1aMw2Kq0g3arPDRrVCmPOp6a+Yi29AjF8J314uOXfqT8XZntzyvHxoSdu34me'
    'pXh7ee1pm4gdtfYkirrNwSN2WCc4axAYg5vlIu/wpmMJcBCm6AI8jEt0njbxdLsRBpXtGMrSKY0W'
    'a8TyJRSMCgcb0rkAwZKKjX/xtM3qq7uQWcjjoKSPknT886ecEQ9iI/39n6clwIPBok6y8Fbe/3x3'
    'MMmr4qMUR4Q4z4fEO6fYwN4u6TuqJ0nfXd7ckrrisC11FpOR50bYsG4RHt3asItTfuPXk8QAGZpm'
    'w8Vkp+doeMA2K9ucF4cJzM7r1AcNW55YaYFAwQ4z+6nkrydJOhKVNfbetA7PS/8/0s4+6fPTDjdw'
    'n0flFHkJwx7K8j/uuZFF9VFodRVGL8YJ/ekw6UJI5+MkOwq/xW8/S4KPf476HskaPkrjySzGVyQB'
    'vP+gU5zAo6a6DKNwc/KwewI6r733PVTH6y/9HDnk6ne669/4KYbI6688G0jkDa9ehvp422s/In5c'
    '+945L9/bmzsn3nv7a9172ure+GFPpse75sWnA6Fc+17381vXqN67bEVPL6reE8r3luRZ654ubuDr'
    'wvkm82WxEmN41YdzoogCM6uBXYRis3bhH3asyWQ7i+fM/WTrt5HAyMNcP4xsXqGTcpqvKQxj9/xc'
    'SETLURkoWSvDyKe36qelS3k+Z9eDaF+nN8E3ZaZ6vJN9SgPwrsEXumbj/FHUv+esW94+z7okfMTC'
    '5e3Z4uWK+dZ2lyIiCesTQgv7EJxCU1VJ9/OBOGRulugqT/G9YnGcDxmG4TYW5gg8UWX9AqYnHWur'
    'FscSjd1r3AG0rTa31SJcVf67LF7uEnc9Ozt5O3vcc96E08/tpOQKbwc/2XnEZGanvG3ul/tlu2/r'
    'yX6oB1RR7C2sV6ISlSytQqMtB4O8ti7GpqFvYmeftksBr0nNBiEl3cosZ3gKFG/t3eJDOwjyRanr'
    '3paYDnol49zDmPo/Uqi9LbvR64nhfspw9NfJxPYoe91zY8l7uskPwufu8uP2PK5cc8qjGeMEzJRc'
    'Xa7VkCHbXi3EEpbkyIDRQQUVmTX34KGOqiaVmbIaqxLWN3JAr/VVK0t7tVo2pbJJFwznKWxrmqoQ'
    'LH817fkv9o1XUmn9yDII/+LA8XuB7FEQ6Y/LPvCQ9Blolw+uzUgwxeYTg9gUGYmJYYRZwa5B8T25'
    'l10rFXNMkOKthPj/t7sraVJVS8L79zPu1q6LMomLjm5RQEVlEBBc3AgmZQYFRIjo/96gVJVaE/jq'
    'vY7biypByATzfHFOjiclyqAm2ImM2LUsLuLlwWPGo4MbnhaEubQBeTPNUv6owPIyUxazKHtoG9c7'
    'N973xVyvGVeCujptGndFT6hBo8XMiISChGPOXCqnLDnixRYldjCVlO+/GsAT5iikhmjmNLiWh+p0'
    '6493cR57yoHHTXLqxTYCD5WYpMTU8o+HP5ux83mjmDcZa2e/KHS3y/m1LDw7Tr72sFbBlAZ3Zabq'
    'Xt8J/i4dXt4Tyfd1ennD/R6Q1XdNO7/4TgB0NRsIRZF3dET2+lN1bQPMbDZL/TSckdxsOx7nDIx2'
    'LHwdb1VpgSICPtmDZrjBrcIbELp1YmwncjV+hK0knBO72f8Ilb8jPC4A/4vQUTK/B0cVx2yIDWnk'
    'jJbb3SLWcigRjLALBpqTLAAzO6iow078SLDMwBUUC4uoQapvgB6LrUI4hUkKN10AdyJGisejRTgf'
    'AnaK01NS5off0S8rTF/W+rctsj7Dzn2Hsou2gDSBF/Rbwut1Dv0IYuCfg1j9gHuY1V+fodbA6F2z'
    'K2BynHCCEkzseB4OFvoenzAzFyTdCQMkXnT0jPwQmD6smlwEW6oN7fLEirMdGnV74SoUPAQ76JFN'
    'Dh0S1A7g0AV/Y6g1Wzh/F0DeZVB8pME+gMRrzhUEr8/P+muTABflAJgCQycIUTfSOEk6M9ine1Y4'
    'pybifKFsVy4zni05ZzkeQeG6x+7ZUmvNwm40F+P1AhAJqmCWwPJkTvKM2C7lJQtJWfOox/sx7XZt'
    'Jj4R/qv9/VEGyQNyr5lWIq8Pz9kjDaQ9PhI5gkjQGO+nbsCHHdhmKAHZsr3Y47GMCy3JcAN7t2EX'
    '0aJkTs+4tZXZCj4czQhI9MBICIaCbVm4EvDWhptQuM1nf1/ObWIH+c4LNS3/pKdxr32K4ivfUqiv'
    'J08Xdl/LNZN5wFAifU/723VEGBvHpmdMNlqSgTHujhfBYQ3oiiNRSUK4+Fba6XNyEpZmmAP3fYeR'
    'bH2Q58sURVQv3pHwkssFFfz+2F3dvf7Hr9te9W86rsM/uw8odK32YWgwxa3SyDzoVhql4/LHNwDH'
    'bb+m79PqrhlX+Lg6barNhUi8YmnC3QHjKbf0JzAkdYHUPMwPUSGZhitaWEItj6opR9sozRzaDLxV'
    'eAJABsAFbyMmhNmZUf0YUSyiQLsY6w0n39LVqFkpchJ7tvbhJPZIl6gzx0qY1ecT2Kw3VGkRpaWV'
    'zmkdWjLSlcjN+1nJch9s/XnMDIFgaKEaSky62YgI6S7gs6YsojqU0WMJgxYuk05YfpKsZJoWB4Mp'
    'rhYrAPxo+uqWS8OPz0Ry+jBLGoQeSR4oOZ4FcnqqOTQIV9jmqcccA6wAT2zErHV3auex1Futcn6h'
    'DHB3TnY6+25O2+PTaM9bYUxvFzvIUQPated4tkF0QDnkXkhn1EY/EH6Snejs2+cdM9ZS2zPqlA8Q'
    'axT8vwj4h1HZ2I8F/qtixPenpK9j/Vctyqs0lmsL5BNM5JH5ZH9Wst3eT1jzrJBxOTqHshp4Breq'
    'Msm6aoBrOuCuSaggBSI4rUhmSInygCI1Bk+s49iYx1OPCNcMySSrbrEb2ZySTWN3PrApeTOH3KE8'
    'xphwA1P+YigMv73G9M4Pfbubyzvdid+Jpvz/+JvPv+u5G/x7GOo/pDG+sq1hdDl56jfTGjFSUdMB'
    'GkJLmrE0h7aB/fJIAWvEsYqTqxk+EjuDobYBEAGJ1/sAsma7+ZY6gf2Ypzdr4ZgXIxYz5jwubJEE'
    'F1a8JC5b1GAMI1W3zNs9pd6ZLvTnNKHqsPVMgVal/4+lBV2J90q4ql1nmrwdt4+J7nN8WtKd2lE9'
    '5/q0ftxdklBTspe0nYeIHnmWF4bB7hFC345iFL7kI7ejbD3mF7KDHevHRwjPaUntyVoOXWAmDyGl'
    'pmv5tGoSfehxz4QtnxenQRi3JbpKnWpPdvOsrxeGamnS7U93A8J+Dh5QL64Zl4vD9enTmWMDF44w'
    'znlBkbF47dPy0HbZyWSV6yg04llCWOhJ7tBkGukjlMHnsgCd4mXXHKhk3+/4UzlNyHUkyqlpJGFG'
    '9e05U0Rdl2tp/H4muTqj+CN78BGZVSzP0qoOzjZgAzlFTg5qirWK02229uiM1TsepC/7nSydeTSa'
    'Fl3FmBGMx401D3VCQPFYG/Y1TN2JrjTCcLIvYcu0MHN2uefdeAhZRUL/jQXPR/WQfxLXba+WVAxL'
    'KVYf5zhuA1UEX1Laer41uqbIqprlyqLkdx0sTY88kQsWEh55FTDyMAPwfamRzPJRB9mKnWnBMYU/'
    'pAtlr/DD6SrkLYM7QOZ0A7Dyfvc3yvDjrsBYaWS0NxqPl37A1cfTmcPXMix6SuTY5myw65qa4HPR'
    'HD8C4X5AQOSAmHqM2enPVWuNrQ4ENBdsCkoNnBdljvEUmR1onekI3IORNTGlkzM4UV4GwQzBfbvR'
    'eNeg8+zkh77yWvVvLr/UxFYJjchP6Ib4Orn83Bq8dxNZv3E1/vhVOxa/NlvrET4rotXxz78qX72l'
    'W616F+cCwH/VLrZ/9r7ZMn7hEpnm4SuFGfj8914vpPW7l7BKwrCuIahKR3rnqs6qbvIul+nF3VCN'
    'W//C+lftebi60bETu1b/f4J3dqZn1sh5k0wbqy+A7L9z6cn0NdOoqyHfuyfJvTR+9r4h8FUNaXU1'
    '3amHmj9y/+TEfEn1Q6oCwduLF39J+b53uYu56nsvCYTg14O1MBP1swG7KTa+29v3veLk98avNY/X'
    'MW1NWo9ya7oaAa3panw8RHcNnvYMnpHVnvIFda1JXzDZnvLGg9qYrIZzM7qvV+SXTXS+L0R/YVmu'
    'ypeDpmF4D15FwJiPzfAwyOYocZTAjpByAQoZC5d1NkAcDWR3ZwmEJg1oj131TmK8gdI+MOUYODsl'
    'OonD2i7iWF7nIW50NAtWf6wjexEaHzq30Qe2ACn5leIo/z+d6Rt0msXW4Bh0RVTF0iDRuwi0lXup'
    'hNPFop/vh6c1ABWZi0EdlM9JsLOimVTq6N0MH1tiVkg9VqXUyN9MOgdfFwt224FGVLZ7eOuaBtEq'
    'PSztakvV3Q/8fFF5Sd2Z1Y1BclD15MaOC1T//Cr/3qW2YV7d84+vrZaPVajLMNZj9mbeL6fjxms0'
    'iJY87ot7/qj+/vPHfwFQSwMEFAAAAAgAAABXXS49FLsbAQAA1gIAABYAAAByZWZlcmVuY2UvcGFj'
    'a2FnZS5qc29uhZJNbsIwEIX3OcXICxaIQBW1qoRa1EVvUXVh7CG1kjjGP0QV4u6MDbQJCrDzPH/z'
    '3ow0+wyAad4gWwLbhLp2nosq978GnbDK+Nwil0qX+TZgQKo2aFELZLPYaazacR+bvQ2YpNgazZpW'
    'hvqMoS6VRkfyntJamYDVe/EMb8ULg0OCutZWznCRuC9Gr4qX6BZTNgPGjYmv70SeJkt2VJKwDqqW'
    '0VObBmzQkATIO/gog5K4EK32lgvvYDKBW1CH63vf3Ki0zXlH8YOi6mf+iY9yx8Cr7DGkn4/OD6Kp'
    'fpg6ZMjtzi+Nc8mSuFvG6F4cSeNzRTa23mR7vnRodrBEEq58CT0dB9l8okEt6fbU5ZL+rzT6vM6f'
    '5gUdU3bIjlBLAwQUAAAACAAAAFddGou2BuoAAADXAQAAKQAAAHJlZmVyZW5jZS9wYWNrYWdlcy9j'
    'b250cmFjdHMvcGFja2FnZS5qc29ufZDBUgMhDIbv+xQM5y5bHa0znnrQB6GQ1uguMBB2ajv77kJo'
    '9VD1lCH5/vw/OXdCSKcnkM9Cbg8ZLQzGO4raUJKrOp0hJvSuAndqrdatGyLOmqqMYgZu0WfgNZO3'
    'eYSGTRpZqQaLiQZ0Fo7q/bK5CtLN1KqrMxyDj1SJc2Fa+U8jpIW9ziP95igWsfDWZCKG69ZdxtFW'
    'nJIRfRCleLfHQ1GUL6+an3kD8/EXJPre+dcJiWlIbO68hTKoT8Exvm+qaq/l4TQWApSIziBcIp08'
    'B3pQG/X0Q80vN+CWbzFUryq43xTFY1F0S/cFUEsDBBQAAAAIAAAAV10TkmQcQQEAABYDAAAyAAAA'
    'cmVmZXJlbmNlL3BhY2thZ2VzL2NvbnRyYWN0cy9zcmMvY29udHJhY3RzLnRlc3QudHOlUstOw0AM'
    'vPcrfEsiVQm9poJLT0gcUBFckbvrtFsl2bB2QqSq/47TFGilgngc12PPjD3rqsYHASEWKIKvIKq9'
    'pXx4R/OJG1FkpnCGj5WMJThz0riDxQbrNT0ISstTWARCoVuhCvbH8TRztaU+3bKOTQadOEJ4pRU8'
    'Lu8Aawsr32qHBXFSEhQ+VIDQYeksmIHP+RoCvbSDxSnECVzfwG4CR5epIljGn8opY0H3GJji3ciZ'
    'QwSwJFSJjWMAZWlDqdWNSMN5llGPVVNSanyVYQT7JOXWGGLdSEJLyfyXav2HwhY7ZBNcIzmWOh/P'
    'knP+Akv+j8CFFQZMqZ6dVVzPuSZ7WXOffCTChwDBHNLkw7ldII0HqG/IiMbTeHbiOoKOAmsm32Rx'
    '8ifO7I8q6kq3szr/zv00MuYw+8nt/8x+9eUV3gBQSwMEFAAAAAgAAABXXTaAZaJHAQAA/gIAACkA'
    'AAByZWZlcmVuY2UvcGFja2FnZXMvY29udHJhY3RzL3NyYy9pbmRleC50c31Sy27CMBC88xV7iyMh'
    'AqiHCgo99NJKSK0K9FLayo034Io4kb1BPMS/1zZIJCTtaa2dmfXs2DLNM01wgD0cIdFZCsE+E8Gw'
    '1cKtR+JMGYInwnRKnAoDI9h3UBUpew8KpZGLoA2Brx/hsKp6sG1Cp/UqQ1rG9Pz9gzGxQwuAJK1x'
    'cEbUkoUdW1NbUqlYzxa+Zb1+N2xbbqHXjmmLxTUmUiHb8HWBMBpD9Lkiys39YBEtokh2CA2d0NCa'
    'mxsEruBxNnth0xDmr5PgNLvfvbm1w4813yuulljat+bceGxQysV5tEMsAcUbaiMz5fxKRdZvnhlJ'
    'coOs6ba/85HCr1xIwXwGtbxKwZRbze42/7kCiP1jiS9OtRty0Yg0bjKR9uC24VrzHXOtC412OV72'
    'lSpBfed6WeK74yrx6vtU6BfsWnT9dlVZCbXCX1BLAwQUAAAACAAAAFddI5i+CM4AAABOAQAAKgAA'
    'AHJlZmVyZW5jZS9wYWNrYWdlcy9jb250cmFjdHMvdHNjb25maWcuanNvblWOTUsDQQyG7/0VyxwX'
    'aWWP3kR7EKSKHyfxMCZBh04nQ5KBLaX/3Znuaukx75s8eQ6LrnPAuxwiyVO2wEndTXeocS3MyzdZ'
    'nd36dbgeBnfVuR1jidSyDSNtaLRz+kLKsTTIZT/R1CRAo5kUqjeJ3xP8EGwJHxLSSHgLQKrnDRo9'
    '2GTl47NwJrH92z7T/85ERoLoxc+P52NhtvsgzUQFmiSXvwCDnrR1G/Jj+LprFpdIm798VE0k91nT'
    'Y6tcSBAL0qmq3FXfr/qlad04Ln4BUEsBAhQAFAAAAAgAAABXXeFkwTNfAAAA3AAAABYAAAAAAAAA'
    'AAAAAKQBAAAAAHJlZmVyZW5jZS8uZW52LmV4YW1wbGVQSwECFAAUAAAACAAAAFddDfZJUikAAAAu'
    'AAAAFAAAAAAAAAAAAAAApAGTAAAAcmVmZXJlbmNlLy5naXRpZ25vcmVQSwECFAAUAAAACAAAAFdd'
    'fXFiSWQFAAAKCwAAHgAAAAAAAAAAAAAApAHuAAAAcmVmZXJlbmNlL2FjY2VwdGFuY2UtcmVjb3Jk'
    'Lm1kUEsBAhQAFAAAAAgAAABXXdijLSA1AQAAYgIAAB8AAAAAAAAAAAAAAKQBjgYAAHJlZmVyZW5j'
    'ZS9hcHBzL2FwaS9wYWNrYWdlLmpzb25QSwECFAAUAAAACAAAAFdd55r/hxIGAACoEgAAIAAAAAAA'
    'AAAAAAAApAEACAAAcmVmZXJlbmNlL2FwcHMvYXBpL3NyYy9zZXJ2ZXIudHNQSwECFAAUAAAACAAA'
    'AFdd7y8GeAoCAAByBAAALgAAAAAAAAAAAAAApAFQDgAAcmVmZXJlbmNlL2FwcHMvYXBpL3NyYy9z'
    'dGF0dXMtcmVzcG9uc2UudGVzdC50c1BLAQIUABQAAAAIAAAAV123W+LttAEAAF0DAAApAAAAAAAA'
    'AAAAAACkAaYQAAByZWZlcmVuY2UvYXBwcy9hcGkvc3JjL3N0YXR1cy1yZXNwb25zZS50c1BLAQIU'
    'ABQAAAAIAAAAV12P4ET5xQAAADkBAAAgAAAAAAAAAAAAAACkAaESAAByZWZlcmVuY2UvYXBwcy9h'
    'cGkvdHNjb25maWcuanNvblBLAQIUABQAAAAIAAAAV11SWXrJtwAAAAMBAAAdAAAAAAAAAAAAAACk'
    'AaQTAAByZWZlcmVuY2UvYXBwcy93ZWIvaW5kZXguaHRtbFBLAQIUABQAAAAIAAAAV12Q7sOC+QAA'
    'ALkBAAAfAAAAAAAAAAAAAACkAZYUAAByZWZlcmVuY2UvYXBwcy93ZWIvcGFja2FnZS5qc29uUEsB'
    'AhQAFAAAAAgAAABXXZy72IzfAAAA1wEAACsAAAAAAAAAAAAAAKQBzBUAAHJlZmVyZW5jZS9hcHBz'
    'L3dlYi9zcmMvYXV0aC1hY3Rpb25zLnRlc3QudHNQSwECFAAUAAAACAAAAFddAaJZr5YAAADbAAAA'
    'JgAAAAAAAAAAAAAApAH0FgAAcmVmZXJlbmNlL2FwcHMvd2ViL3NyYy9hdXRoLWFjdGlvbnMudHNQ'
    'SwECFAAUAAAACAAAAFdd8cf1JTAIAAArFgAAHgAAAAAAAAAAAAAApAHOFwAAcmVmZXJlbmNlL2Fw'
    'cHMvd2ViL3NyYy9tYWluLnRzUEsBAhQAFAAAAAgAAABXXQGI2eHRAAAAQQEAACAAAAAAAAAAAAAA'
    'AKQBOiAAAHJlZmVyZW5jZS9hcHBzL3dlYi90c2NvbmZpZy5qc29uUEsBAhQAFAAAAAgAAABXXc4c'
    'ENdsAQAAiAIAACEAAAAAAAAAAAAAAKQBSSEAAHJlZmVyZW5jZS9hcHBzL3dlYi92aXRlLmNvbmZp'
    'Zy50c1BLAQIUABQAAAAIAAAAV12ldYRutAIAABUIAAAoAAAAAAAAAAAAAACkAfQiAAByZWZlcmVu'
    'Y2UvZGF0YWJhc2UvMDAxX3JlYWRpbmdfaXRlbXMuc3FsUEsBAhQAFAAAAAgAAABXXVRfXfXKSgAA'
    'c2YBABsAAAAAAAAAAAAAAKQB7iUAAHJlZmVyZW5jZS9wYWNrYWdlLWxvY2suanNvblBLAQIUABQA'
    'AAAIAAAAV10uPRS7GwEAANYCAAAWAAAAAAAAAAAAAACkAfFwAAByZWZlcmVuY2UvcGFja2FnZS5q'
    'c29uUEsBAhQAFAAAAAgAAABXXRqLtgbqAAAA1wEAACkAAAAAAAAAAAAAAKQBQHIAAHJlZmVyZW5j'
    'ZS9wYWNrYWdlcy9jb250cmFjdHMvcGFja2FnZS5qc29uUEsBAhQAFAAAAAgAAABXXROSZBxBAQAA'
    'FgMAADIAAAAAAAAAAAAAAKQBcXMAAHJlZmVyZW5jZS9wYWNrYWdlcy9jb250cmFjdHMvc3JjL2Nv'
    'bnRyYWN0cy50ZXN0LnRzUEsBAhQAFAAAAAgAAABXXTaAZaJHAQAA/gIAACkAAAAAAAAAAAAAAKQB'
    'AnUAAHJlZmVyZW5jZS9wYWNrYWdlcy9jb250cmFjdHMvc3JjL2luZGV4LnRzUEsBAhQAFAAAAAgA'
    'AABXXSOYvgjOAAAATgEAACoAAAAAAAAAAAAAAKQBkHYAAHJlZmVyZW5jZS9wYWNrYWdlcy9jb250'
    'cmFjdHMvdHNjb25maWcuanNvblBLBQYAAAAAFgAWAOUGAACmdwAAAAA='
)
EXPECTED_FILES = {
    'reference/.env.example': 'bdd27b4cb05c986cf9a0686d52da07353d2ea78db54696d95dd96e0818fa68f2',
    'reference/.gitignore': 'a459038af144bb649dd32c98f20e160838ec500ed5580fb1669ed0860196e140',
    'reference/acceptance-record.md': 'fd22cbc3604c326f4d835fa1ca89934ce438b7e9da022efc4e2347a48e20912d',
    'reference/apps/api/package.json': '782f94adc230cb8177fd4c35f3ed42a049a88dceb17b670f62700dec8bf8f0af',
    'reference/apps/api/src/server.ts': 'e35aed31ff781c42a584105e4dd0b218d4cc895eae23b13223888e4e4e69ac7e',
    'reference/apps/api/src/status-response.test.ts': '6fc60c449dc52aeeec8353c33929cfb323e41bde604ad8366ea727650db59ab6',
    'reference/apps/api/src/status-response.ts': 'c88955e2225b673ac9aa9d650dbf6d3f1cde35929cd4ec70ca9b17ef2311aaed',
    'reference/apps/api/tsconfig.json': '1c43c49db4250f99b7ecd6ba1d542beb962ea3013f9ee0ab2f1c9cfe5e2ce1c5',
    'reference/apps/web/index.html': '620e74e3d0849e4030230a087e7b3c4598c908f5fbecd7b230f2f7a6f42d9bae',
    'reference/apps/web/package.json': 'fc3d88e763fbd21db3ca3ac451290ed7b404c6b5dddc3ad9f0138b59fcc32f08',
    'reference/apps/web/src/auth-actions.test.ts': '924be2736cb7eeae2ae186950f5edb50401e3c9e9c406a6150c5a92ef43eb4b7',
    'reference/apps/web/src/auth-actions.ts': '8e08b6b98a84ef9c5c4f8bb5af6df33c0b4214d47ba14f2d49978b6f7e90ec42',
    'reference/apps/web/src/main.ts': '305239d8b9c3eac670dbdbaa76658b3f6d5e0dfadc1cd9e02cff3181940e1586',
    'reference/apps/web/tsconfig.json': '1f41b00223b783293f2b9f1f4486070504d57635fc8ee85a04a2a58ec1c0ceb4',
    'reference/apps/web/vite.config.ts': 'caf9f30f5aa80322ee893be099d104f16376f92cc6d05b5969577b9bf5a08813',
    'reference/database/001_reading_items.sql': '50358af2e109fbcb716a3c9b471b908a22fa85bfe0bdb99e9522de0520dd3fcf',
    'reference/package-lock.json': 'f18b20bfad5155ddc3d11bb361da2956bcb7d0efefa8f5f23575e74a544b5383',
    'reference/package.json': 'a8c297bef5ce539daed702fdb3d92c1d5d576469a4fd7151dc143b8d0cb500bc',
    'reference/packages/contracts/package.json': 'fa5157673b451a101bb7f166c5518a1e9d48d32ed35af12633372e30b398a227',
    'reference/packages/contracts/src/contracts.test.ts': '56bdd39742074fec07e1c84e392fbaa74c5addf8584a5c011e278100bf7dd015',
    'reference/packages/contracts/src/index.ts': 'a17294ddf45aa7e37fd6625d837b53361a35fde39ab291204a849f360ca646d1',
    'reference/packages/contracts/tsconfig.json': '52dcc294dde8e99f4b16969e5966d74be878e11453a9aa755a335cda15eba602',
}


def sha256(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()


def checked_files() -> dict[str, bytes]:
    raw = base64.b64decode(ARCHIVE_B64, validate=True)
    if sha256(raw) != ARCHIVE_SHA256:
        raise ValueError("Embedded archive SHA-256 differs from the reviewed archive")
    files = {}
    with zipfile.ZipFile(io.BytesIO(raw)) as archive:
        infos = archive.infolist()
        if len(infos) != len(EXPECTED_FILES):
            raise ValueError("Archive member count differs from the reviewed file list")
        for info in infos:
            name = info.filename
            path = PurePosixPath(name)
            if (not name or name.startswith(("/", "\\")) or "\\" in name
                    or ":" in name.split("/")[0] or path.is_absolute()
                    or any(part in ("", ".", "..") for part in name.split("/"))
                    or info.is_dir() or stat.S_ISLNK(info.external_attr >> 16)):
                raise ValueError("Unsafe archive member path/type")
            if name not in EXPECTED_FILES or name in files:
                raise ValueError("Unexpected or duplicate archive member")
            data = archive.read(info)
            if sha256(data) != EXPECTED_FILES[name]:
                raise ValueError("Reviewed file SHA-256 mismatch: " + name)
            files[name] = data
    if set(files) != set(EXPECTED_FILES):
        raise ValueError("Reviewed file list mismatch")
    return files


def main() -> int:
    if len(sys.argv) != 2:
        print("Usage: python3 restore_reviewed_source.py ABSOLUTE_NEW_DIRECTORY", file=sys.stderr)
        return 2
    target = Path(sys.argv[1])
    if (not target.is_absolute() or target.name in ("", ".", "..")
            or (sys.platform == "win32" and (len(target.drive) != 2 or target.drive[1] != ":"))
            or (sys.platform != "win32" and target.anchor != "/")):
        print("Give one absolute path for a NEW output directory", file=sys.stderr)
        return 2
    try:
        parent = target.parent.resolve(strict=True)
        if parent != target.parent or not parent.is_dir():
            raise ValueError("Output parent must be an existing, direct directory without symlink traversal")
        if target.exists() or target.is_symlink():
            raise FileExistsError("Output directory already exists; nothing was changed")
        files = checked_files()  # Validate archive, names, types and every byte before any write.
        target.mkdir(mode=0o700, parents=False, exist_ok=False)
        root = target.resolve(strict=True)
        if root != target or root.parent != parent:
            raise ValueError("Created output resolved outside the explicit parent")
        for name in sorted(files):
            destination = root.joinpath(*PurePosixPath(name).parts)
            destination.parent.mkdir(parents=True, exist_ok=True)
            verified_parent = destination.parent.resolve(strict=True)
            if not verified_parent.is_relative_to(root):
                raise ValueError("Output path escaped the new directory")
            with destination.open("xb") as stream:  # No overwrite, including a symlink.
                stream.write(files[name])
            if sha256(destination.read_bytes()) != EXPECTED_FILES[name]:
                raise ValueError("Written file did not match reviewed bytes: " + name)
        print(f"Created {len(files)} verified source files in {root}")
        print(f"Reviewed embedded ZIP SHA-256: {ARCHIVE_SHA256}")
        print("Source only: no install, app execution, migration or deployment was performed.")
        return 0
    except (OSError, ValueError, zipfile.BadZipFile) as error:
        print(f"Stopped: {error}", file=sys.stderr)
        print("If a new directory was partly created, inspect it; this script never cleans it up or overwrites it.", file=sys.stderr)
        return 1


if __name__ == "__main__":
    raise SystemExit(main())

Sources & further reading