mirror of
git://f0xx.org/android_cast
synced 2026-07-29 05:37:52 +03:00
sync
This commit is contained in:
357
docs/DRs/20100611_3_url_shortener.md
Normal file
357
docs/DRs/20100611_3_url_shortener.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# URL shortener service — design review (DR)
|
||||
|
||||
**Document type:** DR (Design Review)
|
||||
**Source draft:** [docs/drafts/20100611_3_url_shortener.txt](../drafts/20100611_3_url_shortener.txt)
|
||||
**Specification:** [docs/specs/20100611_3_url_shortener.md](../specs/20100611_3_url_shortener.md)
|
||||
**Date:** 2026-06-11
|
||||
**Status:** Reviewed — ready for post-alpha implementation planning
|
||||
**Severity:** Medium
|
||||
|
||||
**Documentation index:** [README.md](../README.md)
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- toc -->
|
||||
- [1. Executive summary](#1-executive-summary)
|
||||
- [2. Resolved open questions](#2-resolved-open-questions)
|
||||
- [3. Authentication and trust](#3-authentication-and-trust)
|
||||
- [3.1 Bearer token](#31-bearer-token)
|
||||
- [3.2 Signer](#32-signer)
|
||||
- [3.3 Shared session (operators)](#33-shared-session-operators)
|
||||
- [3.4 Trust flow (normative)](#34-trust-flow-normative)
|
||||
- [4. Slug algorithm](#4-slug-algorithm)
|
||||
- [4.1 Decision: SHA-256 truncated](#41-decision-sha-256-truncated)
|
||||
- [4.2 Collision policy](#42-collision-policy)
|
||||
- [4.3 Draft example (preserved for comparison)](#43-draft-example-preserved-for-comparison)
|
||||
- [5. API and flow corrections](#5-api-and-flow-corrections)
|
||||
- [6. Data store](#6-data-store)
|
||||
- [7. Deployment and infra](#7-deployment-and-infra)
|
||||
- [8. QR codes](#8-qr-codes)
|
||||
- [9. Security model](#9-security-model)
|
||||
- [10. Integration with androidcast](#10-integration-with-androidcast)
|
||||
- [11. Estimates](#11-estimates)
|
||||
- [12. Task dependency graph](#12-task-dependency-graph)
|
||||
- [13. Suggestions (PO / dev discretion)](#13-suggestions-po-dev-discretion)
|
||||
- [14. Remaining open items](#14-remaining-open-items)
|
||||
- [15. Changelog](#15-changelog)
|
||||
<!-- /toc -->
|
||||
|
||||
**Documentation index:** [README.md](README.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive summary
|
||||
|
||||
The draft defines a **standalone URL shortener** at `https://s.f0xx.org`, separate from the crash-reporter BE app, with bearer/signer trust, TTL/permalinks, QR support, and a JSON shorten API.
|
||||
|
||||
**DR outcome:**
|
||||
|
||||
| Area | Decision |
|
||||
|------|----------|
|
||||
| Priority | **Post-alpha**; medium severity; may move up if BE load stays low |
|
||||
| Slug hash | **SHA-256 truncated (12 hex)** — reject draft interleave + Java `hashCode` |
|
||||
| Auth | **Bearer tokens** for API; **signer** for permanent TTL; operator **session RBAC** only for token admin UI |
|
||||
| Placement | Submodule `backend/url-shortener`; dedicated nginx vhost; **opt-in** deploy |
|
||||
| Stack | PHP + nginx + MariaDB per draft |
|
||||
| OpenAPI | **Required** in v1 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Resolved open questions
|
||||
|
||||
Questions from draft §“TBD and open questions list” and inline `TBD` markers.
|
||||
|
||||
| # | Draft question / gap | DR answer |
|
||||
|---|----------------------|-----------|
|
||||
| Q1 | Token signing, trust models, sessions, security | See [§3](#3-authentication-and-trust) and [§9](#9-security-model). Machine clients use **bearer** (+ optional **signer**). Humans use existing BE session only to **mint** bearers. Optional HMAC for GET left as [suggestion](#13-suggestions-po-dev-discretion). |
|
||||
| Q2 | `... TBD — open part` | Filled in SPEC: audit log, rate limits, SSRF blocklist, normalization rules, collision policy, admin tables, smoke tests. |
|
||||
| Q3 | Database `*... TBD` columns | Full schema in [SPEC §9](../specs/20100611_3_url_shortener.md#9-database-schema): `origin_hash`, `expires_at`, `access_count`, FK tables for bearer/signer. |
|
||||
| Q4 | Java hash vs SHA-256 | **SHA-256** (see [§4](#4-slug-algorithm)). Java hash is 32-bit, non-cryptographic, JVM-stable but poor for URL slugs. |
|
||||
| Q5 | Interleaved URL+TOKEN string | **Rejected** for production. Deterministic `SHA256(bearer_id ‖ normalized_url)` instead. Draft interleave kept as historical note only. |
|
||||
| Q6 | Authentication: “app-wide shared session, project-wise token” | **Split roles:** `curl`/services → **project bearer token**; console operators → **shared `ac_crash_sess`** to create/revoke tokens (same RBAC as crashes/tickets). Shorten API does **not** accept PHP session cookies. |
|
||||
| Q7 | Submodule remote “available soon” | Track as [open item](#14-remaining-open-items); scaffold in monorepo path first, push to `git://f0xx.org/androidcast_project/url-shortener` before prod. |
|
||||
| Q8 | OTA-style “invalid URL” on unrelated services | N/A here; shorten service validates URL scheme/host and returns `INVALID_URL`. |
|
||||
| Q9 | Step 9.1.1 / 9.1.2 trusted sub-capabilities | `can_temporary` on bearer; `can_permanent` on bearer **and** valid signer required for `ttl=0`. |
|
||||
| Q10 | Cached hit when TTL “exceeds given limits” | If stored link **expired** → error `TTL_EXPIRED`, not silent renew. If valid → return same slug with **remaining** `ttl` in response (draft step 8). |
|
||||
| Q11 | Estimations (draft empty) | See [§11](#11-estimates). |
|
||||
|
||||
---
|
||||
|
||||
## 3. Authentication and trust
|
||||
|
||||
### 3.1 Bearer token
|
||||
|
||||
- Opaque string (≥32 chars random), stored as **SHA-256 hash** in `bearer_tokens`.
|
||||
- **`trusted=1`** required to **create** new links (draft steps 6–7).
|
||||
- **Demo token:** single `trusted=0` token that can only resolve existing slugs in docs/examples — cannot create (403).
|
||||
|
||||
### 3.2 Signer
|
||||
|
||||
- Separate long-lived secret for **elevated** operations.
|
||||
- Required when `ttl=0` (permanent permalink).
|
||||
- Validated against `signer_keys` where `can_permanent=1` and not revoked.
|
||||
|
||||
### 3.3 Shared session (operators)
|
||||
|
||||
- Small PHP admin page under url-shortener **or** a tab in crashes console (suggestion) protected by existing login.
|
||||
- Actions: create bearer, revoke bearer, list links for bearer, purge expired.
|
||||
- Uses same RBAC roles as [REMOTE_ACCESS_IMPL](../REMOTE_ACCESS_IMPL.md) pattern (`admin`, `operator`).
|
||||
|
||||
### 3.4 Trust flow (normative)
|
||||
|
||||
Matches draft low-level flow with SPEC clarifications:
|
||||
|
||||
```text
|
||||
Request → bearer present? ─no→ 401 MISSING_BEARER
|
||||
→ lookup (bearer, url)
|
||||
→ hit & valid TTL → 200 cached (remaining ttl)
|
||||
→ hit & expired → 409 TTL_EXPIRED
|
||||
→ miss → bearer trusted? ─no→ 403 ACCESS_DENIED
|
||||
→ ttl=0 → signer ok? ─no→ 403 SIGNER_REQUIRED
|
||||
→ compute slug, insert, return 200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Slug algorithm
|
||||
|
||||
### 4.1 Decision: SHA-256 truncated
|
||||
|
||||
**Chosen:**
|
||||
|
||||
```text
|
||||
slug = hex(SHA256(bearer_id + "\x1f" + normalized_url))[0:12]
|
||||
```
|
||||
|
||||
| Criterion | Java `hashCode` + interleave (draft) | SHA-256 truncated (chosen) |
|
||||
|-----------|--------------------------------------|----------------------------|
|
||||
| Collision resistance | Poor (~32 bits) | ~48 bits with 12 hex chars |
|
||||
| Determinism | JVM-specified but weak | Standard crypto |
|
||||
| Reversibility | No (good) | No (good) |
|
||||
| Debuggability | Opaque interleave | Simple test vectors |
|
||||
|
||||
### 4.2 Collision policy
|
||||
|
||||
- Unique index on `slug`.
|
||||
- On duplicate insert: append `-1`…`-f` (4 chars max) **or** re-hash with `:\x1e{counter}` appended to material.
|
||||
- Log collision to `audit_log` at `WARN` level.
|
||||
|
||||
### 4.3 Draft example (preserved for comparison)
|
||||
|
||||
Draft interleaved `https://t.co` + token → `htta5bpesf:4/3/3td.2c3oa` → Java hash or SHA slice `4623b436f`.
|
||||
**Do not implement interleave** — kept only to show original intent (per-token namespacing). Namespacing is achieved via `bearer_id` in hash input instead.
|
||||
|
||||
---
|
||||
|
||||
## 5. API and flow corrections
|
||||
|
||||
| Draft item | Correction |
|
||||
|------------|------------|
|
||||
| `GET https://s.f0xx.org?url=...` | Use **`/api/v1/shorten`** path so root `/{slug}` stays redirect-only |
|
||||
| Response `ttl` as string | Keep string in JSON for draft compatibility; document integer seconds |
|
||||
| `signer` on GET | Optional query param; omit from success body (security) |
|
||||
| Fail body echoes `bearer` | Truncate in response to first 6 + `…` in production logs; full echo in JSON only for client debugging (SPEC) |
|
||||
|
||||
**Routing suggestion:** nginx sends `/api/` → PHP front controller; `^~ /[a-f0-9]{6,16}$` → redirect handler.
|
||||
|
||||
---
|
||||
|
||||
## 6. Data store
|
||||
|
||||
| Option | Pros | Cons | DR pick |
|
||||
|--------|------|------|---------|
|
||||
| A. Same MariaDB instance, new schema `url_shortener` | Simple ops, one backup | Shared failure domain | **Recommended v1** |
|
||||
| B. Separate MariaDB database | Blast radius isolation | More admin | If PO wants hard isolation |
|
||||
| C. SQLite on BE | Zero MariaDB migration | Poor fit for BE pattern | **Reject** |
|
||||
|
||||
Retention cron: `scripts/purge_url_shortener.php` (mirror `purge_remote_access.php` style) — delete expired rows + audit >90d.
|
||||
|
||||
---
|
||||
|
||||
## 7. Deployment and infra
|
||||
|
||||
Per [INFRA.md](../INFRA.md) topology:
|
||||
|
||||
```text
|
||||
Internet → FE (s.f0xx.org TLS) → proxy_pass BE :80 → url-shortener php-fpm
|
||||
```
|
||||
|
||||
| Step | Owner | Notes |
|
||||
|------|-------|-------|
|
||||
| DNS `s.f0xx.org` → FE | PO / infra | **Open** — see §14 |
|
||||
| FE nginx `server_name s.f0xx.org` | DEV | Mirror `apps.f0xx.org` TLS pattern |
|
||||
| BE `url-shortener.conf` | DEV | Repo under `examples/` or submodule `deploy/nginx/` |
|
||||
| Submodule init | DEV | `scripts/init-third-party-submodules.sh` update |
|
||||
| Licenses | DEV | Add QR library to BE license inventory |
|
||||
|
||||
**Safe deploy:** nginx fragment only; no topology changes to router/FE↔BE path. Validate with `nginx -t` before reload.
|
||||
|
||||
**Not alpha-blocking:** omit from `validate_be_services.sh` until first deploy.
|
||||
|
||||
---
|
||||
|
||||
## 8. QR codes
|
||||
|
||||
| Decision | Detail |
|
||||
|----------|--------|
|
||||
| Must-have | Yes (draft) |
|
||||
| Format | PNG via `/api/v1/qr/{slug}.png` |
|
||||
| Library | `endroid/qr-code` (MIT) — **suggestion**; PO approves license addition |
|
||||
| Inline in JSON | Optional `qr` URL field in shorten success — **suggestion** for v1.1 |
|
||||
|
||||
---
|
||||
|
||||
## 9. Security model
|
||||
|
||||
| Threat | Mitigation |
|
||||
|--------|------------|
|
||||
| Token leak | Revoke bearer; rotate signer; rate limit |
|
||||
| SSRF via shorten | Block private/metadata IPs at validation |
|
||||
| Slug enumeration | 48+ bits entropy; rate limit redirects (suggestion) |
|
||||
| Open redirect abuse | Only whitelisted bearers create links |
|
||||
| Session fixation | N/A — API is stateless |
|
||||
|
||||
**Trust model summary:**
|
||||
|
||||
```text
|
||||
┌─────────────────┐
|
||||
│ Operator (web) │
|
||||
│ ac_crash_sess │
|
||||
└────────┬────────┘
|
||||
│ mint/revoke
|
||||
▼
|
||||
┌─────────────────┐
|
||||
signer ───────►│ bearer_tokens │◄────── curl / services
|
||||
(permanent) └────────┬────────┘
|
||||
│ trusted create
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ links │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Integration with androidcast
|
||||
|
||||
| Consumer | Use case | When |
|
||||
|----------|----------|------|
|
||||
| BE remote-access UI | Short “open session” links for operators | Post-alpha |
|
||||
| OTA / docs | Stable short links in printed QR | Post-alpha |
|
||||
| Android app | None v1 — use HTTPS from BE | Deferred |
|
||||
| Crash reporter | **No** embed — standalone service | Normative |
|
||||
|
||||
Submodule lives beside `examples/crash_reporter/backend/` conceptually but **not** inside it.
|
||||
|
||||
---
|
||||
|
||||
## 11. Estimates
|
||||
|
||||
Engineering person-days (single DEV, familiar with BE stack):
|
||||
|
||||
| Task | Days |
|
||||
|------|------|
|
||||
| Repo scaffold + OpenAPI + DB migrations | 1.5 |
|
||||
| Shorten API + auth + TTL logic | 2 |
|
||||
| Redirect handler + permalink cache | 1 |
|
||||
| QR endpoint + license | 0.5 |
|
||||
| Admin token UI (minimal) | 1.5 |
|
||||
| nginx FE/BE fragments + deploy doc | 1 |
|
||||
| PHPUnit + smoke script | 1 |
|
||||
| **Total** | **~8.5 days** |
|
||||
|
||||
**Severity:** Medium — no alpha path dependency.
|
||||
|
||||
**Reorder triggers (PO):** high demand for shareable debug links; BE CPU <50%; remote-access operator UX needs short URLs.
|
||||
|
||||
---
|
||||
|
||||
## 12. Task dependency graph
|
||||
|
||||
Legend: **1** = highest priority within this feature.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
T1["1. Submodule scaffold + openapi.yaml"]
|
||||
T2["2. MariaDB schema + migrations"]
|
||||
T3["3. Bearer/signer auth layer"]
|
||||
T4["4. Shorten API (POST/GET)"]
|
||||
T5["5. Redirect /{slug} + TTL"]
|
||||
T6["6. QR PNG endpoint"]
|
||||
T7["7. Admin token UI (RBAC)"]
|
||||
T8["8. nginx FE/BE + DNS s.f0xx.org"]
|
||||
T9["9. Tests + smoke + licenses"]
|
||||
|
||||
T1 --> T2
|
||||
T2 --> T3
|
||||
T3 --> T4
|
||||
T4 --> T5
|
||||
T4 --> T6
|
||||
T3 --> T7
|
||||
T5 --> T8
|
||||
T4 --> T9
|
||||
T6 --> T9
|
||||
T7 --> T9
|
||||
T8 --> T9
|
||||
```
|
||||
|
||||
| # | Task | Blocker | Assignee |
|
||||
|---|------|---------|----------|
|
||||
| 1 | Submodule + OpenAPI | — | DEV |
|
||||
| 2 | Schema | 1 | DEV |
|
||||
| 3 | Auth | 2 | DEV |
|
||||
| 4 | Shorten API | 3 | DEV |
|
||||
| 5 | Redirect | 4 | DEV |
|
||||
| 6 | QR | 4 | DEV |
|
||||
| 7 | Admin UI | 3 | DEV |
|
||||
| 8 | Infra deploy | 5, PO DNS | DEV + PO |
|
||||
| 9 | Tests/licenses | 4–7 | DEV |
|
||||
|
||||
---
|
||||
|
||||
## 13. Suggestions (PO / dev discretion)
|
||||
|
||||
Items intentionally **not** frozen in SPEC — recommended but optional:
|
||||
|
||||
1. **HMAC signed GET** — `&sig=HMAC-SHA256(url|ttl, bearer_secret)` to prevent query tampering on shared links; skip for v1 if all clients use POST.
|
||||
2. **Console integration** — add “Short links” card to hub nav next to Remote access instead of separate admin skin.
|
||||
3. **Response field `qr`** — include ready-made QR URL in shorten JSON.
|
||||
4. **Click analytics** — increment `access_count` only (already in schema); defer graphs to Grafana/nginx logs.
|
||||
5. **Custom slug** — `&alias=` for operators; increases collision/abuse risk — post-v1.
|
||||
6. **Separate PHP-FPM pool** — if redirect traffic is high; share pool initially.
|
||||
7. **FE rate limit** — `limit_req` on `/api/v1/shorten` at nginx.
|
||||
8. **Draft demo token** — ship `examples/url-shortener/demo_curl.sh` with documented read-only token for CI smoke.
|
||||
9. **PDF export** — run `python3 docs/_pdf_build/md_to_pdf.py` on SPEC+DR when PO wants signed-off copies.
|
||||
10. **Atomic commits on `next`** — per [bottomline_reminder.txt](../../bottomline_reminder.txt): one commit per task row above for easy revert.
|
||||
|
||||
---
|
||||
|
||||
## 14. Remaining open items
|
||||
|
||||
Requires PO / infra input (hard blockers for **prod** only):
|
||||
|
||||
| ID | Item | Owner |
|
||||
|----|------|-------|
|
||||
| O1 | Create git remote `git://f0xx.org/androidcast_project/url-shortener` | PO |
|
||||
| O2 | DNS + TLS cert for `s.f0xx.org` on FE | PO / infra |
|
||||
| O3 | Confirm BE docroot path (`/var/www/.../apps/s/` vs subdomain root) | DEV + PO |
|
||||
| O4 | Approve QR library license addition | PO |
|
||||
| O5 | First production bearer token issuance policy | PO |
|
||||
|
||||
Soft blockers — DEV can proceed on `next` with local MariaDB and hosts-file testing without O1–O2.
|
||||
|
||||
---
|
||||
|
||||
## 15. Changelog
|
||||
|
||||
| Date | Rev | Change |
|
||||
|------|-----|--------|
|
||||
| 2026-06-11 | 1 | Draft → SPEC + DR; resolved hash, auth, schema, API paths; task graph + estimates |
|
||||
|
||||
**Source linkage:** [docs/drafts/20100611_3_url_shortener.txt](../drafts/20100611_3_url_shortener.txt)
|
||||
503
docs/DRs/20100611_3_url_shortener.pdf
Normal file
503
docs/DRs/20100611_3_url_shortener.pdf
Normal file
@@ -0,0 +1,503 @@
|
||||
%PDF-1.4
|
||||
%“Œ‹ž ReportLab Generated PDF document (opensource)
|
||||
1 0 obj
|
||||
<<
|
||||
/F1 2 0 R /F2 3 0 R /F3 26 0 R /F4 28 0 R /F5 33 0 R /F6 34 0 R
|
||||
>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 37 0 R /Fit ] /Rect [ 45.68504 716.2874 124.373 727.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 37 0 R /Fit ] /Rect [ 45.68504 705.2874 144.405 716.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 37 0 R /Fit ] /Rect [ 45.68504 694.2874 138.629 705.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 37 0 R /Fit ] /Rect [ 59.68504 683.8499 115.1325 693.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 59.68504 673.8499 93.87004 683.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
9 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 59.68504 663.8499 162.645 673.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
10 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 59.68504 653.8499 144.705 663.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
11 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 45.68504 643.2874 105.709 654.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
12 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 59.68504 632.8499 168.9 642.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
13 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 59.68504 622.8499 121.785 632.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
14 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 59.68504 612.8499 210.9825 622.8499 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
15 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 45.68504 602.2874 140.837 613.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
16 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 45.68504 591.2874 91.48504 602.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
17 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 45.68504 580.2874 130.613 591.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
18 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 45.68504 569.2874 90.14904 580.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
19 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 45.68504 558.2874 107.485 569.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
20 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 45.68504 547.2874 156.853 558.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
21 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 45.68504 536.2874 94.14904 547.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
22 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 40 0 R /Fit ] /Rect [ 45.68504 525.2874 144.853 536.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
23 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 40 0 R /Fit ] /Rect [ 45.68504 514.2874 178.189 525.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
24 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 40 0 R /Fit ] /Rect [ 45.68504 503.2874 138.613 514.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
25 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 41 0 R /Fit ] /Rect [ 45.68504 492.2874 97.71704 503.2874 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
26 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
27 0 obj
|
||||
<<
|
||||
/Annots [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R
|
||||
14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R
|
||||
24 0 R 25 0 R ] /Contents 68 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 67 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0
|
||||
/Trans <<
|
||||
|
||||
>> /Type /Page
|
||||
>>
|
||||
endobj
|
||||
28 0 obj
|
||||
<<
|
||||
/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
29 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 37 0 R /Fit ] /Rect [ 391.5722 464.1984 399.3562 472.5984 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
30 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 414.9242 464.1984 422.7082 472.5984 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
31 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 40 0 R /Fit ] /Rect [ 424.2482 437.1984 458.1002 445.5984 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
32 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 38 0 R /Fit ] /Rect [ 423.4642 362.1984 431.2482 370.5984 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
33 0 obj
|
||||
<<
|
||||
/BaseFont /ZapfDingbats /Name /F5 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
34 0 obj
|
||||
<<
|
||||
/BaseFont /Symbol /Name /F6 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
35 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 40 0 R /Fit ] /Rect [ 405.9572 242.1984 436.6942 250.5984 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
36 0 obj
|
||||
<<
|
||||
/Border [ 0 0 0 ] /Contents () /Dest [ 39 0 R /Fit ] /Rect [ 391.5722 136.1984 403.2482 144.5984 ] /Subtype /Link /Type /Annot
|
||||
>>
|
||||
endobj
|
||||
37 0 obj
|
||||
<<
|
||||
/Annots [ 29 0 R 30 0 R 31 0 R 32 0 R 35 0 R 36 0 R ] /Contents 69 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 67 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0
|
||||
/Trans <<
|
||||
|
||||
>> /Type /Page
|
||||
>>
|
||||
endobj
|
||||
38 0 obj
|
||||
<<
|
||||
/Contents 70 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 67 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
39 0 obj
|
||||
<<
|
||||
/Contents 71 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 67 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
40 0 obj
|
||||
<<
|
||||
/Contents 72 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 67 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
41 0 obj
|
||||
<<
|
||||
/Contents 73 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 67 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
42 0 obj
|
||||
<<
|
||||
/Outlines 44 0 R /PageMode /UseNone /Pages 67 0 R /Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
43 0 obj
|
||||
<<
|
||||
/Author (Android Cast project) /CreationDate (D:20260611175416+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260611175416+02'00') /Producer (ReportLab PDF Library - \(opensource\))
|
||||
/Subject (\(unspecified\)) /Title (URL shortener service \204 design review \(DR\)) /Trapped /False
|
||||
>>
|
||||
endobj
|
||||
44 0 obj
|
||||
<<
|
||||
/Count 24 /First 45 0 R /Last 66 0 R /Type /Outlines
|
||||
>>
|
||||
endobj
|
||||
45 0 obj
|
||||
<<
|
||||
/Dest [ 37 0 R /Fit ] /Next 46 0 R /Parent 44 0 R /Title (1. Executive summary)
|
||||
>>
|
||||
endobj
|
||||
46 0 obj
|
||||
<<
|
||||
/Dest [ 37 0 R /Fit ] /Next 47 0 R /Parent 44 0 R /Prev 45 0 R /Title (2. Resolved open questions)
|
||||
>>
|
||||
endobj
|
||||
47 0 obj
|
||||
<<
|
||||
/Count 4 /Dest [ 37 0 R /Fit ] /First 48 0 R /Last 51 0 R /Next 52 0 R /Parent 44 0 R
|
||||
/Prev 46 0 R /Title (3. Authentication and trust)
|
||||
>>
|
||||
endobj
|
||||
48 0 obj
|
||||
<<
|
||||
/Dest [ 37 0 R /Fit ] /Next 49 0 R /Parent 47 0 R /Title (3.1 Bearer token)
|
||||
>>
|
||||
endobj
|
||||
49 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Next 50 0 R /Parent 47 0 R /Prev 48 0 R /Title (3.2 Signer)
|
||||
>>
|
||||
endobj
|
||||
50 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Next 51 0 R /Parent 47 0 R /Prev 49 0 R /Title (3.3 Shared session \(operators\))
|
||||
>>
|
||||
endobj
|
||||
51 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Parent 47 0 R /Prev 50 0 R /Title (3.4 Trust flow \(normative\))
|
||||
>>
|
||||
endobj
|
||||
52 0 obj
|
||||
<<
|
||||
/Count 3 /Dest [ 38 0 R /Fit ] /First 53 0 R /Last 55 0 R /Next 56 0 R /Parent 44 0 R
|
||||
/Prev 47 0 R /Title (4. Slug algorithm)
|
||||
>>
|
||||
endobj
|
||||
53 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Next 54 0 R /Parent 52 0 R /Title (4.1 Decision: SHA-256 truncated)
|
||||
>>
|
||||
endobj
|
||||
54 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Next 55 0 R /Parent 52 0 R /Prev 53 0 R /Title (4.2 Collision policy)
|
||||
>>
|
||||
endobj
|
||||
55 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Parent 52 0 R /Prev 54 0 R /Title (4.3 Draft example \(preserved for comparison\))
|
||||
>>
|
||||
endobj
|
||||
56 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Next 57 0 R /Parent 44 0 R /Prev 52 0 R /Title (5. API and flow corrections)
|
||||
>>
|
||||
endobj
|
||||
57 0 obj
|
||||
<<
|
||||
/Dest [ 38 0 R /Fit ] /Next 58 0 R /Parent 44 0 R /Prev 56 0 R /Title (6. Data store)
|
||||
>>
|
||||
endobj
|
||||
58 0 obj
|
||||
<<
|
||||
/Dest [ 39 0 R /Fit ] /Next 59 0 R /Parent 44 0 R /Prev 57 0 R /Title (7. Deployment and infra)
|
||||
>>
|
||||
endobj
|
||||
59 0 obj
|
||||
<<
|
||||
/Dest [ 39 0 R /Fit ] /Next 60 0 R /Parent 44 0 R /Prev 58 0 R /Title (8. QR codes)
|
||||
>>
|
||||
endobj
|
||||
60 0 obj
|
||||
<<
|
||||
/Dest [ 39 0 R /Fit ] /Next 61 0 R /Parent 44 0 R /Prev 59 0 R /Title (9. Security model)
|
||||
>>
|
||||
endobj
|
||||
61 0 obj
|
||||
<<
|
||||
/Dest [ 39 0 R /Fit ] /Next 62 0 R /Parent 44 0 R /Prev 60 0 R /Title (10. Integration with androidcast)
|
||||
>>
|
||||
endobj
|
||||
62 0 obj
|
||||
<<
|
||||
/Dest [ 39 0 R /Fit ] /Next 63 0 R /Parent 44 0 R /Prev 61 0 R /Title (11. Estimates)
|
||||
>>
|
||||
endobj
|
||||
63 0 obj
|
||||
<<
|
||||
/Dest [ 40 0 R /Fit ] /Next 64 0 R /Parent 44 0 R /Prev 62 0 R /Title (12. Task dependency graph)
|
||||
>>
|
||||
endobj
|
||||
64 0 obj
|
||||
<<
|
||||
/Dest [ 40 0 R /Fit ] /Next 65 0 R /Parent 44 0 R /Prev 63 0 R /Title (13. Suggestions \(PO / dev discretion\))
|
||||
>>
|
||||
endobj
|
||||
65 0 obj
|
||||
<<
|
||||
/Dest [ 40 0 R /Fit ] /Next 66 0 R /Parent 44 0 R /Prev 64 0 R /Title (14. Remaining open items)
|
||||
>>
|
||||
endobj
|
||||
66 0 obj
|
||||
<<
|
||||
/Dest [ 41 0 R /Fit ] /Parent 44 0 R /Prev 65 0 R /Title (15. Changelog)
|
||||
>>
|
||||
endobj
|
||||
67 0 obj
|
||||
<<
|
||||
/Count 6 /Kids [ 27 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R ] /Type /Pages
|
||||
>>
|
||||
endobj
|
||||
68 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1045
|
||||
>>
|
||||
stream
|
||||
Gatn&>>O95&;B$;(%YO._Sja-]E&0f'%0+9IB/%6M48f_lsM1Err%j]0"Zp.#$I5F._#"\4?bs+&E/C^^T.k&UkHX,$C!ie!h,2Rb"F]Ep[7b=e!3KsZ6G8@aRboinMJ)Zn2,t/(8imKGa_'H!@1Io1ne<G4a\T)Oia<`:kA^BSHNFt@*2$3YWThpAIXiqo1Q<'D$H\e!@uA`<W\SGj\Q=8)[/]IUpu3AA2[f_mmHmib&;7gmphIU)F*\QB9]3qjCq#[)25Q7DolLPmb"Lc$*6n_%UAkj5')/QQKEi8q%i>q$Y&sQJUbpYoMTf)>4bD.J$f@M$7`0>IBXcCfFjh.O.Y`=D!OR"lBK*;K;cdUD?SUslaV64!/TW2!0"]u=P[j_%D!>_mRCUiWKfso12O?`(bpU%EEH`LA]:3&E)je`7QYj6'VFQ]$*_0JRA@H,IY+84,.PHQ*qZR2*X$b%!X9%&1W"BMB;)_C=KM&[CRiAp]!5@4YVch2['?f(o)V],RKsAT[0!F5mJK^ndr@<X]P*J3\Ac'cRLiT.@fsA\[#r8;o2,I==++&+"FG2:.d=t7#Su<Y%p5:2M5"tGLtVreKa)"*WnV\i"MJ\ajl'Sb%8@GPbja-_idl;:3r3mF)r[)+m,O?hB^]6QNO2l72,+d=C75j=mHS0HBA<-^Zn\<G[+MaQL>p8[bkSuii\VDlb'=Rk3CdZ.\,*?sJ);#.Wg2Na$s=X/Tce;;a4b#=n^("::qBT4$s_];/KUTQp!uJNs+Q=H&V1=K23$9@WqU11D?,W]FiAd[ehdl'F^3S8Ck:1)2$ba8aJ"uA8oAQ%M.4E&KrQ0p9@C",-toiD6S[XQ`hn%(=6NI^5N!*@2Gd%N);u)&QkMs\?qcF#IiXkJWb*%IjWHUFiCTo_*0R$bT!#V=7&q7;jWYic/a.]Y#>'rVjO49>f\+2]FuB^kRS"P#MeEg`_K?OLN2F:6g$Fg'hX,CNcIS\SlINhc2Rd@AE&B]^\+('M_Q`/)`r*Qk>OgJkN8cEaa9nPNadZ@e]g"mH>Y4~>endstream
|
||||
endobj
|
||||
69 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3816
|
||||
>>
|
||||
stream
|
||||
Gatm>=`^(T&q801kc4NS,Sji&Ju$\E'0@Seal5bPe9u;$C(+U/(]e&1[a2.l4i<:^SQe^\T\4X;rONpOAGdk8?[E=Q@1A,j$7IC*mm5>I*S+TVI/W?^.j^[a0."M@auZUt;d*q%NpCX$(FmC1WjIHP*Yb#lJ&NF.0_pI/pdA>RSHX2BVg]'EF%G3%L@n>^Y*_)!ZYR(ASPeNeICQ-ZQTj9?(3A&F3&+M0Bd7;&9(GU]\d=P@VVjl'5!G^]$#I$]6YrI=MC]^(ZI(R%jDEO%LgoYu8;a&!&MtE,QS\"UUpbX=g*ChD^R[oM;gN-44!R:$Y$TDn1D1df;jC?m/fSk#)0*6*r!%d_&h!&0r)ABK"1P;AJqt'&)=E+__LTUHie9GqmQU7k=%L/3#X.2EY.kuCY@d]eda8/Vh"^]$ic!=dPPplt2+a)+'gKBAJh1Ud=m;NNEeRc`4VMpO--Ko`"N+,q#n7@m$>4mhk1AeBeb^j0S3Kk4M;87;QL+>kH60f-JMu##TN:6cdcC1LQe=>Xo\T6i!s0A31[3+c9RMV?JPY7nl`X,%:K'_.c;u3R`)"!)%b\J5Jk>_-dutJ6gW#Zq?o0,@g'HJ(_&d']`f:>Zbp+.t@j:\e%O;HYi6dO.E(<JfUBUCE3#"jhMbeBmbgu*`Mi^DTijo$j4+XGJA7<Qg3<?bn?L5k[O7,+-E-cdQNSlB,^KU+bk?Fun(ECWO4[Z\!,dABV1DeD]P/2RRZ37Q)b!D2,WnL>Q8[AhNAV.9mWg9gWUOAh+-Ba/m'\.^o$9:EW^;2u.-_DV:gZD%96QMWQfd]Xs/4)dBfm"gP9c;Sb2[B)rOm2Mt]KSf@n?&SQW2N4k>=1$FH:=;2<pX3#WLfj%lkH@tWKJDD0A?10UDZF;gXs0M!B6S;bN*!=pIM-,jCRBVgu/b#Vqn->/ZmftXm3(NZA9i]eYd<D4m[ka8)mD$4oR^<@3;/k91!Ud\^>a)E<':j1W05VG1*:>WD("tNL+HiLL+Tfegn/WMg&J(k4@hB>oMK[q1q^hPb"MTG4[6$CaC=sq"p9/ETVs\+.\un$*rPBHm+83djeZ=.K:5E["g#%CFW+TPB[3lQL\R0Hk7nLio#CaXEf:*3m\DP01/JqO?30FfttT&*%7SoIh)QDP8JdfDEq@TP%N;f:-UYG$[aU]4b>R7cJJ6Qmu&6qC1BrKDI4Hi"cOA^XkF4$X?:_d<@tc9#>X:+B&L?I2I=L.+P<5,a6VLf*ON[_6iF.Q5J^c`(4.<b+H5Kd?XG@/lHmlc\ig;0^u]+MN03TA^30"dQ_,qYT$hDgKl85Wak6p%9W?_<>XG!-e;o^fW7)so51Q?5dpIqN;5^D7W4%Ji9]?HZrV9&@eWmjJT_X$7k:;37Ns2--Q[tAcH>k*`jQ_8#qcU'qXA%m2LuXW_&3f5D#WaF[pll;jC:gUjj7O>(H?fi]<<hqgEP,=6?-<FOeOl[S:F[E+]!&\Qi=`I:9@LK$Lo$tAZ=S3W&PH7Y-;;Vr<!b??(3g(k>]bK[r(8BtBc7r1Zau"X:&D1cl.Jq>E0[&ZU@g?Ph5^;Yj-[:SE$et9SKdQ.(?;VO``sUjq2r/'Q-EP8';#LJZ#5)`_e'&c^@FGiYaMD36a0_BQ-((P*X>%i\[i.@U(-#2J9*GX?tWKGL3Js.(XT6#[8g7C&tu\(5-V@R%/(.j,tWbRaGSm"#;f_U$JYU0WMI\bOQ;[C]k#_N@9g>`_#h%jljct",q6F2HI5%1BU\9B_Zqhd4#B[')C2Mt.pjUOVJj'^8<0H8fAE0q"Tlmu*9o7bC(Qb/r6J,aZ_!>PZI\.eX^4sr1Cr+)NF9c>VC#o?$\aKY[F/fkPRu9q4769hcUG4_+CVV`jO3&0;$o(*>G,M[HH75gNIp3"Y9it6+;dlbUJL+;OmACH(&MP^:Q]f?1q,od*B2)3M.@7saD(JJ/VEJ=7h4/N4C<_2d5VCNjq^UugXLnF/F13$eoZUHLD>-j[X*(#8WnT/<fnefa;U5?#Hm38X02;=X5%`L:TikX*i%]Vo).N0+Go-uR!bYPM$fg:mbJ_^kN:q';^%5a0<cOCN'@>-&@Jusdu&-uBaIPC"4%WL%1!'^[@bW_?(,]NjA*p/HSf#a;,f\E+!i^+Zb=dV81*6&'9"#9q&)KH#s/2ED_dG4'cS$Qm!B:I.6:aKUIFSqk#:8b_!E)tP?`P<QW`dGj9:[(8^O?5IZtN^Osqd-V\&G/[NS@$4_\e,C`@5>@gC,<8Y<er^G7P8CqJ2eC+Znrk%]D=[8#f[#anKGQIfV7i<To%Z9$;;JLYM:PF=bKMFbe5RZ.b/HGeW[G?rYc1=4PHSQdP8qggu@UZX<@[LigiY'g@YrqSHb6?I15`+[!NIB+P+m/Sfmp6r'l9s0pi/Vh=>Jo*/ug7#o@)/n+kr]:&h/<9QF>D3oZ<N?t=rf!D7p5UqP;9=[s-aC4cPi.KEA`sVL#do`\&@DP(iANK[NU,Zf\#`o^YM3UaA)W]P_crbX&u6)6la)rk#K^YF+<P8F_X%a=6dK1N3;/!7W'&@M@.0BZEk:VL/ZP&KhJ9]:rnLE06tDN@Mg7_@8/TVo?&&L9+_.&_+dP$;1?&AR8a,A,R?4>P,BQ@koAQ.kC\"0SiAM%i:VLW09>fL.HM&1T(5t]f(S,M/f;N$Tp;iS2g<i/rfmTOq'fd5Oc&^#&2I^Br[]%%AhU/;.NcguH)po8QE8`YLJsauH."[XO6k9>aP\"H%3;Q:RVnf@J>`H]lPV#]>*b`d-9=u^cJ]0)d.+suOLMG^/SB!`K%piG`JZ^!r%kd6nLBG6.2Nq7&0T#&KQIY#Oma8%5P;j-*'-<bL_+8FP#34GM?s-"<IM`7H"mC)=\o5NnpP=%7rI*T1`4?K+cd=F3G[0qsB(p2]JSCKZ`%0;t>dLkVr,/d\44=R2^7rDcCm(eoWq`(-,'kd(BJ/MqWUT,"U0gW=L?>`$VsjIlI>VJ3fh3XZq?Mri+sMn**NF,=8(833J_[:7.tKFgIIV`*$9K0RpI.kA3t;B^8-%[LQ0BP!\9,R!'I$P;BUhISCWc>0q`guc0?uKOdS`ni_HBY%.9p#n_O8.(9h[o>Sk9>@`4)2$0t8p#]=CX&Ep$o-E5r5Q2hm![2hb]SItQ;f##YBf8ZcQiKnf=l+UOJM]t"o;;64Rp<YT*9PZ/a2QTV"Dkoh`Zj3TdZrfAMK=;t0YCXf?E0nlX,gO:EHapu:g(`j9Sn6Vur7J^Onl7gl%#Q-GR\47a'j^]H\E=X&>+W^K7RAO6;h![clP<qBkU19nU>rUsH]tCj=Ds#-k>U2f7Hb@TBTu2;C!/XG#@M/^@LB%>VGbS(U+PnG[g_ce/EJp1=]$V=/>tYD4oAgG`&c1![g)"2QOA3Y1s3Kie<R31JAS+#Hf5jVIp*B%WjQ*'DLnB%N1+gu0WKi[pp!N-/rAD4W9hsRDWO)[$j/=;;3O-9>=l"mXO/bSB=:E=E+h8Rjl[;O9dcfcZTBZtO(.3,E$-F?JAuAMpk8KU/`N",qb72_M,-tNae=*C,fi6L;*7a_UDQC(m;AJ<f/KRLgC9isO'd#(Mo't"CXJ./,VTIY4I4D6Gl'B`QY-e[%/pE)omV]*Q5s;[kfL3[EiHFQ[m6'"Eg9G7=Yf2*jT<(<NopXk"QDS3#*iGq]g:t*(@a,u<q3B=.C4b<:nAk3'+)b.HX#G0Z+UpR=-@6.FA5oeJI=7:!+]:nDbe3Ki?DaaQ/'Yrq2EZ%]+)/B'A.IOL8oM@0(ur0U$l(43qa5)G?D*a%=!SeZ'ADRM%"]ZsZW_`b?m%Qc<l\&A?MtClT;Y*~>endstream
|
||||
endobj
|
||||
70 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3796
|
||||
>>
|
||||
stream
|
||||
GauGdCNJ5gnp>i)cHY1)h8V9YU-rX7*QM2Zk@2Jogtp:U4V(4Q&o3A4!QpJh[(lPTi'S,GMPQcNC19O1Fr.cKI3JmZpbC:Uh?)Wk%30k5J76=>'F\3PiT;?nDdND5b/dW;4j=l:F;t(/J_%/4)u&;JDTl2?AlJ$3blS;Zrqr][%O=GJIJ=3\-:Y`\LN)i@:7CG._)YdT8D$(b:9p:(gB!*QRY<TUJB69m$"&RCqJZ&tEWlT/3D%"2&[3[2##5=0+"5L65U6UF7(A`n#U8c+-][F)=i;Hu0JUhdg_DR!bUH+39FbmpRN-&Lc-9=Q+eS:'`>$@qAr7(NN$j7B,:9qkMfkUnRL/"^(/`oi;:!V]QZ7LKA&@?t65Ih+_Vg"A+=J9kJLTVjiR!ZMi*sIFC)0_N'!Op6@?7P*<+e\mQY!speAjS,\?$65\?-1'"!hkP+rVc#ILCel^7@)4rM<3e!O;H`Da7n[LdY,f=X\jYhU?+7-6,h&[r`ZKo<pX)>GJid6p=/djn&TBJD]LN\l4$uFt.:DGYYbH*?e5gOPQm.0J4]-c0-2"I&T_s;5>@?Is2@??f6?mac+(lngT>?&!+Z!nUr*Mb::d3(AAppGL@a]S;90D!tY'nL!g$Yj_RD?<:n9U`1/.'P>])@?5\uhc%;kta.7dl`prs\eRpOkbF+G5q:&>EmNf8<G8+W(?Y<h$L*9G!;Vd&<deVMbP0]pIN9*KC6ZCq-WJnP]o`.8n'LqOdc[[fcC5IJgnFG&QnFlM@CcEKn?<gfd7.DQ0j\h45Wir4&'%uUArQ(8-['%r-GO5<%X>`15l&]9kZ:C]S@X(NZ1oma]JRpe(KO1hpQR)*s[ecLf;;U[0#`U\N;aMOXA.IYci>Hk`iP@A?;KI979N82[.#@`S25aAq,#nGTF<!/+g29Y3*\-96in8l>giR--SB]`DflIKlDTlWpMg(0g1jS!>!.(-XU?^PHl\s0@%Cj%fO"[ZmhnC&$NeX=!;[8E_f,82Af_mQpV9#h_)Q&d''QEf"4qA;$4$6&8"#p!LB)nfhi?(?+nrZ=8([.io5sokmV2<ETc9;5Eh3FnM*WGs4@Pg2s\PO&m&::Hf(46#ul=`Iq*m]UC(DR24oCse;lFnhZ=Ff6-3Cb/u]Y>AFDF_UjhcEEucbk*G&MMOOas>n&H@/#(,2Hn;7*gM;@Db'*R`:rMmi-[h)J^+URVV;Xa&"ab0=`"=OS7-[F&+%$l]0!9@#S%e$"o3lEF6(,jG$TcXP'f1RK;U$$Y44#!or`EO-$D?r?JMe#Bh?Dd5C(-)a'Tmnn_r[-Lu7t-PG2$j[e*O.\k!\8X4h80W.^1"$A3-2E0C"BOAN/^J#tM`q1qZS+?&Wn3?3q.XO?>r)#[5bb(>ga*'&ZE*THF*0,-M7Ls<V:sAt19%+$Be[%NI>Y"5n5jS/<f/D]8,2D>=qOXaUL?ZL9@A+1KoIC%n5M;3k=g^Xri+shAbViUA,@$c'%N!aaJu^@4AfAl2k#V;o_Mba!PB&fa!8LP1n<Qn2l<C;Y7LsR555LUP<U?Vk](lNoDdJJ8jFNP*coEE`B?[8B^6*l()A>M08P$sU9IWrN[Ndc=FB:87Zn^Bt]QHp\SYto((;=pa1:4.G4R-0-)9)mD=VrX++fd8`Mic#TbsLWSkF,h&1HG6d1>siVG3,7u:V.kIh&\!.Bgdq#643f8-GQ8r)jl8\B[/',#UVT`W&O&HX1Er`nAF@MLs_ei".?kU'6p>6^6r?a0o]&c52e]fW6]J#Fta4s?:WWmb\susmXd,`St"E_*PiIXI@;nQ\'_$:#X%PAX?1XLfo3:L95"$l@Y.2,RMBV32kAJGOEFYrA?P\m4]t:T_"%O+r;9/+R!lSZ5l'U,r@@O(O1BaFX?6uQ65Za0IJnM@j(j(NDJ_g"(j)or'0+,^d"/>oi$b55dFna&T22+=>arN+3aqZ^<*k`@@Si.okt]B93F*'!l-Ha<PM+Dih/I*2<(qq&"a^B3-EN/Ubeh/rf>drh2&L"M(!7#/VC4tme48QC[L0r.[OY@4>1A8-I_V<dmHOH]J\R.2=aZoG\o@csNbRR@Bfmj]FXO'C/$G@Y=1R_J)8Une9b*Y.SX^bC3$n60-1E9;`214pCaj<!Dd-dN75qf=KHW5k>EQ-!)kHt$`VYeB0QkS3$IP25KM+O#DF7G?16AWTqnGlr=63G^Ct@_o[T.a=G'CiUF&f3_H;:b5+cBQ0G$njO<[O_t#D-e_CK8<?DV[`uk%[N0b+NZej#fnBEH6GsBHA\1lg(Y"<b1*a9(a\4/lsSSY`R^I9Z?YB5.6KR`7I]/@\es&%nnH<=.5/>`OHa`rkR9'X4WGHh:\)m^/o095p+VH+&2M7qop_d1Y&U)/oMmP<$g/-I_fT&nt*img<N+B(N];+LC.WZ6pe9p!N9nf;(@og/?"A](IYUOTa"T!+Tqk&2\2jOpd;9N_%c]_R>N+b]I_2Z5nksueKU]_9e/O+-f&dt>.9+o]NEOc0[eG.o_Ln^^f9FMA";#T;,U%hSoPdQZ\Gn3jmLl_WNft"OW%_]d0/($bk<"6Rd9c6%_AOmNn$#ebfi[GlZ3ol1,VRGp47Zn#^5ZA[\pT"C9Jk15J2R&(^b,[5<W_>cb<QQn?&S<COU9I*+Ni"_'kWc^)(!clBoN+nUkhOoe_T]R2$QJK"bJDi/DOK]Am70nFKk0$RXu]!]@h*,YO2oD:t&6<7VV)*b'dL#;>$/gPmI0P<oCM_pLM&1UEdF=HQY^PL;Dm09+V>nY[o!CX\lCo!h8W:VMrE6C*<cSl%,t7BjkjRHQS0NpJN6`9O>B)A=g+5tu.WJD$eH<(c$.NBp?k!A]-/q=nIi#1t+j@*7.(`7"7U&9,\fBA)dOhNB*BG%R\-d8_:&,sdomT\c29;=/X4SA3W@e7$)5C11$<4P*2IUXOa'Wp*nJ;^,d)mOlF&T,2J/09u3m*ImS`VTUYmVo][Sn;bXiX,&A:UcS<$5F3iZ3KPiG9&@!PD:&lrjbl*5Q.d#>W`.Y00^-I+F'bW/5Y&4?JYOFPh+4uV<L.H=ABAGT-(>a`.WJ&nMEs]uD=2/KQI^7cZSmUn#*rk5$^sEAXdEqCQKe:Nil/shF0l3apk2*;9gY\1rW6N/I*R>q16T'p8iYrqPeSXlqsWumr$+4jl::8<^H/P-kI83T!S"Y9^dp-L&T*H1c5>c6mF_*^"N)8p$Ta#bNX"Yl+_\M+Y:hlsJK.9'nau\FH7+tTg.&lc&X*s7;cCJ3fbiCmqr0M)RfLI`[f?##6)1UmOG/$H^?2NR2/WR_?/iL;Oh52JC4^6i!V^sEET!+?hX,s9]GBA?q4)1RQEQo50s;tfmo7:P]-4@$U5t#C&Dip0[ZW?R0lMt?CsDP:*ZJZ:<u-_G(k5Al,MrASrZe/Am&f1[K7G7_][,Y;P@bE96F7oq&I*'079ZO60YV5hiLRE'3h)&V7g!m(`/`t\/tG/pK`pEL:AeKK0Q1SIfm/Vdl#asfM$=_rYO$FiUc\4,.9q@S7hR*L4U_!gS7R`sa;IV5o1."eAL.4lfIW-0)#cl_.g3TmB"Xs&3[7O.c"W8'a*otk+%A03V@BEND>>(JrQEnGFg9ro2N+iPc-dfsm+b;ilr<JSS!"9h9[s_h0l>Teb%&t<aTpL@D881d1rI:>CVup]XuZ<0c8FAhQ'FS%O*FpDd4+fP4<DFt3**53D`=2C(=2%.7`$A-I.\!ME\Qa$:)>IT[m['M<SKt5*7Dr;>-@L3LpRnXr]#6=QtE<A4o@\74E0t:09ESm@qGa+]_XisE<Q^~>endstream
|
||||
endobj
|
||||
71 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3237
|
||||
>>
|
||||
stream
|
||||
Gb"/)D/\/g')nJ00jbD][qf-r]=OW_9sU*SR\Yep_Z9c>>,#kNoi=Y-@iXpOhb\7"AA(%GmN$7$g4Ue51E;Q6cU3kGL`_fZDg;=)B/%"E5U;^KJ1-!NZYR(<SU<XFGtUR@1d_umcuiV*AQ-Eo=H+=m.>nb)Gp#\koCPpQbDW`.KP1[i\cCnEFG$^9quis:KB"U/q@7+e_!EGOmk]E]FD?u3Q9#D)<TVkbCZiShdSYhuMeb;c@hDu%>i)(ZSde7&#&^[#IMe_W<D'*;]8P;cLch+ObeBhaD)$VV7OXr"58W)j[,K/'=QHdk;ROtHX]kZOWENV,lNignn9>iZ$h=$q#geF7l\EN)j2H[Kn@X/VBcP%2$i"+cj$g$oG7q*2-t,;c1gG`u7Hdb,f]Y^pOE@4<-giq?$sZ1g"\mOiqX5e`BLoEYK-6YPW#HjeG>f[?bs$;,2&'j6&s5#<&/cYrMk<fks5Zl_\Z(FIMGp2I47Au']lI,$Y6hB$6#pPEWDc5<Bsb?cP3tsLoQ3Al#FeTq6g`YBfj`//R-?^s,V3b;quiobe4&s7\[OeB=gSO%78k<9cLZ:s2aP=?Rc+/$I)i]X8=(4r<N='__GoB;(T#Dq*h_9iC#.YFb:E-YVn66ABCOb!,5^9X?LE#b@;i&n.Uqja@G2Ac9CMV$6`PLn2Iq8bd#X?c6d-DHU$+mY<su#gf)$<Qr2&F<+%u]n2Cs1FWQ1Yi*M*0\//[g$o8BgNNZ:9f:JMT-;12P'%,2R7`d.o9b)-$++"Q&I;_S='bc&I'_$^*/^LmqfYO#CpDabFYj1/f2!,LJ(#OZ0Le-fOt:[>1&R>BI90<j%\.r<p^ZW!)D9c)fr_t?nd,&)#46_P3<XHW9<H+\kt:*s_JPEi_C@k2T:,bB%g-csMflq'aCA327=Qj%3,pf*&NFcW^nRjP5[R:Aa5m9%Sn%rt%$(Z3/fUSXR82LN4Df9o,cg*.<o=No#ZJa6`sW&TUA%>oYUIt*soL86=LJbnj4hbF`]r?reO[mLj3EoA1D&GNpU.pn4HG'bg0`?;nKX2%V1TiZR(3t7"9p+!:G<$46UX2%V15q4odTnB:a2OdrM=X\-N74juE?<n?;lHa;i?UKo.,+Y^ndp3&E(=]u_4iV)A^E=FWGoG3ro0=*#Z=*6sg^cl_+0mGQ=aQRBTtkl]^ORDj$jE^Iop75lb9RGGQis9HIc,1?8oYD^aAr%I's95a+Y*T-;V0kh&:QU\WZEND@jXe'a>mlr$rNuC:g</H9U[N!mMtUG"F<>hE()-q2mC"Vrpmj=J`e<BZbWUP@$?Z>C!N;0<5;3Cmg#Q!s4U6g(D]a[-i(C`)O)W]c'2GaLh[i>K9;DN&9pUI!kT\9'jO=q`'#t@>Y/"C3K6Lgi(AmS/%:r?oZ2G0&^oaF]],Ga:@&,Ncq9HI5ngZdA1,lHO!ZHY3&\0l>0"`q75sT?[N*P:iW$hEoQY+@FHJ]"lc@ufF;lk.1-JS#\%*(bG%07=S)7W6d!D4Lda4D"aRjg9rE&?gQi@gf^R[e5KCH%Mm+st(,;9u+m3lpi[!okZ`W7_SrH'oDI$aB0]M^6Sds?km,Uq=AY1G=W";5E>'Pq`WF#6csInFS48\-h%&\.5NG9*:X*r,]mp86_EUD`uHaA&OLIIb-CFcUs]^W(**>^d:l3<;HU?t&bba12d9;8S%nj@/PIU\6m/;MN#sZ<]86gCo2_J$/oH70SG=]a?;2Mp`lmb[uj(:_n'b>%*djFMSZJet-?-.YsPENme\0/fTbn_572CbZ[M3Z3=boX<+h]1U/-e4_9&0\3FJ<l4KFdQ23;AH%]G%s-32qaa-LPW$KmG.UkaX`H]Ls0YT,Q6];tHY"'jr=muk&NQ^Op!Vq&KoR"#4q$>hk`1gV#4X;$Aa3N+/MnIt/?H;R<:+mK5ZLMm`R:b5:N:mcu]T/&C(I/ft)]ZcF6]d"hT>K,a$oEO*"8$+SA+[PJ-33Yh*fIU`mh42b*K'A.k"ZPaSg4Z[mJ\Zqm]rC>=U>=A]DU-7`5n$=p50%OS@?uNFM<b?5fk8#+O,T^.jnc.'.;#L(MO9nhqrh"rjR%tF9L6@^eBdF_CY^LFS<_S\=&q"=Q/W7$ChrB^>3&Dq_BQraiM%J&.091:gbY?X!Dk*Qe4$rllXkN4"+K;TR^0G8<lOi8NRP0(u6#p7[C0GVUPqRAA\tS]Ku!<YuEe4R752iZLj1Xd.7gc&%EjMFKJM&pl8HU>Af:ki?sDKC:0mfpsXJ'b9?chW@^'DJAD9H&H^b.diWD?]71mOs-7DnerpirGkDblD#T_9][4,X%a]:pA/_;4]4>8=Len!W%qO%]:KlMsAguXeiL$QlB"Na>I!9!+`R/&CK9)q?IQct+ElGH`h_t!2O$&d9ZOHUn2tnsD49%lNrXlj$Cg:gq=YN?YoWKhI8NQElZ\,&GZ<9(&8Q%9?!ImPFbWoibMGLSM+H+8,=ME^p6l5T>pMe\q6<\dLdmu_#?GnZ5dYcglqYA./a+H?PKf8oKpbAZL"(!+/QMi+AJ90Fa=^"!V(bPV,Wrm)pSEM$1fIh+q]HCVrRN8DV\JjtC?p+8GS<JSE3T*"Hc9OU[Pru_Ke%$Sk0cg1dnEY<,mXdEdUpjF/8j70+B:.9:^`%7:4eC@SFRHGnZ0.-fI*SpDSrc.n&%D]`X`KT!`Y6P%//7Z=m!_`i(Om+n$oTBkH,u!(n$C^'6Zs4?Z2IhW_1R[))UI)g77bL,P77K6!An]8OIsl.#[O34MqnO/@r^YUE@GHP`Y-KseE*:GES;AEZ+*@CR+$9l2Oo0(P2f=.?++Mqhg[,rDLO07RaCt9,-Pm\i'c#t;_gop^`f^1.!^HZqgWYU>,$B`jZ<;lC<g;/B!"k?1,`5ck38C>a<0d)9<\99h[4ahKuodpmM=sNA9Xf42=Q6N<tC=`.X$sUNroZ;-#P4"TTD]BfjHAn,6D,gM1Z2Ij*AF8PDE&=eC8R=;1Bs6_4Q63L7s)'Qm^q0T@e7T*]`4]3%*l*?[me6oc2SW;$K6>\`99i^-02G5:S+c9Or%1npgH13q.2[j4Ck'W'4J%3WBcO@JY"#[ch04\2M"_#>IBH7=>^0+2N#=ZI?P]?Z;>s"SHo@$1cj2b^@"ArUCq@=Q9TYa*NY:"6iede9u?1^VVPhZ3[R.:JEf"6oJMVhW-knl+6e+Gk:_P0EZt/_H4+Yp6=MN&,aDdV=R=C@LS3/5pLm0$%<%A^r_'+706CT~>endstream
|
||||
endobj
|
||||
72 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3539
|
||||
>>
|
||||
stream
|
||||
Gb!#^D0+IA&cV3*Z/a,PSBI>[42n#I)8@N/8RfZ)4.WW<*_:r0`"YdqP\p*\[s(,q'LbkEU#nC!hjk2XG_gckYup?j!u6<mo`*r3_!)DVQPsNu$n%^9M@%2HE%sJ"3m^nPmCo;5RK\`9i#f+Ye'_Rm_l!_?%^L11/Q^=Wh1fFa!)?tno7>oTWm`o#qKk*AE9eifi*qa0/rm!#Uo)SuOHmUV.^-Q4/PakP$-P-3Ji0&Q?N[fIrm?Q]B)s::,7WT)'AO[<PKer6s5jb!^VfPRnVV8[Z[RmOk_cLrqn,X%XIZR"k^?UH@*4(&\@h$r?GM5Xl'qrL$u`tWOWQ3l$chX4aM1_jO9(>8&oI,XE#Z"a<uoUa%1nR\Mj!dVbJ1#jh0K;[]aQe-'B44D<u1PfIDl8K/E7Z8hseDL#>/?I9M:$'n*:Jh3;"TR81Mii^$W]H4t&=SG[<4aDKYQ]>!0e:p#FF#PWH%6G@7K$JcFjQ\=6,3fZH6sh9C`g.ju=:2gqa2C0HMN[o=%>RAi0+jp6"n#8j>4Y6I*h84Si)G"i^d5H"/J"oYuhi95nZ;pLQf]2SsNLsc;on:c1)0o(*]G9@0BpsG$c7$<tjE&@&t0O?4jD.:1<h'c;W]sqhrEfY6331EYlO3qMJY3t1`X`_X\@TdabGVBFa`Z)>OsgNYYR_=n!9C#BUquK3S+L3rR,tIsR/NG9/+'R#K'BNZj?0-OBk0rY5K,]blkuT"sadkI?_WWo=r/'kR.:H%1MT9bU4aHHq.VQ\j(2"bn:O/9)2!:81ngU21&FbM&;#nZPsgs%K?c[Wet8H_m@"D^k5VCT7CR-P185$?Le8QH[9U1Li.5-qP2EG$r[=qtX]N)K:SFS<G4lhLKRN_lma^S&s'i6t+','<s+\/e^Hs)5AK'0KdZgI0B>k:qJg='Y%;)k+T9RKc;A&8a(NbQdGp;&i!rhk5O>s2Q,e`LT#t]KJRXtMN_XcEB%OT:_a9EK=EtY\2uM]32L;J]GIngJ@8,e\:o=9UqAbB]K7ri<PmbbJ3Fiu9$R<Hf_]VB]RNj#D;?49$=)UDj`I"XmiSgLR/RJ[1E:kHNj\<cD$@XZ_r0hc5`J5V$^0ctkO-\o?n4^V5!:p\IXD+_Ycg=f8:Cs0?Z.&f-L0ot'(TaZL3n..U(O/_`5V9@(3eo."u.\a=4.^$+9*3]Y:(Q@C/gSGSsgB`Z_pjk;nEg]WN_mUmFNPl'p`X-3jhc\Q)El4W8/#nJei6'I7bRI)YUcBks/,C\mZJL(hooTMIYnRWN@C?[5F3!crKNHbDN.)+M6>K^aMSiY&3QW>CR==^o`[p>B&nH!h0VM`r3l<2"&s7idOUCA`KjVm.@rhDP`D[Zk'/rO?/&to"_/P3.@ZNG6Eg_4B'3<hB(;sEU&<n"ha`?92k4"(Q5K]QUb='?Z4m1:G"[_3bUn[4X'soTF,u&o8C@?>Z,U7ef@P)Vcb)5-9^JFM3USK\=r#[b(DTng/hkUN-7tX5u00;C1gKeGIISeN66c21MT"WG\0%4nt;hPZ(5!Bpt\tI&1\:F9WVgJipG#L'u\7Ik4*RUX7FoT/YQQP*jh>8q(/,ncDj"j\*MoriRi]WH-g.ejn">@O4&VUH-kp+G2$Hob@>bKqspE)XNG0;q]-k3C!]YlKTfD^q=dG->/.l29&,js6s%gpa=tVfK<,#-%D78VG-G7TbVUKibL6GU-HEd`'ek*E3s;e9_"BV@4`)cgiu;-1[4Ob:-+_\1lSI@.+E<l(G@@iA_CKuD$_)DXhUG1]fZH;F2I>[a<o/COn59M"rc^qV9f"TS'-n9O2$rqIpN=5ZR[F24rh>PLn'&on[\:42B(&Fe)RcNA[dEK(J8<73aJOS!OhI8[EUS^jA""cu*kJ@an5qg8<'5&slE/ZgHs-,XB[70<9'AAA(1?&LhFDsC=j7Wc@8b>b:O)YYN)]>[\f"bCAb?4cYep3@,doiQ/J8>a%.IQ7"M/C8OoS4P=TD0qY4ptCP;>`C"<Ms#(fo7[/p?p7b^@7S+1#\`:ARu75/-i;U0I?id=V8q9G7@A(o?KSLR8F^XHZW"9L=OpI7=_*BgMP-&i,LrB>G;!+KK$tGl].=A5QOgGh.C>!#^QscU8e\a=])S$6j3>+ka$mNElb@Y'bYU]/-h4d&3j/X:jO#r"76gIi.F@-'Jb,)!DV##rZCR&Hq/4!rA@Ap2sQ5JQ7P]"`Zkc#N5ep)A.?-G,=..OqVr"g<oXRH"0M4CDo\k3/%[6^/m1P-XKFH$c`1_UM0D?>9;)srqYqb<11\5Lf\f2heoU2G*0hrpXc.MX[P@0++`A4>:+/+mohoQUAS=42q-0l3*ZSjq`YG84kq+k58?3o1ek+-^Nkm#CI3;Id#*P"5B&Bo-1nM>Jfdb"<8VdjgL%5:2A(j,$0NG2.M?WLpl*/+DYZEMZ?^:![rKP4_/KY!U$o<)G=mpT`6RHqIa$`F0M[Y#[4ZKhgAV:aDomEkn#F4E_=?XF$a(cIlcigh#.uEM-)e'T)Zu#I;W.GrEM[_R>a@'`3cktR;"n%cZR*iW"f/I!CsKI?Z;-DD^^!W,[`u9BZpu=kHe*MDrE>aWP,pds7;,u_?\A;/U!HRPM(".7=WO\HmWaIV8OXj"MFW_'iuXdta"+DCmg5eF0g8Oq=VXSoH,Z[?$fMTbTG!ak38Nk&#uOh(fr(q,f7aO]h-^-K())>l9;&I#$<#%J?Yh/K=sgR00SDu:mih6K�="^#%Ok84(^)U1K<uLf!7$q),h/:hG[*?ASA7.17D]_oW$?HGjJ50;c9AUV_0YYcCC4#s'frQQj.Q\>3st(<:5C46WkU'IGd]cY/2_!Y8FpE[?!*hB<A7@A`&tnSJ=<?\"*PB:<QU*S_8q@)J1'@bV7Hn[@_QlN+Fs%$6I79i3:1'D+X9W/="8.72VrX"mu"WIJWo19Tlj!hEg0Bl))CA-*,_$ubTqAg5eDAS&#(V5p?!Lkf<m$(?AA;Rc#*-7lkI1A![XdoI,_CWiWFQ.p>a'RB+I\S\N->NJa=?J>Bc.]dNSXQr>Un^I;/X_=$&W/g02K8N^@4)ohS;D[i009:JQ&o:QLbHmZGTRH&El;^1P1hXkVGOB9+hdFal#!9`?#1)ulqOm12Y,Z9TSp.kSr]s/;"<J(V3[VNiH".I7&%L*&@g',`k-_NJcU)+ocK\<KhB]M&gmO@@eK,r0S;M60hI>@ON6uX34]>,@q?rq45<6\CG^7]^S@ke9#MN/2OKLfT2&%uj#'2H/$)TVLAJe)XT8Tl^0oFmtR&$?K(,tm_UM:qI9R-$fje\k'$3lbmgl$MZDP&YP=H'mhS72Yb^i%6a'TC46dij&hT9?p'."16*bG1Xs\:^F&$ae5LSFC+h;45K^YTaP(aNtu8ErXM1qGfoQZ7n^McqDC-0/>n50buUI1/Y*nSAk#M"ClFA6b[^[3!t\Ahd9$=7"/CK2A=S@a8C0:E(>Ai"QXHrVqlKAg=_kQPeIdf8>ob<rcr;&aRkq`Xn0PYEJA4@]Vg&>]TMr$H"f85&#d[LOo~>endstream
|
||||
endobj
|
||||
73 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 771
|
||||
>>
|
||||
stream
|
||||
Gat=(D,8n?&H88.E?@83NR(@iA:,;[9q.MpBs^Z,a@k?dO<tON^sAXDUhpkc&<kX6kBlVWh^\c9#ODD3"`TX?d5M2=ON[`Ri^7_rB8QBH@>ja[,,0Va&B9<T+bnRn]@mXK"CWn?dBh',FiHrPaU4-@ms4:UEZSqCWWe?YjkRYD]M.coV;[06&12&)+dE3n<+W)Z%*AW86#pV?XY4<M.b'AjY?JdT4>0D5Q:L*,93+\G3<<:,+=jkIj7tH3@$ERm@SnAn[=J^mm_f8R2-"\TikHB=OV=A%Ob*QlqHa@;>lkjY_Ip:3N?86(VjT(O.PDTj%hTDI*!6J/mJIM60ck9V4;Kc4J:mr]IC-@f@BFc^h\Qr\9Y_K*<!qamQI26=@\:&\=J5u!RtNXZ8+rrM3&&*maX3NanQk3[K%Sb;-ISj/-nu9dL,Al?hJ;d@8BY^@d'ruLES@9F4m&oXCV\p,fODVa&A&DiAR\?P)"IPUI@P_QFI/c331FOJO\RB?8%9R0dFI$V5]"KJEt?aCZW$W-PNu`5Ek9Jem$)-\B87V]-9L"qEhq/XXlLXQ^&.mAdU`1kN7@U+W8p<X$/@eLCe*_QEW*8Z4-)c\oE0dGp\ML7=46\P:fb1gYYkt[>!]dpoUfp1_fZOfC$]5M'NSr_)"=D_c>G.Km5PhT7@\ZS[-F^.7:fOPMO4ol.M9]h[".n:21*$<f2\gn?P`BVTt^/#n>o=VdEK"N5%53T'o9?sG$X4=3\)_U$<7\eY3oT'_#"M.$[hU~>endstream
|
||||
endobj
|
||||
xref
|
||||
0 74
|
||||
0000000000 65535 f
|
||||
0000000061 00000 n
|
||||
0000000146 00000 n
|
||||
0000000253 00000 n
|
||||
0000000365 00000 n
|
||||
0000000512 00000 n
|
||||
0000000659 00000 n
|
||||
0000000806 00000 n
|
||||
0000000954 00000 n
|
||||
0000001102 00000 n
|
||||
0000001249 00000 n
|
||||
0000001397 00000 n
|
||||
0000001545 00000 n
|
||||
0000001691 00000 n
|
||||
0000001839 00000 n
|
||||
0000001988 00000 n
|
||||
0000002136 00000 n
|
||||
0000002285 00000 n
|
||||
0000002433 00000 n
|
||||
0000002582 00000 n
|
||||
0000002730 00000 n
|
||||
0000002878 00000 n
|
||||
0000003027 00000 n
|
||||
0000003175 00000 n
|
||||
0000003323 00000 n
|
||||
0000003471 00000 n
|
||||
0000003620 00000 n
|
||||
0000003736 00000 n
|
||||
0000004108 00000 n
|
||||
0000004214 00000 n
|
||||
0000004363 00000 n
|
||||
0000004512 00000 n
|
||||
0000004661 00000 n
|
||||
0000004810 00000 n
|
||||
0000004894 00000 n
|
||||
0000004972 00000 n
|
||||
0000005121 00000 n
|
||||
0000005270 00000 n
|
||||
0000005530 00000 n
|
||||
0000005736 00000 n
|
||||
0000005942 00000 n
|
||||
0000006148 00000 n
|
||||
0000006354 00000 n
|
||||
0000006441 00000 n
|
||||
0000006763 00000 n
|
||||
0000006838 00000 n
|
||||
0000006940 00000 n
|
||||
0000007061 00000 n
|
||||
0000007222 00000 n
|
||||
0000007320 00000 n
|
||||
0000007425 00000 n
|
||||
0000007552 00000 n
|
||||
0000007662 00000 n
|
||||
0000007813 00000 n
|
||||
0000007926 00000 n
|
||||
0000008041 00000 n
|
||||
0000008169 00000 n
|
||||
0000008291 00000 n
|
||||
0000008399 00000 n
|
||||
0000008517 00000 n
|
||||
0000008623 00000 n
|
||||
0000008735 00000 n
|
||||
0000008862 00000 n
|
||||
0000008970 00000 n
|
||||
0000009090 00000 n
|
||||
0000009224 00000 n
|
||||
0000009343 00000 n
|
||||
0000009438 00000 n
|
||||
0000009534 00000 n
|
||||
0000010671 00000 n
|
||||
0000014579 00000 n
|
||||
0000018467 00000 n
|
||||
0000021796 00000 n
|
||||
0000025427 00000 n
|
||||
trailer
|
||||
<<
|
||||
/ID
|
||||
[<84821a2348f034264701e135e5d978bf><84821a2348f034264701e135e5d978bf>]
|
||||
% ReportLab generated PDF document -- digest (opensource)
|
||||
|
||||
/Info 43 0 R
|
||||
/Root 42 0 R
|
||||
/Size 74
|
||||
>>
|
||||
startxref
|
||||
26289
|
||||
%%EOF
|
||||
Reference in New Issue
Block a user